diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/src/cli-cmd-volume.c | 12 | ||||
-rw-r--r-- | cli/src/cli-rpc-ops.c | 94 | ||||
-rw-r--r-- | cli/src/cli.c | 1 | ||||
-rw-r--r-- | cli/src/cli.h | 1 |
4 files changed, 89 insertions, 19 deletions
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index e26f5435c63..040e255f89d 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1376,18 +1376,6 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) CLI_LOCAL_INIT (local, words, frame, xdata); proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT]; - if (!(global_state->mode & GLUSTER_MODE_XML)) { - print_quota_list_header (type); - } else { - ret = cli_xml_output_vol_quota_limit_list_begin - (local, 0, 0, NULL); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, "Error in printing " - "xml output"); - goto out; - } - } - gfid_str = GF_CALLOC (1, gf_common_mt_char, 64); if (!gfid_str) { ret = -1; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index c10554daaee..3df9226d9e9 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3232,7 +3232,8 @@ out: } int -print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict) +print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict, + int32_t list_count) { char *path = NULL; char *default_sl = NULL; @@ -3244,11 +3245,11 @@ print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict) quota_limits_t *size_limits = NULL; int32_t type = 0; + GF_ASSERT (frame); + local = frame->local; gd_rsp_dict = local->dict; - GF_ASSERT (frame); - ret = dict_get_int32 (rsp_dict, "type", &type); if (ret) { gf_log ("cli", GF_LOG_ERROR, "Failed to get type"); @@ -3306,12 +3307,37 @@ print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict) goto out; } + if (list_count == 0) { + if (!(global_state->mode & GLUSTER_MODE_XML)) { + print_quota_list_header (type); + } else { + ret = cli_xml_output_vol_quota_limit_list_begin + (local, 0, 0, NULL); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error in " + "printing xml output"); + goto out; + } + } + } + ret = print_quota_list_output (local, path, default_sl, &limits, &used_space, type); out: return ret; } +void* +cli_cmd_broadcast_response_detached (void *opaque) +{ + int32_t ret = 0; + + ret = (intptr_t) opaque; + cli_cmd_broadcast_response (ret); + + return NULL; +} + int cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) @@ -3321,12 +3347,41 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov, int ret = -1; dict_t *dict = NULL; call_frame_t *frame = NULL; + cli_local_t *local = NULL; + dict_t *gd_rsp_dict = NULL; + int32_t list_count = 0; + pthread_t th_id = {0, }; - if (-1 == req->rpc_status) { + frame = myframe; + GF_ASSERT (frame); + + local = frame->local; + gd_rsp_dict = local->dict; + + LOCK (&local->lock); + { + ret = dict_get_int32 (gd_rsp_dict, "quota-list-count", + &list_count); + if (ret) + list_count = 0; + ret = dict_set_int32 (gd_rsp_dict, "quota-list-count", + list_count + 1); + } + UNLOCK (&local->lock); + + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to set " + "quota-list-count in dict"); goto out; } - frame = myframe; + if (-1 == req->rpc_status) { + if (list_count == 0) + cli_err ("Connection failed. Please check if quota " + "daemon is operational."); + ret = -1; + goto out; + } ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp); if (ret < 0) { @@ -3357,11 +3412,36 @@ cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov, "unserialize req-buffer to dictionary"); goto out; } - print_quota_list_from_quotad (frame, dict); + print_quota_list_from_quotad (frame, dict, list_count); } out: - cli_cmd_broadcast_response (ret); + /* Bad Fix: CLI holds the lock to process a command. + * When processing quota list command, below sequence of steps executed + * in the same thread and causing deadlock + * + * 1) CLI holds the lock + * 2) Send rpc_clnt_submit request to quotad for quota usage + * 3) If quotad is down, rpc_clnt_submit invokes cbk function with error + * 4) cbk function cli_quotad_getlimit_cbk invokes + * cli_cmd_broadcast_response which tries to hold lock to broadcast + * the results and hangs, because same thread has already holding + * the lock + * + * Broadcasting response in a seperate thread which is not a + * good fix. This needs to be re-visted with better solution + */ + if (ret == -1) { + ret = pthread_create (&th_id, NULL, + cli_cmd_broadcast_response_detached, + (void *)-1); + if (ret) + gf_log ("cli", GF_LOG_ERROR, "pthread_create failed: " + "%s", strerror (errno)); + } else { + cli_cmd_broadcast_response (ret); + } + if (dict) dict_unref (dict); diff --git a/cli/src/cli.c b/cli/src/cli.c index 3a27a3e7085..5707d3fbdd7 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -652,6 +652,7 @@ cli_local_get () cli_local_t *local = NULL; local = GF_CALLOC (1, sizeof (*local), cli_mt_cli_local_t); + LOCK_INIT (&local->lock); return local; } diff --git a/cli/src/cli.h b/cli/src/cli.h index 965ce3f9ee4..deadd2d0a5d 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -146,6 +146,7 @@ struct cli_local { xmlDocPtr doc; int vol_count; #endif + gf_lock_t lock; }; struct cli_volume_status { |