From 0486b355db0c014f49662ed593a7ab7e74c2cb59 Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Thu, 12 Nov 2009 03:23:27 +0000 Subject: mount/fuse: Prevent a hang on the mount point if no server is up when the client is started. Signed-off-by: Pavan Vilas Sondur Signed-off-by: Anand V. Avati BUG: 373 (Spawn fuse thread after a parent_up and wait and block until child_up) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=373 --- xlators/mount/fuse/src/fuse-bridge.c | 53 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'xlators/mount') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 886600522..94ed59a98 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifndef _CONFIG_H #define _CONFIG_H @@ -64,6 +65,8 @@ #define FUSE_712_OP_HIGH (FUSE_POLL + 1) #define GLUSTERFS_XATTR_LEN_MAX 65536 +#define MAX_FUSE_PROC_DELAY 1 + typedef struct fuse_in_header fuse_in_header_t; typedef void (fuse_handler_t) (xlator_t *this, fuse_in_header_t *finh, void *msg); @@ -85,6 +88,10 @@ struct fuse_private { pthread_mutex_t first_call_mutex; char first_call; gf_boolean_t strict_volfile_check; + pthread_cond_t child_up_cond; + pthread_mutex_t child_up_mutex; + char child_up_value; + }; typedef struct fuse_private fuse_private_t; @@ -3029,6 +3036,10 @@ fuse_thread_proc (void *data) struct iovec iov_in[2]; void *msg = NULL; const size_t msg0_size = sizeof (*finh) + 128; + int ret = -1; + + struct timeval now; + struct timespec timeout; this = data; priv = this->private; @@ -3040,6 +3051,28 @@ fuse_thread_proc (void *data) ->page_size; priv->msg0_len_p = &iov_in[0].iov_len; + pthread_mutex_lock (&priv->child_up_mutex); + { + gettimeofday (&now, NULL); + timeout.tv_sec = now.tv_sec + MAX_FUSE_PROC_DELAY; + timeout.tv_nsec = now.tv_usec * 1000; + + while (priv->child_up_value) { + + ret = pthread_cond_timedwait (&priv->child_up_cond, + &priv->child_up_mutex, + &timeout); + if (ret != 0) + break; + + } + } + pthread_mutex_unlock (&priv->child_up_mutex); + + gf_log (this->name, GF_LOG_DEBUG, + " pthread_cond_timedout returned non zero value" + " ret: %d errno: %d", ret, errno); + for (;;) { iobuf = iobuf_get (this->ctx->iobuf_pool); /* Add extra 128 byte to the first iov so that it can @@ -3222,6 +3255,18 @@ notify (xlator_t *this, int32_t event, void *data, ...) { case GF_EVENT_CHILD_UP: case GF_EVENT_CHILD_CONNECTING: + { + pthread_mutex_lock (&private->child_up_mutex); + { + private->child_up_value = 0; + pthread_cond_broadcast (&private->child_up_cond); + } + pthread_mutex_unlock (&private->child_up_mutex); + + break; + } + + case GF_EVENT_PARENT_UP: { if (!private->fuse_thread_started) { @@ -3240,11 +3285,7 @@ notify (xlator_t *this, int32_t event, void *data, ...) raise (SIGTERM); } } - break; - } - case GF_EVENT_PARENT_UP: - { default_notify (this, GF_EVENT_PARENT_UP, data); break; } @@ -3398,6 +3439,10 @@ init (xlator_t *this_xl) priv->first_call = 2; + pthread_cond_init (&priv->child_up_cond, NULL); + pthread_mutex_init (&priv->child_up_mutex, NULL); + priv->child_up_value = 1; + for (i = 0; i < FUSE_712_OP_HIGH; i++) fuse_ops[i] = fuse_enosys; fuse_ops[FUSE_INIT] = fuse_init; -- cgit