Trait nbdkit::Server

source ·
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§

source

fn get_size(&self) -> Result<i64>

Return the size in bytes of the exported block device

source

fn name() -> &'static strwhere Self: Sized,

The name of the plugin.

It must contain only ASCII alphanumeric characters and be unique amongst all plugins.

source

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.

source

fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<()>

Read data from the backing store, starting at offset.

The callback must read the entire range if it can. If it, it should return an error.

Provided Methods§

source

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.

source

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.

source

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.

source

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

source

fn can_flush(&self) -> Result<bool>

Indicate to the client wheter the plugin supports the flush-to-disk operation.

source

fn can_fast_zero(&self) -> Result<bool>

Indicate to the client whether the plugin supports fast-zero requests.

source

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.

source

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.

source

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.

source

fn can_write(&self) -> Result<bool>

Indicates to the client whether the plugin supports writes

source

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.

source

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.

source

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.

source

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.

source

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.

source

fn description() -> Option<&'static str>where Self: Sized,

An optional multi-line description of the plugin.

source

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.

source

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.

source

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.

source

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.

source

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.

source

fn longname() -> Option<&'static str>where Self: Sized,

An optional free text name of the plugin. This field is used in error messages.

source

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.

source

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.

source

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).

source

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.

source

fn unload()where Self: Sized,

This may be called once just before the plugin is unloaded from memory.

source

fn version() -> Option<&'static str>where Self: Sized,

An optional version string which is displayed in help and debugging output.

source

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.

source

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

Implementors§