lib/mount_bsd.c: ditch the kvm(8) stuff and fix unmounting in a simple and sensible way
authorCsaba Henk <csaba.henk@creo.hu>
Sun, 3 Feb 2008 15:00:22 +0000 (15:00 +0000)
committerCsaba Henk <csaba.henk@creo.hu>
Sun, 3 Feb 2008 15:00:22 +0000 (15:00 +0000)
ChangeLog
lib/Makefile.am
lib/mount_bsd.c

index e922630015d8f92e7f186b7c619437f197461a1f..d8135003d4f80c939dd8d0a8a00edbbffb265c4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@
          (in FreeBSD a mount failure is not critical per se, as the daemon
          still could be mounted externally, but waiting for such an event
          is more confusing than fruitful)
+       - ditch the kvm(8) stuff and fix unmounting in a simple and sensible
+         way
 
 2008-01-07  Csaba Henk <csaba.henk@creo.hu>
 
index 48986bbabf71b8a5ac8304a2d4af31c16cca3252..4d14ef47aa1984032bd2761b52958ba511472a5d 100644 (file)
@@ -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
index aa24b55db61cfb1e1ef8ef9d1ba39802ff4a934d..2e8c96fc2c44881d38bebc5e334e82f0a455c8b7 100644 (file)
 #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)