diff options
author | Csaba Henk <csaba.henk@creo.hu> | 2008-02-03 15:00:22 +0000 |
---|---|---|
committer | Csaba Henk <csaba.henk@creo.hu> | 2008-02-03 15:00:22 +0000 |
commit | 7b3f3a8c2bc912a668586b350ceedb1aac2c8a00 (patch) | |
tree | 3fb81b31811e99c59e34229d128e71ff3be12644 /lib | |
parent | de094131902a0cda6cdb6483a0fc1beb8596ba4b (diff) |
lib/mount_bsd.c: ditch the kvm(8) stuff and fix unmounting in a simple and sensible way
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rw-r--r-- | lib/mount_bsd.c | 65 |
2 files changed, 15 insertions, 53 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 48986bb..4d14ef4 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,9 +36,6 @@ libfuse_la_SOURCES = \ libfuse_la_LDFLAGS = @libfuse_libs@ -version-number 2:7:2 \ -Wl,--version-script,$(srcdir)/fuse_versionscript -if BSD -libfuse_la_LDFLAGS += -lkvm -endif libulockmgr_la_SOURCES = ulockmgr.c libulockmgr_la_LDFLAGS = -version-number 1:0:1 diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index aa24b55..2e8c96f 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -23,11 +23,9 @@ #include <string.h> #include <paths.h> #include <limits.h> -#include <kvm.h> #define FUSERMOUNT_PROG "mount_fusefs" #define FUSE_DEV_TRUNK "/dev/fuse" -#define FUSE_ANS_WCHAN "fu_ans" enum { KEY_ALLOW_ROOT, @@ -221,72 +219,39 @@ void fuse_unmount_compat22(const char *mountpoint) static void do_unmount(char *dev, int fd) { char device_path[SPECNAMELEN + 12]; - const char *argv[3]; + const char *argv[4]; const char umount_cmd[] = "/sbin/umount"; - pid_t pid, rpid = 0; + pid_t pid; snprintf(device_path, SPECNAMELEN + 12, _PATH_DEV "%s", dev); argv[0] = umount_cmd; - argv[1] = device_path; - argv[2] = NULL; + argv[1] = "-f"; + argv[2] = device_path; + argv[3] = NULL; pid = fork(); if (pid == -1) return; - /* - * We don't simply close the device fd, because that's what - * guarantees us exclusive access to the device. - * - * OTOH, unmount(2) might get stuck if the device is kept - * open. - * - * So after we have spawn the umount process, we monitor it - * using the kvm(3) interface, and if we see it's waiting - * for an answer from us -- which implies the umount process - * still keeps the device occupied, regardless of the fd -- - * _then_ we close the device, interrupting thus unmount(2) - * in its futile waiting. - */ if (pid) { - kvm_t *kd; - struct kinfo_proc *kp; - char errbuf[_POSIX2_LINE_MAX]; - int nentries; - - kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, - O_RDONLY, errbuf); - if (!kd) - goto out; - - for (;;) { - kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &nentries); - - if (kp && nentries == 1 && - strcmp(kp->ki_wmesg, FUSE_ANS_WCHAN) == 0) { - close(fd); - - break; - } - - rpid = waitpid(pid, NULL, WNOHANG); - if (rpid) - break; - usleep(10000); - } - - kvm_close(kd); + char c; + + /* + * This will get us banned by the kernel so if + * unmount(2) is waiting for us (ie., for an answer + * to DESTROY), then it will be interrupted and can + * go on. + */ + read(fd, &c, 1); } else { close(fd); execvp(umount_cmd, (char **)argv); exit(1); } -out: - if (!rpid) - waitpid(pid, NULL, 0); + waitpid(pid, NULL, 0); } void fuse_kern_unmount(const char *mountpoint, int fd) |