Hi Amit. For me personally, it's like a testbed for finding out what works and what doesn't concerning different methods of unmounting file system. It is not deployed in the current ntfs-3g packages and I don't mean to do so, as long as I can find another solution.
I was just carrying out some tests, restarting the computer a few times and finding various ways to get past the issue. These are my findings so far: - hello world file system, calling the simple fuse_main(3 arguments) at startup, has no problem unmounting at shutdown. - Not all ntfs-3g processes lock up at shutdown. Unfortunately I have very few physical test cases, but as far as I can see the ntfs partition on my internal SATA drive fails to unmount properly while my USB2 drive unmounts properly. Not sure if the connection type is relevant. - When unmounted from an external process (fuse_daemon) all ntfs-3g processes exit and unmount properly at shutdown (as far as I have observed). At this stage, I have managed to build a ntfs-3g binary which seems to handle unmounting perfectly by itself. I removed the call to fuse_set_signal_handlers and implemented a custom signal handler which unmounts the disk through DiskArbitration, but I'm not sure why this works because it doesn't seem like the actual unmount succeeds, looking at the log. (It does succeed when SIGTERM:ing the process in a non-shutdown situation) Still the file system is unmounted in some way or another... (magic?) So... I'm somewhat confused at the moment. - Erik Amit Singh skrev: > As I asked earlier, have you tried other MacFUSE file systems to see > if they get stuck at shutdown time? > > Why do you need your fuse_daemon implementation? > > Amit > > On Feb 6, 10:01 am, Erik Larsson <[EMAIL PROTECTED]> wrote: > >> Hi Paul. >> >> My fuse_daemon implementation does exactly as you describe. >> Experimentally, I have discovered that DiskArbitration services aren't >> available at shutdown time (trying to create a DADiskRef from a BSD name >> fails, at least), but resorting to unmount(const char*, int) does the job. >> However, if ntfs-3g manages to catch the signal before fuse_daemon, both >> processes both lock up (in the fuse_daemon case, it happens when >> fuse_daemon is in the process of carrying out the unmount(...) system >> call for the ntfs-3g file system). >> In that situation both ntfs-3g and fuse_daemon gets forcibly terminated >> with SIGKILL after 30 seconds. >> >> - Erik >> >> Paul Marks skrev: >> >> >>> Good afternoon, >>> >>> When I was working on NTFS-3G, I tried to avoid modifying FUSE or >>> ntfs-3g itself. Instead, I just wrote a short daemon that blocked on >>> sigsuspend() until it received SIGTERM, SIGQUIT, or SIGINT. >>> >>> If it received SIGTERM from its parent (i.e. launchd), that implies >>> system shutdown. Then I would scan mounted filesystems with >>> getmntinfo() looking for those of type "fusefs," and unmount() those, >>> perhaps with MNT_FORCE. With some of the changes to MacFUSE, you may >>> also want to scan for anything of a type matching "fusefs_*" as well. >>> >>> This would cause the ntfs-3g binary to terminate cleanly, without >>> needing to handle SIGTERM. A more advisable option would be to go >>> through DiskArbitration and give DADiskUnmount() a shot before >>> resorting to unmount(), which will assure proper notifications get >>> sent to things like Spotlight before the volume is forcibly unmounted. >>> >>> It worked for me, at the time. >>> >>> Hope this helps, >>> - Paul >>> >>> On Feb 6, 2008, at 4:04 AM, Erik Larsson wrote: >>> >>>> Hi group, hi Amit. >>>> >>>> I'm maintaining an ntfs-3g package for OS X at >>>> http://macntfs-3g.blogspot.comand 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 -~----------~----~----~----~------~----~------~--~---
