summaryrefslogtreecommitdiffstats
path: root/contrib/fuse-lib/mount.c
diff options
context:
space:
mode:
authorCsaba Henk <csaba@gluster.com>2011-05-15 04:52:33 +0000
committerAnand Avati <avati@gluster.com>2011-05-19 15:41:47 -0700
commitc5d781e05599e9e7ad736d42c9c1033992c76ded (patch)
treeaff88649bc98a6c8babc3d75760fae2ef36b4cc3 /contrib/fuse-lib/mount.c
parent357df32e16dd21e7aedb699c7bd99cac9b95a040 (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/mount.c')
-rw-r--r--contrib/fuse-lib/mount.c52
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), "