File fuse-umount-race-fix.patch of Package fuse

---
 lib/mount_util.c  |   59 ++++++++++++++++++++++++++++++++++++++++++++----------
 lib/mount_util.h  |    1 
 util/fusermount.c |    9 +++++++-
 3 files changed, 58 insertions(+), 11 deletions(-)

Index: fuse-2.8.5/lib/mount_util.c
===================================================================
--- fuse-2.8.5.orig/lib/mount_util.c	2010-09-28 10:03:09.000000000 +0200
+++ fuse-2.8.5/lib/mount_util.c	2010-12-02 14:58:34.000000000 +0100
@@ -140,14 +140,6 @@ static int add_mount(const char *prognam
 		goto out_restore;
 	}
 	if (res == 0) {
-		/*
-		 * Hide output, because old versions don't support
-		 * --no-canonicalize
-		 */
-		int fd = open("/dev/null", O_RDONLY);
-		dup2(fd, 1);
-		dup2(fd, 2);
-
 		sigprocmask(SIG_SETMASK, &oldmask, NULL);
 		setuid(geteuid());
 		execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
@@ -178,8 +170,6 @@ int fuse_mnt_add_mount(const char *progn
 		return 0;
 
 	res = add_mount(progname, fsname, mnt, type, opts);
-	if (res == -1)
-		res = add_mount_legacy(progname, fsname, mnt, type, opts);
 
 	return res;
 }
@@ -243,6 +233,55 @@ int fuse_mnt_umount(const char *progname
 	return exec_umount(progname, rel_mnt, lazy);
 }
 
+static int remove_mount(const char *progname, const char *mnt)
+{
+	int res;
+	int status;
+	sigset_t blockmask;
+	sigset_t oldmask;
+
+	sigemptyset(&blockmask);
+	sigaddset(&blockmask, SIGCHLD);
+	res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
+	if (res == -1) {
+		fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno));
+		return -1;
+	}
+
+	res = fork();
+	if (res == -1) {
+		fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
+		goto out_restore;
+	}
+	if (res == 0) {
+		sigprocmask(SIG_SETMASK, &oldmask, NULL);
+		setuid(geteuid());
+		execl("/bin/umount", "/bin/umount", "--no-canonicalize", "-i",
+		      "--fake", mnt, NULL);
+		fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
+			progname, strerror(errno));
+		exit(1);
+	}
+	res = waitpid(res, &status, 0);
+	if (res == -1)
+		fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
+
+	if (status != 0)
+		res = -1;
+
+ out_restore:
+	sigprocmask(SIG_SETMASK, &oldmask, NULL);
+	return res;
+}
+
+int fuse_mnt_remove_mount(const char *progname, const char *mnt)
+{
+	if (!mtab_needs_update(mnt))
+		return 0;
+
+	return remove_mount(progname, mnt);
+}
+
 char *fuse_mnt_resolve_path(const char *progname, const char *orig)
 {
 	char buf[PATH_MAX];
Index: fuse-2.8.5/lib/mount_util.h
===================================================================
--- fuse-2.8.5.orig/lib/mount_util.h	2010-06-23 15:04:14.000000000 +0200
+++ fuse-2.8.5/lib/mount_util.h	2010-12-02 14:58:34.000000000 +0100
@@ -10,6 +10,7 @@
 
 int fuse_mnt_add_mount(const char *progname, const char *fsname,
 		       const char *mnt, const char *type, const char *opts);
+int fuse_mnt_remove_mount(const char *progname, const char *mnt);
 int fuse_mnt_umount(const char *progname, const char *abs_mnt,
 		    const char *rel_mnt, int lazy);
 char *fuse_mnt_resolve_path(const char *progname, const char *orig);
Index: fuse-2.8.5/util/fusermount.c
===================================================================
--- fuse-2.8.5.orig/util/fusermount.c	2010-09-28 10:04:13.000000000 +0200
+++ fuse-2.8.5/util/fusermount.c	2010-12-02 14:58:34.000000000 +0100
@@ -407,8 +407,15 @@ static int unmount_fuse_locked(const cha
 	if (res == -1)
 		goto out;
 
-	res = fuse_mnt_umount(progname, mnt, last, lazy);
+	res = umount2(last, lazy ? 2 : 0);
+	if (res == -1 && !quiet) {
+		fprintf(stderr,
+			"%s: failed to unmount %s: %s\n",
+			progname, mnt, strerror(errno));
+	}
 
+	if (res == 0)
+		res = fuse_mnt_remove_mount(progname, mnt);
 out:
 	free(copy);
 	if (currdir_fd != -1) {
openSUSE Build Service is sponsored by