From c9e92231e8fb31e6e4a9f061746daaedd77ad1b7 Mon Sep 17 00:00:00 2001 From: vmallika Date: Mon, 15 Jun 2015 12:31:48 +0530 Subject: features/quota : Fix XML output for quota list command This is a backport of http://review.gluster.org/#/c/9481/ > Sample output: > --------------- > > Sample 1) > ---------- > [root@snapshot-28 glusterfs]# gluster volume quota vol1 list /dir1 /dir4 > /dir5 --xml > > > 0 > 0 > > > > /dir1 > 10.0MB > 80% > 0Bytes > 10.0MB > > > /dir4 > No such file or directory > > > /dir5 > No such file or directory > > > > > Sample 2) > --------- > gluster volume quota vol1 list --xml > > > 0 > 0 > > > > > > > > /dir > 10.0MB > 80% > 0Bytes > 10.0MB > > > /dir1 > 10.0MB > 80% > 0Bytes > 10.0MB > > > > > Change-Id: I8a8d83cff88f778e5ee01fbca07d9f94c412317a > BUG: 1185259 > Signed-off-by: Sachin Pandit > Reviewed-on: http://review.gluster.org/9481 > Reviewed-by: Vijaikumar Mallikarjuna > Tested-by: Gluster Build System > Reviewed-by: Kaushal M Change-Id: Ibdf51db626a07e68b5ace98140877f6d21918c20 BUG: 1231641 Signed-off-by: vmallika Reviewed-on: http://review.gluster.org/11220 Tested-by: Gluster Build System Reviewed-by: Sachin Pandit Reviewed-by: Niels de Vos --- cli/src/cli-cmd-volume.c | 42 ++++++++- cli/src/cli-rpc-ops.c | 146 ++++++++++++++++++++++------- cli/src/cli-xml-output.c | 234 ++++++++++++++++++++++------------------------- cli/src/cli.h | 15 ++- 4 files changed, 277 insertions(+), 160 deletions(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 822da7d4e48..c235594e769 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1245,6 +1245,8 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) unsigned char buf[16] = {0}; int fd = -1; char quota_conf_file[PATH_MAX] = {0}; + gf_boolean_t xml_err_flag = _gf_false; + char err_str[NAME_MAX] = {0,}; xdata = dict_new (); if (!xdata) { @@ -1269,7 +1271,13 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) * quota enabled as cli_get_soft_limit() handles that */ if (!_limits_set_on_volume (volname)) { - cli_out ("quota: No quota configured on volume %s", volname); + snprintf (err_str, sizeof (err_str), "No quota configured on " + "volume %s", volname); + if (global_state->mode & GLUSTER_MODE_XML) { + xml_err_flag = _gf_true; + } else { + cli_out ("quota: %s", err_str); + } ret = 0; goto out; } @@ -1319,7 +1327,18 @@ 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]; - print_quota_list_header (); + if (!(global_state->mode & GLUSTER_MODE_XML)) { + print_quota_list_header (); + } 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; @@ -1355,12 +1374,31 @@ cli_cmd_quota_handle_list_all (const char **words, dict_t *options) all_failed = all_failed && ret; } + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_xml_output_vol_quota_limit_list_end (local); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error in printing " + "xml output"); + goto out; + } + } + if (count > 0) { ret = all_failed? -1: 0; } else { ret = 0; } + + out: + if (xml_err_flag) { + ret = cli_xml_output_str ("volQuota", NULL, -1, 0, err_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error outputting in " + "xml format"); + } + } + if (fd != -1) { close (fd); } diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 013dd09b640..252f0b12279 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2298,7 +2298,8 @@ out: } static int -print_quota_list_output (char *mountdir, char *default_sl, char *path) +print_quota_list_output (cli_local_t *local, char *mountdir, + char *default_sl, char *path) { int64_t used_space = 0; int64_t avail = 0; @@ -2328,10 +2329,30 @@ print_quota_list_output (char *mountdir, char *default_sl, char *path) #if defined(ENOATTR) && (ENOATTR != ENODATA) case ENOATTR: #endif - cli_err ("%-40s %s", path, "Limit not set"); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_quota_list_xml_error + (local, path, "Limit not set"); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed " + "to print xml output"); + goto out; + } + } else { + cli_err ("%-40s %s", path, "Limit not set"); + } break; default: - cli_err ("%-40s %s", path, strerror (errno)); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_quota_list_xml_error + (local, path, strerror (errno)); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed " + "to print xml output"); + goto out; + } + } else { + cli_err ("%-40s %s", path, strerror (errno)); + } break; } @@ -2355,8 +2376,18 @@ print_quota_list_output (char *mountdir, char *default_sl, char *path) &used_space, sizeof (used_space)); if (ret < 0) { - cli_out ("%-40s %7s %9s %11s %7s", path, hl_str, sl_final, - "N/A", "N/A"); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_quota_xml_output (local, path, hl_str, + sl_final, "N/A", "N/A"); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to " + "output in xml format for quota " + "list command"); + } + } else { + cli_out ("%-40s %7s %9s %11s %7s", path, hl_str, + sl_final, "N/A", "N/A"); + } } else { used_space = ntoh64 (used_space); @@ -2368,6 +2399,17 @@ print_quota_list_output (char *mountdir, char *default_sl, char *path) avail = 0; avail_str = gf_uint64_2human_readable (avail); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_quota_xml_output (local, path, hl_str, + sl_final, used_str, avail_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed to " + "output in xml format for quota " + "list command"); + } + goto out; + } + if (used_str == NULL) cli_out ("%-40s %7s %9s %11"PRIu64 "%9"PRIu64, path, hl_str, @@ -2385,14 +2427,17 @@ out: } int -gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict, - char *default_sl, int count, char *op_errstr) +gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname, + dict_t *dict, char *default_sl, int count, + int op_ret, int op_errno, char *op_errstr) { - int ret = -1; - int i = 0; - char key[1024] = {0,}; - char mountdir[PATH_MAX] = {0,}; - char *path = NULL; + int ret = -1; + int i = 0; + char key[1024] = {0,}; + char mountdir[PATH_MAX] = {0,}; + char *path = NULL; + gf_boolean_t xml_err_flag = _gf_false; + char err_str[NAME_MAX] = {0,}; if (!dict|| count <= 0) goto out; @@ -2401,8 +2446,15 @@ gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict, * to list them */ if (!_limits_set_on_volume (volname)) { + snprintf (err_str, sizeof (err_str), "No quota configured on " + "volume %s", volname); + if (global_state->mode & GLUSTER_MODE_XML) { + xml_err_flag = _gf_true; + } else { + cli_out ("quota: %s", err_str); + } + ret = 0; - cli_out ("quota: No quota configured on volume %s", volname); goto out; } @@ -2412,10 +2464,20 @@ gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict, goto out; } - cli_out (" Path Hard-limit " - "Soft-limit Used Available"); - cli_out ("-----------------------------------------------------" - "---------------------------"); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_xml_output_vol_quota_limit_list_begin + (local, op_ret, op_errno, op_errstr); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, + "Error outputting xml begin"); + goto out; + } + } else { + cli_out (" Path Hard-limit " + "Soft-limit Used Available"); + cli_out ("-----------------------------------------------------" + "---------------------------"); + } while (count--) { snprintf (key, sizeof (key), "path%d", i++); @@ -2431,10 +2493,18 @@ gf_cli_print_limit_list_from_dict (char *volname, dict_t *dict, if (ret) goto out; GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path); - ret = print_quota_list_output (mountdir, default_sl, path); + ret = print_quota_list_output (local, mountdir, default_sl, + path); } out: + if (xml_err_flag) { + ret = cli_xml_output_str ("volQuota", NULL, -1, 0, err_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Error outputting in xml " + "format"); + } + } return ret; } @@ -2514,6 +2584,17 @@ print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict) avail = 0; avail_str = gf_uint64_2human_readable (avail); + if (global_state->mode & GLUSTER_MODE_XML) { + ret = cli_quota_xml_output (local, path, hl_str, + sl_final, used_str, avail_str); + if (ret) { + gf_log ("cli", GF_LOG_ERROR, "Failed in " + "printing xml output for quota list " + "command"); + } + goto out; + } + if (used_str == NULL) cli_out ("%-40s %7s %9s %11"PRIu64 "%9"PRIu64, path, hl_str, @@ -2623,8 +2704,9 @@ out: } void -gf_cli_quota_list (char *volname, dict_t *dict, int count, char *op_errstr, - char *default_sl) +gf_cli_quota_list (cli_local_t *local, char *volname, dict_t *dict, + char *default_sl, int count, int op_ret, + int op_errno, char *op_errstr) { GF_VALIDATE_OR_GOTO ("cli", volname, out); @@ -2632,8 +2714,9 @@ gf_cli_quota_list (char *volname, dict_t *dict, int count, char *op_errstr, goto out; if (count > 0) - gf_cli_print_limit_list_from_dict (volname, dict, default_sl, - count, op_errstr); + gf_cli_print_limit_list_from_dict (local, volname, dict, + default_sl, count, op_ret, + op_errno, op_errstr); out: return; } @@ -2649,7 +2732,6 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, int32_t type = 0; call_frame_t *frame = NULL; char *default_sl = NULL; - char *limit_list = NULL; cli_local_t *local = NULL; dict_t *aggr = NULL; char *default_sl_dup = NULL; @@ -2736,18 +2818,18 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, gf_log (frame->this->name, GF_LOG_TRACE, "failed to get count"); if (type == GF_QUOTA_OPTION_TYPE_LIST) { + gf_cli_quota_list (local, volname, dict, default_sl, + entry_count, rsp.op_ret, + rsp.op_errno, rsp.op_errstr); if (global_state->mode & GLUSTER_MODE_XML) { - ret = cli_xml_output_vol_quota_limit_list - (volname, limit_list, rsp.op_ret, - rsp.op_errno, rsp.op_errstr); - if (ret) - gf_log ("cli", GF_LOG_ERROR, - "Error outputting to xml"); + ret = cli_xml_output_vol_quota_limit_list_end (local); + if (ret < 0) { + ret = -1; + gf_log ("cli", GF_LOG_ERROR, "Error in printing" + " xml output"); + } goto out; } - - gf_cli_quota_list (volname, dict, entry_count, rsp.op_errstr, - default_sl); } xml_output: diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 8def609459e..4787cec322f 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -2828,145 +2828,46 @@ out: } int -cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list, - int op_ret, int op_errno, - char *op_errstr) +cli_xml_output_vol_quota_limit_list_end (cli_local_t *local) { #if (HAVE_LIB_XML) int ret = -1; - xmlTextWriterPtr writer = NULL; - xmlDocPtr doc = NULL; - int64_t size = 0; - int64_t limit_value = 0; - int i = 0; - int j = 0; - int k = 0; - int len = 0; - char *size_str = NULL; - char path[PATH_MAX] = {0,}; - char ret_str[1024] = {0,}; - char value[1024] = {0,}; - char mountdir[] = "/tmp/mountXXXXXX"; - char abspath[PATH_MAX] = {0,}; - runner_t runner = {0,}; - - GF_ASSERT (volname); - GF_ASSERT (limit_list); - - ret = cli_begin_xml_output (&writer, &doc); - if (ret) - goto out; - ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr); - if (ret) - goto out; - - /* */ - ret = xmlTextWriterStartElement (writer, (xmlChar *)"volQuota"); - XML_RET_CHECK_AND_GOTO (ret, out); - - if (!limit_list) - goto cont; - - len = strlen (limit_list); - if (len == 0) - goto cont; - - if (mkdtemp (mountdir) == NULL) { - gf_log ("cli", GF_LOG_ERROR, "failed to create a temporary" - " mount directory"); - ret = -1; - goto out; - } - - ret = runcmd (SBIN_DIR"/glusterfs", "-s", "localhost", - "--volfile-id", volname, "-l", - DEFAULT_LOG_FILE_DIRECTORY"/quota-list-xml.log", - mountdir, NULL); + ret = xmlTextWriterEndElement (local->writer); if (ret) { - gf_log ("cli", GF_LOG_ERROR, - "failed to mount glusterfs client"); - ret = -1; - goto rm_dir; + goto out; } - while (i < len) { - j = 0; - k = 0; - size = 0; - - while (limit_list[i] != ':') - path[k++] = limit_list[i++]; - path[k] = '\0'; - - i++; - - while (limit_list[i] != ',' && limit_list[i] != '\0') - value[j++] = limit_list[i++]; - i++; - - snprintf (abspath, sizeof (abspath), "%s/%s", mountdir, path); - ret = sys_lgetxattr (abspath, "trusted.limit.list", - (void *)ret_str, 4096); - if (ret >= 0) { - sscanf (ret_str, "%"SCNd64",%"SCNd64, &size, - &limit_value); - size_str = gf_uint64_2human_readable ((uint64_t)size); - } - - /* */ - ret = xmlTextWriterStartElement (writer, (xmlChar *)"quota"); - XML_RET_CHECK_AND_GOTO (ret, unmount); - - ret = xmlTextWriterWriteFormatElement - (writer, (xmlChar *)"path", "%s", path); - XML_RET_CHECK_AND_GOTO (ret, unmount); - - ret = xmlTextWriterWriteFormatElement - (writer, (xmlChar *)"limit", "%s", value); - XML_RET_CHECK_AND_GOTO (ret, unmount); - - if (size_str) { - ret = xmlTextWriterWriteFormatElement - (writer, (xmlChar *)"size", "%s", size_str); - XML_RET_CHECK_AND_GOTO (ret, unmount); - GF_FREE (size_str); - } else { - ret = xmlTextWriterWriteFormatElement - (writer, (xmlChar *)"size", "%"PRId64, size); - XML_RET_CHECK_AND_GOTO (ret, unmount); - } + ret = cli_end_xml_output (local->writer, local->doc); - /* */ - ret = xmlTextWriterEndElement (writer); - XML_RET_CHECK_AND_GOTO (ret, unmount); +out: + return ret; +#else + return 0 +#endif +} - } +int +cli_xml_output_vol_quota_limit_list_begin (cli_local_t *local, int op_ret, + int op_errno, char *op_errstr) +{ +#if (HAVE_LIB_XML) + int ret = -1; -unmount: - runinit (&runner); - runner_add_args (&runner, "umount", -#if GF_LINUX_HOST_OS - "-l", -#endif - mountdir, NULL); - ret = runner_run_reuse (&runner); + ret = cli_begin_xml_output (&(local->writer), &(local->doc)); if (ret) - runner_log (&runner, "cli", GF_LOG_WARNING, "error executing"); - runner_end (&runner); + goto out; -rm_dir: - rmdir (mountdir); + ret = cli_xml_output_common (local->writer, op_ret, op_errno, + op_errstr); + if (ret) + goto out; -cont: - /* */ - ret = xmlTextWriterEndElement (writer); + /* */ + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volQuota"); XML_RET_CHECK_AND_GOTO (ret, out); - ret = cli_end_xml_output (writer, doc); - out: - GF_FREE (size_str); gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); return ret; #else @@ -3808,3 +3709,90 @@ out: return 0; #endif } + +int +cli_quota_list_xml_error (cli_local_t *local, char *path, + char *errstr) +{ +#if (HAVE_LIB_XML) + int ret = -1; + + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"path", + "%s", path); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"errstr", + "%s", errstr); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterEndElement (local->writer); + XML_RET_CHECK_AND_GOTO (ret, out); + +out: + return ret; +#else + return 0; +#endif +} + +int +cli_quota_xml_output (cli_local_t *local, char *path, char *hl_str, + char *sl_final, void *used, void *avail) +{ +#if (HAVE_LIB_XML) + int ret = -1; + + ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit"); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"path", + "%s", path); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"hard_limit", + "%s", hl_str); + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterWriteFormatElement (local->writer, + (xmlChar *)"soft_limit", + "%s", sl_final); + XML_RET_CHECK_AND_GOTO (ret, out); + + if ((char *)used) { + ret = xmlTextWriterWriteFormatElement + (local->writer, (xmlChar *)"used_space", "%s", + (char *)used); + } else { + ret = xmlTextWriterWriteFormatElement + (local->writer, (xmlChar *)"user_space", "%11"PRIu64, + *(long unsigned int *)used); + } + XML_RET_CHECK_AND_GOTO (ret, out); + + if ((char *)avail) { + ret = xmlTextWriterWriteFormatElement + (local->writer, (xmlChar *)"avail_space", "%s", + (char *)avail); + } else { + ret = xmlTextWriterWriteFormatElement + (local->writer, (xmlChar *)"avail_space", "%11"PRIu64, + *(long unsigned int *)avail); + } + XML_RET_CHECK_AND_GOTO (ret, out); + + ret = xmlTextWriterEndElement (local->writer); + XML_RET_CHECK_AND_GOTO (ret, out); + +out: + return ret; +#else + return 0; +#endif /* HAVE_LIB_XML */ +} diff --git a/cli/src/cli.h b/cli/src/cli.h index 73d23d684db..c4f9f98e5cf 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -348,9 +348,18 @@ int cli_xml_output_vol_info (cli_local_t *local, dict_t *dict); int -cli_xml_output_vol_quota_limit_list (char *volname, char *limit_list, - int op_ret, int op_errno, - char *op_errstr); +cli_xml_output_vol_quota_limit_list_begin (cli_local_t *local, int op_ret, + int op_errno, char *op_errstr); +int +cli_xml_output_vol_quota_limit_list_end (cli_local_t *local); + +int +cli_quota_list_xml_error (cli_local_t *local, char *path, + char *errstr); + +int +cli_quota_xml_output (cli_local_t *local, char *path, char *hl_str, + char *sl_final, void *used, void *avail); int cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno, -- cgit