|
|
21ab4e |
From 7d1da6b73706ce2cbbfa9eac302d415757167d57 Mon Sep 17 00:00:00 2001
|
|
|
3604df |
From: Amar Tumballi <amarts@redhat.com>
|
|
|
3604df |
Date: Mon, 29 May 2017 17:26:35 +0530
|
|
|
21ab4e |
Subject: [PATCH 476/486] fuse: implement "-oauto_unmount"
|
|
|
3604df |
|
|
|
3604df |
libfuse has an auto_unmount option which,
|
|
|
3604df |
if enabled, ensures that the file system
|
|
|
3604df |
is unmounted at FUSE server termination
|
|
|
3604df |
by running a separate monitor process
|
|
|
3604df |
that performs the unmount when that
|
|
|
3604df |
occurs. (This feature would probably
|
|
|
3604df |
better be called "robust auto-unmount",
|
|
|
3604df |
as FUSE servers usually do try to unmount
|
|
|
3604df |
their file systems upon termination,
|
|
|
3604df |
it's just this mechanism is not crash
|
|
|
3604df |
resilient.)
|
|
|
3604df |
|
|
|
3604df |
This change implements that option and
|
|
|
3604df |
behavior for glusterfs.
|
|
|
3604df |
|
|
|
3604df |
Note that "auto unmount" (robust or not) is
|
|
|
3604df |
a leaky abstraction, as the kernel cannot
|
|
|
3604df |
guarantee that at the path where the FUSE
|
|
|
3604df |
fs is mounted is actually the toplevel mount
|
|
|
3604df |
at the time of the umount(2) call, for
|
|
|
3604df |
multiple reasons, among others, see:
|
|
|
3604df |
|
|
|
3604df |
fuse-devel: "fuse: feasible to distinguish between umount and abort?"
|
|
|
3604df |
http://fuse.996288.n3.nabble.com/fuse-feasible-to-distinguish-between-umount-and-abort-tt14358.html
|
|
|
3604df |
https://github.com/libfuse/libfuse/issues/122
|
|
|
3604df |
|
|
|
3604df |
> Change-Id: Ia4432580c9fd2c156d9c73c3a44f4bfd42437599
|
|
|
3604df |
> Signed-off-by: Csaba Henk <csaba@redhat.com>
|
|
|
3604df |
> Reviewed-on: https://review.gluster.org/17230
|
|
|
3604df |
> Tested-by: Amar Tumballi <amarts@redhat.com>
|
|
|
3604df |
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
> Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
> Reviewed-by: Amar Tumballi <amarts@redhat.com>
|
|
|
3604df |
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
3604df |
|
|
|
21ab4e |
BUG: 1424680
|
|
|
3604df |
Change-Id: I4bae611254bad749b02abaf18d0ed6f447aec7b8
|
|
|
3604df |
Signed-off-by: Amar Tumballi <amarts@redhat.com>
|
|
|
21ab4e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/107571
|
|
|
3604df |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
3604df |
---
|
|
|
3604df |
contrib/fuse-include/fuse-mount.h | 1 +
|
|
|
3604df |
contrib/fuse-lib/mount.c | 46 +++++++++++++++++++++++++++++
|
|
|
3604df |
xlators/mount/fuse/src/fuse-bridge.c | 34 +++++++++++++++++++--
|
|
|
3604df |
xlators/mount/fuse/src/fuse-bridge.h | 3 ++
|
|
|
3604df |
xlators/mount/fuse/utils/mount.glusterfs.in | 2 +-
|
|
|
3604df |
5 files changed, 82 insertions(+), 4 deletions(-)
|
|
|
3604df |
|
|
|
3604df |
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h
|
|
|
3604df |
index 9358ac8..f2f08e3 100644
|
|
|
3604df |
--- a/contrib/fuse-include/fuse-mount.h
|
|
|
3604df |
+++ b/contrib/fuse-include/fuse-mount.h
|
|
|
3604df |
@@ -8,6 +8,7 @@
|
|
|
3604df |
*/
|
|
|
3604df |
|
|
|
3604df |
void gf_fuse_unmount (const char *mountpoint, int fd);
|
|
|
3604df |
+int gf_fuse_unmount_daemon (const char *mountpoint, int fd);
|
|
|
3604df |
int gf_fuse_mount (const char *mountpoint, char *fsname,
|
|
|
3604df |
unsigned long mountflags, char *mnt_param,
|
|
|
3604df |
pid_t *mtab_pid, int status_fd);
|
|
|
3604df |
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
|
|
|
3604df |
index 5e0b4dd..876ac90 100644
|
|
|
3604df |
--- a/contrib/fuse-lib/mount.c
|
|
|
3604df |
+++ b/contrib/fuse-lib/mount.c
|
|
|
3604df |
@@ -75,6 +75,52 @@ gf_fuse_unmount (const char *mountpoint, int fd)
|
|
|
3604df |
|
|
|
3604df |
/* gluster-specific routines */
|
|
|
3604df |
|
|
|
3604df |
+/* Unmounting in a daemon that lurks 'till main process exits */
|
|
|
3604df |
+int
|
|
|
3604df |
+gf_fuse_unmount_daemon (const char *mountpoint, int fd)
|
|
|
3604df |
+{
|
|
|
3604df |
+ int ret = -1;
|
|
|
3604df |
+ pid_t pid = -1;
|
|
|
3604df |
+
|
|
|
3604df |
+ if (fd == -1)
|
|
|
3604df |
+ return -1;
|
|
|
3604df |
+
|
|
|
3604df |
+ int ump[2] = {0,};
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = pipe(ump);
|
|
|
3604df |
+ if (ret == -1) {
|
|
|
3604df |
+ close (fd);
|
|
|
3604df |
+ return -1;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ pid = fork ();
|
|
|
3604df |
+ switch (pid) {
|
|
|
3604df |
+ char c = 0;
|
|
|
3604df |
+ sigset_t sigset;
|
|
|
3604df |
+ case 0:
|
|
|
3604df |
+
|
|
|
3604df |
+ close_fds_except (ump, 1);
|
|
|
3604df |
+
|
|
|
3604df |
+ setsid();
|
|
|
3604df |
+ chdir("/");
|
|
|
3604df |
+ sigfillset(&sigset);
|
|
|
3604df |
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
|
|
|
3604df |
+
|
|
|
3604df |
+ read (ump[0], &c, 1);
|
|
|
3604df |
+
|
|
|
3604df |
+ gf_fuse_unmount (mountpoint, fd);
|
|
|
3604df |
+ exit (0);
|
|
|
3604df |
+ case -1:
|
|
|
3604df |
+ close (fd);
|
|
|
3604df |
+ fd = -1;
|
|
|
3604df |
+ ret = -1;
|
|
|
3604df |
+ close (ump[1]);
|
|
|
3604df |
+ }
|
|
|
3604df |
+ close (ump[0]);
|
|
|
3604df |
+
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
static char *
|
|
|
3604df |
escape (char *s)
|
|
|
3604df |
{
|
|
|
3604df |
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
21ab4e |
index a0eb146..a8d936d 100644
|
|
|
3604df |
--- a/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
3604df |
+++ b/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
21ab4e |
@@ -5089,7 +5089,7 @@ fuse_thread_proc (void *data)
|
|
|
3604df |
ZR_MOUNTPOINT_OPT));
|
|
|
3604df |
if (mount_point) {
|
|
|
3604df |
gf_log (this->name, GF_LOG_INFO,
|
|
|
3604df |
- "unmounting %s", mount_point);
|
|
|
3604df |
+ "initating unmount of %s", mount_point);
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
/* Kill the whole process, not just this thread. */
|
|
|
21ab4e |
@@ -5711,6 +5711,24 @@ init (xlator_t *this_xl)
|
|
|
3604df |
if (!mnt_args)
|
|
|
3604df |
goto cleanup_exit;
|
|
|
3604df |
|
|
|
3604df |
+ {
|
|
|
3604df |
+ char *mnt_tok = NULL;
|
|
|
3604df |
+ token_iter_t tit = {0,};
|
|
|
3604df |
+ gf_boolean_t iter_end = _gf_false;
|
|
|
3604df |
+
|
|
|
3604df |
+ for (mnt_tok = token_iter_init (mnt_args, ',', &tit) ;;) {
|
|
|
3604df |
+ iter_end = next_token (&mnt_tok, &tit;;
|
|
|
3604df |
+
|
|
|
3604df |
+ if (strcmp (mnt_tok, "auto_unmount") == 0) {
|
|
|
3604df |
+ priv->auto_unmount = _gf_true;
|
|
|
3604df |
+ drop_token (mnt_tok, &tit;;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ if (iter_end)
|
|
|
3604df |
+ break;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
if (pipe(priv->status_pipe) < 0) {
|
|
|
3604df |
gf_log (this_xl->name, GF_LOG_ERROR,
|
|
|
3604df |
"could not create pipe to separate mount process");
|
|
|
21ab4e |
@@ -5722,6 +5740,11 @@ init (xlator_t *this_xl)
|
|
|
3604df |
priv->status_pipe[1]);
|
|
|
3604df |
if (priv->fd == -1)
|
|
|
3604df |
goto cleanup_exit;
|
|
|
3604df |
+ if (priv->auto_unmount) {
|
|
|
3604df |
+ ret = gf_fuse_unmount_daemon (priv->mount_point, priv->fd);
|
|
|
3604df |
+ if (ret == -1)
|
|
|
3604df |
+ goto cleanup_exit;
|
|
|
3604df |
+ }
|
|
|
3604df |
|
|
|
3604df |
event = eh_new (FUSE_EVENT_HISTORY_SIZE, _gf_false, NULL);
|
|
|
3604df |
if (!event) {
|
|
|
21ab4e |
@@ -5799,10 +5822,15 @@ fini (xlator_t *this_xl)
|
|
|
3604df |
mount_point = data_to_str (dict_get (this_xl->options,
|
|
|
3604df |
ZR_MOUNTPOINT_OPT));
|
|
|
3604df |
if (mount_point != NULL) {
|
|
|
3604df |
+ if (!priv->auto_unmount) {
|
|
|
3604df |
+ gf_log (this_xl->name, GF_LOG_INFO,
|
|
|
3604df |
+ "Unmounting '%s'.", mount_point);
|
|
|
3604df |
+ gf_fuse_unmount (mount_point, priv->fd);
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
gf_log (this_xl->name, GF_LOG_INFO,
|
|
|
3604df |
- "Unmounting '%s'.", mount_point);
|
|
|
3604df |
+ "Closing fuse connection to '%s'.", mount_point);
|
|
|
3604df |
|
|
|
3604df |
- gf_fuse_unmount (mount_point, priv->fd);
|
|
|
3604df |
sys_close (priv->fuse_dump_fd);
|
|
|
3604df |
dict_del (this_xl->options, ZR_MOUNTPOINT_OPT);
|
|
|
3604df |
}
|
|
|
3604df |
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
3604df |
index 40bd17b..0c70189 100644
|
|
|
3604df |
--- a/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
3604df |
+++ b/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
3604df |
@@ -134,6 +134,9 @@ struct fuse_private {
|
|
|
3604df |
|
|
|
3604df |
/* Enable or disable capability support */
|
|
|
3604df |
gf_boolean_t capability;
|
|
|
3604df |
+
|
|
|
3604df |
+ /* whether to run the unmount daemon */
|
|
|
3604df |
+ gf_boolean_t auto_unmount;
|
|
|
3604df |
};
|
|
|
3604df |
typedef struct fuse_private fuse_private_t;
|
|
|
3604df |
|
|
|
3604df |
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
|
|
|
3604df |
index 6c4cdfe..2c5e466 100755
|
|
|
3604df |
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
|
|
|
3604df |
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
|
|
|
3604df |
@@ -538,7 +538,7 @@ without_options()
|
|
|
3604df |
"atime"|"noatime"|"diratime"|"nodiratime"|\
|
|
|
3604df |
"relatime"|"norelatime"|\
|
|
|
3604df |
"strictatime"|"nostrictatime"|"lazyatime"|"nolazyatime"|\
|
|
|
3604df |
- "dev"|"nodev"|"exec"|"noexec"|"suid"|"nosuid")
|
|
|
3604df |
+ "dev"|"nodev"|"exec"|"noexec"|"suid"|"nosuid"|"auto_unmount")
|
|
|
3604df |
[ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"
|
|
|
3604df |
fuse_mountopts="${fuse_mountopts}${option}"
|
|
|
3604df |
;;
|
|
|
3604df |
--
|
|
|
3604df |
1.8.3.1
|
|
|
3604df |
|