From b1573bcff0c63743cf6a2273b95508efa5714cc5 Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Thu, 12 Nov 2009 02:22:00 +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, 48 insertions(+), 5 deletions(-) (limited to 'xlators/mount') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index b123d16ef..78ae9c0ef 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -50,12 +50,15 @@ #include "compat.h" #include "compat-errno.h" +#include + /* TODO: when supporting posix acl, remove this definition */ #define DISABLE_POSIX_ACL #define ZR_MOUNTPOINT_OPT "mountpoint" #define ZR_DIRECT_IO_OPT "direct-io-mode" #define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check" +#define MAX_FUSE_PROC_DELAY 1 struct fuse_private { int fd; @@ -75,6 +78,9 @@ 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; @@ -2491,11 +2497,37 @@ fuse_thread_proc (void *data) int32_t res = 0; struct iobuf *iobuf = NULL; size_t chan_size = 0; + int ret = -1; + + struct timeval now; + struct timespec timeout; + this = data; priv = this->private; chan_size = fuse_chan_bufsize (priv->ch); + 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); + while (!fuse_session_exited (priv->se)) { iobuf = iobuf_get (this->ctx->iobuf_pool); @@ -2568,7 +2600,18 @@ notify (xlator_t *this, int32_t event, void *data, ...) case GF_EVENT_CHILD_UP: case GF_EVENT_CHILD_CONNECTING: { - if (!private->fuse_thread_started) + 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) { private->fuse_thread_started = 1; @@ -2585,11 +2628,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; } @@ -2843,6 +2882,10 @@ init (xlator_t *this_xl) this_xl->ctx->top = this_xl; + pthread_cond_init (&priv->child_up_cond, NULL); + pthread_mutex_init (&priv->child_up_mutex, NULL); + priv->child_up_value = 1; + priv->first_call = 2; this_xl->itable = inode_table_new (0, this_xl); return 0; -- cgit