Scroll to navigation

NBD(3) NBD(3)

NAME

NBD - OCaml bindings for libnbd.

Module

Module NBD

Documentation

Module NBD
: sig end

OCaml bindings for libnbd.

For full documentation see libnbd-ocaml(3) and libnbd(3).

For examples written in OCaml see the libnbd source code ocaml/examples subdirectory.

exception Error of string * int

Exception thrown when an API call fails.

The string is the error message, and the int is the raw errno (if available).

exception Closed of string

Exception thrown if you call a closed handle.

type cookie = int64

module TLS : sig end

module SIZE : sig end

module CMD_FLAG : sig end

module HANDSHAKE_FLAG : sig end

module STRICT : sig end

module ALLOW_TRANSPORT : sig end

module SHUTDOWN : sig end

val aio_direction_read : int32

val aio_direction_write : int32

val aio_direction_both : int32

val read_data : int32

val read_hole : int32

val read_error : int32

val namespace_base : string

val context_base_allocation : string

val state_hole : int32

val state_zero : int32

module Buffer : sig end

Persistent buffer used in AIO calls.

type t

The handle.

val create : unit -> t

Create a new handle.

val close : t -> unit

Close a handle.

Handles can also be closed by the garbage collector when they become unreachable. This call is used only if you want to force the handle to close now and reclaim resources immediately.

val set_debug : t -> bool -> unit

set or clear the debug flag

Set or clear the debug flag. When debugging is enabled, debugging messages from the library are printed to stderr, unless a debugging callback has been defined too (see nbd_set_debug_callback(3)) in which case they are sent to that function. This flag defaults to false on newly created handles, except if "LIBNBD_DEBUG=1" is set in the environment in which case it defaults to true.

val get_debug : t -> bool

return the state of the debug flag

Return the state of the debug flag on this handle.

val set_debug_callback : t -> (string -> string -> int) -> unit

set the debug callback

Set the debug callback. This function is called when the library emits debug messages, when debugging is enabled on a handle. The callback parameters are "user_data" passed to this function, the name of the libnbd function emitting the debug message ("context"), and the message itself ("msg"). If no debug callback is set on a handle then messages are printed on "stderr".

The callback should not call "nbd_*" APIs on the same handle since it can be called while holding the handle lock and will cause a deadlock.

val clear_debug_callback : t -> unit

clear the debug callback

Remove the debug callback if one was previously associated with the handle (with nbd_set_debug_callback(3)). If no callback was associated this does nothing.

val set_handle_name : t -> string -> unit

set the handle name

Handles have a name which is unique within the current process. The handle name is used in debug output.

Handle names are normally generated automatically and have the form "nbd1", "nbd2", etc., but you can optionally use this call to give the handles a name which is meaningful for your application to make debugging output easier to understand.

val get_handle_name : t -> string

get the handle name

Get the name of the handle. If it was previously set by calling nbd_set_handle_name(3) then this returns the name that was set. Otherwise it will return a generic name like "nbd1", "nbd2", etc.

val set_export_name : t -> string -> unit

set the export name

For servers which require an export name or can serve different content on different exports, set the "export_name" to connect to. The default is the empty string "".

This is only relevant when connecting to servers using the newstyle protocol as the oldstyle protocol did not support export names. The NBD protocol limits export names to 4096 bytes, but servers may not support the full length. The encoding of export names is always UTF-8.

When option mode is not in use, the export name must be set before beginning a connection. However, when nbd_set_opt_mode(3) has enabled option mode, it is possible to change the export name prior to nbd_opt_go(3). In particular, the use of nbd_opt_list(3) during negotiation can be used to determine a name the server is likely to accept, and nbd_opt_info(3) can be used to learn details about an export before connecting.

This call may be skipped if using nbd_connect_uri(3) to connect to a URI that includes an export name.

val get_export_name : t -> string

get the export name

Get the export name associated with the handle. This is the name that libnbd requests; see nbd_get_canonical_export_name(3) for determining if the server has a different canonical name for the given export (most common when requesting the default export name of an empty string "")

val set_full_info : t -> bool -> unit

control whether NBD_OPT_GO requests extra details

By default, when connecting to an export, libnbd only requests the details it needs to service data operations. The NBD protocol says that a server can supply optional information, such as a canonical name of the export (see nbd_get_canonical_export_name(3)) or a description of the export (see nbd_get_export_description(3)), but that a hint from the client makes it more likely for this extra information to be provided. This function controls whether libnbd will provide that hint.

Note that even when full info is requested, the server is not obligated to reply with all information that libnbd requested. Similarly, libnbd will ignore any optional server information that libnbd has not yet been taught to recognize.

val get_full_info : t -> bool

see if NBD_OPT_GO requests extra details

Return the state of the full info request flag on this handle.

val get_canonical_export_name : t -> string

return the canonical export name, if the server has one

The NBD protocol permits a server to report an optional canonical export name, which may differ from the client's request (as set by nbd_set_export_name(3) or nbd_connect_uri(3)). This function accesses any name returned by the server; it may be the same as the client request, but is more likely to differ when the client requested a connection to the default export name (an empty string "").

Some servers are unlikely to report a canonical name unless the client specifically hinted about wanting it, via nbd_set_full_info(3).

val get_export_description : t -> string

return the export description, if the server has one

The NBD protocol permits a server to report an optional export description. This function reports any description returned by the server.

Some servers are unlikely to report a description unless the client specifically hinted about wanting it, via nbd_set_full_info(3). For qemu-nbd(8), a description is set with *-D*.

val set_tls : t -> TLS.t -> unit

enable or require TLS (authentication and encryption)

Enable or require TLS (authenticated and encrypted connections) to the NBD server. The possible settings are:

"LIBNBD_TLS_DISABLE" Disable TLS. (The default setting, unless using nbd_connect_uri(3) with a URI that requires TLS)

"LIBNBD_TLS_ALLOW" Enable TLS if possible.

This option is insecure (or best effort) in that in some cases it will fall back to an unencrypted and/or unauthenticated connection if TLS could not be established. Use "LIBNBD_TLS_REQUIRE" below if the connection must be encrypted.

Some servers will drop the connection if TLS fails so fallback may not be possible.

"LIBNBD_TLS_REQUIRE" Require an encrypted and authenticated TLS connection. Always fail to connect if the connection is not encrypted and authenticated.

As well as calling this you may also need to supply the path to the certificates directory (nbd_set_tls_certificates(3)), the username (nbd_set_tls_username(3)) and/or the Pre-Shared Keys (PSK) file (nbd_set_tls_psk_file(3)). For now, when using nbd_connect_uri(3), any URI query parameters related to TLS are not handled automatically. Setting the level higher than zero will fail if libnbd was not compiled against gnutls; you can test whether this is the case with nbd_supports_tls(3).

val get_tls : t -> TLS.t

get the TLS request setting

Get the TLS request setting.

Note: If you want to find out if TLS was actually negotiated on a particular connection use nbd_get_tls_negotiated(3) instead.

val get_tls_negotiated : t -> bool

find out if TLS was negotiated on a connection

After connecting you may call this to find out if the connection is using TLS.

This is only really useful if you set the TLS request mode to "LIBNBD_TLS_ALLOW" (see nbd_set_tls(3)), because in this mode we try to use TLS but fall back to unencrypted if it was not available. This function will tell you if TLS was negotiated or not.

In "LIBNBD_TLS_REQUIRE" mode (the most secure) the connection would have failed if TLS could not be negotiated, and in "LIBNBD_TLS_DISABLE" mode TLS is not tried.

val set_tls_certificates : t -> string -> unit

set the path to the TLS certificates directory

Set the path to the TLS certificates directory. If not set and TLS is used then a compiled in default is used. For root this is "/etc/pki/libnbd/". For non-root this is "$HOME/.pki/libnbd" and "$HOME/.config/pki/libnbd". If none of these directories can be found then the system trusted CAs are used.

This function may be called regardless of whether TLS is supported, but will have no effect unless nbd_set_tls(3) is also used to request or require TLS.

val set_tls_verify_peer : t -> bool -> unit

set whether we verify the identity of the server

Set this flag to control whether libnbd will verify the identity of the server from the server's certificate and the certificate authority. This defaults to true when connecting to TCP servers using TLS certificate authentication, and false otherwise.

This function may be called regardless of whether TLS is supported, but will have no effect unless nbd_set_tls(3) is also used to request or require TLS.

val get_tls_verify_peer : t -> bool

get whether we verify the identity of the server

Get the verify peer flag.

val set_tls_username : t -> string -> unit

set the TLS username

Set the TLS client username. This is used if authenticating with PSK over TLS is enabled. If not set then the local username is used.

This function may be called regardless of whether TLS is supported, but will have no effect unless nbd_set_tls(3) is also used to request or require TLS.

val get_tls_username : t -> string

get the current TLS username

Get the current TLS username.

val set_tls_psk_file : t -> string -> unit

set the TLS Pre-Shared Keys (PSK) filename

Set the TLS Pre-Shared Keys (PSK) filename. This is used if trying to authenticate to the server using with a pre-shared key. There is no default so if this is not set then PSK authentication cannot be used to connect to the server.

This function may be called regardless of whether TLS is supported, but will have no effect unless nbd_set_tls(3) is also used to request or require TLS.

val set_request_structured_replies : t -> bool -> unit

control use of structured replies

By default, libnbd tries to negotiate structured replies with the server, as this protocol extension must be in use before nbd_can_meta_context(3) or nbd_can_df(3) can return true. However, for integration testing, it can be useful to clear this flag rather than find a way to alter the server to fail the negotiation request.

val get_request_structured_replies : t -> bool

see if structured replies are attempted

Return the state of the request structured replies flag on this handle.

Note: If you want to find out if structured replies were actually negotiated on a particular connection use nbd_get_structured_replies_negotiated(3) instead.

val get_structured_replies_negotiated : t -> bool

see if structured replies are in use

After connecting you may call this to find out if the connection is using structured replies.

val set_handshake_flags : t -> HANDSHAKE_FLAG.t list -> unit

control use of handshake flags

By default, libnbd tries to negotiate all possible handshake flags that are also supported by the server, since omitting a handshake flag can prevent the use of other functionality such as TLS encryption or structured replies. However, for integration testing, it can be useful to reduce the set of flags supported by the client to test that a particular server can handle various clients that were compliant to older versions of the NBD specification.

The "flags" argument is a bitmask, including zero or more of the following handshake flags:

"LIBNBD_HANDSHAKE_FLAG_FIXED_NEWSTYLE" = 1 The server gracefully handles unknown option requests from the client, rather than disconnecting. Without this flag, a client cannot safely request to use extensions such as TLS encryption or structured replies, as the request may cause an older server to drop the connection.

"LIBNBD_HANDSHAKE_FLAG_NO_ZEROES" = 2 If the client is forced to use "NBD_OPT_EXPORT_NAME" instead of the preferred "NBD_OPT_GO", this flag allows the server to send fewer all-zero padding bytes over the connection.

For convenience, the constant "LIBNBD_HANDSHAKE_FLAG_MASK" is available to describe all flags supported by this build of libnbd. Future NBD extensions may add further flags, which in turn may be enabled by default in newer libnbd. As such, when attempting to disable only one specific bit, it is wiser to first call nbd_get_handshake_flags(3) and modify that value, rather than blindly setting a constant value.

val get_handshake_flags : t -> HANDSHAKE_FLAG.t list

see which handshake flags are supported

Return the state of the handshake flags on this handle. When the handle has not yet completed a connection (see nbd_aio_is_created(3)), this returns the flags that the client is willing to use, provided the server also advertises those flags. After the connection is ready (see nbd_aio_is_ready(3)), this returns the flags that were actually agreed on between the server and client. If the NBD protocol defines new handshake flags, then the return value from a newer library version may include bits that were undefined at the time of compilation.

val set_strict_mode : t -> STRICT.t list -> unit

control how strictly to follow NBD protocol

By default, libnbd tries to detect requests that would trigger undefined behavior in the NBD protocol, and rejects them client side without causing any network traffic, rather than risking undefined server behavior. However, for integration testing, it can be handy to relax the strictness of libnbd, to coerce it into sending such requests over the network for testing the robustness of the server in dealing with such traffic.

The "flags" argument is a bitmask, including zero or more of the following strictness flags:

"LIBNBD_STRICT_COMMANDS" = 1 If set, this flag rejects client requests that do not comply with the set of advertised server flags (for example, attempting a write on a read-only server, or attempting to use "LIBNBD_CMD_FLAG_FUA" when nbd_can_fua(3) returned false). If clear, this flag relies on the server to reject unexpected commands.

"LIBNBD_STRICT_FLAGS" = 2 If set, this flag rejects client requests that attempt to set a command flag not recognized by libnbd (those outside of "LIBNBD_CMD_FLAG_MASK"), or a flag not normally associated with a command (such as using "LIBNBD_CMD_FLAG_FUA" on a read command). If clear, all flags are sent on to the server, even if sending such a flag may cause the server to change its reply in a manner that confuses libnbd, perhaps causing deadlock or ending the connection.

Flags that are known by libnbd as associated with a given command (such as "LIBNBD_CMD_FLAG_DF" for nbd_pread_structured(3) gated by nbd_can_df(3)) are controlled by "LIBNBD_STRICT_COMMANDS" instead.

Note that the NBD protocol only supports 16 bits of command flags, even though the libnbd API uses "uint32_t"; bits outside of the range permitted by the protocol are always a client-side error.

"LIBNBD_STRICT_BOUNDS" = 3 If set, this flag rejects client requests that would exceed the export bounds without sending any traffic to the server. If clear, this flag relies on the server to detect out-of-bounds requests.

"LIBNBD_STRICT_ZERO_SIZE" = 4 If set, this flag rejects client requests with length 0. If clear, this permits zero-length requests to the server, which may produce undefined results.

"LIBNBD_STRICT_ALIGN" = 5 If set, and the server provided minimum block sizes (see nbd_get_block_size(3), this flag rejects client requests that do not have length and offset aligned to the server's minimum requirements. If clear, unaligned requests are sent to the server, where it is up to the server whether to honor or reject the request.

For convenience, the constant "LIBNBD_STRICT_MASK" is available to describe all strictness flags supported by this build of libnbd. Future versions of libnbd may add further flags, which are likely to be enabled by default for additional client-side filtering. As such, when attempting to relax only one specific bit while keeping remaining checks at the client side, it is wiser to first call nbd_get_strict_mode(3) and modify that value, rather than blindly setting a constant value.

val get_strict_mode : t -> STRICT.t list

see which strictness flags are in effect

Return flags indicating which protocol strictness items are being enforced locally by libnbd rather than the server. The return value from a newer library version may include bits that were undefined at the time of compilation.

val set_opt_mode : t -> bool -> unit

control option mode, for pausing during option negotiation

Set this flag to true in order to request that a connection command "nbd_connect_*" will pause for negotiation options rather than proceeding all the way to the ready state, when communicating with a newstyle server. This setting has no effect when connecting to an oldstyle server.

When option mode is enabled, you have fine-grained control over which options are negotiated, compared to the default of the server negotiating everything on your behalf using settings made before starting the connection. To leave the mode and proceed on to the ready state, you must use nbd_opt_go(3) successfully; a failed nbd_opt_go(3) returns to the negotiating state to allow a change of export name before trying again. You may also use nbd_opt_abort(3) to end the connection without finishing negotiation.

val get_opt_mode : t -> bool

return whether option mode was enabled

Return true if option negotiation mode was enabled on this handle.

val opt_go : t -> unit

end negotiation and move on to using an export

Request that the server finish negotiation and move on to serving the export previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

If this fails, the server may still be in negotiation, where it is possible to attempt another option such as a different export name; although older servers will instead have killed the connection.

val opt_abort : t -> unit

end negotiation and close the connection

Request that the server finish negotiation, gracefully if possible, then close the connection. This can only be used if nbd_set_opt_mode(3) enabled option mode.

val opt_list : t -> (string -> string -> int) -> int

request the server to list all exports during negotiation

Request that the server list all exports that it supports. This can only be used if nbd_set_opt_mode(3) enabled option mode.

The "list" function is called once per advertised export, with any "user_data" passed to this function, and with "name" and "description" supplied by the server. Many servers omit descriptions, in which case "description" will be an empty string. Remember that it is not safe to call nbd_set_export_name(3) from within the context of the callback function; rather, your code must copy any "name" needed for later use after this function completes. At present, the return value of the callback is ignored, although a return of -1 should be avoided.

For convenience, when this function succeeds, it returns the number of exports that were advertised by the server.

Not all servers understand this request, and even when it is understood, the server might intentionally send an empty list to avoid being an information leak, may encounter a failure after delivering partial results, or may refuse to answer more than one query per connection in the interest of avoiding negotiation that does not resolve. Thus, this function may succeed even when no exports are reported, or may fail but have a non-empty list. Likewise, the NBD protocol does not specify an upper bound for the number of exports that might be advertised, so client code should be aware that a server may send a lengthy list.

For nbd-server(1) you will need to allow clients to make list requests by adding "allowlist=true" to the " generic " section of /etc/nbd-server/config. For qemu-nbd(8), a description is set with *-D*.

val opt_info : t -> unit

request the server for information about an export

Request that the server supply information about the export name previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

If successful, functions like nbd_is_read_only(3) and nbd_get_size(3) will report details about that export. In general, if nbd_opt_go(3) is called next, that call will likely succeed with the details remaining the same, although this is not guaranteed by all servers.

Not all servers understand this request, and even when it is understood, the server might fail the request even when a corresponding nbd_opt_go(3) would succeed.

val opt_list_meta_context : t -> (string -> int) -> int

request the server to list available meta contexts

Request that the server list available meta contexts associated with the export previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

The NBD protocol allows a client to decide how many queries to ask the server. Rather than taking that list of queries as a parameter to this function, libnbd reuses the current list of requested meta contexts as set by nbd_add_meta_context(3); you can use nbd_clear_meta_contexts(3) to set up a different list of queries. When the list is empty, a server will typically reply with all contexts that it supports; when the list is non-empty, the server will reply only with supported contexts that match the client's request. Note that a reply by the server might be encoded to represent several feasible contexts within one string, rather than multiple strings per actual context name that would actually succeed during nbd_opt_go(3); so it is still necessary to use nbd_can_meta_context(3) after connecting to see which contexts are actually supported.

The "context" function is called once per server reply, with any "user_data" passed to this function, and with "name" supplied by the server. Remember that it is not safe to call nbd_add_meta_context(3) from within the context of the callback function; rather, your code must copy any "name" needed for later use after this function completes. At present, the return value of the callback is ignored, although a return of -1 should be avoided.

For convenience, when this function succeeds, it returns the number of replies returned by the server.

Not all servers understand this request, and even when it is understood, the server might intentionally send an empty list because it does not support the requested context, or may encounter a failure after delivering partial results. Thus, this function may succeed even when no contexts are reported, or may fail but have a non-empty list. Likewise, the NBD protocol does not specify an upper bound for the number of replies that might be advertised, so client code should be aware that a server may send a lengthy list.

val add_meta_context : t -> string -> unit

ask server to negotiate metadata context

During connection libnbd can negotiate zero or more metadata contexts with the server. Metadata contexts are features (such as "base:allocation") which describe information returned by the nbd_block_status(3) command (for "base:allocation" this is whether blocks of data are allocated, zero or sparse).

This call adds one metadata context to the list to be negotiated. You can call it as many times as needed. The list is initially empty when the handle is created; you can check the contents of the list with nbd_get_nr_meta_contexts(3) and nbd_get_meta_context(3), or clear it with nbd_clear_meta_contexts(3).

The NBD protocol limits meta context names to 4096 bytes, but servers may not support the full length. The encoding of meta context names is always UTF-8.

Not all servers support all metadata contexts. To learn if a context was actually negotiated, call nbd_can_meta_context(3) after connecting.

The single parameter is the name of the metadata context, for example "LIBNBD_CONTEXT_BASE_ALLOCATION". <libnbd.h> includes defined constants beginning with "LIBNBD_CONTEXT_" for some well-known contexts, but you are free to pass in other contexts.

Other metadata contexts are server-specific, but include "qemu:dirty-bitmap:..." and "qemu:allocation-depth" for qemu-nbd (see qemu-nbd *-B* and *-A* options).

val get_nr_meta_contexts : t -> int

return the current number of requested meta contexts

During connection libnbd can negotiate zero or more metadata contexts with the server. Metadata contexts are features (such as "base:allocation") which describe information returned by the nbd_block_status(3) command (for "base:allocation" this is whether blocks of data are allocated, zero or sparse).

This command returns how many meta contexts have been added to the list to request from the server via nbd_add_meta_context(3). The server is not obligated to honor all of the requests; to see what it actually supports, see nbd_can_meta_context(3).

val get_meta_context : t -> int -> string

return the i'th meta context request

During connection libnbd can negotiate zero or more metadata contexts with the server. Metadata contexts are features (such as "base:allocation") which describe information returned by the nbd_block_status(3) command (for "base:allocation" this is whether blocks of data are allocated, zero or sparse).

This command returns the i'th meta context request, as added by nbd_add_meta_context(3), and bounded by nbd_get_nr_meta_contexts(3).

val clear_meta_contexts : t -> unit

reset the list of requested meta contexts

During connection libnbd can negotiate zero or more metadata contexts with the server. Metadata contexts are features (such as "base:allocation") which describe information returned by the nbd_block_status(3) command (for "base:allocation" this is whether blocks of data are allocated, zero or sparse).

This command resets the list of meta contexts to request back to an empty list, for re-population by further use of nbd_add_meta_context(3). It is primarily useful when option negotiation mode is selected (see nbd_set_opt_mode(3)), for altering the list of attempted contexts between subsequent export queries.

val set_uri_allow_transports : t -> ALLOW_TRANSPORT.t list -> unit

set the allowed transports in NBD URIs

Set which transports are allowed to appear in NBD URIs. The default is to allow any transport.

The "mask" parameter may contain any of the following flags ORed together:

"LIBNBD_ALLOW_TRANSPORT_TCP" "LIBNBD_ALLOW_TRANSPORT_UNIX" "LIBNBD_ALLOW_TRANSPORT_VSOCK"

For convenience, the constant "LIBNBD_ALLOW_TRANSPORT_MASK" is available to describe all transports recognized by this build of libnbd. A future version of the library may add new flags.

val set_uri_allow_tls : t -> TLS.t -> unit

set the allowed TLS settings in NBD URIs

Set which TLS settings are allowed to appear in NBD URIs. The default is to allow either non-TLS or TLS URIs.

The "tls" parameter can be:

"LIBNBD_TLS_DISABLE" TLS URIs are not permitted, ie. a URI such as "nbds://..." will be rejected.

"LIBNBD_TLS_ALLOW" This is the default. TLS may be used or not, depending on whether the URI uses "nbds" or "nbd".

"LIBNBD_TLS_REQUIRE" TLS URIs are required. All URIs must use "nbds".

val set_uri_allow_local_file : t -> bool -> unit

set the allowed transports in NBD URIs

Allow NBD URIs to reference local files. This is *disabled* by default.

Currently this setting only controls whether the "tls-psk-file" parameter in NBD URIs is allowed.

val connect_uri : t -> string -> unit

connect to NBD URI

Connect (synchronously) to an NBD server and export by specifying the NBD URI. This call parses the URI and calls nbd_set_export_name(3) and nbd_set_tls(3) and other calls as needed, followed by nbd_connect_tcp(3) or nbd_connect_unix(3). However, it is possible to override the export name portion of a URI by using nbd_set_opt_mode(3) to enable option mode, then using nbd_set_export_name(3) and nbd_opt_go(3) as part of subsequent negotiation.

This call returns when the connection has been made.

Example URIs supported "nbd://example.com" Connect over TCP, unencrypted, to "example.com" port 10809.

"nbds://example.com" Connect over TCP with TLS, to "example.com" port 10809. If the server does not support TLS then this will fail.

"nbd+unix:///foo?socket=/tmp/nbd.sock" Connect over the Unix domain socket /tmp/nbd.sock to an NBD server running locally. The export name is set to "foo" (note without any leading "/" character).

"nbd+vsock:///" In this scenario libnbd is running in a virtual machine. Connect over "AF_VSOCK" to an NBD server running on the hypervisor.

Supported URI formats The following schemes are supported in the current version of libnbd:

"nbd:" Connect over TCP without using TLS.

"nbds:" Connect over TCP. TLS is required and the connection will fail if the server does not support TLS.

"nbd+unix:" "nbds+unix:" Connect over a Unix domain socket, without or with TLS respectively. The "socket" parameter is required.

"nbd+vsock:" "nbds+vsock:" Connect over the "AF_VSOCK" transport, without or with TLS respectively.

The authority part of the URI (" username@ servername :port ") is parsed depending on the transport. For TCP it specifies the server to connect to and optional port number. For "+unix" it should not be present. For "+vsock" the server name is the numeric CID (eg. 2 to connect to the host), and the optional port number may be present. If the "username" is present it is used for TLS authentication.

For all transports, an export name may be present, parsed in accordance with the NBD URI specification.

Finally the query part of the URI can contain:

socket=SOCKET Specifies the Unix domain socket to connect on. Must be present for the "+unix" transport and must not be present for the other transports.

tls-psk-file=PSKFILE Set the PSK file. See nbd_set_tls_psk_file(3). Note this is not allowed by default - see next section.

Disable URI features For security reasons you might want to disable certain URI features. Pre-filtering URIs is error-prone and should not be attempted. Instead use the libnbd APIs below to control what can appear in URIs. Note you must call these functions on the same handle before calling nbd_connect_uri(3) or nbd_aio_connect_uri(3).

TCP, Unix domain socket or "AF_VSOCK" transports Default: all allowed

To select which transports are allowed call nbd_set_uri_allow_transports(3).

TLS Default: both non-TLS and TLS connections allowed

To force TLS off or on in URIs call nbd_set_uri_allow_tls(3).

Connect to Unix domain socket in the local filesystem Default: allowed

To prevent this you must disable the "+unix" transport using nbd_set_uri_allow_transports(3).

Read from local files Default: denied

To allow URIs to contain references to local files (eg. for parameters like "tls-psk-file") call nbd_set_uri_allow_local_file(3).

Optional features This call will fail if libnbd was not compiled with libxml2; you can test whether this is the case with nbd_supports_uri(3).

Support for URIs that require TLS will fail if libnbd was not compiled with gnutls; you can test whether this is the case with nbd_supports_tls(3).

val connect_unix : t -> string -> unit

connect to NBD server over a Unix domain socket

Connect (synchronously) over the named Unix domain socket ("unixsocket") to an NBD server running on the same machine. This call returns when the connection has been made.

val connect_vsock : t -> int32 -> int32 -> unit

connect to NBD server over AF_VSOCK protocol

Connect (synchronously) over the "AF_VSOCK" protocol from a virtual machine to an NBD server, usually running on the host. The "cid" and "port" parameters specify the server address. Usually "cid" should be 2 (to connect to the host), and "port" might be 10809 or another port number assigned to you by the host administrator. This call returns when the connection has been made.

val connect_tcp : t -> string -> string -> unit

connect to NBD server over a TCP port

Connect (synchronously) to the NBD server listening on "hostname:port". The "port" may be a port name such as "nbd", or it may be a port number as a string such as "10809". This call returns when the connection has been made.

val connect_socket : t -> Unix.file_descr -> unit

connect directly to a connected socket

Pass a connected socket "sock" through which libnbd will talk to the NBD server.

The caller is responsible for creating and connecting this socket by some method, before passing it to libnbd.

If this call returns without error then socket ownership is passed to libnbd. Libnbd will close the socket when the handle is closed. The caller must not use the socket in any way.

val connect_command : t -> string list -> unit

connect to NBD server command

Run the command as a subprocess and connect to it over stdin/stdout. This is for use with NBD servers which can behave like inetd clients, such as "nbdkit --single".

Subprocess Libnbd will fork the "argv" command and pass the NBD socket to it using file descriptors 0 and 1 (stdin/stdout):

┌─────────┬─────────┐ ┌────────────────┐ │ program │ libnbd │ │ NBD server │ │ │ │ │ (argv) │ │ │ socket ╍╍╍╍╍╍╍╍▶ stdin/stdout │ └─────────┴─────────┘ └────────────────┘

When the NBD handle is closed the server subprocess is killed.

val connect_systemd_socket_activation : t -> string list -> unit

connect using systemd socket activation

Run the command as a subprocess and connect to it using systemd socket activation.

This is especially useful for running qemu-nbd(1) as a subprocess of libnbd, for example to use it to open qcow2 files. To run nbdkit as a subprocess it is usually better to use nbd_connect_command(3).

Socket activation Libnbd will fork the "argv" command and pass an NBD socket to it using special "LISTEN_*" environment variables (as defined by the systemd socket activation protocol).

┌─────────┬─────────┐ ┌───────────────┐ │ program │ libnbd │ │ qemu-nbd or │ │ │ │ │ other server │ │ │ socket ╍╍╍╍╍╍╍╍▶ │ └─────────┴─────────┘ └───────────────┘

When the NBD handle is closed the server subprocess is killed.

val is_read_only : t -> bool

is the NBD export read-only?

Returns true if the NBD export is read-only; writes and write-like operations will fail.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_flush : t -> bool

does the server support the flush command?

Returns true if the server supports the flush command (see nbd_flush(3), nbd_aio_flush(3)). Returns false if the server does not.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_fua : t -> bool

does the server support the FUA flag?

Returns true if the server supports the FUA flag on certain commands (see nbd_pwrite(3)).

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val is_rotational : t -> bool

is the NBD disk rotational (like a disk)?

Returns true if the disk exposed over NBD is rotational (like a traditional floppy or hard disk). Returns false if the disk has no penalty for random access (like an SSD or RAM disk).

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_trim : t -> bool

does the server support the trim command?

Returns true if the server supports the trim command (see nbd_trim(3), nbd_aio_trim(3)). Returns false if the server does not.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_zero : t -> bool

does the server support the zero command?

Returns true if the server supports the zero command (see nbd_zero(3), nbd_aio_zero(3)). Returns false if the server does not.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_fast_zero : t -> bool

does the server support the fast zero flag?

Returns true if the server supports the use of the "LIBNBD_CMD_FLAG_FAST_ZERO" flag to the zero command (see nbd_zero(3), nbd_aio_zero(3)). Returns false if the server does not.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_df : t -> bool

does the server support the don't fragment flag to pread?

Returns true if the server supports structured reads with an ability to request a non-fragmented read (see nbd_pread_structured(3), nbd_aio_pread_structured(3)). Returns false if the server either lacks structured reads or if it does not support a non-fragmented read request.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_multi_conn : t -> bool

does the server support multi-conn?

Returns true if the server supports multi-conn. Returns false if the server does not.

It is not safe to open multiple handles connecting to the same server if you will write to the server and the server does not advertise multi-conn support. The safe way to check for this is to open one connection, check this flag is true, then open further connections as required.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_cache : t -> bool

does the server support the cache command?

Returns true if the server supports the cache command (see nbd_cache(3), nbd_aio_cache(3)). Returns false if the server does not.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val can_meta_context : t -> string -> bool

does the server support a specific meta context?

Returns true if the server supports the given meta context (see nbd_add_meta_context(3)). Returns false if the server does not.

The single parameter is the name of the metadata context, for example "LIBNBD_CONTEXT_BASE_ALLOCATION". <libnbd.h> includes defined constants for well-known namespace contexts beginning with "LIBNBD_CONTEXT_", but you are free to pass in other contexts.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val get_protocol : t -> string

return the NBD protocol variant

Return the NBD protocol variant in use on the connection. At the moment this returns one of the strings "oldstyle", "newstyle" or "newstyle-fixed". Other strings might be returned in the future. Most modern NBD servers use "newstyle-fixed".

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val get_size : t -> int64

return the export size

Returns the size in bytes of the NBD export.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val get_block_size : t -> SIZE.t -> int64

return a specific server block size constraint

Returns a specific size constraint advertised by the server, if any. If the return is zero, the server did not advertise a constraint. "size_type" must be one of the following constraints:

"LIBNBD_SIZE_MINIMUM" = 0 If non-zero, this will be a power of 2 between 1 and 64k; any client request that is not aligned in length or offset to this size is likely to fail with "EINVAL". The image size will generally also be a multiple of this value (if not, the final few bytes are inaccessible while obeying alignment constraints). If zero, it is safest to assume a minimum block size of 512, although many servers support a minimum block size of 1. If the server provides a constraint, then libnbd defaults to honoring that constraint client-side unless "LIBNBD_STRICT_ALIGN" is cleared in nbd_set_strict_mode(3).

"LIBNBD_SIZE_PREFERRED" = 1 If non-zero, this is a power of 2 representing the preferred size for efficient I/O. Smaller requests may incur overhead such as read-modify-write cycles that will not be present when using I/O that is a multiple of this value. This value may be larger than the size of the export. If zero, using 4k as a preferred block size tends to give decent performance.

"LIBNBD_SIZE_MAXIMUM" = 2 If non-zero, this represents the maximum length that the server is willing to handle during nbd_pread(3) or nbd_pwrite(3). Other functions like nbd_zero(3) may still be able to use larger sizes. Note that this function returns what the server advertised, but libnbd itself imposes a maximum of 64M. If zero, some NBD servers will abruptly disconnect if a transaction involves more than 32M.

Future NBD extensions may result in additional "size_type" values.

This call does not block, because it returns data that is saved in the handle from the NBD protocol handshake.

val pread : ?flags:CMD_FLAG.t list -> t -> bytes -> int64 -> unit

read from the NBD server

Issue a read command to the NBD server for the range starting at "offset" and ending at "offset" + "count" - 1. NBD can only read all or nothing using this call. The call returns when the data has been read fully into "buf" or there is an error. See also nbd_pread_structured(3), if finer visibility is required into the server's replies, or if you want to use "LIBNBD_CMD_FLAG_DF".

The "flags" parameter must be 0 for now (it exists for future NBD protocol extensions).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val pread_structured : ?flags:CMD_FLAG.t list -> t -> bytes -> int64 -> (bytes -> int64 -> int -> int Stdlib.ref -> int) -> unit

read from the NBD server

Issue a read command to the NBD server for the range starting at "offset" and ending at "offset" + "count" - 1. The server's response may be subdivided into chunks which may arrive out of order before reassembly into the original buffer; the "chunk" callback is used for notification after each chunk arrives, and may perform additional sanity checking on the server's reply. The callback cannot call "nbd_*" APIs on the same handle since it holds the handle lock and will cause a deadlock. If the callback returns -1, and no earlier error has been detected, then the overall read command will fail with any non-zero value stored into the callback's "error" parameter (with a default of "EPROTO"); but any further chunks will still invoke the callback.

The "chunk" function is called once per chunk of data received, with the "user_data" passed to this function. The "subbuf" and "count" parameters represent the subset of the original buffer which has just been populated by results from the server (in C, "subbuf" always points within the original "buf"; but this guarantee may not extend to other language bindings). The "offset" parameter represents the absolute offset at which "subbuf" begins within the image (note that this is not the relative offset of "subbuf" within the original buffer "buf"). Changes to "error" on output are ignored unless the callback fails. The input meaning of the "error" parameter is controlled by the "status" parameter, which is one of

"LIBNBD_READ_DATA" = 1 "subbuf" was populated with "count" bytes of data. On input, "error" contains the errno value of any earlier detected error, or zero.

"LIBNBD_READ_HOLE" = 2 "subbuf" represents a hole, and contains "count" NUL bytes. On input, "error" contains the errno value of any earlier detected error, or zero.

"LIBNBD_READ_ERROR" = 3 "count" is 0, so "subbuf" is unusable. On input, "error" contains the errno value reported by the server as occurring while reading that "offset", regardless if any earlier error has been detected.

Future NBD extensions may permit other values for "status", but those will not be returned to a client that has not opted in to requesting such extensions. If the server is non-compliant, it is possible for the "chunk" function to be called more times than you expect or with "count" 0 for "LIBNBD_READ_DATA" or "LIBNBD_READ_HOLE". It is also possible that the "chunk" function is not called at all (in particular, "LIBNBD_READ_ERROR" is used only when an error is associated with a particular offset, and not when the server reports a generic error), but you are guaranteed that the callback was called at least once if the overall read succeeds. Libnbd does not validate that the server obeyed the requirement that a read call must not have overlapping chunks and must not succeed without enough chunks to cover the entire request.

The "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_DF" meaning that the server should not reply with more than one fragment (if that is supported - some servers cannot do this, see nbd_can_df(3)). Libnbd does not validate that the server actually obeys the flag.

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val pwrite : ?flags:CMD_FLAG.t list -> t -> bytes -> int64 -> unit

write to the NBD server

Issue a write command to the NBD server, writing the data in "buf" to the range starting at "offset" and ending at "offset" + "count" - 1. NBD can only write all or nothing using this call. The call returns when the command has been acknowledged by the server, or there is an error. Note this will generally return an error if nbd_is_read_only(3) is true.

The "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_FUA" meaning that the server should not return until the data has been committed to permanent storage (if that is supported - some servers cannot do this, see nbd_can_fua(3)).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val shutdown : ?flags:SHUTDOWN.t list -> t -> unit

disconnect from the NBD server

Issue the disconnect command to the NBD server. This is a nice way to tell the server we are going away, but from the client's point of view has no advantage over abruptly closing the connection (see nbd_close(3)).

This function works whether or not the handle is ready for transmission of commands. If more fine-grained control is needed, see nbd_aio_disconnect(3).

The "flags" argument is a bitmask, including zero or more of the following shutdown flags:

"LIBNBD_SHUTDOWN_ABANDON_PENDING" = 0x10000 If there are any pending requests which have not yet been sent to the server (see nbd_aio_in_flight(3)), abandon them without sending them to the server, rather than the usual practice of issuing those commands before informing the server of the intent to disconnect.

For convenience, the constant "LIBNBD_SHUTDOWN_MASK" is available to describe all shutdown flags recognized by this build of libnbd. A future version of the library may add new flags.

val flush : ?flags:CMD_FLAG.t list -> t -> unit

send flush command to the NBD server

Issue the flush command to the NBD server. The function should return when all write commands which have completed have been committed to permanent storage on the server. Note this will generally return an error if nbd_can_flush(3) is false.

The "flags" parameter must be 0 for now (it exists for future NBD protocol extensions).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val trim : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> unit

send trim command to the NBD server

Issue a trim command to the NBD server, which if supported by the server causes a hole to be punched in the backing store starting at "offset" and ending at "offset" + "count" - 1. The call returns when the command has been acknowledged by the server, or there is an error. Note this will generally return an error if nbd_can_trim(3) is false or nbd_is_read_only(3) is true.

The "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_FUA" meaning that the server should not return until the data has been committed to permanent storage (if that is supported - some servers cannot do this, see nbd_can_fua(3)).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val cache : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> unit

send cache (prefetch) command to the NBD server

Issue the cache (prefetch) command to the NBD server, which if supported by the server causes data to be prefetched into faster storage by the server, speeding up a subsequent nbd_pread(3) call. The server can also silently ignore this command. Note this will generally return an error if nbd_can_cache(3) is false.

The "flags" parameter must be 0 for now (it exists for future NBD protocol extensions).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val zero : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> unit

send write zeroes command to the NBD server

Issue a write zeroes command to the NBD server, which if supported by the server causes a zeroes to be written efficiently starting at "offset" and ending at "offset"

-"count" - 1. The call returns when the command has been acknowledged by the server, or there is an error. Note this will generally return an error if nbd_can_zero(3) is false or nbd_is_read_only(3) is true.

The "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_FUA" meaning that the server should not return until the data has been committed to permanent storage (if that is supported - some servers cannot do this, see nbd_can_fua(3)), "LIBNBD_CMD_FLAG_NO_HOLE" meaning that the server should favor writing actual allocated zeroes over punching a hole, and/or "LIBNBD_CMD_FLAG_FAST_ZERO" meaning that the server must fail quickly if writing zeroes is no faster than a normal write (if that is supported - some servers cannot do this, see nbd_can_fast_zero(3)).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val block_status : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> (string -> int64 -> int32 array -> int Stdlib.ref -> int) -> unit

send block status command to the NBD server

Issue the block status command to the NBD server. If supported by the server, this causes metadata context information about blocks beginning from the specified offset to be returned. The "count" parameter is a hint: the server may choose to return less status, or the final block may extend beyond the requested range. If multiple contexts are supported, the number of blocks and cumulative length of those blocks need not be identical between contexts.

Depending on which metadata contexts were enabled before connecting (see nbd_add_meta_context(3)) and which are supported by the server (see nbd_can_meta_context(3)) this call returns information about extents by calling back to the "extent" function. The callback cannot call "nbd_*" APIs on the same handle since it holds the handle lock and will cause a deadlock. If the callback returns -1, and no earlier error has been detected, then the overall block status command will fail with any non-zero value stored into the callback's "error" parameter (with a default of "EPROTO"); but any further contexts will still invoke the callback.

The "extent" function is called once per type of metadata available, with the "user_data" passed to this function. The "metacontext" parameter is a string such as "base:allocation". The "entries" array is an array of pairs of integers with the first entry in each pair being the length (in bytes) of the block and the second entry being a status/flags field which is specific to the metadata context. (The number of pairs passed to the function is "nr_entries/2".) The NBD protocol document in the section about "NBD_REPLY_TYPE_BLOCK_STATUS" describes the meaning of this array; for contexts known to libnbd, <libnbd.h> contains constants beginning with "LIBNBD_STATE_" that may help decipher the values. On entry to the callback, the "error" parameter contains the errno value of any previously detected error.

It is possible for the extent function to be called more times than you expect (if the server is buggy), so always check the "metacontext" field to ensure you are receiving the data you expect. It is also possible that the extent function is not called at all, even for metadata contexts that you requested. This indicates either that the server doesn't support the context or for some other reason cannot return the data.

The "flags" parameter may be 0 for no flags, or may contain "LIBNBD_CMD_FLAG_REQ_ONE" meaning that the server should return only one extent per metadata context where that extent does not exceed "count" bytes; however, libnbd does not validate that the server obeyed the flag.

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val poll : t -> int -> int

poll the handle once

This is a simple implementation of poll(2) which is used internally by synchronous API calls. On success, it returns 0 if the "timeout" (in milliseconds) occurs, or 1 if the poll completed and the state machine progressed. Set "timeout" to -1 to block indefinitely (but be careful that eventual action is actually expected - for example, if the connection is established but there are no commands in flight, using an infinite timeout will permanently block).

This function is mainly useful as an example of how you might integrate libnbd with your own main loop, rather than being intended as something you would use.

val aio_connect : t -> string -> unit

connect to the NBD server

Begin connecting to the NBD server. The "addr" and "addrlen" parameters specify the address of the socket to connect to.

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_uri : t -> string -> unit

connect to an NBD URI

Begin connecting to the NBD URI "uri". Parameters behave as documented in nbd_connect_uri(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_unix : t -> string -> unit

connect to the NBD server over a Unix domain socket

Begin connecting to the NBD server over Unix domain socket ("unixsocket"). Parameters behave as documented in nbd_connect_unix(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_vsock : t -> int32 -> int32 -> unit

connect to the NBD server over AF_VSOCK socket

Begin connecting to the NBD server over the "AF_VSOCK" protocol to the server "cid:port". Parameters behave as documented in nbd_connect_vsock(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_tcp : t -> string -> string -> unit

connect to the NBD server over a TCP port

Begin connecting to the NBD server listening on "hostname:port". Parameters behave as documented in nbd_connect_tcp(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_socket : t -> Unix.file_descr -> unit

connect directly to a connected socket

Begin connecting to the connected socket "fd". Parameters behave as documented in nbd_connect_socket(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_command : t -> string list -> unit

connect to the NBD server

Run the command as a subprocess and begin connecting to it over stdin/stdout. Parameters behave as documented in nbd_connect_command(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_connect_systemd_socket_activation : t -> string list -> unit

connect using systemd socket activation

Run the command as a subprocess and begin connecting to it using systemd socket activation. Parameters behave as documented in nbd_connect_systemd_socket_activation(3).

You can check if the connection is still connecting by calling nbd_aio_is_connecting(3), or if it has connected to the server and completed the NBD handshake by calling nbd_aio_is_ready(3), on the connection.

val aio_opt_go : ?completion:(int Stdlib.ref -> int) -> t -> unit

end negotiation and move on to using an export

Request that the server finish negotiation and move on to serving the export previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

To determine when the request completes, wait for nbd_aio_is_connecting(3) to return false. Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3), except that it is automatically retired regardless of return value. Note that directly detecting whether the server returns an error (as is done by the return value of the synchronous counterpart) is only possible with a completion callback; however it is also possible to indirectly detect an error when nbd_aio_is_negotiating(3) returns true.

val aio_opt_abort : t -> unit

end negotiation and close the connection

Request that the server finish negotiation, gracefully if possible, then close the connection. This can only be used if nbd_set_opt_mode(3) enabled option mode.

To determine when the request completes, wait for nbd_aio_is_connecting(3) to return false.

val aio_opt_list : ?completion:(int Stdlib.ref -> int) -> t -> (string -> string -> int) -> unit

request the server to list all exports during negotiation

Request that the server list all exports that it supports. This can only be used if nbd_set_opt_mode(3) enabled option mode.

To determine when the request completes, wait for nbd_aio_is_connecting(3) to return false. Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3), except that it is automatically retired regardless of return value. Note that detecting whether the server returns an error (as is done by the return value of the synchronous counterpart) is only possible with a completion callback.

val aio_opt_info : ?completion:(int Stdlib.ref -> int) -> t -> unit

request the server for information about an export

Request that the server supply information about the export name previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

To determine when the request completes, wait for nbd_aio_is_connecting(3) to return false. Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3), except that it is automatically retired regardless of return value. Note that detecting whether the server returns an error (as is done by the return value of the synchronous counterpart) is only possible with a completion callback.

val aio_opt_list_meta_context : ?completion:(int Stdlib.ref -> int) -> t -> (string -> int) -> int

request the server to list available meta contexts

Request that the server list available meta contexts associated with the export previously specified by the most recent nbd_set_export_name(3) or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3) enabled option mode.

To determine when the request completes, wait for nbd_aio_is_connecting(3) to return false. Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3), except that it is automatically retired regardless of return value. Note that detecting whether the server returns an error (as is done by the return value of the synchronous counterpart) is only possible with a completion callback.

val aio_pread : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> Buffer.t -> int64 -> cookie

read from the NBD server

Issue a read command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Note that you must ensure "buf" is valid until the command has completed. Other parameters behave as documented in nbd_pread(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_pread_structured : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> Buffer.t -> int64 -> (bytes -> int64 -> int -> int Stdlib.ref -> int) -> cookie

read from the NBD server

Issue a read command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_pread_structured(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_pwrite : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> Buffer.t -> int64 -> cookie

write to the NBD server

Issue a write command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Note that you must ensure "buf" is valid until the command has completed. Other parameters behave as documented in nbd_pwrite(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_disconnect : ?flags:CMD_FLAG.t list -> t -> unit

disconnect from the NBD server

Issue the disconnect command to the NBD server. This is not a normal command because NBD servers are not obliged to send a reply. Instead you should wait for nbd_aio_is_closed(3) to become true on the connection. Once this command is issued, you cannot issue any further commands.

Although libnbd does not prevent you from issuing this command while still waiting on the replies to previous commands, the NBD protocol recommends that you wait until there are no other commands in flight (see nbd_aio_in_flight(3)), to give the server a better chance at a clean shutdown.

The "flags" parameter must be 0 for now (it exists for future NBD protocol extensions). There is no direct synchronous counterpart; however, nbd_shutdown(3) will call this function if appropriate.

val aio_flush : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> cookie

send flush command to the NBD server

Issue the flush command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_flush(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_trim : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> cookie

send trim command to the NBD server

Issue a trim command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_trim(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_cache : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> cookie

send cache (prefetch) command to the NBD server

Issue the cache (prefetch) command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_cache(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_zero : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> cookie

send write zeroes command to the NBD server

Issue a write zeroes command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_zero(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_block_status : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> (string -> int64 -> int32 array -> int Stdlib.ref -> int) -> cookie

send block status command to the NBD server

Send the block status command to the NBD server.

To check if the command completed, call nbd_aio_command_completed(3). Or supply the optional "completion_callback" which will be invoked as described in "Completion callbacks" in libnbd(3).

Other parameters behave as documented in nbd_block_status(3).

By default, libnbd will reject attempts to use this function with parameters that are likely to result in server failure, such as requesting an unknown command flag. The nbd_set_strict_mode(3) function can be used to alter which scenarios should await a server reply rather than failing fast.

val aio_get_fd : t -> Unix.file_descr

return file descriptor associated with this connection

Return the underlying file descriptor associated with this connection. You can use this to check if the file descriptor is ready for reading or writing and call nbd_aio_notify_read(3) or nbd_aio_notify_write(3). See also nbd_aio_get_direction(3). Do not do anything else with the file descriptor.

val aio_get_direction : t -> int

return the read or write direction

Return the current direction of this connection, which means whether we are next expecting to read data from the server, write data to the server, or both. It returns

0 We are not expected to interact with the server file descriptor from the current state. It is not worth attempting to use poll(2); if the connection is not dead, then state machine progress must instead come from some other means such as nbd_aio_connect(3).

"LIBNBD_AIO_DIRECTION_READ" = 1 We are expected next to read from the server. If using poll(2) you would set "events = POLLIN". If "revents" returns "POLLIN" or "POLLHUP" you would then call nbd_aio_notify_read(3).

Note that once libnbd reaches nbd_aio_is_ready(3), this direction is returned even when there are no commands in flight (see nbd_aio_in_flight(3)). In a single-threaded use of libnbd, it is not worth polling until after issuing a command, as otherwise the server will never wake up the poll. In a multi-threaded scenario, you can have one thread begin a polling loop prior to any commands, but any other thread that issues a command will need a way to kick the polling thread out of poll in case issuing the command changes the needed polling direction. Possible ways to do this include polling for activity on a pipe-to-self, or using pthread_kill(3) to send a signal that is masked except during ppoll(2).

"LIBNBD_AIO_DIRECTION_WRITE" = 2 We are expected next to write to the server. If using poll(2) you would set "events = POLLOUT". If "revents" returns "POLLOUT" you would then call nbd_aio_notify_write(3).

"LIBNBD_AIO_DIRECTION_BOTH" = 3 We are expected next to either read or write to the server. If using poll(2) you would set "events = POLLIN|POLLOUT". If only one of "POLLIN" or "POLLOUT" is returned, then see above. However, if both are returned, it is better to call only nbd_aio_notify_read(3), as processing the server's reply may change the state of the connection and invalidate the need to write more commands.

val aio_notify_read : t -> unit

notify that the connection is readable

Send notification to the state machine that the connection is readable. Typically this is called after your main loop has detected that the file descriptor associated with this connection is readable.

val aio_notify_write : t -> unit

notify that the connection is writable

Send notification to the state machine that the connection is writable. Typically this is called after your main loop has detected that the file descriptor associated with this connection is writable.

val aio_is_created : t -> bool

check if the connection has just been created

Return true if this connection has just been created. This is the state before the handle has started connecting to a server. In this state the handle can start to be connected by calling functions such as nbd_aio_connect(3).

val aio_is_connecting : t -> bool

check if the connection is connecting or handshaking

Return true if this connection is connecting to the server or in the process of handshaking and negotiating options which happens before the handle becomes ready to issue commands (see nbd_aio_is_ready(3)).

val aio_is_negotiating : t -> bool

check if connection is ready to send handshake option

Return true if this connection is ready to start another option negotiation command while handshaking with the server. An option command will move back to the connecting state (see nbd_aio_is_connecting(3)). Note that this state cannot be reached unless requested by nbd_set_opt_mode(3), and even then it only works with newstyle servers; an oldstyle server will skip straight to nbd_aio_is_ready(3).

val aio_is_ready : t -> bool

check if the connection is in the ready state

Return true if this connection is connected to the NBD server, the handshake has completed, and the connection is idle or waiting for a reply. In this state the handle is ready to issue commands.

val aio_is_processing : t -> bool

check if the connection is processing a command

Return true if this connection is connected to the NBD server, the handshake has completed, and the connection is processing commands (either writing out a request or reading a reply).

Note the ready state (nbd_aio_is_ready(3)) is not included. In the ready state commands may be *in flight* (the *server* is processing them), but libnbd is not processing them.

val aio_is_dead : t -> bool

check if the connection is dead

Return true if the connection has encountered a fatal error and is dead. In this state the handle may only be closed. There is no way to recover a handle from the dead state.

val aio_is_closed : t -> bool

check if the connection is closed

Return true if the connection has closed. There is no way to reconnect a closed connection. Instead you must close the whole handle.

val aio_command_completed : t -> int64 -> bool

check if the command completed

Return true if the command completed. If this function returns true then the command was successful and it has been retired. Return false if the command is still in flight. This can also fail with an error in case the command failed (in this case the command is also retired). A command is retired either via this command, or by using a completion callback which returns 1.

The "cookie" parameter is the positive unique 64 bit cookie for the command, as returned by a call such as nbd_aio_pread(3).

val aio_peek_command_completed : t -> int64

check if any command has completed

Return the unique positive 64 bit cookie of the first non-retired but completed command, 0 if there are in-flight commands but none of them are awaiting retirement, or -1 on error including when there are no in-flight commands. Any cookie returned by this function must still be passed to nbd_aio_command_completed(3) to actually retire the command and learn whether the command was successful.

val aio_in_flight : t -> int

check how many aio commands are still in flight

Return the number of in-flight aio commands that are still awaiting a response from the server before they can be retired. If this returns a non-zero value when requesting a disconnect from the server (see nbd_aio_disconnect(3) and nbd_shutdown(3)), libnbd does not try to wait for those commands to complete gracefully; if the server strands commands while shutting down, nbd_aio_command_completed(3) will report those commands as failed with a status of "ENOTCONN".

val connection_state : t -> string

return string describing the state of the connection

Returns a descriptive string for the state of the connection. This can be used for debugging or troubleshooting, but you should not rely on the state of connections since it may change in future versions.

val get_package_name : t -> string

return the name of the library

Returns the name of the library, always "libnbd" unless the library was modified with another name at compile time.

val get_version : t -> string

return the version of the library

Return the version of libnbd. This is returned as a string in the form "major.minor.release" where each of major, minor and release is a small positive integer. For example:

minor ↓ "1.0.3" ↑ ↑ major release

major = 0 The major number was 0 for the early experimental versions of libnbd where we still had an unstable API.

major = 1 The major number is 1 for the versions of libnbd with a long-term stable API and ABI. It is not anticipated that major will be any number other than 1.

minor = 0, 2, ... (even) The minor number is even for stable releases.

minor = 1, 3, ... (odd) The minor number is odd for development versions. Note that new APIs added in a development version remain experimental and subject to change in that branch until they appear in a stable release.

release The release number is incremented for each release along a particular branch.

val kill_subprocess : t -> int -> unit

kill server running as a subprocess

This call may be used to kill the server running as a subprocess that was previously created using nbd_connect_command(3). You do not need to use this call. It is only needed if the server does not exit when the socket is closed.

The "signum" parameter is the optional signal number to send (see signal(7)). If "signum" is 0 then "SIGTERM" is sent.

val supports_tls : t -> bool

true if libnbd was compiled with support for TLS

Returns true if libnbd was compiled with gnutls which is required to support TLS encryption, or false if not.

val supports_uri : t -> bool

true if libnbd was compiled with support for NBD URIs

Returns true if libnbd was compiled with libxml2 which is required to support NBD URIs, or false if not.

2021-02-09 OCamldoc