summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/fd-lk.c21
-rw-r--r--libglusterfs/src/fd-lk.h3
-rw-r--r--libglusterfs/src/statedump.c3
-rw-r--r--xlators/protocol/client/src/client-handshake.c20
-rw-r--r--xlators/protocol/client/src/client-helpers.c26
-rw-r--r--xlators/protocol/client/src/client.c62
-rw-r--r--xlators/protocol/client/src/client.h2
7 files changed, 109 insertions, 28 deletions
diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c
index 8df43bb602f..4e10d649ee9 100644
--- a/libglusterfs/src/fd-lk.c
+++ b/libglusterfs/src/fd-lk.c
@@ -129,6 +129,27 @@ fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
}
fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx)
+{
+ int ret = -1;
+ fd_lk_ctx_t *new_lk_ctx = NULL;
+
+ if (!lk_ctx) {
+ goto out;
+ }
+
+ ret = TRY_LOCK (&lk_ctx->lock);
+ if (ret)
+ goto out;
+
+ new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
+ UNLOCK (&lk_ctx->lock);
+
+out:
+ return new_lk_ctx;
+}
+
+fd_lk_ctx_t *
fd_lk_ctx_create ()
{
fd_lk_ctx_t *fd_lk_ctx = NULL;
diff --git a/libglusterfs/src/fd-lk.h b/libglusterfs/src/fd-lk.h
index 3e419e14377..7adbb5131b7 100644
--- a/libglusterfs/src/fd-lk.h
+++ b/libglusterfs/src/fd-lk.h
@@ -60,6 +60,9 @@ fd_lk_ctx_t *
fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx);
fd_lk_ctx_t *
+fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx);
+
+fd_lk_ctx_t *
fd_lk_ctx_create ();
int
diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c
index 9b15c5ba50d..f438c5a61ea 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -30,7 +30,8 @@
#endif /* MALLOC_H */
/* We don't want gf_log in this function because it may cause
- 'deadlock' with statedump */
+ 'deadlock' with statedump. This is because statedump happens
+ inside a signal handler and cannot afford to block on a lock.*/
#ifdef gf_log
# undef gf_log
#endif
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
index 34222f845a1..6d6e8ebc77b 100644
--- a/xlators/protocol/client/src/client-handshake.c
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -470,22 +470,6 @@ out:
}
int
-client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx)
-{
- int ret = 1;
-
- GF_VALIDATE_OR_GOTO ("client", lk_ctx, out);
-
- LOCK (&lk_ctx->lock);
- {
- ret = list_empty (&lk_ctx->lk_list);
- }
- UNLOCK (&lk_ctx->lock);
-out:
- return ret;
-}
-
-int
client_fd_lk_count (fd_lk_ctx_t *lk_ctx)
{
int count = 0;
@@ -789,7 +773,7 @@ client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx)
int32_t ret = -1;
fd_lk_ctx_t *lk_ctx = NULL;
- if (client_fd_lk_list_empty (fdctx->lk_ctx)) {
+ if (client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) {
gf_log (this->name, GF_LOG_WARNING,
"fd lock list is empty");
decrement_reopen_fd_count (this, (clnt_conf_t *)this->private);
@@ -874,7 +858,7 @@ client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
fdctx->remote_fd = rsp.fd;
if (!fdctx->released) {
list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
- if (!client_fd_lk_list_empty (fdctx->lk_ctx))
+ if (!client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false))
attempt_lock_recovery = _gf_true;
fdctx = NULL;
}
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c
index b9b0a0edf61..8cf83fe3094 100644
--- a/xlators/protocol/client/src/client-helpers.c
+++ b/xlators/protocol/client/src/client-helpers.c
@@ -26,6 +26,32 @@
#include "fd.h"
+int
+client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock)
+{
+ int ret = 1;
+
+ if (!lk_ctx) {
+ ret = -1;
+ goto out;
+ }
+
+ if (try_lock) {
+ ret = TRY_LOCK (&lk_ctx->lock);
+ if (ret != 0) {
+ ret = -1;
+ goto out;
+ }
+ } else {
+ LOCK (&lk_ctx->lock);
+ }
+
+ ret = list_empty (&lk_ctx->lk_list);
+ UNLOCK (&lk_ctx->lock);
+out:
+ return ret;
+}
+
clnt_fd_ctx_t *
this_fd_del_ctx (fd_t *file, xlator_t *this)
{
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index 19c8a62ee86..b954906c1ce 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -2409,6 +2409,54 @@ fini (xlator_t *this)
return;
}
+static void
+client_fd_lk_ctx_dump (xlator_t *this, fd_lk_ctx_t *lk_ctx, int nth_fd)
+{
+ gf_boolean_t use_try_lock = _gf_true;
+ int ret = -1;
+ int lock_no = 0;
+ fd_lk_ctx_t *lk_ctx_ref = NULL;
+ fd_lk_ctx_node_t *plock = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+
+ lk_ctx_ref = fd_lk_ctx_try_ref (lk_ctx);
+ if (!lk_ctx_ref)
+ return;
+
+ ret = client_fd_lk_list_empty (lk_ctx_ref, (use_try_lock = _gf_true));
+ if (ret != 0)
+ return;
+
+ ret = TRY_LOCK (&lk_ctx_ref->lock);
+ if (ret)
+ return;
+
+ gf_proc_dump_write ("------","------");
+
+ lock_no = 0;
+ list_for_each_entry (plock, &lk_ctx_ref->lk_list, next) {
+ snprintf (key, sizeof (key), "granted-posix-lock[%d]",
+ lock_no++);
+ gf_proc_dump_write (key, "owner = %s, cmd = %s "
+ "fl_type = %s, fl_start = %"
+ PRId64", fl_end = %"PRId64
+ ", user_flock: l_type = %s, "
+ "l_start = %"PRId64", l_len = %"PRId64,
+ lkowner_utoa (&plock->user_flock.l_owner),
+ get_lk_cmd (plock->cmd),
+ get_lk_type (plock->fl_type),
+ plock->fl_start, plock->fl_end,
+ get_lk_type (plock->user_flock.l_type),
+ plock->user_flock.l_start,
+ plock->user_flock.l_len);
+ }
+ gf_proc_dump_write ("------","------");
+
+ UNLOCK (&lk_ctx_ref->lock);
+ fd_lk_ctx_unref (lk_ctx_ref);
+
+}
+
int
client_priv_dump (xlator_t *this)
{
@@ -2423,18 +2471,12 @@ client_priv_dump (xlator_t *this)
return -1;
conf = this->private;
- if (!conf) {
- gf_log (this->name, GF_LOG_WARNING,
- "conf null in xlator");
+ if (!conf)
return -1;
- }
ret = pthread_mutex_trylock(&conf->lock);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING, "Unable to lock client %s"
- " errno: %d", this->name, errno);
+ if (ret)
return -1;
- }
gf_proc_dump_build_key(key_prefix, "xlator.protocol.client",
"%s.priv", this->name);
@@ -2442,8 +2484,10 @@ client_priv_dump (xlator_t *this)
gf_proc_dump_add_section(key_prefix);
list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) {
- sprintf (key, "fd.%d.remote_fd", ++i);
+ sprintf (key, "fd.%d.remote_fd", i);
gf_proc_dump_write(key, "%d", tmp->remote_fd);
+ client_fd_lk_ctx_dump (this, tmp->lk_ctx, i);
+ i++;
}
gf_proc_dump_write("connecting", "%d", conf->connecting);
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
index f5f3aa1fec8..1f8f75cece5 100644
--- a/xlators/protocol/client/src/client.h
+++ b/xlators/protocol/client/src/client.h
@@ -229,4 +229,6 @@ int32_t client_type_to_gf_type (short l_type);
int client_mark_fd_bad (xlator_t *this);
int client_set_lk_version (xlator_t *this);
+
+int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t use_try_lock);
#endif /* !_CLIENT_H */