gonbdserver
is an NBD server written in Go. Its purpose is not to
be especially performant, but rather to act as a simple demonstration
of the implementation of the NBD protocol. That said, where tested
it appears to be at least as fast as the reference nbdserver implementation.
-
Wide protocol support. Supports both FLUSH and FUA.
-
Multithreaded. Defaults to 5 worker threads per connection, so able to process requests in parallel.
-
TLS support. With client certificates if required.
-
Ceph RBD support. Almost entirely untested.
-
Linux AIO support. Experimental.
-
Pluggable backends. By default a file backend is provided, as well as a Ceph/RBD backend on linux, but it would be possible to supply any backend. The ceph driver is there mostly to illustrate just how easy this is.
-
Reloadable configuration. It is possible to reload the configuration using
SIGHUP
without affecting existing servers. -
Newstyle negotiation (only). Oldstyle negotiation is not supported. This is a feature, not a bug.
-
Logging. To syslog, a file, or stderr
-
WRITE_ZEROES
- support forNBD_CMD_WRITE_ZEROES
-
INFO
- support forNBD_OPT_INFO
,NBD_OPT_GO
andNBD_OPT_BLOCK_SIZE
.
Invocation is very easy. It takes a minimum number of command-line flags. Most of the configuration is within the configuration file.
$ ./gonbdserver --help
Usage of ./gonbdserver:
-c string
Path to YAML config file (default "/etc/gonbdserver.conf")
-f Run in foreground (not as daemon)
-p string
Path to PID file (default "/var/run/gonbdserver.pid")
-s string
Send signal to daemon (either "stop" or "reload")
By default gonbdserver
runs as a daemon. You can use -f
to make it run in the foreground.
If you are running on Linux and want to run from init
, you may wish to consider using
start-stop-daemon
with the -b
flag, and invoking gondbserver
with the -f
flag,
as start-stop-daemon
is probably better at dealing with the many possible failure modes.
When running in foreground mode, the pid
file is not used, and -s
is irrelevant.
Note that to use the -s
option, it is necessary to specify the -c
and -p
options
that you used in launching the daemon.
-
SIGHUP
(orgonbdserver -s reload
) will cleanly reload the configuration. Existing connections to the server will be unaffected (i.e. they will run with the previous configuration) until a disconnect / reconnect occurs. -
SIGTERM
(orgonbdserver -s stop
) will cleanly terminate the daemon. Existing connections to the server will be terminated.
Configuration is provided through a YAML file which by default lives at
/etc/gonbdserver.conf
, though this can be specified using the -c
option.
An example of a configuration is set out below:
servers:
- protocol: tcp # A first server, using TCP
address: 127.0.0.1:6666 # on port 6666
exports: # It has two exports
- name: foo # The first is named 'foo' and
driver: file # Uses the 'file' driver
path: /tmp/test # This uses /tmp/test as the file
workers: 4 # Use 4 workers
- name: bar # The second export is called 'bar'
readonly: true # This is readonly
driver: rbd # And uses the (currently imaginary) rbd driver
image: rbdbar # on this rados block device name
tlsonly: true # require TLS on this device
tls: # use the following certificates
keyfile: /path/to/server-key.pem
certfile: /path/to/server-cert.pem
cacertfile: /path/to/ca-cert.pem
servername: foo.example.com # present the server name as 'foo.example.com'
clientauth: requireverify # require and verify client certificates
- protocol: unix # Another server uses UNIX
address: /var/run/nbd.sock # served on this socket
exports: # it has one export
- name: baz # named bar
driver: file # using the file driver
path: /tmp/baz # on this file
sync: true # open with O_SYNC
disablenozeroes: true # disable nozereos for back compatibility
logging: # log to
syslogfacility: local1 # local1
A description of the configuration file's sections is set out below
The top level of the configuration file consists of the following sections:
servers:
A list of zero or moreserver
itemslogging:
Alogging
item (optional)
Each server
item specifies a TCP port or unix socket that is listened to for new connections.
Each server
item consists of the following:
protocol:
a description of the protocol it should listen. Valid values aretcp
,tcp4
(TCP on IPv4 only),tcp6
(TCP on IPv6 ony), orunix
. Optional, defaults totcp
.address:
the address to listen on. For TCP protocols, this takes the formaddress:port
in the normal manner. For UNIX protocols, this is the path to a Unix domain socket. Mandatory.exports:
a list of zero or moreexport
items each representing an export to be served by this server. This section is optional (and can be empty), but the server will be of little use if so.defaultexport:
the name of the default export, which should be selected if no name is specified by the client. Optional, defaults to none.tls:
a TLS itemdisablenozeroes:
: disableNBD_FLAG_NO_ZEROES
for back compatibility with nbd client prior to 3.10, where in error this was sent to the kernel as a 'read-only' flag. Optional, defaults to false.
Each export
item represents an export (i.e. an NBD disk) to be served by the server. Each export is served by a driver, and the drivers parameters (which are specific to the driver) may be intermingled with the export parameters.
Each export
item consists of the following (common to all drivers):
name:
the name of the export as served over NBD. Mandatory.description:
the human readable description of the export. Optional, defaults to an empty string.driver:
the driver. Currently valid drivers are:file
. Mandatory.readonly:
set totrue
for readonly,false
otherwise. Optional, defaults tofalse
.workers:
the number of simultaneous worker threads. Optional, defaults to 5.tlsonly:
set totrue
if the export is only to be provided over TLS,false
otherwise. Optional, defaults tofalse
minimumblocksize:
set to the minimum block size (must be a power of two). Optional, defaults to driver's minimum block sizepreferredblocksize:
set to the preferred block size (must be a power of two). Optional, defaults to driver's preferred block sizemaximumblocksize:
set to the maximum block size (must be a multiple of preferredblocksize). Optional, defaults to driver's maximum block sizeflush:
set totrue
to forcibly enable support of the flush command, even if the driver does not support it; set tofalse
to forcibly disable support for the flush command, even if the driver does support it. Optional, defaults to unset (i.e. use the driver's own setting)fua:
set totrue
to forcibly enable support of the FUA (force unit access) flag, even if the driver does not support it; set tofalse
to forcibly disable support for the FUA flag, even if the driver does support it. Optional, defaults to unset (i.e. use the driver's own setting)
The file
driver reads the disk from a file on the host OS's disks. It has the following options:
path:
path to the file. Mandatory.sync:
set totrue
to open the file withO_SYNC
, else tofalse
. Optional, defaults tofalse
.
The aiofile
driver reads the disk from a file on the host OS's disks using AIO (available on Linux only). This driver is experimental; do not use it in production. It has the following options:
path:
path to the file. Mandatory.sync:
set totrue
to open the file withO_SYNC
, else tofalse
. Optional, defaults tofalse
.
The rbd
driver reads the disk from Ceph. It relies on your ceph.conf
file being set up correctly, and has the following options:
image:
RBD name of image. Mandatory.pool:
RBD pool for image. Optional, defaults torbd
.cluster:
ceph cluster name. Defaults toceph
.user:
ceph user name. Defaults toclient.admin
.
Note the Ceph driver is almost entirely untested
The tls
item is used to enable TLS encryption on a server. If TLS is enabled on a server, the exports will be available over TLS. To make individual exports available only over TLS, add tlsonly: true
to the export
keyfile:
Path to TLS key file in PEM format. Mandatory.certfile:
Path to TLS cert file in PEM format. Optional, if not provided, defaults toKeyFile
and assumes the PEM atkeyfile
has the certificate in as well as the private key.servername:
Server name as announced by TLS. Optional, if not provided defaults to host name.cacertfile:
Path to a file containing one or more CA certificates in PEM format. Optional, but required if validating client certificatesclientauth:
Client authentication strategy. Optional, defaulting tonone
. Must be one of the following values:none
(no client certificate is requested or verified),request
(a client certificate is requested but not verified),require
(a client certificate is requested and required, but not verified),verify
(a client certificate is requested and if provided is verified), orrequireverify
(a client certificate is requested and required, then verified)minversion:
minimum TLS version. Optional, defaults to no minimum version. Must be one of the following values:ssl3.0
,tls1.0
,tls1.1
ortls1.2
.maxversion:
maximum TLS version. Optional, defaults to no maximum version. Must be one of the following values:ssl3.0
,tls1.0
,tls1.1
ortls1.2
.
The logging
item controls logging. There are three types of logging supported:
- Logging to
stderr
(the default) - Logging to a file
- Logging to syslog
The logging
item consists of the following:
File:
a the path to a file to log to. Optional. If not specified, will not log to a file. May not be specified together withSyslogFacility
.FileMode:
the permission mode (in octal) used to create the file. Optional. Defaults to0644
.SyslogFacility:
the name of a syslog facility. Optional. If not specified, will not log to syslog. May not be specified together withFile:
.Date
: set totrue
to log the date, else set tofalse
. Optional. Defaults tofalse
. Note if logging to syslog, your syslog daemon may add the date anyway.Time
: set totrue
to log the time, else set tofalse
. Optional. Defaults tofalse
. Note if logging to syslog, your syslog daemon may add the time anyway.Microseconds
: set totrue
to log the time in microseconds, else set tofalse
. Optional. Defaults tofalse
. Note if logging to syslog, your syslog daemon may add the time anyway.UTC
: set totrue
to log the time in UTC, else set tofalse
. Optional. Defaults tofalse
. Note if logging to syslog, your syslog daemon may add the time anyway.SourceFile
: set totrue
to log the source file emitting the log message, else set tofalse
. Optional. Defaults tofalse
.
The code is licensed under the MIT licence.