diff options
author | Csaba Henk <csaba@gluster.com> | 2011-05-15 04:52:33 +0000 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2011-05-19 15:41:47 -0700 |
commit | c5d781e05599e9e7ad736d42c9c1033992c76ded (patch) | |
tree | aff88649bc98a6c8babc3d75760fae2ef36b4cc3 /contrib/fuse-lib | |
parent | 357df32e16dd21e7aedb699c7bd99cac9b95a040 (diff) |
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 <csaba@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2690 (race between mtab updates of mount and umount)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2690
Diffstat (limited to 'contrib/fuse-lib')
-rw-r--r-- | contrib/fuse-lib/mount.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c index 47592a62dd8..f922b07d44b 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), " |