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 | |
| 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')
| -rw-r--r-- | contrib/apple/daemon.c | 26 | ||||
| -rw-r--r-- | contrib/apple/daemon.h | 1 | ||||
| -rw-r--r-- | contrib/fuse-include/fuse-mount.h | 3 | ||||
| -rw-r--r-- | contrib/fuse-lib/mount.c | 52 | ||||
| -rw-r--r-- | contrib/macfuse/mount_darwin.c | 3 | 
5 files changed, 52 insertions, 33 deletions
diff --git a/contrib/apple/daemon.c b/contrib/apple/daemon.c index 9389201a1af..07dbbc400b3 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 7a2824b6a47..aa88d9baa56 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 ca571ce5e30..9f83faf02a0 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 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), " diff --git a/contrib/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c index 9d87fca3596..c485583e96b 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;  | 
