diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2010-11-08 16:00:16 +0100 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2010-11-08 16:00:16 +0100 |
commit | eba226948b44d5a303a10908d440e808eaf0bae6 (patch) | |
tree | d4159cf06f50b52cd3bfdfc6e6ec58d4969523e2 /lib | |
parent | 9b2ab7ebed39ab680e0d9a489e213cb8c4f49970 (diff) | |
download | libfuse-eba226948b44d5a303a10908d440e808eaf0bae6.tar.gz |
update umount procedure
If umount(8) supports --fake and --no-canonicalize (util-linux-ng
version 2.18 or later), and umount(2) supports the UMOUNT_NOFOLLOW
flag (linux kernel version 2.6.35 or later) then, "fusermount -u" will
call the umount(2) system call and use "umount --fake ..." to update
/etc/mtab
Added --disable-legacy-umount option to configure. This disables the
runtime checking of umount(8) version. When built with this option
then "fusermount -u" will fail if umount(8) doesn't support the --fake
and --no-canonicalize options.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mount_util.c | 49 | ||||
-rw-r--r-- | lib/mount_util.h | 1 |
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/mount_util.c b/lib/mount_util.c index 25b7e43..edbba12 100644 --- a/lib/mount_util.c +++ b/lib/mount_util.c @@ -262,6 +262,55 @@ int fuse_mnt_umount(const char *progname, const char *abs_mnt, return exec_umount(progname, rel_mnt, lazy); } +static int remove_mount(const char *progname, const char *mnt) +{ + int res; + int status; + sigset_t blockmask; + sigset_t oldmask; + + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + + res = fork(); + if (res == -1) { + fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); + goto out_restore; + } + if (res == 0) { + sigprocmask(SIG_SETMASK, &oldmask, NULL); + setuid(geteuid()); + execl("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", + "--fake", mnt, NULL); + fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", + progname, strerror(errno)); + exit(1); + } + res = waitpid(res, &status, 0); + if (res == -1) + fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); + + if (status != 0) + res = -1; + + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return res; +} + +int fuse_mnt_remove_mount(const char *progname, const char *mnt) +{ + if (!mtab_needs_update(mnt)) + return 0; + + return remove_mount(progname, mnt); +} + char *fuse_mnt_resolve_path(const char *progname, const char *orig) { char buf[PATH_MAX]; diff --git a/lib/mount_util.h b/lib/mount_util.h index f392f99..dc5c916 100644 --- a/lib/mount_util.h +++ b/lib/mount_util.h @@ -10,6 +10,7 @@ int fuse_mnt_add_mount(const char *progname, const char *fsname, const char *mnt, const char *type, const char *opts); +int fuse_mnt_remove_mount(const char *progname, const char *mnt); int fuse_mnt_umount(const char *progname, const char *abs_mnt, const char *rel_mnt, int lazy); char *fuse_mnt_resolve_path(const char *progname, const char *orig); |