Hi group, hi Amit.

I'm maintaining an ntfs-3g package for OS X at 
http://macntfs-3g.blogspot.com and I'm struggling with an issue where 
the ntfs-3g process locks up at shutdown, and has to be SIGKILL'd by the 
OS after a delay of 30 seconds.
ntfs-3g is not doing any signal handling itself in the current version, 
and instead passes that responsibility over the fuse library by invoking:

    fuse_set_signal_handlers(fuse_get_session(struct fuse*))

When I send the ntfs-3g process SIGTERM under "normal" circumstances, in 
a non-shutdown situation, there is no problem. ntfs-3g terminates 
gracefully. Some kind of deadlock seems to occur when this is done in a 
shutdown situation though.

I looked through the MacFUSE patchset and found a modification to 
fuse_signals.c which seems suspicious to me (scroll down to the end of 
the mail to see what I'm talking about). I don't have a very good view 
of the internal structure of fuse, but it seems like a fair assumption 
that fuse_signals.c takes care of signal handling.
In the below code snippet, the exit_handler forks (seems dangerous to me 
in a shutdown situation where processes are killed off all the time), 
and invokes the command /sbin/umount . I'm suggesting that this behavior 
is somehow causing the lockup, but I have no real "evidence" for it, 
just thoughts.

As a workaround, I have written a daemon, fuse_daemon (actually a 
reimplementation of Paul Marks' utility for the older ntfs-3g package) 
that waits in the background until it gets SIGTERM, and then iterates 
through all fuse file systems and unmounts them cleanly. This only seems 
to work if fuse_daemon gets SIGTERM before ntfs-3g does, so signal 
handling in ntfs-3g needs to be turned off completely for this solution 
work.

I hope you realize the serious implication of this problem... if ntfs-3g 
(or indeed any other FUSE file system) doesn't terminate gracefully, it 
might leave the user's hard drive in an inconsistent state, worst case.
Has anyone encountered this issue before, and solved it without having 
an external daemon manage unmounting of file systems?

- Erik Larsson

---------
diff -Naur old/lib/fuse_signals.c new/lib/fuse_signals.c
--- old/lib/fuse_signals.c    2007-10-16 09:35:23.000000000 -0700
+++ new/lib/fuse_signals.c    2008-01-01 15:56:28.000000000 -0800
@@ -13,12 +13,45 @@
#include <signal.h>

static struct fuse_session *fuse_instance;
+#if (__FreeBSD__ >= 10)
+extern char *fuse_session_get_mntonname(struct fuse_session *se);
+
+#include <unistd.h>
+
+int
+fuse_chan_fd_np(void)
+{
+    if (fuse_instance && !fuse_session_exited(fuse_instance)) {
+        return fuse_chan_fd(fuse_session_next_chan(fuse_instance, NULL));
+    } else {
+        return -1;
+    }
+}
+
+#endif

static void exit_handler(int sig)
{
    (void) sig;
+#if (__FreeBSD__ >= 10)
+    if (fuse_instance && !fuse_session_exited(fuse_instance)) {
+        int fd;
+        pid_t pid;
+
+        fd = fuse_chan_fd(fuse_session_next_chan(fuse_instance, NULL));
+        pid = fork();
+        if (pid == 0) { /* child */
+             char *mntonname = fuse_session_get_mntonname(fuse_instance);
+             fcntl(fd, F_SETFD, 1); /* close-on-exec */
+             execl("/sbin/umount", "/sbin/umount", mntonname, NULL);
+        } else {
+            /* We do nothing in the parent. */
+        }
+    }
+#else
    if (fuse_instance)
        fuse_session_exit(fuse_instance);
+#endif
}

static int set_one_signal_handler(int sig, void (*handler)(int))
---------


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"macfuse-devel" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/macfuse-devel?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to