Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
f8d7d3d
fix generation of systemd service
eworm-de Mar 4, 2024
256f95a
Set sensible default for port
waveform80 Mar 14, 2024
f0418b0
Fix the check & no cases of enable_manpages
waveform80 Mar 14, 2024
c1899cf
fix clang warnings in nbd-server.c
Mar 30, 2024
ac83952
Drop now-superfluous g_key_file_free()
yoe Apr 3, 2024
c9eb9b2
Enable TLS1.3 by default
yoe Apr 7, 2024
4efb275
Actually, do this differently
yoe Apr 7, 2024
a956b6b
clean-up headers necessary for treefiles.o, minor source formatting f…
Apr 10, 2024
22ba4a8
umask(77) -> umask(077): "allow rwx permission for the owner, but pro…
Apr 10, 2024
4a4c3ad
buffer is 'const void*' in output functions, as in write(2), fwrite(3…
RokerHRO May 6, 2024
d294cda
Depend on the nbd module being loaded
yoe May 15, 2024
4664b8d
nbd-client: Fix build on musl + gcc14
kraj May 21, 2024
99cb654
Clarify error message when not root
yoe Aug 6, 2024
da5e07c
Reimplement daemonize() without using daemon()
yoe Aug 6, 2024
e788607
Drop gznbd
yoe Aug 6, 2024
ff5846d
Stop using gcc linker magic
yoe Aug 6, 2024
29171ec
docs: Tweak location of qemu nbd extensions
ebblake Aug 2, 2024
6ff6c94
Drop note about sourceforge.
yoe Aug 18, 2024
82c500f
nbd: add nbd-get-status
Mar 28, 2017
17043b0
Refactor the negotiate() and connected functions
yoe Sep 28, 2024
7a64238
Fix nbd-server infinite loop for TLS
kalofoli Oct 1, 2024
cf5a774
nbd-client: Exit with error code other than EXIT_FAILURE
liulinC Sep 29, 2024
a78ea37
nbd-client: Fix use without -N
ebblake Nov 19, 2024
87c5318
nbd-client: Add support for setting /sys/block/nbdN/backend
ebblake Nov 19, 2024
eaac99e
README: update qemu-nbd doc link
darkk Apr 30, 2025
6725f91
spec: Relax block status alignment to match existing servers
ebblake May 31, 2025
f123be9
Fix copy-on-write corruption
berenddeschouwer May 8, 2025
39dc924
Remove the maillinglist reference
berenddeschouwer Jun 26, 2025
3b7fcea
nbd: fix build failure after openunix/opennet refactor
yskzalloc Sep 15, 2025
f94113c
Fix wrong compare in test
BMBurstein Jun 5, 2025
bafb5ff
u64 -> uint64_t, u32 -> uint32_t
RokerHRO Dec 4, 2025
2ce490c
One more u32 -> uint32_t change
yoe Dec 28, 2025
8f3c209
Fix typo
yoe Dec 28, 2025
4ceb6ed
Do the coverage thing
yoe Feb 20, 2026
22591fc
Fix missing install, and also publish to coveralls
yoe Feb 20, 2026
41a712e
Include an introductory paragraph.
yoe Feb 21, 2026
4ea7321
Refactor netlink_configure to have less arguments
yoe Feb 22, 2026
41bdbee
Add tests for nbd-client
yoe Feb 22, 2026
a770c32
Move the netlink-based connection status into nbd-client
yoe Feb 22, 2026
99622f8
Ignore our LD_PRELOAD thingy
yoe Feb 22, 2026
b1cfcf0
Enable socket_wrapper and nss_wrapper support for tests
yoe Feb 22, 2026
90b88fa
Don't set custom push/pull functions unconditionally
yoe Feb 23, 2026
5b2d384
Implement persist mode for netlink
yoe Feb 23, 2026
26fd0eb
Add cautionary note about the nature of this documentation.
yoe Feb 23, 2026
a4b504b
Drop libnl_mock.h, not actually used
yoe Mar 19, 2026
d1133b7
We're not interested in GNUTLS_E_AGAIN
yoe Mar 19, 2026
8273f1e
Fix nbd-client cannot find the index when the device name were given …
conanoc Sep 23, 2025
31e30a8
Refactor argument parsing into a separate file
yoe Apr 9, 2026
8b4b6d6
Add tests for nbd-client argument parsing
yoe Apr 9, 2026
f96f7fc
Don't forget the args.h file
yoe Apr 9, 2026
a80304e
Fix nbd device parsing, for reals
yoe Apr 14, 2026
1523d99
nbdtab man page: Add missing closing tag
yoe May 1, 2026
89ba7b5
Fix --help parsing
yoe May 1, 2026
3c53950
Fixing TLS send as well
May 12, 2026
e251de2
Merge nbd-3.27-2 onto debian
May 12, 2026
02322cc
Changelog
May 12, 2026
13d4861
Added nbd-server systemd service
May 12, 2026
ad2a7ab
Merge with nbd-3.27.3
May 12, 2026
66b3ad1
Changelog and merge fixes
May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: install dependencies
run: sudo apt-get update && sudo apt-get -y install docbook-utils libglib2.0-dev libgnutls28-dev libnl-genl-3-dev autoconf-archive
run: sudo apt-get update && sudo apt-get -y install docbook-utils libglib2.0-dev libgnutls28-dev libnl-genl-3-dev autoconf-archive gcovr
- name: Check out repository
uses: actions/checkout@v4
- run: ./autogen.sh
- run: ./configure --enable-syslog
- run: make distcheck
- name: Build and run tests (coverage)
run: |
make CFLAGS="--coverage -O0 -g" CXXFLAGS="--coverage -O0 -g" LDFLAGS="--coverage"
make check CFLAGS="--coverage -O0 -g" CXXFLAGS="--coverage -O0 -g" LDFLAGS="--coverage"
- name: Generate coverage reports
run: |
gcovr -r . --exclude-directories tests --print-summary --xml-pretty -o coverage.xml --html=coverage.html --html-details
- name: Submit coverage to Coveralls
uses: coverallsapp/github-action@v2
with:
file: coverage.xml
format: cobertura
- name: Upload coverage reports
uses: actions/upload-artifact@v4
with:
name: coverage
path: |
coverage.xml
coverage.html
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ support/lt*
support/libtool.m4
ar-lib
tests/run/cliserv.c
tests/run/buffer.c
tests/run/crypto-gnutls.c
tests/run/buffer.c
.debhelper
Expand All @@ -68,3 +69,5 @@ nbdtab_parser.tab.h
tests/parse/parser
.pc
debian/patches
/systemd/nbd-server.service
/systemd/nbd-server.service.sh
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
ACLOCAL_AMFLAGS = -I support
SUBDIRS = . man doc tests systemd gznbd
SUBDIRS = . man doc tests systemd
bin_PROGRAMS = nbd-server nbd-trdump nbd-trplay
EXTRA_PROGRAMS = nbd-client make-integrityhuge
noinst_LTLIBRARIES = libnbdsrv.la libcliserv.la libnbdclt.la
libcliserv_la_SOURCES = cliserv.h cliserv.c
libcliserv_la_CFLAGS = @CFLAGS@
client_srcs = nbd-client.c cliserv.h nbd-netlink.h
client_srcs = nbd-client.c args.c args.h cliserv.h nbd-netlink.h
nbd_server_SOURCES = nbd-server.c cliserv.h lfs.h nbd.h nbdsrv.h backend.h \
netdb-compat.h nbd-helper.h
nbd_trdump_SOURCES = nbd-trdump.c cliserv.h nbd.h
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@ Welcome to the NBD userland support files!

This package contains nbd-server and nbd-client.

The Network Block Device (NBD) is a protocol, originally implemented for
Linux but that now has [a number of
implementations](#alternate-implementations) that lets a computer access
a remote storage device (like a hard drive or partition) as if it were a
local, physical disk, using a simple client-server model over a TCP/IP
network. This allows remote booting, swapping, or filesystem access
without complex network file systems like NFS. It works by exporting a
block device from a server and presenting it as a local block device on
a client machine, allowing standard block-level operations (read/write)
over the network.

To install the package, download the source and do the normal
`configure`/`make`/`make install` dance. You'll need to install it on both the
client and the server. Note that released nbd tarballs are found on
[sourceforge](http://sourceforge.net/projects/nbd/files/nbd/).
client and the server.

For compiling from git, do a checkout, install the SGML tools
(docbook2man), and then run './autogen.sh' while inside your checkout.
Expand Down Expand Up @@ -118,7 +128,7 @@ other people. A (probably incomplete) list follows:
* [qemu](https://www.qemu.org) contains an embedded NBD server, an
embedded NBD client, and a standalone NBD server (`qemu-nbd`). They
maintain a [status
document](https://gitlab.com/qemu-project/qemu/-/blob/master/docs/interop/nbd.txt)
document](https://gitlab.com/qemu-project/qemu/-/blob/master/docs/interop/nbd.rst)
of their NBD implementation.
* A [GEOM gate-based client implementation for
FreeBSD](https://github.com/freqlabs/nbd-client) exists. It has not
Expand Down
255 changes: 255 additions & 0 deletions args.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
#include "args.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include "config.h"

#define NBD_DEFAULT_PORT "10809"

void init_client(CLIENT *client) {
memset(client, 0, sizeof(CLIENT));
client->bs = 512;
client->nconn = 1;
client->port = NBD_DEFAULT_PORT;
}

void free_client_fields(CLIENT *client) {
// Note: In a real implementation, we'd free allocated strings
// For testing, we'll just reset pointers to avoid double-free issues
memset(client, 0, sizeof(CLIENT));
client->bs = 512;
client->nconn = 1;
client->port = NBD_DEFAULT_PORT;
}

static void usage_error(parse_result_t *result, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vsnprintf(result->error_msg, sizeof(result->error_msg), fmt, ap);
va_end(ap);
result->exit_code = 1;
result->should_exit = true;
}

parse_result_t parse_nbd_client_args(int argc, char *argv[], CLIENT *client) {
parse_result_t result = {0};
int nonspecial = 0;
char *port = NBD_DEFAULT_PORT;

static const char *short_opts = "-B:b:c:d:gH:hlnN:PpRSst:uVxy:T:C"
#if HAVE_NETLINK
"i:L"
#endif
;

static struct option long_options[] = {
{"cacertfile", required_argument, NULL, 'A'},
{"block-size", required_argument, NULL, 'b'},
{"size", required_argument, NULL, 'B'},
{"check", required_argument, NULL, 'c'},
{"connections", required_argument, NULL, 'C'},
{"disconnect", required_argument, NULL, 'd'},
{"certfile", required_argument, NULL, 'F'},
{"no-optgo", no_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{"tlshostname", required_argument, NULL, 'H'},
#if HAVE_NETLINK
{"identifier", required_argument, NULL, 'i'},
#endif
{"keyfile", required_argument, NULL, 'K'},
{"list", no_argument, NULL, 'l'},
#if HAVE_NETLINK
{"nonetlink", no_argument, NULL, 'L'},
#endif
{"systemd-mark", no_argument, NULL, 'm'},
{"nofork", no_argument, NULL, 'n'},
{"name", required_argument, NULL, 'N'},
{"persist", no_argument, NULL, 'p'},
{"preinit", no_argument, NULL, 'P'},
{"readonly", no_argument, NULL, 'R'},
{"swap", no_argument, NULL, 's'},
{"timeout", required_argument, NULL, 't'},
{"dead-timeout", required_argument, NULL, 'T'},
{"unix", no_argument, NULL, 'u'},
{"version", no_argument, NULL, 'V'},
{"enable-tls", no_argument, NULL, 'x'},
{"priority", required_argument, NULL, 'y'},
{0, 0, 0, 0}
};

optind = 1; // Reset getopt

int c;
while((c = getopt_long_only(argc, argv, short_opts, long_options, NULL)) >= 0) {
switch(c) {
case 1:
// non-option argument
if(strchr(optarg, '=')) {
// old-style 'bs=' or 'timeout=' argument
fprintf(stderr, "WARNING: old-style command-line argument encountered. This is deprecated.\n");
if(!strncmp(optarg, "bs=", 3)) {
optarg += 3;
goto blocksize;
}
if(!strncmp(optarg, "timeout=", 8)) {
optarg += 8;
goto timeout;
}
usage_error(&result, "unknown option %s encountered", optarg);
return result;
}
switch(nonspecial++) {
case 0:
// host
client->hostn = optarg;
break;
case 1:
// port
if(!strtol(optarg, NULL, 0)) {
// not parseable as a number, assume it's the device
client->dev = optarg;
nonspecial++;
} else {
port = optarg;
}
break;
case 2:
// device
client->dev = optarg;
break;
default:
usage_error(&result, "too many non-option arguments specified");
return result;
}
break;
case 'b':
blocksize:
client->bs = (int)strtol(optarg, NULL, 0);
if(client->bs == 0 || (client->bs % 512) != 0) {
usage_error(&result, "blocksize is not a multiple of 512! This is not allowed");
return result;
}
break;
case 'B':
client->force_size64 = (uint64_t)strtoull(optarg, NULL, 0);
if(client->force_size64 == 0) {
usage_error(&result, "Invalid size");
return result;
}
break;
case 'c':
result.check_conn = true;
result.check_device = optarg;
break;
case 'C':
client->nconn = (int)strtol(optarg, NULL, 0);
break;
case 'd':
result.need_disconnect = true;
client->dev = optarg;
break;
case 'g':
client->no_optgo = true;
break;
case 'h':
usage_error(&result, ""); // Will show help
return result;
#if HAVE_NETLINK
case 'i':
// identifier - store for later use in nbd-client.c
result.identifier = optarg;
break;
#endif
case 'l':
result.list_exports = true;
client->dev = "";
break;
#if HAVE_NETLINK
case 'L':
// nonetlink - store for later use in nbd-client.c
result.nonetlink = true;
break;
#endif
case 'm':
// systemd mark - ignore for parsing test
break;
case 'n':
// nofork - ignore for parsing test
break;
case 'N':
client->name = optarg;
break;
case 'p':
client->persist = true;
break;
case 'P':
client->preinit = true;
break;
case 'R':
client->force_ro = true;
break;
case 's':
client->swap = true;
break;
case 'T':
client->dead_conn_timeout = strtol(optarg, NULL, 0);
break;
case 't':
timeout:
client->timeout = strtol(optarg, NULL, 0);
break;
case 'u':
client->b_unix = true;
break;
case 'V':
result.show_version = true;
return result;
case 'x':
client->tls = true;
break;
case 'F':
client->cert = optarg;
break;
case 'K':
client->key = optarg;
break;
case 'A':
client->cacert = optarg;
break;
case 'H':
client->tlshostn = optarg;
break;
case 'y':
client->priority = optarg;
break;
default:
usage_error(&result, "option eaten by 42 mice");
return result;
}
}

// Handle post-parsing logic for nbdtab functionality
if(client->hostn) {
if((!client->name || !client->dev) && !result.list_exports) {
if(!strncmp(client->hostn, "nbd", 3) || !strncmp(client->hostn, "/dev/nbd", 8)) {
client->dev = client->hostn;
// In real implementation, this would call get_from_config()
// For testing, we just note that this is the nbdtab case
}
}
} else if (!result.check_conn && !result.need_disconnect && !result.list_exports && !result.show_version) {
usage_error(&result, "no information specified");
return result;
}

// Copy final port value
if(port != NBD_DEFAULT_PORT) {
client->port = port;
}

return result;
}
32 changes: 32 additions & 0 deletions args.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef ARGS_H
#define ARGS_H

#include <stdbool.h>
#include <stdint.h>
#include "config.h"

// Include nbdclt.h to get CLIENT definition
#include "nbdclt.h"

// Argument parsing result structure
typedef struct {
int exit_code;
char error_msg[256];
bool should_exit;
bool check_conn;
char *check_device;
bool need_disconnect;
bool list_exports;
bool show_version;
#if HAVE_NETLINK
char *identifier;
bool nonetlink;
#endif
} parse_result_t;

// Function prototypes
parse_result_t parse_nbd_client_args(int argc, char *argv[], CLIENT *client);
void free_client_fields(CLIENT *client);
void init_client(CLIENT *client);

#endif // ARGS_H
2 changes: 1 addition & 1 deletion autogen.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
set -ex
make -C systemd -f Makefile.am nbd@.service.sh.in
make -C systemd -f Makefile.am nbd@.service.sh.in nbd-server.service.sh.in
exec autoreconf -f -i
Loading