diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fuse_versionscript | 3 | ||||
-rw-r--r-- | lib/helper.c | 6 | ||||
-rw-r--r-- | lib/mount.c | 10 | ||||
-rw-r--r-- | lib/mount_bsd.c | 39 |
4 files changed, 50 insertions, 8 deletions
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript index b6e6e18..02ac176 100644 --- a/lib/fuse_versionscript +++ b/lib/fuse_versionscript @@ -20,7 +20,6 @@ FUSE_2.2 { fuse_set_getcontext_func; fuse_setup_compat2; fuse_teardown; - fuse_unmount; }; FUSE_2.4 { @@ -95,6 +94,8 @@ FUSE_2.6 { fuse_opt_insert_arg; fuse_setup; fuse_setup_compat25; + fuse_unmount; + fuse_unmount_compat22; local: *; diff --git a/lib/helper.c b/lib/helper.c index f937366..a5935de 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -225,7 +225,7 @@ static struct fuse *fuse_setup_common(int argc, char *argv[], err_destroy: fuse_destroy(fuse); err_unmount: - fuse_unmount(*mountpoint); + fuse_unmount(*mountpoint, *fd); err_free: free(*mountpoint); return NULL; @@ -242,10 +242,8 @@ struct fuse *fuse_setup(int argc, char *argv[], void fuse_teardown(struct fuse *fuse, int fd, char *mountpoint) { - (void) fd; - fuse_remove_signal_handlers(fuse_get_session(fuse)); - fuse_unmount(mountpoint); + fuse_unmount(mountpoint, fd); fuse_destroy(fuse); free(mountpoint); } diff --git a/lib/mount.c b/lib/mount.c index 0a14df3..a1875f0 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -166,11 +166,18 @@ static int receive_fd(int fd) return *(int*)CMSG_DATA(cmsg); } -void fuse_unmount(const char *mountpoint) +void fuse_unmount_compat22(const char *mountpoint) +{ + fuse_unmount(mountpoint, -1); +} + +void fuse_unmount(const char *mountpoint, int fd) { const char *mountprog = FUSERMOUNT_PROG; int pid; + (void) fd; + if (!mountpoint) return; @@ -293,3 +300,4 @@ int fuse_mount_compat1(const char *mountpoint, const char *args[]) } __asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2"); +__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index cb1b2b9..c5661d2 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -9,14 +9,16 @@ #include "fuse.h" #include "fuse_opt.h" +#include <sys/stat.h> +#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stddef.h> #include <fcntl.h> #include <errno.h> -#include <sys/wait.h> #include <string.h> +#include <paths.h> #define FUSERMOUNT_PROG "mount_fusefs" #define FUSE_DEV_TRUNK "/dev/fuse" @@ -154,7 +156,7 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key, return 1; } -void fuse_unmount(const char *mountpoint) +void fuse_unmount_compat22(const char *mountpoint) { char dev[128]; char *ssc, *umount_cmd; @@ -171,6 +173,14 @@ void fuse_unmount(const char *mountpoint) (void) mountpoint; + /* + * If we don't know the fd, we have to resort to the scripted solution -- + * iterating over the fd-s is unpractical, as we don't know how many of + * open files we have. (This could be looked up in procfs -- however, + * that's optional on FBSD; or read out from the kmem -- however, that's + * bound to privileges (in fact, that's what happens when we call the + * setgid kmem fstat(1) utility). + */ asprintf(&ssc, seekscript, getpid()); errno = 0; @@ -187,6 +197,29 @@ void fuse_unmount(const char *mountpoint) system(umount_cmd); } +void fuse_unmount(const char *mountpoint, int fd) +{ + char *ep, *umount_cmd, dev[128]; + struct stat sbuf; + + (void)mountpoint; + + if (fstat(fd, &sbuf) == -1) + return; + + devname_r(sbuf.st_rdev, S_IFCHR, dev, 128); + + if (strncmp(dev, "fuse", 4)) + return; + + strtol(dev + 4, &ep, 10); + if (*ep != '\0') + return; + + asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev); + system(umount_cmd); +} + static int fuse_mount_core(const char *mountpoint, const char *opts) { const char *mountprog = FUSERMOUNT_PROG; @@ -299,3 +332,5 @@ int fuse_mount(const char *mountpoint, struct fuse_args *args) free(mo.kernel_opts); return res; } + +__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2"); |