plucky (3) NBD.3.gz

Provided by: libnbd-dev_1.20.3-1build1_amd64 bug

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 * Unix.error option

       Exception thrown when an API call fails.

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

       exception Closed of string

       Exception thrown if you call a closed handle.

       type cookie = int64

       type extent = int64 * int64

       Length and flags of an extent in NBD.block_status_64 callback.

       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

       val namespace_qemu : string

       val context_qemu_dirty_bitmap : string

       val state_dirty : int32

       val context_qemu_allocation_depth : string

       module Buffer : sig end

       Persistent buffer used in AIO calls.

       val errno_of_unix_error : Unix.error -> int

       Return  the  raw C errno corresponding to a Unix.error .  This can be used in callbacks to update the int
       ref parameter.

       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 with_handle : (t -> 'a) -> 'a

       Wrapper  around  NBD.create  .   It calls the function parameter with a newly created handle, and ensures
       that NBD.close is always called even if the function throws an exception.

       Use this when it is essential that the handle is closed in order to  free  up  external  resources  in  a
       timely  manner;  for  example  if  running  the  server  as  a subprocess and you want to ensure that the
       subprocess is always killed; or if you need to disconnect from the server before continuing with  another
       operation.

       val set_debug : t -> bool -> unit

       NBD.set_debug t debug

       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

       NBD.get_debug t

       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

       NBD.set_debug_callback t debug

       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

       NBD.clear_debug_callback t

       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 stats_bytes_sent : t -> int64

       NBD.stats_bytes_sent t

       statistics of bytes sent over connection so far

       Return the number of bytes that the client has sent to the server.

       This  tracks  the  plaintext  bytes  utilized by the NBD protocol; it may differ from the number of bytes
       actually sent over the connection, particularly when TLS is in use.

       val stats_chunks_sent : t -> int64

       NBD.stats_chunks_sent t

       statistics of chunks sent over connection so far

       Return the number of chunks that the client has sent to the server, where a chunk is  a  group  of  bytes
       delineated by a magic number that cannot be further subdivided without breaking the protocol.

       This number does not necessarily relate to the number of API calls made, nor to the number of TCP packets
       sent over the connection.

       val stats_bytes_received : t -> int64

       NBD.stats_bytes_received t

       statistics of bytes received over connection so far

       Return the number of bytes that the client has received from the server.

       This tracks the plaintext bytes utilized by the NBD protocol; it may differ  from  the  number  of  bytes
       actually received over the connection, particularly when TLS is in use.

       val stats_chunks_received : t -> int64

       NBD.stats_chunks_received t

       statistics of chunks received over connection so far

       Return  the  number  of  chunks that the client has received from the server, where a chunk is a group of
       bytes delineated by a magic number that cannot be further subdivided without breaking the protocol.

       This number does not necessarily relate to the number of API calls made, nor to the number of TCP packets
       received over the connection.

       val set_handle_name : t -> string -> unit

       NBD.set_handle_name t handle_name

       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

       NBD.get_handle_name t

       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_private_data : t -> int -> int

       NBD.set_private_data t private_data

       set the per-handle private data

       Handles contain a private data field for applications to use for any purpose.

       When calling libnbd from C, the type of this field is "uintptr_t" so it can be used to store an  unsigned
       integer or a pointer.

       In non-C bindings it can be used to store an unsigned integer.

       This function sets the value of this field and returns the old value (or 0 if it was not previously set).

       val get_private_data : t -> int

       NBD.get_private_data t

       get the per-handle private data

       Return  the  value of the private data field set previously by a call to nbd_set_private_data(3) (or 0 if
       it was not previously set).

       val set_export_name : t -> string -> unit

       NBD.set_export_name t export_name

       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

       NBD.get_export_name t

       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_request_block_size : t -> bool -> unit

       NBD.set_request_block_size t request

       control whether NBD_OPT_GO requests block size

       By  default,  when  connecting  to  an  export,  libnbd  requests  that  the server report any block size
       restrictions. The NBD protocol states that a server may supply block  sizes  regardless  of  whether  the
       client  requests  them, and libnbd will report those block sizes (see nbd_get_block_size(3)); conversely,
       if a client does not request block sizes, the server may reject the connection instead of dealing with  a
       client  sending  unaligned requests. This function makes it possible to test server behavior by emulating
       older clients.

       Note that even when block size is requested, the server is not obligated to provide any. Furthermore,  if
       block  sizes  are provided (whether or not the client requested them), libnbd enforces alignment to those
       sizes unless nbd_set_strict_mode(3) is used to bypass client-side safety checks.

       val get_request_block_size : t -> bool

       NBD.get_request_block_size t

       see if NBD_OPT_GO requests block size

       Return the state of the block size request flag on this handle.

       val set_full_info : t -> bool -> unit

       NBD.set_full_info t request

       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. Furthermore, the hint to request block sizes  is  independently  controlled
       via nbd_set_request_block_size(3).

       val get_full_info : t -> bool

       NBD.get_full_info t

       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

       NBD.get_canonical_export_name t

       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

       NBD.get_export_description t

       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

       NBD.set_tls t tls

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

       This  setting  is  also necessary if you use nbd_set_opt_mode(3) and want to interact in plaintext with a
       server  that  implements  the  NBD  protocol's  "SELECTIVETLS"  mode,  prior   to   enabling   TLS   with
       nbd_opt_starttls(3).  Most  NBD  servers  with TLS support prefer the NBD protocol's "FORCEDTLS" mode, so
       this sort of manual interaction tends to be useful mainly during integration testing.

       "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

       NBD.get_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

       NBD.get_tls_negotiated t

       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 normally useful only 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.  With  "LIBNBD_TLS_DISABLE"  mode, TLS is not tried automatically; but if the NBD server uses
       the less-common "SELECTIVETLS" mode, this function reports whether a manual  nbd_opt_starttls(3)  enabled
       TLS or if the connection is still plaintext.

       val set_tls_certificates : t -> string -> unit

       NBD.set_tls_certificates t dir

       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

       NBD.set_tls_verify_peer t verify

       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

       NBD.get_tls_verify_peer t

       get whether we verify the identity of the server

       Get the verify peer flag.

       val set_tls_username : t -> string -> unit

       NBD.set_tls_username t username

       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

       NBD.get_tls_username t

       get the current TLS username

       Get the current TLS username.

       val set_tls_psk_file : t -> string -> unit

       NBD.set_tls_psk_file t filename

       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_extended_headers : t -> bool -> unit

       NBD.set_request_extended_headers t request

       control use of extended headers

       By  default,  libnbd  tries  to  negotiate  extended  headers with the server, as this protocol extension
       permits the use of 64-bit zero, trim, and block status actions.  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.

       For backwards compatibility, the setting of this knob is ignored if nbd_set_request_structured_replies(3)
       is also set to false, since the use of extended headers implies structured replies.

       val get_request_extended_headers : t -> bool

       NBD.get_request_extended_headers t

       see if extended headers are attempted

       Return the state of the request extended headers flag on this handle.

       Note: If you want to find out if extended headers were actually negotiated on a particular connection use
       nbd_get_extended_headers_negotiated(3) instead.

       val get_extended_headers_negotiated : t -> bool

       NBD.get_extended_headers_negotiated t

       see if extended headers are in use

       After  connecting  you  may  call this to find out if the connection is using extended headers. Note that
       this setting is sticky; this can return true even  after  a  second  nbd_opt_extended_headers(3)  returns
       false because the server detected a duplicate request.

       When  extended  headers are not in use, commands are limited to a 32-bit length, even when the libnbd API
       uses a 64-bit parameter to express the length. But even when extended headers are supported,  the  server
       may enforce other limits, visible through nbd_get_block_size(3).

       Note  that  when  extended  headers  are  negotiated, you should prefer the use of nbd_block_status_64(3)
       instead of nbd_block_status(3) if any of the meta  contexts  you  requested  via  nbd_add_meta_context(3)
       might  return  64-bit  status  values;  however,  all  of the well-known meta contexts covered by current
       "LIBNBD_CONTEXT_*" constants only return 32-bit status.

       val set_request_structured_replies : t -> bool -> unit

       NBD.set_request_structured_replies t request

       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.  It is also useful to set this to false prior to using nbd_set_opt_mode(3) if it is
       desired to control when to send nbd_opt_structured_reply(3) during negotiation.

       Note that setting this knob to false also disables any automatic request for extended headers.

       val get_request_structured_replies : t -> bool

       NBD.get_request_structured_replies t

       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

       NBD.get_structured_replies_negotiated t

       see if structured replies are in use

       After  connecting  you may call this to find out if the connection is using structured replies. Note that
       this setting is sticky; this can return true even  after  a  second  nbd_opt_structured_reply(3)  returns
       false because the server detected a duplicate request.

       Note  that if the connection negotiates extended headers, this function returns true (as extended headers
       imply structured replies) even if no explicit request for structured replies was attempted.

       val set_request_meta_context : t -> bool -> unit

       NBD.set_request_meta_context t request

       control whether connect automatically requests meta contexts

       This function controls whether the act of  connecting  to  an  export  (all  "nbd_connect_*"  calls  when
       nbd_set_opt_mode(3) is false, or nbd_opt_go(3) and nbd_opt_info(3) when option mode is enabled) will also
       try to issue NBD_OPT_SET_META_CONTEXT when the server supports structured replies or extended headers and
       any  contexts  were registered by nbd_add_meta_context(3). The default setting is true; however the extra
       step of negotiating meta contexts is not always desirable: performing both info and go on the same export
       works  without  needing to re-negotiate contexts on the second call; integration testing of other servers
       may benefit from manual invocation of nbd_opt_set_meta_context(3)  at  other  times  in  the  negotiation
       sequence;  and  even when using just nbd_opt_info(3), it can be faster to collect the server's results by
       relying on the callback function passed to nbd_opt_list_meta_context(3) than  a  series  of  post-process
       calls to nbd_can_meta_context(3).

       Note  that  this  control  has  no effect if the server does not negotiate structured replies or extended
       headers, or if the client did not request any contexts via nbd_add_meta_context(3). Setting this  control
       to false may cause nbd_block_status(3) to fail.

       val get_request_meta_context : t -> bool

       NBD.get_request_meta_context t

       see if connect automatically requests meta contexts

       Return the state of the automatic meta context request flag on this handle.

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

       NBD.set_handshake_flags t flags

       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

       NBD.get_handshake_flags t

       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_pread_initialize : t -> bool -> unit

       NBD.set_pread_initialize t request

       control whether libnbd pre-initializes read buffers

       By default, libnbd will pre-initialize the contents of a buffer passed to calls such as  nbd_pread(3)  to
       all  zeroes  prior  to  checking  for any other errors, so that even if a client application passed in an
       uninitialized buffer but fails to check for errors, it will not  result  in  a  potential  security  risk
       caused  by  an  accidental  leak  of  prior heap contents (see CVE-2022-0485 in libnbd-security(3) for an
       example of a security hole in an application built against an  earlier  version  of  libnbd  that  lacked
       consistent pre-initialization).  However, for a client application that has audited that an uninitialized
       buffer is never dereferenced, or which performs its own pre-initialization, libnbd's sanitization efforts
       merely  pessimize  performance  (although  the time spent in pre-initialization may pale in comparison to
       time spent waiting on network packets).

       Calling this function with "request" set to false tells libnbd to skip the buffer initialization step  in
       read commands.

       val get_pread_initialize : t -> bool

       NBD.get_pread_initialize t

       see whether libnbd pre-initializes read buffers

       Return whether libnbd performs a pre-initialization of a buffer passed to nbd_pread(3) and similar to all
       zeroes, as set by nbd_set_pread_initialize(3).

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

       NBD.set_strict_mode t flags

       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" = 0x1 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"  = 0x2 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;  and
       "LIBNBD_CMD_FLAG_PAYLOAD_LEN"  is  managed  automatically  by  libnbd unless "LIBNBD_STRICT_AUTO_FLAG" is
       disabled.

       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"  =  0x4  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"  =  0x8 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"  =  0x10  If  set,   and   the   server   provided   minimum   block   sizes   (see
       "LIBNBD_SIZE_MINIMUM"  for  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.

       "LIBNBD_STRICT_PAYLOAD"  = 0x20 If set, the client refuses to send a command to the server with more than
       libnbd's outgoing payload maximum (see "LIBNBD_SIZE_PAYLOAD" for nbd_get_block_size(3)), whether  or  not
       the  server  advertised  a  block size maximum. If clear, oversize requests up to 64MiB may be attempted,
       although requests larger than 32MiB are liable to cause some servers to disconnect.

       "LIBNBD_STRICT_AUTO_FLAG" = 0x40 If set, commands  that  accept  the  "LIBNBD_CMD_FLAG_PAYLOAD_LEN"  flag
       (such  as  nbd_pwrite(3) and nbd_block_status_filter(3)) ignore the presence or absence of that flag from
       the caller, instead sending the value over the wire that  matches  the  server's  expectations  based  on
       whether  extended headers were negotiated when the connection was made. If clear, the caller takes on the
       responsibility for whether the payload length flag is set or clear during the affected command, which can
       be useful during integration testing but is more likely to lead to undefined behavior.

       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

       NBD.get_strict_mode t

       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

       NBD.set_opt_mode t enable

       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.

       Note   that   libnbd   defaults   to   attempting   "NBD_OPT_STARTTLS",  "NBD_OPT_EXTENDED_HEADERS",  and
       "NBD_OPT_STRUCTURED_REPLY" before letting you control remaining negotiation steps; if  you  need  control
       over    these    steps    as    well,    first    set   nbd_set_tls(3)   to   "LIBNBD_TLS_DISABLE",   and
       nbd_set_request_extended_headers(3) or nbd_set_request_structured_replies(3) to  false,  before  starting
       the connection attempt.

       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)  or nbd_shutdown(3) to end the connection without finishing
       negotiation.

       val get_opt_mode : t -> bool

       NBD.get_opt_mode t

       return whether option mode was enabled

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

       val opt_go : t -> unit

       NBD.opt_go t

       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.

       By default, libnbd will automatically request all meta contexts registered by nbd_add_meta_context(3)  as
       part  of  this  call;  but  this  can be suppressed with nbd_set_request_meta_context(3), particularly if
       nbd_opt_set_meta_context(3) was used earlier in the negotiation sequence.

       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

       NBD.opt_abort t

       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_starttls : t -> bool

       NBD.opt_starttls t

       request the server to initiate TLS

       Request that the server initiate a secure TLS connection, by sending "NBD_OPT_STARTTLS". This can only be
       used  if  nbd_set_opt_mode(3)  enabled  option  mode;  furthermore,  if you use nbd_set_tls(3) to request
       anything other than the default of "LIBNBD_TLS_DISABLE", then libnbd will have already  attempted  a  TLS
       connection  prior  to  allowing  you  control  over  option  negotiation.   This  command  is disabled if
       nbd_supports_tls(3) reports false.

       This function is mainly useful for integration testing of corner cases in server handling; in particular,
       misuse  of this function when coupled with a server that is not careful about resetting stateful commands
       such as nbd_opt_structured_reply(3) could result in a security hole (see  CVE-2021-3716  against  nbdkit,
       for  example).   Thus,  when  security is a concern, you should instead prefer to use nbd_set_tls(3) with
       "LIBNBD_TLS_REQUIRE" and let libnbd negotiate TLS automatically.

       This function returns true if the server replies with success, false if the server replies with an error,
       and fails only if the server does not reply (such as for a loss of connection, which can include when the
       server rejects credentials supplied during the TLS handshake).  Note that the NBD protocol documents that
       requesting  TLS after it is already enabled is a client error; most servers will gracefully fail a second
       request, but that does not downgrade a TLS session that has already  been  established,  as  reported  by
       nbd_get_tls_negotiated(3).

       val opt_extended_headers : t -> bool

       NBD.opt_extended_headers t

       request the server to enable extended headers

       Request  that  the  server  use extended headers, by sending "NBD_OPT_EXTENDED_HEADERS". This can only be
       used if nbd_set_opt_mode(3) enabled option mode; furthermore, libnbd defaults to automatically requesting
       this unless you use nbd_set_request_extended_headers(3) or nbd_set_request_structured_replies(3) prior to
       connecting. This function is mainly useful for integration testing of corner cases in server handling.

       This function returns true if the server replies with success, false if the server replies with an error,
       and  fails  only  if the server does not reply (such as for a loss of connection). Note that some servers
       fail a second request as redundant; libnbd assumes that once one request  has  succeeded,  then  extended
       headers are supported (as visible by nbd_get_extended_headers_negotiated(3)) regardless if later calls to
       this function return false. If this function returns true, the use of structured replies is implied.

       val opt_structured_reply : t -> bool

       NBD.opt_structured_reply t

       request the server to enable structured replies

       Request that the server use structured replies, by sending "NBD_OPT_STRUCTURED_REPLY". This can  only  be
       used if nbd_set_opt_mode(3) enabled option mode; furthermore, libnbd defaults to automatically requesting
       this unless you use nbd_set_request_structured_replies(3) prior to connecting. This  function  is  mainly
       useful for integration testing of corner cases in server handling.

       This function returns true if the server replies with success, false if the server replies with an error,
       and fails only if the server does not reply (such as for a loss of connection). Note  that  some  servers
       fail  a  second request as redundant; libnbd assumes that once one request has succeeded, then structured
       replies are supported (as visible by nbd_get_structured_replies_negotiated(3)) regardless if later  calls
       to  this function return false. Similarly, a server may fail this request if extended headers are already
       negotiated, since extended headers take priority.

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

       NBD.opt_list t list

       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

       NBD.opt_info t

       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.   If  nbd_set_request_meta_context(3)  is  set  (the  default) and structured replies or extended
       headers were negotiated, it is also valid to use nbd_can_meta_context(3) after this call. However, it may
       be  more  efficient  to  clear  that  setting  and manually utilize nbd_opt_list_meta_context(3) with its
       callback approach, for learning which contexts an export supports. 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

       NBD.opt_list_meta_context t context

       list available meta contexts, using implicit query list

       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), and with a list of queries from prior calls
       to  nbd_add_meta_context(3)  (see  nbd_opt_list_meta_context_queries(3) if you want to supply an explicit
       query list instead). 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 opt_list_meta_context_queries : t -> string list -> (string -> int) -> int

       NBD.opt_list_meta_context_queries t queries context

       list available meta contexts, using explicit query list

       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),  and  with  an  explicit  list  of  queries
       provided  as  a  parameter  (see nbd_opt_list_meta_context(3) if you want to reuse an implicit query list
       instead). 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.  For  this  function,  the
       list  is  explicit in the "queries" parameter. 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 opt_set_meta_context : t -> (string -> int) -> int

       NBD.opt_set_meta_context t context

       select specific meta contexts, using implicit query list

       Request  that  the  server  supply  all  recognized  meta  contexts  registered  through  prior  calls to
       nbd_add_meta_context(3), in  conjunction  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.  Normally, this function is redundant,  as  nbd_opt_go(3)  automatically  does  the  same  task  if
       structured replies or extended headers have already been negotiated. But manual control over meta context
       requests can be useful for fine-grained testing of how a server handles  unusual  negotiation  sequences.
       Often,  use  of  this  function  is  coupled with nbd_set_request_meta_context(3) to bypass the automatic
       context request normally performed by nbd_opt_go(3).

       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 (see nbd_opt_set_meta_context_queries(3) to pass an explicit list of contexts instead).
       Since this function is primarily designed for testing servers, libnbd does not prevent the  use  of  this
       function  on an empty list or when nbd_set_request_structured_replies(3) has disabled structured replies,
       in order to see how a server behaves.

       The "context" function is called once per server reply, with any "user_data" passed to this function, and
       with  "name"  supplied  by  the  server.  Additionally,  each  server  name  will  remain visible through
       nbd_can_meta_context(3) until the next attempt at nbd_set_export_name(3) or  nbd_opt_set_meta_context(3),
       as well as nbd_opt_go(3) or nbd_opt_info(3) that trigger an automatic meta context request. Remember that
       it is not safe to call any "nbd_*" APIs from within the context of the callback function. 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.

       val opt_set_meta_context_queries : t -> string list -> (string -> int) -> int

       NBD.opt_set_meta_context_queries t queries context

       select specific meta contexts, using explicit query list

       Request that the server supply all recognized meta contexts passed in through "queries",  in  conjunction
       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.  Normally, this function is  redundant,
       as  nbd_opt_go(3) automatically does the same task if structured replies or extended headers have already
       been negotiated. But manual control over meta context requests can be useful for fine-grained testing  of
       how  a  server  handles  unusual  negotiation  sequences.  Often,  use  of  this function is coupled with
       nbd_set_request_meta_context(3)  to  bypass  the  automatic  context  request   normally   performed   by
       nbd_opt_go(3).

       The  NBD  protocol  allows  a client to decide how many queries to ask the server. This function takes an
       explicit list of queries; to instead reuse an implicit list, see nbd_opt_set_meta_context(3). Since  this
       function  is  primarily designed for testing servers, libnbd does not prevent the use of this function on
       an empty list or when nbd_set_request_structured_replies(3) has disabled structured replies, in order  to
       see how a server behaves.

       The "context" function is called once per server reply, with any "user_data" passed to this function, and
       with "name" supplied  by  the  server.  Additionally,  each  server  name  will  remain  visible  through
       nbd_can_meta_context(3)  until the next attempt at nbd_set_export_name(3) or nbd_opt_set_meta_context(3),
       as well as nbd_opt_go(3) or nbd_opt_info(3) that trigger an automatic meta context request. Remember that
       it is not safe to call any "nbd_*" APIs from within the context of the callback function. 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.

       val add_meta_context : t -> string -> unit

       NBD.add_meta_context t name

       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_64(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

       NBD.get_nr_meta_contexts t

       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_64(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

       NBD.get_meta_context t i

       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_64(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

       NBD.clear_meta_contexts t

       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_64(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

       NBD.set_uri_allow_transports t mask

       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" = 0x1 "LIBNBD_ALLOW_TRANSPORT_UNIX" = 0x2  "LIBNBD_ALLOW_TRANSPORT_VSOCK"  =
       0x4

       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

       NBD.set_uri_allow_tls t tls

       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

       NBD.set_uri_allow_local_file t allow

       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

       NBD.connect_uri t uri

       connect to NBD URI

       Connect (synchronously) to an NBD server and export by specifying the NBD URI. NBD URIs  are  a  standard
       way  to  specify  a  network  block  device  endpoint,  using  a syntax like "nbd://example.com" which is
       convenient, well defined and future proof.

       This call works by parsing the URI parameter and calling nbd_set_export_name(3)  and  nbd_set_tls(3)  and
       other calls as needed, followed by nbd_connect_tcp(3), nbd_connect_unix(3) or nbd_connect_vsock(3).

       This  call  returns  when  the  connection  has  been  made.  By  default,  this  proceeds all the way to
       transmission phase, but nbd_set_opt_mode(3) can be  used  for  manual  control  over  option  negotiation
       performed before transmission phase.

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

       "nbds+unix://alice@/?socket=/tmp/nbd.sock&tls-certificat  es=certs"  Connect  over  a Unix domain socket,
       enabling TLS and setting the path to a directory containing certificates and keys.

       "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. You
       can use nbd_supports_vsock(3) to see if this build of libnbd supports "AF_VSOCK".

       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-certificates=DIR Set the certificates directory. See nbd_set_tls_certificates(3). Note  this  is  not
       allowed by default - see next section.

       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.

       tls-verify-peer=false Do not verify the server certificate. See nbd_set_tls_verify_peer(3).  The  default
       is "true".

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

       Overriding  the  export  name  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.

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

       Constructing a URI from an existing connection See nbd_get_uri(3).

       val connect_unix : t -> string -> unit

       NBD.connect_unix t unixsocket

       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.  By  default,  this  proceeds  all  the  way  to
       transmission  phase,  but  nbd_set_opt_mode(3)  can  be  used  for manual control over option negotiation
       performed before transmission phase.

       val connect_vsock : t -> int64 -> int64 -> unit

       NBD.connect_vsock t cid port

       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.

       Not  all systems support "AF_VSOCK"; to determine if libnbd was built on a system with vsock support, see
       nbd_supports_vsock(3).

       This call returns when the  connection  has  been  made.  By  default,  this  proceeds  all  the  way  to
       transmission  phase,  but  nbd_set_opt_mode(3)  can  be  used  for manual control over option negotiation
       performed before transmission phase.

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

       NBD.connect_tcp t hostname port

       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.  By  default,  this  proceeds all the way to
       transmission phase, but nbd_set_opt_mode(3) can be  used  for  manual  control  over  option  negotiation
       performed before transmission phase.

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

       NBD.connect_socket t sock

       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.

       This  call  returns  when  the  connection  has  been  made.  By  default,  this  proceeds all the way to
       transmission phase, but nbd_set_opt_mode(3) can be  used  for  manual  control  over  option  negotiation
       performed before transmission phase.

       val connect_command : t -> string list -> unit

       NBD.connect_command t argv

       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(1) using the *-s*/*--single* flag, and  nbd-server(1)
       with port number set to 0.

       To run qemu-nbd(1), use nbd_connect_systemd_socket_activation(3) instead.

       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.

       This call returns when the  connection  has  been  made.  By  default,  this  proceeds  all  the  way  to
       transmission  phase,  but  nbd_set_opt_mode(3)  can  be  used  for manual control over option negotiation
       performed before transmission phase.

       val connect_systemd_socket_activation : t -> string list -> unit

       NBD.connect_systemd_socket_activation t argv

       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, this function can be used, or nbd_connect_command(3).

       To run nbd-server(1) as a subprocess, this function cannot be used, you must 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.

       Socket name The socket activation protocol lets you optionally give the socket a name. If used, the  name
       is  passed  to  the NBD server using the "LISTEN_FDNAMES" environment variable. To provide a socket name,
       call nbd_set_socket_activation_name(3) before calling the connect function.

       This call returns when the  connection  has  been  made.  By  default,  this  proceeds  all  the  way  to
       transmission  phase,  but  nbd_set_opt_mode(3)  can  be  used  for manual control over option negotiation
       performed before transmission phase.

       val set_socket_activation_name : t -> string -> unit

       NBD.set_socket_activation_name t socket_name

       set the socket activation name

       When running an NBD server using nbd_connect_systemd_socket_activation(3) you  can  optionally  name  the
       socket. Call this function before connecting to the server.

       Some  servers such as qemu-storage-daemon(1) can use this information to associate the socket with a name
       used  on  the  command  line,  but  most  servers  will  ignore  it.  The  name  is  passed  through  the
       "LISTEN_FDNAMES" environment variable.

       The  parameter  "socket_name"  can be a short alphanumeric string. If it is set to the empty string (also
       the default when the handle is created) then the name "unknown" will be seen by the server.

       val get_socket_activation_name : t -> string

       NBD.get_socket_activation_name t

       get the socket activation name

       Return the socket name used when you call nbd_connect_systemd_socket_activation(3) on the same handle. By
       default this will return the empty string meaning that the server will see the name "unknown".

       val is_read_only : t -> bool

       NBD.is_read_only t

       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

       NBD.can_flush t

       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

       NBD.can_fua t

       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

       NBD.is_rotational t

       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

       NBD.can_trim t

       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

       NBD.can_zero t

       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

       NBD.can_fast_zero t

       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_block_status_payload : t -> bool

       NBD.can_block_status_payload t

       does the server support the block status payload flag?

       Returns  true if the server supports the use of the "LIBNBD_CMD_FLAG_PAYLOAD_LEN" flag to allow filtering
       of the block status command (see nbd_block_status_filter(3)). Returns false if the server does not.  Note
       that this will never return true if nbd_get_extended_headers_negotiated(3) is false.

       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

       NBD.can_df t

       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

       NBD.can_multi_conn t

       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

       NBD.can_cache t

       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

       NBD.can_meta_context t metacontext

       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. It is possible for this command to fail if meta contexts were requested but there
       is a missing or failed attempt at NBD_OPT_SET_META_CONTEXT during option negotiation.

       If the server supports block status filtering (see nbd_can_block_status_payload(3),  this  function  must
       return true for any filter name passed to nbd_block_status_filter(3).

       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

       NBD.get_protocol t

       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

       NBD.get_size t

       return the export size

       Returns the size in bytes of the NBD export.

       Note that this call fails with "EOVERFLOW" for an unlikely server that advertises a size which cannot fit
       in a 64-bit signed integer.

       nbdinfo(1) *--size* option is a way to access this API from shell scripts.

       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

       NBD.get_block_size t size_type

       return a specific server block size constraint

       Returns  a  specific  block  size  constraint  advertised by the server. If zero is returned it means the
       server did not advertise a constraint.

       Constraints are hints. Servers differ in their behaviour as to whether they enforce constraints or not.

       The "size_type" parameter selects which constraint to read. It can be one of:

       "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 (meaning no information was returned by the server), 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 (meaning no information was returned by the server), 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 (meaning no information was returned by the server), some NBD servers will abruptly disconnect if
       a transaction sends or receives more than 32M of data.

       "LIBNBD_SIZE_PAYLOAD"  =  3 This value is not advertised by the server, but rather represents the maximum
       outgoing payload size for a given connection that libnbd will enforce unless  "LIBNBD_STRICT_PAYLOAD"  is
       cleared  in  nbd_set_strict_mode(3). It is always non-zero: never smaller than 1M, never larger than 64M,
       and matches "LIBNBD_SIZE_MAXIMUM" when possible.

       Future NBD extensions may result in additional "size_type" values. Note that by default, libnbd  requests
       all  available  block  sizes,  but  that  a  server  may  differ  in  what  sizes it chooses to report if
       nbd_set_request_block_size(3) alters whether the client requests sizes.

       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

       NBD.pread t ?flags buf offset

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

       Note that libnbd currently enforces a maximum read buffer of 64MiB, even if the  server  would  permit  a
       larger  buffer  in  a  single  transaction; attempts to exceed this will result in an "ERANGE" error. The
       server may enforce a smaller limit, which can be learned with nbd_get_block_size(3).

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

       Note that if this command fails, and nbd_get_pread_initialize(3)  returns  true,  then  libnbd  sanitized
       "buf",  but  it is unspecified whether the contents of "buf" will read as zero or as partial results from
       the server. If nbd_get_pread_initialize(3) returns false, then libnbd did not  sanitize  "buf",  and  the
       contents are undefined on failure.

       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

       NBD.pread_structured t ?flags buf offset chunk

       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.

       Note that libnbd currently enforces a maximum read buffer of 64MiB, even if the  server  would  permit  a
       larger  buffer  in  a  single  transaction; attempts to exceed this will result in an "ERANGE" error. The
       server may enforce a smaller limit, which can be learned with nbd_get_block_size(3).

       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.

       Note that if this command fails, and nbd_get_pread_initialize(3)  returns  true,  then  libnbd  sanitized
       "buf",  but  it is unspecified whether the contents of "buf" will read as zero or as partial results from
       the server. If nbd_get_pread_initialize(3) returns false, then libnbd did not  sanitize  "buf",  and  the
       contents are undefined on failure.

       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

       NBD.pwrite t ?flags buf offset

       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.

       Note that libnbd defaults to enforcing a maximum write buffer of the  lesser  of  64MiB  or  any  maximum
       payload  size  advertised  by  the server; attempts to exceed this will generally result in a client-side
       "ERANGE" error,  rather  than  a  server-side  disconnection.  The  actual  limit  can  be  learned  with
       nbd_get_block_size(3).

       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)). For convenience, unless nbd_set_strict_flags(3) was used to
       disable   "LIBNBD_STRICT_AUTO_FLAG",   libnbd   ignores   the   presence   or   absence   of   the   flag
       "LIBNBD_CMD_FLAG_PAYLOAD_LEN"  in  "flags",  while  correctly  using  the flag over the wire according to
       whether extended headers were negotiated.

       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

       NBD.shutdown t ?flags

       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_opt_abort(3) and 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

       NBD.flush t ?flags

       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

       NBD.trim t ?flags count offset

       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.

       Note that not all servers can support a "count" of 4GiB or larger; nbd_get_extended_headers_negotiated(3)
       indicates  which  servers  will parse a request larger than 32 bits. The NBD protocol does not yet have a
       way for a client to learn if the server will enforce an even smaller maximum trim size, although a future
       extension may add a constraint visible in nbd_get_block_size(3).

       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

       NBD.cache t ?flags count offset

       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.

       Note that not all servers can support a "count" of 4GiB or larger; nbd_get_extended_headers_negotiated(3)
       indicates which servers will parse a request larger than 32 bits. The NBD protocol does not  yet  have  a
       way  for  a  client  to  learn  if the server will enforce an even smaller maximum cache size, although a
       future extension may add a constraint visible in nbd_get_block_size(3).

       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

       NBD.zero t ?flags count offset

       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.

       Note that not all servers can support a "count" of 4GiB or larger; nbd_get_extended_headers_negotiated(3)
       indicates which servers will parse a request larger than 32 bits. The NBD protocol does not  yet  have  a
       way for a client to learn if the server will enforce an even smaller maximum zero size, although a future
       extension may add a constraint visible in nbd_get_block_size(3).  Also, some servers may permit a  larger
       zero request only when the "LIBNBD_CMD_FLAG_FAST_ZERO" is in use.

       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 ->  int64  array  ->
       int Stdlib.ref -> int) -> unit

       NBD.block_status t ?flags count offset extent

       send block status command, with 32-bit callback

       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.

       Note that not all servers can support a "count" of 4GiB or larger; nbd_get_extended_headers_negotiated(3)
       indicates which servers will parse a request larger than 32 bits. The NBD protocol does not  yet  have  a
       way  for a client to learn if the server will enforce an even smaller maximum block status size, although
       a future extension may add a constraint visible in nbd_get_block_size(3). Furthermore, this  function  is
       inherently  limited  to  32-bit  values.  If  the server replies with a larger extent, the length of that
       extent will be truncated to just below 32 bits and any further extents from the server will  be  ignored.
       If the server replies with a status value larger than 32 bits (only possible when extended headers are in
       use), the callback function will be passed an "EOVERFLOW" error. To get the full extent information  from
       a server that supports 64-bit extents, you must use nbd_block_status_64(3).

       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,  but
       even if an earlier error was detected, the current "metacontext" and "entries" are valid.

       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  block_status_64  : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 -> (string -> int64 -> extent array
       -> int Stdlib.ref -> int) -> unit

       NBD.block_status_64 t ?flags count offset extent64

       send block status command, with 64-bit callback

       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. When multiple contexts are supported, the number of blocks and cumulative length of
       those blocks need not be identical between contexts; this command generally returns  the  status  of  all
       negotiated    contexts,    while    some    servers    also    support    a    filtered    request   (see
       nbd_can_block_status_payload(3), nbd_block_status_filter(3)).

       Note that not all servers can support a "count" of 4GiB or larger; nbd_get_extended_headers_negotiated(3)
       indicates  which  servers  will parse a request larger than 32 bits. The NBD protocol does not yet have a
       way for a client to learn if the server will enforce an even smaller maximum block status size,  although
       a future extension may add a constraint visible in nbd_get_block_size(3).

       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 "extent64" 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  "extent64"  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 nbd_extent structs, containing length (in bytes) of the block and a status/flags field which
       is specific to the metadata context. The number of array entries passed to the function is  "nr_entries".
       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 block_status_filter : ?flags:CMD_FLAG.t list -> t -> int64 -> int64 ->  string  list  ->  (string  ->
       int64 -> extent array -> int Stdlib.ref -> int) -> unit

       NBD.block_status_filter t ?flags count offset contexts extent64

       send filtered block status command, with 64-bit callback

       Issue   a  filtered  block  status  command  to  the  NBD  server.   If  supported  by  the  server  (see
       nbd_can_block_status_payload(3)), this causes metadata context information about  blocks  beginning  from
       the  specified  offset  to  be  returned,  and  with the result limited to just the contexts specified in
       "filter". Note that all strings in "filter" must be supported by nbd_can_meta_context(3).

       All other parameters to this function have the same semantics as in nbd_block_status_64(3);  except  that
       for  convenience,  unless <nbd_set_strict_flags(3)> was used to disable "LIBNBD_STRICT_AUTO_FLAG", libnbd
       ignores the presence or absence of the flag "LIBNBD_CMD_FLAG_PAYLOAD_LEN"  in  "flags",  while  correctly
       using the flag over the wire.

       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

       NBD.poll t timeout

       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 poll2 : t -> Unix.file_descr -> int -> int

       NBD.poll2 t fd timeout

       poll the handle once, with fd

       This is the same as nbd_poll(3), but an additional file descriptor parameter is passed. The additional fd
       is also polled (using "POLLIN"). One use for this is to wait for an eventfd(2).

       val aio_connect : t -> Unix.sockaddr -> unit

       NBD.aio_connect t addr

       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  attempt  is  still  underway  by  calling  nbd_aio_is_connecting(3).  If
       nbd_set_opt_mode(3)   is   enabled,   the   connection  is  ready  for  manual  option  negotiation  once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

       val aio_connect_uri : t -> string -> unit

       NBD.aio_connect_uri t uri

       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  attempt  is  still underway by calling nbd_aio_is_connecting(3). If
       nbd_set_opt_mode(3)  is  enabled,  the  connection  is  ready  for   manual   option   negotiation   once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

       val aio_connect_unix : t -> string -> unit

       NBD.aio_connect_unix t unixsocket

       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  attempt  is  still underway by calling nbd_aio_is_connecting(3). If
       nbd_set_opt_mode(3)  is  enabled,  the  connection  is  ready  for   manual   option   negotiation   once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

       val aio_connect_vsock : t -> int64 -> int64 -> unit

       NBD.aio_connect_vsock t cid port

       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  attempt  is  still underway by calling nbd_aio_is_connecting(3). If
       nbd_set_opt_mode(3)  is  enabled,  the  connection  is  ready  for   manual   option   negotiation   once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

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

       NBD.aio_connect_tcp t hostname port

       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  attempt  is  still underway by calling nbd_aio_is_connecting(3). If
       nbd_set_opt_mode(3)  is  enabled,  the  connection  is  ready  for   manual   option   negotiation   once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

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

       NBD.aio_connect_socket t sock

       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  attempt  is  still  underway  by  calling  nbd_aio_is_connecting(3).  If
       nbd_set_opt_mode(3)   is   enabled,   the   connection  is  ready  for  manual  option  negotiation  once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

       val aio_connect_command : t -> string list -> unit

       NBD.aio_connect_command t argv

       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  attempt  is  still  underway  by  calling  nbd_aio_is_connecting(3).  If
       nbd_set_opt_mode(3)   is   enabled,   the   connection  is  ready  for  manual  option  negotiation  once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

       val aio_connect_systemd_socket_activation : t -> string list -> unit

       NBD.aio_connect_systemd_socket_activation t argv

       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  attempt  is  still  underway  by  calling  nbd_aio_is_connecting(3).  If
       nbd_set_opt_mode(3)   is   enabled,   the   connection  is  ready  for  manual  option  negotiation  once
       nbd_aio_is_negotiating(3) returns true; otherwise, the connection attempt will include the NBD handshake,
       and is ready for use once nbd_aio_is_ready(3) returns true.

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

       NBD.aio_opt_go t ?completion

       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

       NBD.aio_opt_abort t

       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_starttls : ?completion:(int Stdlib.ref -> int) -> t -> unit

       NBD.aio_opt_starttls t ?completion

       request the server to initiate TLS

       Request  that  the  server  initiate a secure TLS connection, by sending "NBD_OPT_STARTTLS". This behaves
       like the synchronous counterpart nbd_opt_starttls(3), except that it  does  not  wait  for  the  server's
       response.

       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_extended_headers : ?completion:(int Stdlib.ref -> int) -> t -> unit

       NBD.aio_opt_extended_headers t ?completion

       request the server to enable extended headers

       Request  that  the  server use extended headers, by sending "NBD_OPT_EXTENDED_HEADERS". This behaves like
       the synchronous counterpart nbd_opt_extended_headers(3), except that it does not wait  for  the  server's
       response.

       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_structured_reply : ?completion:(int Stdlib.ref -> int) -> t -> unit

       NBD.aio_opt_structured_reply t ?completion

       request the server to enable structured replies

       Request  that the server use structured replies, by sending "NBD_OPT_STRUCTURED_REPLY". This behaves like
       the synchronous counterpart nbd_opt_structured_reply(3), except that it does not wait  for  the  server's
       response.

       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 : ?completion:(int Stdlib.ref -> int) -> t -> (string -> string -> int) -> unit

       NBD.aio_opt_list t ?completion list

       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

       NBD.aio_opt_info t ?completion

       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

       NBD.aio_opt_list_meta_context t ?completion context

       request list of available meta contexts, using implicit query

       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), and with a list of queries from prior calls
       to nbd_add_meta_context(3)  (see  nbd_aio_opt_list_meta_context_queries(3)  if  you  want  to  supply  an
       explicit query list instead). 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_queries  :  ?completion:(int  Stdlib.ref  ->  int)  -> t -> string list ->
       (string -> int) -> int

       NBD.aio_opt_list_meta_context_queries t ?completion queries context

       request list of available meta contexts, using explicit query

       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),  and  with an explicit list of queries
       provided as a parameter (see nbd_aio_opt_list_meta_context(3) if you want to reuse an implicit query list
       instead). 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_set_meta_context : ?completion:(int Stdlib.ref -> int) -> t -> (string -> int) -> int

       NBD.aio_opt_set_meta_context t ?completion context

       select specific meta contexts, with implicit query list

       Request  that  the  server  supply  all  recognized  meta  contexts  registered  through  prior  calls to
       nbd_add_meta_context(3), in  conjunction  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.  Normally, this function is redundant,  as  nbd_opt_go(3)  automatically  does  the  same  task  if
       structured replies or extended headers have already been negotiated. But manual control over meta context
       requests can be useful for fine-grained testing of how a server handles  unusual  negotiation  sequences.
       Often,  use  of  this  function  is  coupled with nbd_set_request_meta_context(3) to bypass the automatic
       context request normally performed by nbd_opt_go(3).

       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_set_meta_context_queries : ?completion:(int Stdlib.ref -> int) -> t -> string list -> (string
       -> int) -> int

       NBD.aio_opt_set_meta_context_queries t ?completion queries context

       select specific meta contexts, with explicit query list

       Request  that  the server supply all recognized meta contexts passed in through "queries", in conjunction
       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.  Normally, this function is redundant,
       as nbd_opt_go(3) automatically does the same task if structured replies or extended headers have  already
       been  negotiated. But manual control over meta context requests can be useful for fine-grained testing of
       how a server handles unusual  negotiation  sequences.  Often,  use  of  this  function  is  coupled  with
       nbd_set_request_meta_context(3)   to   bypass   the  automatic  context  request  normally  performed  by
       nbd_opt_go(3).

       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

       NBD.aio_pread t ?completion ?flags buf offset

       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.  Furthermore,  if  the  "error"
       parameter  to  "completion_callback"  is  set  or if nbd_aio_command_completed(3) reports failure, and if
       nbd_get_pread_initialize(3) returns true, then libnbd sanitized "buf", but it is unspecified whether  the
       contents of "buf" will read as zero or as partial results from the server. If nbd_get_pread_initialize(3)
       returns false, then libnbd did not sanitize "buf", and the contents are undefined on failure.

       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

       NBD.aio_pread_structured t ?completion ?flags buf offset chunk

       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.  Furthermore,  if  the  "error"
       parameter  to  "completion_callback"  is  set  or if nbd_aio_command_completed(3) reports failure, and if
       nbd_get_pread_initialize(3) returns true, then libnbd sanitized "buf", but it is unspecified whether  the
       contents of "buf" will read as zero or as partial results from the server. If nbd_get_pread_initialize(3)
       returns false, then libnbd did not sanitize "buf", and the contents are undefined on failure.

       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

       NBD.aio_pwrite t ?completion ?flags buf offset

       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

       NBD.aio_disconnect t ?flags

       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

       NBD.aio_flush t ?completion ?flags

       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

       NBD.aio_trim t ?completion ?flags count offset

       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

       NBD.aio_cache t ?completion ?flags count offset

       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

       NBD.aio_zero t ?completion ?flags count offset

       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 -> int64 array -> int Stdlib.ref -> int) -> cookie

       NBD.aio_block_status t ?completion ?flags count offset extent

       send block status command, with 32-bit callback

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

       This  function  is  inherently  limited to 32-bit values. If the server replies with a larger extent, the
       length of that extent will be truncated to just below 32 bits and any further  extents  from  the  server
       will  be  ignored.  If  the  server  replies  with a status value larger than 32 bits (only possible when
       extended headers are in use), the callback function will be passed an "EOVERFLOW" error. To get the  full
       extent information from a server that supports 64-bit extents, you must use nbd_aio_block_status_64(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_64 : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64 ->
       int64 -> (string -> int64 -> extent array -> int Stdlib.ref -> int) -> cookie

       NBD.aio_block_status_64 t ?completion ?flags count offset extent64

       send block status command, with 64-bit callback

       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_64(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_filter : ?completion:(int Stdlib.ref -> int) -> ?flags:CMD_FLAG.t list -> t -> int64
       -> int64 -> string list -> (string -> int64 -> extent array -> int Stdlib.ref -> int) -> cookie

       NBD.aio_block_status_filter t ?completion ?flags count offset contexts extent64

       send filtered block status command to the NBD server

       Send a filtered 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_filter(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

       NBD.aio_get_fd t

       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

       NBD.aio_get_direction t

       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

       NBD.aio_notify_read t

       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

       NBD.aio_notify_write t

       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

       NBD.aio_is_created t

       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

       NBD.aio_is_connecting t

       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

       NBD.aio_is_negotiating t

       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

       NBD.aio_is_ready t

       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

       NBD.aio_is_processing t

       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

       NBD.aio_is_dead t

       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

       NBD.aio_is_closed t

       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

       NBD.aio_command_completed t cookie

       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

       NBD.aio_peek_command_completed t

       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

       NBD.aio_in_flight t

       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

       NBD.connection_state t

       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

       NBD.get_package_name t

       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

       NBD.get_version t

       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

       NBD.kill_subprocess t signum

       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

       NBD.supports_tls t

       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_vsock : t -> bool

       NBD.supports_vsock t

       true if libnbd was compiled with support for AF_VSOCK

       Returns true if libnbd was compiled with support for the "AF_VSOCK" family of sockets, or false if not.

       Note that on the Linux operating system, this returns true if there is compile-time support, but you  may
       still  need runtime support for some aspects of AF_VSOCK usage; for example, use of "VMADDR_CID_LOCAL" as
       the server name requires that the *vsock_loopback* kernel module is loaded.

       val supports_uri : t -> bool

       NBD.supports_uri t

       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.

       val get_uri : t -> string

       NBD.get_uri t

       construct an NBD URI for a connection

       This makes a best effort attempt to construct an NBD URI which could be used to connect back to the  same
       server (using nbd_connect_uri(3)).

       In  some  cases  there  is  not enough information in the handle to successfully create a URI (eg. if you
       connected with nbd_connect_socket(3)). In such cases the  call  returns  "NULL"  and  further  diagnostic
       information is available via nbd_get_errno(3) and nbd_get_error(3) as usual.

       Even if a URI is returned it is not guaranteed to work, and it may not be optimal.

       nbdinfo(1) *--uri* option is a way to access this API from shell scripts.