fuse: graceful shutdown when startup fails

When FUSE startup encounters an error after opening the filesystem--for
example because of a bad mountpoint--it exited uncleanly, which is a
bit unfriendly.

Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Thomas Bertschinger 2024-10-04 20:06:54 -06:00 committed by Kent Overstreet
parent 9f20109509
commit 3829e49167

View File

@ -1203,6 +1203,7 @@ int cmd_fusemount(int argc, char *argv[])
struct bch_opts bch_opts = bch2_opts_empty(); struct bch_opts bch_opts = bch2_opts_empty();
struct bf_context ctx = { 0 }; struct bf_context ctx = { 0 };
struct bch_fs *c = NULL; struct bch_fs *c = NULL;
struct fuse_session *se = NULL;
int ret = 0, i; int ret = 0, i;
/* Parse arguments. */ /* Parse arguments. */
@ -1263,17 +1264,22 @@ int cmd_fusemount(int argc, char *argv[])
bch2_err_str(PTR_ERR(c))); bch2_err_str(PTR_ERR(c)));
/* Fuse */ /* Fuse */
struct fuse_session *se = se = fuse_session_new(&args, &bcachefs_fuse_ops,
fuse_session_new(&args, &bcachefs_fuse_ops, sizeof(bcachefs_fuse_ops), c);
sizeof(bcachefs_fuse_ops), c); if (!se) {
if (!se) fprintf(stderr, "fuse_lowlevel_new err: %m\n");
die("fuse_lowlevel_new err: %m"); goto err;
}
if (fuse_set_signal_handlers(se) < 0) if (fuse_set_signal_handlers(se) < 0) {
die("fuse_set_signal_handlers err: %m"); fprintf(stderr, "fuse_set_signal_handlers err: %m\n");
goto err;
}
if (fuse_session_mount(se, fuse_opts.mountpoint)) if (fuse_session_mount(se, fuse_opts.mountpoint)) {
die("fuse_mount err: %m"); fprintf(stderr, "fuse_mount err: %m\n");
goto err;
}
/* This print statement is a trigger for tests. */ /* This print statement is a trigger for tests. */
printf("Fuse mount initialized.\n"); printf("Fuse mount initialized.\n");
@ -1287,17 +1293,22 @@ int cmd_fusemount(int argc, char *argv[])
ret = fuse_session_loop(se); ret = fuse_session_loop(se);
/* Cleanup */
fuse_session_unmount(se);
fuse_remove_signal_handlers(se);
fuse_session_destroy(se);
out: out:
if (se) {
fuse_session_unmount(se);
fuse_remove_signal_handlers(se);
fuse_session_destroy(se);
}
free(fuse_opts.mountpoint); free(fuse_opts.mountpoint);
fuse_opt_free_args(&args); fuse_opt_free_args(&args);
bf_context_free(&ctx); bf_context_free(&ctx);
return ret ? 1 : 0; return ret ? 1 : 0;
err:
bch2_fs_stop(c);
goto out;
} }
#endif /* BCACHEFS_FUSE */ #endif /* BCACHEFS_FUSE */