From: Miklos S. <mi...@sz...> - 2007-10-17 17:36:43
|
> I think there's a weird problem combining mandriva* systems and latests > fuse. > We use mandriva free 2008 64bits + kernel 2.6.23.1 along with > fuse-2.7.1(quite new ;-) and we use standard API (not the low-level > one). > > The problem is that whenever our FS launch fuse_main ... we gather this > strange message. > "fuse: waitpid: No child processes" > and fuse stops. > > Going a bit further, i found that in lib/mount_util.c function > fuse_mnt_add_mount > > res = waitpid(res, &status, 0); > > ... waitpid return ( waitpid returned res='-1', status_of_child='11011' ) > ... it looks like a 32 bits value read as an int in a 64bits context ... > > The same situation arises with mandriva 2007Spring and kernel-2.6.17. > > I just patched waitpid return value (res=status=0) and everything is OK. > > Any clues ? Can you please try the following patch? Thanks, Miklos Index: lib/mount_util.c =================================================================== RCS file: /cvsroot/fuse/fuse/lib/mount_util.c,v retrieving revision 1.8 diff -u -r1.8 mount_util.c --- lib/mount_util.c 16 Oct 2007 15:12:08 -0000 1.8 +++ lib/mount_util.c 17 Oct 2007 17:35:20 -0000 @@ -38,19 +38,30 @@ { int res; int status; + sigset_t blockmask; + sigset_t oldmask; if (!mtab_needs_update(mnt)) return 0; + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + res = fork(); if (res == -1) { fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - return -1; + goto out_restore; } if (res == 0) { char templ[] = "/tmp/fusermountXXXXXX"; char *tmp; + sigprocmask(SIG_SETMASK, &oldmask, NULL); setuid(geteuid()); /* @@ -76,30 +87,42 @@ exit(1); } res = waitpid(res, &status, 0); - if (res == -1) { + if (res == -1) fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - return -1; - } + if (status != 0) - return -1; + res = -1; - return 0; + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return res; } int fuse_mnt_umount(const char *progname, const char *mnt, int lazy) { int res; int status; + sigset_t blockmask; + sigset_t oldmask; if (!mtab_needs_update(mnt)) return 0; + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + res = fork(); if (res == -1) { fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - return -1; + goto out_restore; } if (res == 0) { + sigprocmask(SIG_SETMASK, &oldmask, NULL); setuid(geteuid()); execl("/bin/umount", "/bin/umount", "-i", mnt, lazy ? "-l" : NULL, NULL); @@ -108,14 +131,15 @@ exit(1); } res = waitpid(res, &status, 0); - if (res == -1) { + if (res == -1) fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - return -1; - } + if (status != 0) - return -1; + res = -1; - return 0; + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return res; } char *fuse_mnt_resolve_path(const char *progname, const char *orig) |