summaryrefslogtreecommitdiffstats
path: root/contrib
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
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')
-rw-r--r--contrib/apple/daemon.c26
-rw-r--r--contrib/apple/daemon.h1
-rw-r--r--contrib/fuse-include/fuse-mount.h3
-rw-r--r--contrib/fuse-lib/mount.c52
-rw-r--r--contrib/macfuse/mount_darwin.c3
5 files changed, 52 insertions, 33 deletions
diff --git a/contrib/apple/daemon.c b/contrib/apple/daemon.c
index 9389201..07dbbc4 100644
--- a/contrib/apple/daemon.c
+++ b/contrib/apple/daemon.c
@@ -44,7 +44,7 @@
#include <unistd.h>
int
-os_daemon(nochdir, noclose)
+os_daemon_return(nochdir, noclose)
int nochdir, noclose;
{
struct sigaction osa, sa;
@@ -52,6 +52,7 @@ os_daemon(nochdir, noclose)
pid_t newgrp;
int oerrno;
int osa_ok;
+ int ret;
/* A SIGHUP may be thrown when the parent exits below. */
sigemptyset(&sa.sa_mask);
@@ -59,14 +60,9 @@ os_daemon(nochdir, noclose)
sa.sa_flags = 0;
osa_ok = sigaction(SIGHUP, &sa, &osa);
- switch (fork()) {
- case -1:
- return (-1);
- case 0:
- break;
- default:
- _exit(0);
- }
+ ret = fork();
+ if (ret)
+ return ret;
newgrp = setsid();
oerrno = errno;
@@ -90,3 +86,15 @@ os_daemon(nochdir, noclose)
}
return (0);
}
+
+int
+os_daemon(int nochdir, int noclose)
+{
+ int ret;
+
+ ret = os_daemon_return(nochdir, noclose);
+ if (ret <= 0)
+ return ret;
+
+ _exit(0);
+}
diff --git a/contrib/apple/daemon.h b/contrib/apple/daemon.h
index 7a2824b..aa88d9b 100644
--- a/contrib/apple/daemon.h
+++ b/contrib/apple/daemon.h
@@ -17,4 +17,5 @@
<http://www.gnu.org/licenses/>.
*/
+int os_daemon_return(int nochdir, int noclose);
int os_daemon(int nochdir, int noclose);
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h
index ca571ce..9f83faf 100644
--- a/contrib/fuse-include/fuse-mount.h
+++ b/contrib/fuse-include/fuse-mount.h
@@ -8,4 +8,5 @@
*/
void gf_fuse_unmount (const char *mountpoint, int fd);
-int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param);
+int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
+ pid_t *mtab_pid);
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 47592a6..f922b07 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), "
diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c
index 9d87fca..c485583 100644
--- a/contrib/macfuse/mount_darwin.c
+++ b/contrib/macfuse/mount_darwin.c
@@ -133,7 +133,8 @@ Return:
}
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 /* not used on OS X */)
{
int fd, pid;
int result;