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 <[email protected]> --- 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
