[PATCH 1/2] erofs-utils: mount: gracefully exit when `erofsmount_nbd()` encounts an error

Yifan Zhao zhaoyifan28 at huawei.com
Sat Dec 27 22:39:32 AEDT 2025


If the main process of `erofsmount_nbd()` encounters an error after the
nbd device has been successfully set up, it fails to disconnect it
before exiting, resulting in the subprocess not being cleaned up and
keeping its connection with NBD device.

This patch resolves the issue by disconnecting NBD device before exiting
on error.

Signed-off-by: Yifan Zhao <zhaoyifan28 at huawei.com>
---
 mount/main.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/mount/main.c b/mount/main.c
index 02a7962..5ba2e0a 100644
--- a/mount/main.c
+++ b/mount/main.c
@@ -1194,7 +1194,7 @@ static int erofsmount_nbd(struct erofs_nbd_source *source,
 {
 	bool is_netlink = false;
 	char nbdpath[32], *id;
-	int num, nbdfd;
+	int num, nbdfd = -1;
 	pid_t pid = 0;
 	long err;
 
@@ -1220,7 +1220,6 @@ static int erofsmount_nbd(struct erofs_nbd_source *source,
 		if ((pid = fork()) == 0)
 			return erofsmount_startnbd(nbdfd, source) ?
 				EXIT_FAILURE : EXIT_SUCCESS;
-		close(nbdfd);
 	} else {
 		num = err;
 		(void)snprintf(nbdpath, sizeof(nbdpath), "/dev/nbd%d", num);
@@ -1230,13 +1229,15 @@ static int erofsmount_nbd(struct erofs_nbd_source *source,
 	while (1) {
 		err = erofs_nbd_in_service(num);
 		if (err == -ENOENT || err == -ENOTCONN) {
-			int status;
-
-			err = waitpid(pid, &status, WNOHANG);
-			if (err < 0)
-				return -errno;
-			else if (err > 0)
-				return status ? -EIO : 0;
+			err = waitpid(pid, NULL, WNOHANG);
+			if (err < 0) {
+				err = -errno;
+				break;
+			} else if (err > 0) {
+				/* child process exited unexpectedly */
+				err = -EIO;
+				break;
+			}
 
 			usleep(50000);
 			continue;
@@ -1246,9 +1247,13 @@ static int erofsmount_nbd(struct erofs_nbd_source *source,
 		break;
 	}
 	if (!err) {
-		err = mount(nbdpath, mountpoint, fstype, flags, options);
-		if (err < 0)
+		if (mount(nbdpath, mountpoint, fstype, flags, options) < 0) {
 			err = -errno;
+			if (is_netlink)
+				erofs_nbd_nl_disconnect(num);
+			else
+				erofs_nbd_disconnect(nbdfd);
+		}
 
 		if (!err && is_netlink) {
 			id = erofs_nbd_get_identifier(num);
@@ -1262,6 +1267,8 @@ static int erofsmount_nbd(struct erofs_nbd_source *source,
 				free(id);
 		}
 	}
+	if (!is_netlink)
+		close(nbdfd);
 	return err;
 }
 
-- 
2.43.0



More information about the Linux-erofs mailing list