pub trait Server {
Show 34 methods
// Required methods
fn get_size(&self) -> Result<i64>;
fn name() -> &'static str
where Self: Sized;
fn open(readonly: bool) -> Result<Box<dyn Server>>
where Self: Sized;
fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<()>;
// Provided methods
fn after_fork() -> Result<()>
where Self: Sized { ... }
fn cache(&self, count: u32, offset: u64) -> Result<()> { ... }
fn can_cache(&self) -> Result<CacheFlags> { ... }
fn can_extents(&self) -> Result<bool> { ... }
fn can_flush(&self) -> Result<bool> { ... }
fn can_fast_zero(&self) -> Result<bool> { ... }
fn can_fua(&self) -> Result<FuaFlags> { ... }
fn can_multi_conn(&self) -> Result<bool> { ... }
fn can_trim(&self) -> Result<bool> { ... }
fn can_write(&self) -> Result<bool> { ... }
fn can_zero(&self) -> Result<bool> { ... }
fn config(key: &str, value: &str) -> Result<()>
where Self: Sized { ... }
fn config_complete() -> Result<()>
where Self: Sized { ... }
fn dump_plugin()
where Self: Sized { ... }
fn config_help() -> Option<&'static str>
where Self: Sized { ... }
fn description() -> Option<&'static str>
where Self: Sized { ... }
fn extents(
&self,
count: u32,
offset: u64,
flags: Flags,
extent_handle: &mut ExtentHandle
) -> Result<()> { ... }
fn flush(&self) -> Result<()> { ... }
fn get_ready() -> Result<()>
where Self: Sized { ... }
fn is_rotational(&self) -> Result<bool> { ... }
fn load()
where Self: Sized { ... }
fn longname() -> Option<&'static str>
where Self: Sized { ... }
fn magic_config_key() -> Option<&'static str>
where Self: Sized { ... }
fn preconnect(readonly: bool) -> Result<()>
where Self: Sized { ... }
fn thread_model() -> Result<ThreadModel>
where Self: Sized { ... }
fn trim(&self, count: u32, offset: u64, flags: Flags) -> Result<()> { ... }
fn unload()
where Self: Sized { ... }
fn version() -> Option<&'static str>
where Self: Sized { ... }
fn write_at(&self, buf: &[u8], offset: u64, flags: Flags) -> Result<()> { ... }
fn zero(&self, count: u32, offset: u64, flags: Flags) -> Result<()> { ... }
}
Expand description
Define the entry point for your plugin.
Any of the optional methods may be implemented. If so, each must be
registered with plugin!
. It is an error to register any method that you
don’t implement.
Required Methods§
sourcefn name() -> &'static strwhere
Self: Sized,
fn name() -> &'static strwhere Self: Sized,
The name of the plugin.
It must contain only ASCII alphanumeric characters and be unique amongst all plugins.
sourcefn open(readonly: bool) -> Result<Box<dyn Server>>where
Self: Sized,
fn open(readonly: bool) -> Result<Box<dyn Server>>where Self: Sized,
Allocate and return a new Server
handle to the client.
Called whenever a new client connects to the server. The readonly
flag informs the plugin that the server was started with the -r flag on
the command line which forces connections to be read-only. Note that the
plugin may additionally force the connection to be readonly (even if
this flag is false) by returning false from the Server::can_write
callback. So if your plugin can only serve read-only, you can ignore
this parameter.
Provided Methods§
sourcefn after_fork() -> Result<()>where
Self: Sized,
fn after_fork() -> Result<()>where Self: Sized,
This optional callback is called before the server starts serving.
It is called after the server forks and changes directory. If a plugin needs to create background threads it should do so here.
sourcefn cache(&self, count: u32, offset: u64) -> Result<()>
fn cache(&self, count: u32, offset: u64) -> Result<()>
Indicates that the client intends to make further accesses to the given data region.
The nature of caching is not specified further by the NBD specification
(for example, a server may place limits on how much may be cached at
once, and there is no way to control if writes to a cached area have
write-through or write-back semantics). In fact, the cache command can
always fail and still be compliant, and success might not guarantee a
performance gain. If this callback is omitted, then the results of
Server::can_cache
determine whether nbdkit will reject cache
requests, treat them as instant success, or emulate caching by calling
[Server::pread
over the same region and ignoring the results.
sourcefn can_cache(&self) -> Result<CacheFlags>
fn can_cache(&self) -> Result<CacheFlags>
Indicate level of cacheing support to the client.
This is called during the option negotiation phase to find out if the plugin supports a cache operation. The nature of the caching is unspecified (including whether there are limits on how much can be cached at once, and whether writes to a cached region have write-through or write-back semantics), but the command exists to let clients issue a hint to the server that they will be accessing that region of the export.
sourcefn can_extents(&self) -> Result<bool>
fn can_extents(&self) -> Result<bool>
Indicate to the client whether the plugin supports detecting allocated
(non-sparse) regions of the disk with the Server::extents
sourcefn can_flush(&self) -> Result<bool>
fn can_flush(&self) -> Result<bool>
Indicate to the client wheter the plugin supports the flush-to-disk operation.
sourcefn can_fast_zero(&self) -> Result<bool>
fn can_fast_zero(&self) -> Result<bool>
Indicate to the client whether the plugin supports fast-zero requests.
sourcefn can_fua(&self) -> Result<FuaFlags>
fn can_fua(&self) -> Result<FuaFlags>
Indicate to the client whether the plugin supports Forced Unit Access (FUA) flag on write, trim, and zero requests.
If this callback is not implemented, then nbdkit checks whether
Server::flush
is implemented,
exists, and behaves as if this function returns FuaFlags::None
or
FuaFlags::Emulate
as appropriate.
sourcefn can_multi_conn(&self) -> Result<bool>
fn can_multi_conn(&self) -> Result<bool>
Indicate to the client whether the plugin is prepared to handle multiple connections from a single client.
If thie method returns true
then a
client may try to open multiple connections to the nbdkit server and
spread requests across all connections to maximize parallelism. If it
returns false
false (which is the default) then well-behaved clients
should only open a single connection, although we cannot control what
clients do in practice.
Specifically it means that either the plugin does not cache requests at
all, or if it does cache them then the effects of a Server::flush
request or setting Flags::FUA
on a write/trim/zero must be visible
across all connections to the plugin before the plugin replies to that
request.
sourcefn can_trim(&self) -> Result<bool>
fn can_trim(&self) -> Result<bool>
Indicate to the client whether the plugin supports the trim/discard operation for punching holes in the backing store.
sourcefn can_zero(&self) -> Result<bool>
fn can_zero(&self) -> Result<bool>
Indicates to the client whether the Server::zero
callback should be
used.
Support for writing zeroes is still advertised to the client, so
returning false merely serves as a way to avoid complicating the
Server::zero
callback to have to fail with ENOTSUP
or
EOPNOTSUPP
on the connections where it will never be more efficient
than using Server::write_at
up front.
sourcefn config(key: &str, value: &str) -> Result<()>where
Self: Sized,
fn config(key: &str, value: &str) -> Result<()>where Self: Sized,
Supplies command-line parameters, one at a time, to the plugin.
On the nbdkit command line, after the plugin filename, come an optional list of key=value arguments. These are passed to the plugin through this callback when the plugin is first loaded and before any connections are accepted.
This callback may be called zero or more times.
The key will be a non-empty string beginning with an ASCII alphabetic character (A-Z a-z). The rest of the key must contain only ASCII alphanumeric plus period, underscore or dash characters (A-Z a-z 0-9 . _ -). The value may be an arbitrary string, including an empty string.
The names of keys accepted by plugins is up to the plugin, but you should probably look at other plugins and follow the same conventions.
sourcefn config_complete() -> Result<()>where
Self: Sized,
fn config_complete() -> Result<()>where Self: Sized,
This optional callback is called after all the configuration has been passed to the plugin.
It is a good place to do checks, for example that the user has passed the required parameters to the plugin.
sourcefn dump_plugin()where
Self: Sized,
fn dump_plugin()where Self: Sized,
This optional callback is called when the nbdkit plugin --dump-plugin
command is used. It should print any additional informative key=value
fields to stdout as needed. Prefixing the keys with the name of the
plugin will avoid conflicts.
sourcefn config_help() -> Option<&'static str>where
Self: Sized,
fn config_help() -> Option<&'static str>where Self: Sized,
This optional multi-line help message should summarize any key=value
parameters that it takes. It does not need to repeat what already
appears in Server::description
.
sourcefn description() -> Option<&'static str>where
Self: Sized,
fn description() -> Option<&'static str>where Self: Sized,
An optional multi-line description of the plugin.
sourcefn extents(
&self,
count: u32,
offset: u64,
flags: Flags,
extent_handle: &mut ExtentHandle
) -> Result<()>
fn extents( &self, count: u32, offset: u64, flags: Flags, extent_handle: &mut ExtentHandle ) -> Result<()>
During the data serving phase, this callback is used to detect allocated, sparse and zeroed regions of the disk.
This function will not be called if Server::can_extents
returned false
.
nbdkit’s default behaviour in this case is to treat the whole virtual
disk as if it were allocated. Also, this function will not be called by
a client that does not request structured replies (the --no-sr
option
of nbdkit can be used to test behavior when extents
is unavailable to
the client).
The callback should detect and return the list of extents overlapping
the range [offset...offset+count)
. Each extent should be reported
by calling ExtentHandle::add
.
The flags parameter of the extents
callback may contain
Flags::REQ_ONE
. This means that the client is only requesting
information about the extent overlapping offset
. The plugin may ignore
this flag, or as an optimization it may return just a single extent for
offset.
sourcefn flush(&self) -> Result<()>
fn flush(&self) -> Result<()>
During the data serving phase, this callback is used to sync the backing store, ie. to ensure it has been completely written to a permanent medium. If that is not possible then you can omit this callback.
This function will not be called directly by the client if
Server::can_flush
returned false
; however, it may still be called
by nbdkit if Server::can_fua
returned FuaFlags::Emulate
.
sourcefn get_ready() -> Result<()>where
Self: Sized,
fn get_ready() -> Result<()>where Self: Sized,
This optional callback is called before the server starts serving.
It is called before the server forks or changes directory. It is the last chance to do any global preparation that is needed to serve connections.
sourcefn is_rotational(&self) -> Result<bool>
fn is_rotational(&self) -> Result<bool>
Return true
if the backing store is a rotational medium (like a
traditional hard disk) as opposed to a non-rotating one like an SSD.
This may cause the client to reorder requests to make them more efficient for a slow rotating disk.
sourcefn load()where
Self: Sized,
fn load()where Self: Sized,
This is called once just after the plugin is loaded into memory. You can use this to perform any global initialization needed by the plugin.
sourcefn longname() -> Option<&'static str>where
Self: Sized,
fn longname() -> Option<&'static str>where Self: Sized,
An optional free text name of the plugin. This field is used in error messages.
sourcefn magic_config_key() -> Option<&'static str>where
Self: Sized,
fn magic_config_key() -> Option<&'static str>where Self: Sized,
This optional string can be used to set a “magic” key used when parsing plugin parameters. It affects how “bare parameters” (those which do not contain an = character) are parsed on the command line.
If magic_config_key().is_some()
then any bare parameters are passed to
the Server::config
method as: config (magic_config_key, argv[i]);
.
If magic_config_key().is_none()
then we behave as in nbdkit < 1.7: If
the first parameter on the command line is bare then it is passed to the
Server::config
method as: config("script", value);
. Any other bare
parameters give errors.
sourcefn preconnect(readonly: bool) -> Result<()>where
Self: Sized,
fn preconnect(readonly: bool) -> Result<()>where Self: Sized,
This optional callback is called when a TCP connection has been made to the server. This happens early, before NBD or TLS negotiation. If TLS authentication is required to access the server, then it has not been negotiated at this point.
For security reasons (to avoid denial of service attacks) this callback
should be written to be as fast and take as few resources as possible.
If you use this callback, only use it to do basic access control, such
as checking
peername
against a whitelist. It may be better to do access control outside the
server, for example using TCP wrappers or a firewall.
The readonly
flag informs the plugin that the server was started with
the -r
flag on the command line.
Returning Ok(())
will allow the connection to continue. If there is an
error or you want to deny the connection, return an error.
sourcefn thread_model() -> Result<ThreadModel>where
Self: Sized,
fn thread_model() -> Result<ThreadModel>where Self: Sized,
This optional callback is called after all the configuration has been passed to the plugin.
It can be used to force a stricter thread model than the default
(ThreadModel::Parallel
).
sourcefn trim(&self, count: u32, offset: u64, flags: Flags) -> Result<()>
fn trim(&self, count: u32, offset: u64, flags: Flags) -> Result<()>
Punch a hole in the backing store.
This function will not be called if Server::can_trim
returned
false
. The parameter flags may include Flags::FUA
on input based on
the result of Server::can_fua
.
sourcefn unload()where
Self: Sized,
fn unload()where Self: Sized,
This may be called once just before the plugin is unloaded from memory.
sourcefn version() -> Option<&'static str>where
Self: Sized,
fn version() -> Option<&'static str>where Self: Sized,
An optional version string which is displayed in help and debugging output.
sourcefn write_at(&self, buf: &[u8], offset: u64, flags: Flags) -> Result<()>
fn write_at(&self, buf: &[u8], offset: u64, flags: Flags) -> Result<()>
Write data to the backing store.
The flags
argument may include Flags::FUA
based on the result of
Server::can_fua
.
The callback must write the entire range if it can. If it, it should return an error.
sourcefn zero(&self, count: u32, offset: u64, flags: Flags) -> Result<()>
fn zero(&self, count: u32, offset: u64, flags: Flags) -> Result<()>
Write consecutive zeros to the backing store.
The callback must write the whole region if it can. The NBD protocol doesn’t allow partial writes (instead, these are errors).
If this callback is omitted, or if it fails with ENOTSUP
or
EOPNOTSUPP
, then Server::write_at
will be used as an
automatic fallback except when the client requested a fast zero.
Arguments
count
: Length of the region to write in bytesoffset
: Offset of the region to write in the backing store.flags
: May includeFlags::MAY_TRIM
,Flags::FAST_ZERO
, and/orFlags::FUA
.