diff options
Diffstat (limited to 'cli/src')
-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 6dd30580004..ca181084668 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1381,18 +1381,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 c27573f89da..61699004ded 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -3237,7 +3237,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; @@ -3249,11 +3250,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"); @@ -3311,12 +3312,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) @@ -3326,12 +3352,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) { @@ -3362,11 +3417,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 e3cef2e4236..9650e364a8e 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -657,6 +657,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 6c0fbcedd45..d831af049cc 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -151,6 +151,7 @@ struct cli_local { xmlDocPtr doc; int vol_count; #endif + gf_lock_t lock; }; struct cli_volume_status { |