aboutsummaryrefslogtreecommitdiff
path: root/lib/mount.c
diff options
context:
space:
mode:
authorGravatar Max Krasnyansky <maxk@kernel.org>2011-03-11 20:49:18 -0800
committerGravatar Max Krasnyansky <maxk@kernel.org>2011-04-15 15:10:04 -0700
commit9ca8283f6f4ba78019978d3a5e423ca3e66f58ba (patch)
treeb4e0412d9a3974cc447233a6454397903e4566d4 /lib/mount.c
parent5e1b1932395dd749c542f96bfcfe51ff955a7ebe (diff)
libfuse: Added support for auto_unmount option
This change adds support for "auto_unmount" option to libfuse. auto_umount option unmounts the fs automatically on application termination, whether normal or not (segfault, etc). When auto_unmount option is specified libfuse will alway use fusermount for mounting the fs. This change is selfcontained but for complete functionaly it requires auto_unmount support in fusermount tool.
Diffstat (limited to 'lib/mount.c')
-rw-r--r--lib/mount.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/mount.c b/lib/mount.c
index 0e585a4..a159a14 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -68,6 +68,7 @@ struct mount_opts {
int ishelp;
int flags;
int nonempty;
+ int auto_unmount;
int blkdev;
char *fsname;
char *subtype;
@@ -84,11 +85,13 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_MOUNT_OPT("allow_root", allow_root),
FUSE_MOUNT_OPT("nonempty", nonempty),
FUSE_MOUNT_OPT("blkdev", blkdev),
+ FUSE_MOUNT_OPT("auto_unmount", auto_unmount),
FUSE_MOUNT_OPT("fsname=%s", fsname),
FUSE_MOUNT_OPT("subtype=%s", subtype),
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("auto_unmount", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
@@ -124,6 +127,7 @@ static void mount_help(void)
fprintf(stderr,
" -o allow_other allow access to other users\n"
" -o allow_root allow access to root\n"
+" -o auto_unmount auto unmount on process termination\n"
" -o nonempty allow mounts over non-empty file/dir\n"
" -o default_permissions enable permission checking by kernel\n"
" -o fsname=NAME set filesystem name\n"
@@ -334,8 +338,8 @@ void fuse_unmount_compat22(const char *mountpoint)
fuse_kern_unmount(mountpoint, -1);
}
-static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
- int quiet)
+static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
+ const char *opts, int quiet)
{
int fds[2], pid;
int res;
@@ -393,15 +397,24 @@ static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
close(fds[0]);
rv = receive_fd(fds[1]);
- close(fds[1]);
- waitpid(pid, NULL, 0); /* bury zombie */
+
+ if (!mo->auto_unmount) {
+ /* with auto_unmount option fusermount will not exit until
+ this socket is closed */
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+ }
return rv;
}
int fuse_mount_compat22(const char *mountpoint, const char *opts)
{
- return fuse_mount_fusermount(mountpoint, opts, 0);
+ struct mount_opts mo;
+ memset(&mo, 0, sizeof(mo));
+ mo.flags = MS_NOSUID | MS_NODEV;
+
+ return fuse_mount_fusermount(mountpoint, &mo, opts, 0);
}
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
@@ -434,6 +447,12 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
return -1;
}
+ if (mo->auto_unmount) {
+ /* Tell the caller to fallback to fusermount because
+ auto-unmount does not work otherwise. */
+ return -2;
+ }
+
fd = open(devname, O_RDWR);
if (fd == -1) {
if (errno == ENODEV || errno == ENOENT)
@@ -591,13 +610,13 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
goto out;
}
- res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
+ res = fuse_mount_fusermount(mountpoint, &mo, tmp_opts, 1);
free(tmp_opts);
if (res == -1)
- res = fuse_mount_fusermount(mountpoint,
+ res = fuse_mount_fusermount(mountpoint, &mo,
mnt_opts, 0);
} else {
- res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+ res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0);
}
}
out: