Description: Autogenerated patch header for a single-debian-patch file.
 The delta against upstream is either kept as a single patch, or maintained
 in some VCS, and exported as a single patch instead of more manageable
 atomic patches.
Forwarded: not-needed

---
--- /dev/null
+++ nbd-3.27.1/.dir-locals.el
@@ -0,0 +1,2 @@
+((c-mode . ((c-file-style . "linux")
+	    (indent-tabs-mode . t))))
--- /dev/null
+++ nbd-3.27.1/.github/workflows/build.yml
@@ -0,0 +1,31 @@
+name: Build NBD
+on: [push]
+jobs:
+  Build-NBD:
+    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 gcovr
+      - name: Check out repository
+        uses: actions/checkout@v4
+      - run: ./autogen.sh
+      - run: ./configure --enable-syslog
+      - 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
--- /dev/null
+++ nbd-3.27.1/.gitlab-ci.yml
@@ -0,0 +1,14 @@
+before_script:
+  - apt-get update
+  - apt-get install -y devscripts fakeroot build-essential git autoconf automake docbook-utils pkg-config
+  - mk-build-deps -t "apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends" -i -r
+  - rm -f nbd-build-deps*
+  - ./autogen.sh
+build_unstable:
+  image: debian:sid
+  script:
+  - dpkg-buildpackage -rfakeroot -b
+build_testing:
+  image: debian:testing
+  script:
+  - dpkg-buildpackage -rfakeroot -b
--- nbd-3.27.1.orig/configure.ac
+++ nbd-3.27.1/configure.ac
@@ -2,7 +2,7 @@ dnl Configure script for NBD system
 dnl (c) 1998 Martin Mares <mj@ucw.cz>, (c) 2000 Pavel Machek <pavel@ucw.cz>,
 dnl (c) 2003-2024 Wouter Verhelst <wouter@debian.org>
 AC_INIT([nbd],
-  m4_esyscmd(support/genver.sh | tr -d '\n'),
+  [3.26.1],
   [nbd@other.debian.org],,
   [http://nbd.sourceforge.net/])
 m4_define([serial_tests], [
--- /dev/null
+++ nbd-3.27.1/coverity_model.c
@@ -0,0 +1,7 @@
+
+typedef struct _GArray GArray;
+#define g_array_append_val(a, v) g_array_append_vals(a, &(v), 1)
+
+GArray* g_array_append_vals(GArray*, void*, unsigned int) {
+	__coverity_escape__;
+}
--- /dev/null
+++ nbd-3.27.1/doc/netlink-proto.md
@@ -0,0 +1,257 @@
+# The NBD Netlink Control Protocol
+
+NOTE: this documentation is AI-generated and still needs review. Use with
+caution.
+
+## Introduction
+
+The NBD kernel driver provides a netlink-based control interface that allows userspace
+tools to configure, manage, and monitor NBD devices. This interface is used by the
+nbd-client utility to establish connections, configure devices, and query status.
+
+The netlink protocol uses the generic netlink (genl) framework with family name "nbd"
+and version 0x1. It supports both unicast commands/responses and multicast notifications
+for link death events.
+
+## Protocol Overview
+
+### Family Information
+
+- **Family Name**: `nbd`
+- **Version**: `0x1`
+- **Multicast Group**: `nbd_mc_group`
+
+### Message Types
+
+The protocol defines the following command types:
+
+- `NBD_CMD_CONNECT` - Connect and configure an NBD device
+- `NBD_CMD_DISCONNECT` - Disconnect an NBD device
+- `NBD_CMD_RECONFIGURE` - Reconfigure an existing connection
+- `NBD_CMD_STATUS` - Query device status
+- `NBD_CMD_LINK_DEAD` - Multicast notification of link failure (kernel → userspace)
+
+## Attributes
+
+### Configuration Attributes
+
+These attributes are used with various commands:
+
+- `NBD_ATTR_INDEX` (u32) - NBD device index
+- `NBD_ATTR_SIZE_BYTES` (u64) - Device size in bytes
+- `NBD_ATTR_BLOCK_SIZE_BYTES` (u64) - Block size in bytes
+- `NBD_ATTR_TIMEOUT` (u64) - Connection timeout
+- `NBD_ATTR_SERVER_FLAGS` (u64) - Server flags from negotiation
+- `NBD_ATTR_CLIENT_FLAGS` (u64) - Client flags
+- `NBD_ATTR_SOCKETS` (nested) - Socket configuration
+- `NBD_ATTR_DEAD_CONN_TIMEOUT` (u64) - Dead connection timeout
+- `NBD_ATTR_DEVICE_LIST` (nested) - List of devices (for STATUS response)
+- `NBD_ATTR_BACKEND_IDENTIFIER` (string) - Backend identifier
+
+### Socket Attributes
+
+Nested within `NBD_ATTR_SOCKETS`:
+
+- `NBD_SOCK_ITEM` (nested) - Individual socket item
+  - `NBD_SOCK_FD` (u32) - File descriptor for the socket
+
+### Device List Attributes
+
+Nested within `NBD_ATTR_DEVICE_LIST`:
+
+- `NBD_DEVICE_ITEM` (nested) - Individual device item
+  - `NBD_DEVICE_INDEX` (u32) - Device index
+  - `NBD_DEVICE_CONNECTED` (u8) - Connection status (1 = connected, 0 = disconnected)
+
+## Command Details
+
+### NBD_CMD_CONNECT
+
+Connect and configure an NBD device.
+
+**Request Attributes:**
+- `NBD_ATTR_INDEX` (optional) - Device index to use, kernel assigns if not specified
+- `NBD_ATTR_SIZE_BYTES` (required) - Export size in bytes
+- `NBD_ATTR_BLOCK_SIZE_BYTES` (required) - Block size in bytes
+- `NBD_ATTR_SERVER_FLAGS` (required) - Flags from server negotiation
+- `NBD_ATTR_TIMEOUT` (optional) - Connection timeout in seconds
+- `NBD_ATTR_SOCKETS` (required) - Nested socket configuration
+- `NBD_ATTR_DEAD_CONN_TIMEOUT` (optional) - Dead connection timeout
+- `NBD_ATTR_BACKEND_IDENTIFIER` (optional) - Backend identifier string
+
+**Response Attributes:**
+- `NBD_ATTR_INDEX` - Assigned device index
+
+**Example Request Structure:**
+```
+NBD_CMD_CONNECT
+├── NBD_ATTR_SIZE_BYTES: 10737418240
+├── NBD_ATTR_BLOCK_SIZE_BYTES: 4096
+├── NBD_ATTR_SERVER_FLAGS: 0x123
+├── NBD_ATTR_TIMEOUT: 30
+└── NBD_ATTR_SOCKETS
+    ├── NBD_SOCK_ITEM
+    │   └── NBD_SOCK_FD: 5
+    └── NBD_SOCK_ITEM
+        └── NBD_SOCK_FD: 6
+```
+
+### NBD_CMD_DISCONNECT
+
+Disconnect an NBD device.
+
+**Request Attributes:**
+- `NBD_ATTR_INDEX` (required) - Device index to disconnect
+
+**Response Attributes:**
+- None (success/failure indicated by return code)
+
+### NBD_CMD_RECONFIGURE
+
+Reconfigure an existing NBD connection.
+
+**Request Attributes:**
+- `NBD_ATTR_INDEX` (required) - Device index to reconfigure
+- `NBD_ATTR_SOCKETS` (required) - New socket configuration
+- `NBD_ATTR_DEAD_CONN_TIMEOUT` (optional) - New dead connection timeout
+
+**Response Attributes:**
+- None (success/failure indicated by return code)
+
+### NBD_CMD_STATUS
+
+Query the status of NBD devices.
+
+**Request Attributes:**
+- `NBD_ATTR_INDEX` (optional) - Specific device index, or all devices if not specified
+
+**Response Attributes:**
+- `NBD_ATTR_DEVICE_LIST` - Nested list of device statuses
+  - `NBD_DEVICE_ITEM` (repeated)
+    - `NBD_DEVICE_INDEX` - Device index
+    - `NBD_DEVICE_CONNECTED` - Connection status
+
+**Example Response Structure:**
+```
+NBD_CMD_STATUS Response
+└── NBD_ATTR_DEVICE_LIST
+    ├── NBD_DEVICE_ITEM
+    │   ├── NBD_DEVICE_INDEX: 0
+    │   └── NBD_DEVICE_CONNECTED: 1
+    ├── NBD_DEVICE_ITEM
+    │   ├── NBD_DEVICE_INDEX: 1
+    │   └── NBD_DEVICE_CONNECTED: 0
+    └── NBD_DEVICE_ITEM
+        ├── NBD_DEVICE_INDEX: 2
+        └── NBD_DEVICE_CONNECTED: 1
+```
+
+### NBD_CMD_LINK_DEAD
+
+Multicast notification sent by kernel when a link dies.
+
+**Message Attributes:**
+- `NBD_ATTR_INDEX` - Device index whose link died
+
+**Delivery:**
+- Sent via multicast group `nbd_mc_group`
+- No direct response expected
+
+## Error Handling
+
+Commands return standard netlink error codes:
+- Success: 0
+- Invalid parameters: `-EINVAL`
+- Device not found: `-ENOENT`
+- Device busy: `-EBUSY`
+- Memory allocation failure: `-ENOMEM`
+- Permission denied: `-EPERM`
+
+## Implementation Notes
+
+### Socket Management
+
+The kernel expects file descriptors for already-connected sockets to be passed
+via `NBD_ATTR_SOCKETS`. This allows userspace to handle:
+- TCP connections
+- TLS negotiations
+- Authentication
+- Connection establishment
+
+The kernel takes ownership of these file descriptors and will close them
+when the device is disconnected.
+
+### Timeout Handling
+
+Two timeout types are supported:
+- `NBD_ATTR_TIMEOUT` - Initial connection timeout
+- `NBD_ATTR_DEAD_CONN_TIMEOUT` - Timeout for detecting dead connections
+
+### Multicast Notifications
+
+Userspace applications can subscribe to the `nbd_mc_group` multicast group
+to receive asynchronous notifications about link death events.
+
+## Security Considerations
+
+- Netlink communications require appropriate capabilities (typically CAP_NET_ADMIN)
+- File descriptors passed to the kernel are validated
+- Backend identifiers should be treated as opaque strings
+- Timeout values should be reasonable to avoid resource exhaustion
+
+## Protocol Evolution
+
+The protocol version is 0x1. Future versions will maintain backward compatibility
+where possible, with new attributes being optional. Unknown attributes should be
+ignored by implementations.
+
+## Usage Examples
+
+### Connecting a Device
+
+```c
+// Create netlink message
+struct nl_msg *msg = nlmsg_alloc();
+genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, 0,
+           NBD_CMD_CONNECT, 0);
+
+// Add attributes
+NLA_PUT_U64(msg, NBD_ATTR_SIZE_BYTES, size);
+NLA_PUT_U64(msg, NBD_ATTR_BLOCK_SIZE_BYTES, blocksize);
+NLA_PUT_U64(msg, NBD_ATTR_SERVER_FLAGS, flags);
+
+// Add sockets
+struct nlattr *socks = nla_nest_start(msg, NBD_ATTR_SOCKETS);
+for (i = 0; i < num_sockets; i++) {
+    struct nlattr *sock = nla_nest_start(msg, NBD_SOCK_ITEM);
+    NLA_PUT_U32(msg, NBD_SOCK_FD, sock_fds[i]);
+    nla_nest_end(msg, sock);
+}
+nla_nest_end(msg, socks);
+
+// Send message
+nl_send_sync(socket, msg);
+```
+
+### Querying Status
+
+```c
+struct nl_msg *msg = nlmsg_alloc();
+genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, 0,
+           NBD_CMD_STATUS, 0);
+
+// Optional: query specific device
+NLA_PUT_U32(msg, NBD_ATTR_INDEX, device_index);
+
+nl_send_sync(socket, msg);
+```
+
+### Disconnecting a Device
+
+```c
+struct nl_msg *msg = nlmsg_alloc();
+genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, 0,
+           NBD_CMD_DISCONNECT, 0);
+NLA_PUT_U32(msg, NBD_ATTR_INDEX, device_index);
+nl_send_sync(socket, msg);
+```
--- nbd-3.27.1.orig/nbd-client.c
+++ nbd-3.27.1/nbd-client.c
@@ -209,12 +209,12 @@ static void netlink_configure(int index,
 
 	ret = nl_send_sync(socket, msg);
 	if (ret < 0) {
-                if(geteuid() != 0) {
-                        err_code("Failed to setup device. Are you root?\n", ret);
-                } else {
-		        err_code("Failed to setup device, check dmesg\n", ret);
-                }
-        }
+		if(geteuid() != 0) {
+			err_code("Failed to setup device. Are you root?\n", ret);
+		} else {
+			err_code("Failed to setup device, check dmesg\n", ret);
+		}
+	}
 	return;
 nla_put_failure:
 	err("Failed to create netlink message\n");
@@ -225,10 +225,14 @@ static void netlink_disconnect(char *nbd
 	struct nl_msg *msg;
 	int driver_id;
 	int ret;
+	char *local_dev = nbddev;
 
 	int index = -1;
 	if (nbddev) {
-		if (sscanf(nbddev, "nbd%d", &index) != 1)
+		if (!strncmp(local_dev, "/dev/", 5)) {
+			local_dev += 5;
+		}
+		if (sscanf(local_dev, "nbd%d", &index) != 1)
 			err("Invalid nbd device target\n");
 	}
 	if (index < 0)
@@ -313,13 +317,15 @@ static int netlink_check_conn(char* devn
 	struct nl_msg *msg;
 	int driver_id, ret;
 	int index = -1;
+	char *local_dev = devname;
 	int connected = -1; /* -1 = unknown, 0 = connected, 1 = disconnected */
 
 	/* Parse device index from name */
-	if (sscanf(devname, "/dev/nbd%d", &index) != 1) {
-		if (sscanf(devname, "nbd%d", &index) != 1) {
-			return 2; /* Invalid device name */
-		}
+	if (!strncmp(local_dev, "/dev/", 5)) {
+		local_dev += 5;
+	}
+	if (sscanf(local_dev, "nbd%d", &index) != 1) {
+		return 2; /* Invalid device name */
 	}
 
 	/* Setup netlink socket */
@@ -513,7 +519,7 @@ err:
 
 int openunix() {
 	int sock;
-        char *path = cur_client->hostn;
+	char *path = cur_client->hostn;
 	struct sockaddr_un un_addr;
 	memset(&un_addr, 0, sizeof(un_addr));
 
@@ -770,8 +776,8 @@ void negotiate(int *sockp, uint16_t *fla
 		err("Failed/2.1: %m");
 
 #if HAVE_GNUTLS && !defined(NOTLS)
-        /* TLS */
-        if (cur_client->tls) {
+	/* TLS */
+	if (cur_client->tls) {
 		int plainfd[2]; // [0] is used by the proxy, [1] is used by NBD
 		tlssession_t *s = NULL;
 		int ret;
@@ -1224,7 +1230,7 @@ bool get_from_config() {
 		goto out;
 	}
 
-        retval = true;
+	retval = true;
 out:
 	if(yyin != NULL) {
 		fclose(yyin);
@@ -1377,10 +1383,10 @@ int main(int argc, char *argv[]) {
 	logging(MY_NAME);
 
 #if HAVE_GNUTLS && !defined(NOTLS)
-        tlssession_init();
+	tlssession_init();
 #endif
-        cur_client = calloc(sizeof(CLIENT), 1);
-        init_client(cur_client);
+	cur_client = calloc(sizeof(CLIENT), 1);
+	init_client(cur_client);
 
 	// Use refactored argument parsing
 	parse_result_t parse_result = parse_nbd_client_args(argc, argv, cur_client);
@@ -1435,7 +1441,7 @@ int main(int argc, char *argv[]) {
 	if(cur_client->hostn) {
 		if((!cur_client->name || !cur_client->dev) && !(opts & NBDC_DO_LIST)) {
 			if(!strncmp(cur_client->hostn, "nbd", 3) || !strncmp(cur_client->hostn, "/dev/nbd", 8)) {
-                                cur_client->dev = cur_client->hostn;
+				cur_client->dev = cur_client->hostn;
 				if(!get_from_config()) {
 					usage("no valid configuration for specified device found", cur_client->hostn);
 					exit(EXIT_FAILURE);
@@ -1450,7 +1456,7 @@ int main(int argc, char *argv[]) {
 		exit(EXIT_FAILURE);
 	}
 
-        if (cur_client->key && !cur_client->cert)
+	if (cur_client->key && !cur_client->cert)
 		cur_client->cert = strdup(cur_client->key);
 
 	if (cur_client->cert != NULL || cur_client->key != NULL || cur_client->cacert != NULL || cur_client->tlshostn != NULL) {
@@ -1468,8 +1474,8 @@ int main(int argc, char *argv[]) {
 		}
 	}
 
-        if (!cur_client->tlshostn && cur_client->hostn && !cur_client->b_unix)
-                cur_client->tlshostn = strdup(cur_client->hostn);
+	if (!cur_client->tlshostn && cur_client->hostn && !cur_client->b_unix)
+		cur_client->tlshostn = strdup(cur_client->hostn);
 
 	if (netlink)
 		nofork = 1;
@@ -1539,7 +1545,11 @@ int main(int argc, char *argv[]) {
 	if (netlink) {
 		int index = -1;
 		if (cur_client->dev) {
-			if (sscanf(cur_client->dev, "nbd%d", &index) != 1)
+			char *local_dev = cur_client->dev;
+			if(!strncmp(local_dev, "/dev/", 5)) {
+				local_dev += 5;
+			}
+			if (sscanf(local_dev, "nbd%d", &index) != 1)
 				err("Invalid nbd device target\n");
 		}
 		netlink_configure(index, sockfds, flags, identifier);
@@ -1613,7 +1623,7 @@ int main(int argc, char *argv[]) {
 			if(error==EBADR) {
 				/* The user probably did 'nbd-client -d' on us.
 				 * quit */
-                                cur_client->persist_mode = false;
+				cur_client->persist_mode = false;
 			} else {
 				if(cur_client->persist_mode) {
 					uint64_t old_size = cur_client->size64;
@@ -1649,7 +1659,7 @@ int main(int argc, char *argv[]) {
 			 * happened at this point. Probably best to quit, now
 			 */
 			fprintf(stderr, "Kernel call returned.\n");
-                        cur_client->persist_mode = false;
+			cur_client->persist_mode = false;
 		}
 	} while(cur_client->persist_mode);
 	printf("sock, ");
--- nbd-3.27.1.orig/nbd-server.c
+++ nbd-3.27.1/nbd-server.c
@@ -777,14 +777,6 @@ GArray* do_cfile_dir(gchar* dir, struct
 }
 
 /**
- * To be called by GArray clearing function.
- * @param server pointer to server element
- */
-static void serve_clear_element(SERVER **server) {
-	serve_dec_ref(*server);
-}
-
-/**
  * Parse the config file.
  *
  * @param f the name of the config file
--- nbd-3.27.1.orig/nbdsrv.h
+++ nbd-3.27.1/nbdsrv.h
@@ -238,6 +238,13 @@ SERVER* serve_inc_ref(SERVER *s);
 SERVER* serve_dec_ref(SERVER *s);
 
 /**
+ * call serve_dec_ref on *s
+ *
+ * @param s a pointer to a pointer to a SERVER to decrement
+ **/
+void serve_clear_element(SERVER **s);
+
+/**
  * Punch a hole in the backend file (if supported by the current system).
  *
  * @param req the request for which this is being processed
--- nbd-3.27.1.orig/systemd/nbd@.service.sh.in
+++ nbd-3.27.1/systemd/nbd@.service.sh.in
@@ -10,7 +10,9 @@ Description=NBD client connection for %i
 Documentation=man:nbd-client
 PartOf=nbd.service
 Before=dev-%i.device
+Before=remote-fs-pre.target
 After=network-online.target
+Before=shutdown.target
 Conflicts=shutdown.target
 DefaultDependencies=no
 [Service]
@@ -18,6 +20,8 @@ Type=oneshot
 RemainAfterExit=yes
 ExecStart=@sbindir@/nbd-client %i
 ExecStop=@sbindir@/nbd-client -d /dev/%i
+NoNewPrivileges=true
+ProtectSystem=full
 [Install]
 RequiredBy=dev-%i.device
 RequiredBy=dev-%ip1.device
--- nbd-3.27.1.orig/systemd/nbd@.service.tmpl
+++ nbd-3.27.1/systemd/nbd@.service.tmpl
@@ -10,8 +10,10 @@ After=modprobe@nbd.service
 Conflicts=shutdown.target
 DefaultDependencies=no
 [Service]
-Type=forking
+Type=oneshot
+RemainAfterExit=yes
 ExecStart=@sbindir@/nbd-client %i
+ExecStop=@sbindir@/nbd-client -d /dev/%i
 [Install]
 RequiredBy=dev-%i.device
 RequiredBy=dev-%ip1.device
--- nbd-3.27.1.orig/tests/parse/ipv6
+++ nbd-3.27.1/tests/parse/ipv6
@@ -1,5 +1,3 @@
-
-
 # This config file contains a few empty lines.
 
 # It also contains an IPv6 address
