From c5d781e05599e9e7ad736d42c9c1033992c76ded Mon Sep 17 00:00:00 2001 From: Csaba Henk Date: Sun, 15 May 2011 04:52:33 +0000 Subject: upon daemonizing, wait on mtab update to terminate in parent This fixes the race in between the mtab update attempts of mount and umount when we do a lazy umount right after mounting, in order to hide the given fs instance; yet this way we still avoid the deadlock of the fs and mount which we can hit if we wait unconditionally for the mtab update to terminate (cf. bz #511). Signed-off-by: Csaba Henk Signed-off-by: Anand Avati BUG: 2690 (race between mtab updates of mount and umount) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2690 --- contrib/fuse-lib/mount.c | 52 ++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'contrib/fuse-lib') diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c index 47592a62..f922b07d 100644 --- a/contrib/fuse-lib/mount.c +++ b/contrib/fuse-lib/mount.c @@ -97,7 +97,8 @@ static #endif int fuse_mnt_add_mount (const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts) + const char *mnt, const char *type, const char *opts, + pid_t *mtab_pid) { int res; int status; @@ -125,19 +126,22 @@ fuse_mnt_add_mount (const char *progname, const char *fsname, char templ[] = "/tmp/fusermountXXXXXX"; char *tmp; - /* mtab update done async, just log if fails */ - res = fork (); - if (res) - exit (res == -1 ? 1 : 0); - res = fork (); - if (res) { - if (res != -1) - res = waitpid (res, &status, 0); - if (res == -1) - GFFUSE_LOGERR ("%s: /etc/mtab update failed", - progname); - - exit (0); + if (!mtab_pid) { + /* mtab update done async, just log if fails */ + res = fork (); + if (res) + exit (res == -1 ? 1 : 0); + res = fork (); + if (res) { + if (res != -1) { + if (!(res == waitpid (res, &status, 0) + && status == 0)) + GFFUSE_LOGERR ("%s: /etc/mtab " + "update failed", + progname); + } + exit (0); + } } sigprocmask (SIG_SETMASK, &oldmask, NULL); @@ -165,13 +169,16 @@ fuse_mnt_add_mount (const char *progname, const char *fsname, progname, strerror (errno)); exit (1); } - res = waitpid (res, &status, 0); + if (mtab_pid) { + *mtab_pid = res; + res = 0; + } else { + if (!(res == waitpid (res, &status, 0) && status == 0)) + res = -1; + } if (res == -1) GFFUSE_LOGERR ("%s: waitpid: %s", progname, strerror (errno)); - if (status != 0) - res = -1; - out_restore: sigprocmask (SIG_SETMASK, &oldmask, NULL); return res; @@ -519,7 +526,7 @@ gf_fuse_unmount (const char *mountpoint, int fd) #ifndef FUSE_UTIL static int -fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param) +fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param, pid_t *mtab_pid) { int fd = -1, ret = -1; unsigned mounted = 0; @@ -573,7 +580,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname, char *mnt_param) } ret = fuse_mnt_add_mount ("fuse", source, newmnt, fstype, - mnt_param); + mnt_param, mtab_pid); FREE (newmnt); if (ret == -1) { GFFUSE_LOGERR ("failed to add mtab entry"); @@ -625,13 +632,14 @@ escape (char *s) } int -gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param) +gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param, + pid_t *mtab_pid) { int fd = -1, rv = -1; char *fm_mnt_params = NULL, *p = NULL; char *efsname = NULL; - fd = fuse_mount_sys (mountpoint, fsname, mnt_param); + fd = fuse_mount_sys (mountpoint, fsname, mnt_param, mtab_pid); if (fd == -1) { gf_log ("glusterfs-fuse", GF_LOG_INFO, "direct mount failed (%s), " -- cgit