Patch-Source: https://github.com/NetworkBlockDevice/nbd/commit/3cb679f4a97e1a54a7285ee1f22e2888c9d3b900
--
From 3cb679f4a97e1a54a7285ee1f22e2888c9d3b900 Mon Sep 17 00:00:00 2001
From: Wouter Verhelst <w@uter.be>
Date: Thu, 27 Apr 2023 15:35:40 +0200
Subject: [PATCH] nbd-server: do not straddle uses of GThreadPool across a
 fork()

We created the thread pool at the main initialization, before forking
off a child. This used to work just fine, but as of GLib 2.76, this no
longer works due to changes internal to the implementation of
GThreadPool.

Since we don't need to use the thread pool before the fork() call
anyway, stop trying to do so and avoid the problem altogether.

Closes: gh-146
Signed-off-by: Wouter Verhelst <w@uter.be>
---
 nbd-server.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/nbd-server.c b/nbd-server.c
index fe97ca7..473fb71 100644
--- a/nbd-server.c
+++ b/nbd-server.c
@@ -200,7 +200,7 @@ char default_authname[] = SYSCONFDIR "/nbd-server/allow"; /**< default name of a
 #include <nbdsrv.h>
 
 /* Our thread pool */
-GThreadPool *tpool;
+GThreadPool *tpool = NULL;
 
 /* A work package for the thread pool functions */
 struct work_package {
@@ -2895,7 +2895,6 @@ static int mainloop_threaded(CLIENT* client) {
 		req->type = ntohl(req->type);
 		req->len = ntohl(req->len);
 
-
 		if(req->magic != htonl(NBD_REQUEST_MAGIC))
 			err("Protocol error: not enough magic.");
 
@@ -2934,9 +2933,7 @@ void destroy_pid_t(gpointer data) {
 	g_free(data);
 }
 
-static pid_t
-spawn_child(int* socket)
-{
+static pid_t spawn_child(int* socket) {
         pid_t pid;
         sigset_t newset;
         sigset_t oldset;
@@ -3019,6 +3016,7 @@ handle_modern_connection(GArray *const servers, const int sock, struct generic_c
                 }
                 /* Child just continues. */
         }
+	tpool = g_thread_pool_new(handle_request, NULL, genconf->threads, FALSE, NULL);
 
         sock_flags_old = fcntl(net, F_GETFL, 0);
         if (sock_flags_old == -1) {
@@ -3151,11 +3149,11 @@ static int append_new_servers(GArray *const servers, struct generic_conf *gencon
         int retval = -1;
 
         new_servers = parse_cfile(config_file_pos, genconf, true, gerror);
-        g_thread_pool_set_max_threads(tpool, genconf->threads, NULL);
-        if (!new_servers)
+        if(tpool) g_thread_pool_set_max_threads(tpool, genconf->threads, NULL);
+        if(!new_servers)
                 goto out;
 
-        for (i = 0; i < new_servers->len; ++i) {
+        for(i = 0; i < new_servers->len; ++i) {
                 SERVER *new_server = g_array_index(new_servers, SERVER*, i);
 
                 if (new_server->servename
@@ -3704,7 +3702,6 @@ int main(int argc, char *argv[]) {
 #if HAVE_OLD_GLIB
 	g_thread_init(NULL);
 #endif
-	tpool = g_thread_pool_new(handle_request, NULL, genconf.threads, FALSE, NULL);
 
 	setup_servers(servers, genconf.modernaddr, genconf.modernport,
 			genconf.unixsock, genconf.flags);
