Currently erofsmount_startnbd() doesn't ignore SIGPIPE, causing erofsmount_nbd_loopfn() to be killed abruptly without clean up during disconnect. Moreover, -EPIPE from NBD socket I/O is expected while disconnecting, and erofsmount_startnbd() treats it as error, leading to redundant print: ``` <E> erofs: NBD worker failed with [Error 32] Broken pipe ```
Signed-off-by: Yifan Zhao <[email protected]> --- mount/main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mount/main.c b/mount/main.c index 5ba2e0a..965b0b8 100644 --- a/mount/main.c +++ b/mount/main.c @@ -621,11 +621,8 @@ static void *erofsmount_nbd_loopfn(void *arg) off_t pos; err = erofs_nbd_get_request(ctx->sk.fd, &rq); - if (err < 0) { - if (err == -EPIPE) - err = 0; + if (err < 0) break; - } if (rq.type != EROFS_NBD_CMD_READ) { err = erofs_nbd_send_reply_header(ctx->sk.fd, @@ -653,6 +650,8 @@ static void *erofsmount_nbd_loopfn(void *arg) out: erofs_io_close(&ctx->vd); erofs_io_close(&ctx->sk); + if (err == -EPIPE) + err = 0; return (void *)(uintptr_t)err; } @@ -663,6 +662,12 @@ static int erofsmount_startnbd(int nbdfd, struct erofs_nbd_source *source) pthread_t th; int err, err2; + /* Otherwise, NBD disconnect sends SIGPIPE, skipping cleanup */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + err = -errno; + goto out_closefd; + } + if (source->type == EROFSNBD_SOURCE_OCI) { if (source->ocicfg.tarindex_path || source->ocicfg.zinfo_path) { err = erofsmount_tarindex_open(&ctx.vd, &source->ocicfg, -- 2.43.0
