diff options
Diffstat (limited to 'cli/src/cli-rpc-ops.c')
-rw-r--r-- | cli/src/cli-rpc-ops.c | 378 |
1 files changed, 292 insertions, 86 deletions
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 28b92ee2..05f2e957 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -2322,101 +2322,288 @@ out: return ret; } -int32_t -gf_cli_print_limit_list (char *volname, char *limit_list, - char *op_errstr) +static void +print_quota_output_for_version_1 (char *path, char *hl, char *mountdir) { - int64_t size = 0; - int64_t limit_value = 0; - int32_t i, j; - int32_t len = 0, ret = -1; - char *size_str = NULL; - char path [PATH_MAX] = {0, }; - char ret_str [1024] = {0, }; - char value [1024] = {0, }; - char mountdir [] = "/tmp/mntXXXXXX"; - char abspath [PATH_MAX] = {0, }; - char *colon_ptr = NULL; - runner_t runner = {0,}; + uint64_t used_space = 0; + uint64_t limit_value = 0; + char *used_str = NULL; + char abspath[PATH_MAX] = {0,}; + char ret_str[1024] = {0,}; + int ret = -1; - GF_VALIDATE_OR_GOTO ("cli", volname, out); - GF_VALIDATE_OR_GOTO ("cli", limit_list, out); + snprintf (abspath, sizeof (abspath) - 1, "%s/%s", mountdir, path); - if (!connected) - goto out; + ret = sys_lgetxattr (abspath, "trusted.limit.list", (void *) ret_str, + 4096); + if (ret < 0) { + cli_out ("%-20s %10s", path, hl); + } else { + sscanf (ret_str, "%"PRIu64",%"PRIu64, &used_space, + &limit_value); - len = strlen (limit_list); - if (len == 0) { - cli_err ("%s", op_errstr?op_errstr:"quota limit not set "); - goto out; + used_str = gf_uint64_2human_readable (used_space); + + if (used_str == NULL) + cli_out ("%-20s %10s %20"PRIu64, path, hl, + used_space); + else + cli_out ("%-20s %10s %20s", path, hl, used_str); } - if (mkdtemp (mountdir) == NULL) { - gf_log ("cli", GF_LOG_WARNING, "failed to create a temporary " - "mount directory"); - ret = -1; + GF_FREE (used_str); + return; +} + +static void +print_quota_output_for_version_2 (char *path, char *hl, char *sl, + char *mountdir) +{ + uint64_t used_space = 0; + uint64_t limit_value = 0; + uint64_t hard_limit = 0; + uint64_t avail = 0; + char *used_str = NULL; + char *avail_str = NULL; + char abspath[PATH_MAX] = {0,}; + char ret_str[1024] = {0,}; + int ret = -1; + + + snprintf (abspath, sizeof (abspath) - 1, "%s/%s", mountdir, path); + + ret = sys_lgetxattr (abspath, "trusted.limit.list", (void *) ret_str, + 4096); + + if (ret < 0) { + cli_out ("%-40s %7s %9s %11s %7s", path, hl, sl, "N/A", "N/A"); + } else { + sscanf (ret_str, "%"PRIu64",%"PRIu64, &used_space, + &limit_value); + + used_str = gf_uint64_2human_readable (used_space); + + ret = gf_string2bytesize (hl, &hard_limit); + + if (hard_limit > used_space) + avail = hard_limit - used_space; + else + avail = 0; + + avail_str = gf_uint64_2human_readable (avail); + if (used_str == NULL) + cli_out ("%-40s %7s %9s %11"PRIu64 + "%9"PRIu64, path, hl, + sl, used_space, avail); + else + cli_out ("%-40s %7s %9s %11s %7s", path, hl, sl, + used_str, avail_str); + } + + GF_FREE (used_str); + GF_FREE (avail_str); + return; +} + +static void +gf_quota_print_limit_list (char *path, char *hl, char *sl, char *mountdir, + uint32_t op_version) +{ + if (op_version == 1) + print_quota_output_for_version_1 (path, hl, mountdir); + else + print_quota_output_for_version_2 (path, hl, sl, mountdir); +} + +void +gf_cli_quota_print_first_row (uint32_t op_version) +{ + if (op_version == 1) { + cli_out ("\tpath\t\t limit_set \t\t size"); + cli_out ("-----------------------------------------------------" + "-----------------------------"); + } else { + cli_out (" Path Hard-limit " + "Soft-limit Used Available"); + cli_out ("-----------------------------------------------------" + "---------------------------"); + } +} + +int +gf_cli_print_limit_list_from_dict (char *volname, uint32_t op_version, + dict_t *dict, char *default_sl, int count, + char *mountdir, int entry_count, + char *op_errstr) +{ + int ret = -1; + int i = 0; + int j = 0; + char key[1024] = {0,}; + char *limit = NULL; + char path[PATH_MAX] = {0,}; + char *hl = NULL; + char *sl = NULL; + char *sl_final = NULL; + + if (!dict|| count <= 0) + goto out; + + if (entry_count == 0) { + if (strlen (op_errstr) == 0) + cli_err ("Limit not set on specified directories"); goto out; } - /* Mount a temporary client to fetch the disk usage - * of the directory on which the limit is set. - */ - ret = runcmd (SBIN_DIR"/glusterfs", "-s", - "localhost", "--volfile-id", volname, "-l", - DEFAULT_LOG_FILE_DIRECTORY"/quota-list.log", - mountdir, NULL); - if (ret) { - gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs client"); - ret = -1; - goto rm_dir; + gf_cli_quota_print_first_row (op_version); + + while (count--) { + j = 0; + sl = NULL; + hl = NULL; + snprintf (key, sizeof (key), "path%d", i++); + + ret = dict_get_str (dict, key, &limit); + if (ret < 0) { + gf_log ("cli", GF_LOG_DEBUG, "Path not present in limit" + " list"); + continue; + } + if (!strcmp (limit, "Not set")) + continue; + + ret = gf_get_hard_limit (limit, &hl); + + ret = gf_get_soft_limit (limit, &sl); + if (ret == 1) + sl_final = sl; + else + sl_final = default_sl; + + while (limit[j] != ':') { + path[j] = limit[j]; + j = j + 1; + } + + path[j] = '\0'; + + ret = gf_canonicalize_path (path); + if (ret) + goto out; + + gf_quota_print_limit_list (path, hl, sl_final, mountdir, + op_version); + + GF_FREE (hl); + GF_FREE (sl); } +out: + return ret; +} + +int32_t +gf_cli_print_limit_list_from_string (char *volname, char *limit_list, + uint32_t op_version, char *default_sl, + char *mountdir) +{ + int32_t i = 0; + int32_t j = 0; + int32_t len = 0; + int ret = -1; + char path[PATH_MAX] = {0,}; + char *colon_ptr = NULL; + char *sl_final = NULL; + char *hl = NULL; + char *sl = NULL; len = strlen (limit_list); if (len == 0) { - cli_err ("quota limit not set "); - goto unmount; + ret = -1; + goto out; } - i = 0; + gf_cli_quota_print_first_row (op_version); - cli_out ("\tpath\t\t limit_set\t size"); - cli_out ("-----------------------------------------------------------" - "-----------------------"); while (i < len) { j = 0; + sl = hl = NULL; while (limit_list [i] != ',' && limit_list [i] != '\0') { path [j++] = limit_list[i++]; } path [j] = '\0'; - //here path[] contains both path and limit value + //here path[] contains both path and limit value - colon_ptr = strrchr (path, ':'); + ret = gf_get_hard_limit (path, &hl); + ret = gf_get_soft_limit (path, &sl); + + if (ret == 1) + sl_final = sl; + else + sl_final = default_sl; + + colon_ptr = strchr (path, ':'); *colon_ptr = '\0'; - strcpy (value, ++colon_ptr); - snprintf (abspath, sizeof (abspath), "%s/%s", mountdir, path); + gf_quota_print_limit_list (path, hl, sl_final, mountdir, + op_version); - ret = sys_lgetxattr (abspath, "trusted.limit.list", (void *) ret_str, 4096); - if (ret < 0) { - cli_out ("%-20s %10s", path, value); - } else { - sscanf (ret_str, "%"PRId64",%"PRId64, &size, - &limit_value); - size_str = gf_uint64_2human_readable ((uint64_t) size); - if (size_str == NULL) { - cli_out ("%-20s %10s %20"PRId64, path, - value, size); - } else { - cli_out ("%-20s %10s %20s", path, - value, size_str); - GF_FREE (size_str); - } - } i++; + + GF_FREE (hl); + GF_FREE (sl); } -unmount: +out: + return ret; +} + +int +gf_cli_quota_list_run_crawler (char *volname, char *limit_list, dict_t *dict, + int count, char *op_errstr, uint32_t op_version, + char *default_sl, int entry_count) +{ + int ret = -1; + runner_t runner = {0,}; + char mountdir [] = "/tmp/mntXXXXXX"; + + GF_VALIDATE_OR_GOTO ("cli", volname, out); + + if (!connected) + goto out; + + if ((!limit_list) && (count <= 0)) + goto out; + + if (mkdtemp (mountdir) == NULL) { + gf_log ("cli", GF_LOG_WARNING, "failed to create a temporary " + "mount directory"); + ret = -1; + goto out; + } + + /* Mount a temporary client to fetch the disk usage + * of the directory on which the limit is set. + */ + ret = runcmd (SBIN_DIR"/glusterfs", "-s", + "localhost", "--volfile-id", volname, "-l", + DEFAULT_LOG_FILE_DIRECTORY"/quota-list.log", + mountdir, NULL); + if (ret) { + gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs " + "client"); + ret = -1; + goto rm_dir; + } + + if (limit_list) + gf_cli_print_limit_list_from_string (volname, limit_list, + op_version, default_sl, + mountdir); + else if (count > 0) + gf_cli_print_limit_list_from_dict (volname, op_version, dict, + default_sl, count, mountdir, + entry_count, op_errstr); runinit (&runner); runner_add_args (&runner, "umount", @@ -2433,20 +2620,24 @@ rm_dir: rmdir (mountdir); out: return ret; + } int gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, int count, void *myframe) { - gf_cli_rsp rsp = {0,}; - int ret = -1; - dict_t *dict = NULL; - char *volname = NULL; - char *limit_list = NULL; - int32_t type = 0; - char msg[1024] = {0,}; - call_frame_t *frame = NULL; + gf_cli_rsp rsp = {0,}; + int ret = -1; + dict_t *dict = NULL; + char *volname = NULL; + char *limit_list = NULL; + int32_t type = 0; + char msg[5120] = {0,}; + call_frame_t *frame = NULL; + uint32_t op_version = 1; + char *default_sl = NULL; + int entry_count = 0; if (-1 == req->rpc_status) { goto out; @@ -2479,7 +2670,7 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, rsp.dict.dict_len, &dict); if (ret < 0) { - gf_log ("glusterd", GF_LOG_ERROR, + gf_log ("cli", GF_LOG_ERROR, "failed to " "unserialize req-buffer to dictionary"); goto out; @@ -2496,11 +2687,30 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, gf_log (frame->this->name, GF_LOG_TRACE, "failed to get limit_list"); + ret = dict_get_uint32 (dict, "op-version", &op_version); + if (ret) + gf_log (frame->this->name, GF_LOG_TRACE, "failed to get " + "op-version"); + + ret = dict_get_str (dict, "default-soft-limit", &default_sl); + if (ret) + gf_log (frame->this->name, GF_LOG_TRACE, "failed to get " + "default soft limit"); + ret = dict_get_int32 (dict, "type", &type); if (ret) gf_log (frame->this->name, GF_LOG_TRACE, "failed to get type"); + ret = dict_get_int32 (dict, "count", &count); + if (ret) + gf_log (frame->this->name, GF_LOG_TRACE, "failed to get count"); + + ret = dict_get_int32 (dict, "entry-count", &entry_count); + if (ret) + gf_log (frame->this->name, GF_LOG_TRACE, "failed to get entry " + "count"); + if (type == GF_QUOTA_OPTION_TYPE_LIST) { if (global_state->mode & GLUSTER_MODE_XML) { ret = cli_xml_output_vol_quota_limit_list @@ -2513,19 +2723,15 @@ gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov, } - if (limit_list) { - gf_cli_print_limit_list (volname, - limit_list, - rsp.op_errstr); - } else { - gf_log ("cli", GF_LOG_INFO, "Received resp to quota " - "command "); - if (rsp.op_errstr) - snprintf (msg, sizeof (msg), "%s", - rsp.op_errstr); - } + gf_log ("cli", GF_LOG_INFO, "Received resp to quota command"); + + gf_cli_quota_list_run_crawler (volname, limit_list, dict, count, + rsp.op_errstr, op_version, + default_sl, entry_count); + if (rsp.op_errstr) + snprintf (msg, sizeof (msg), "%s", rsp.op_errstr); } else { - gf_log ("cli", GF_LOG_INFO, "Received resp to quota command "); + gf_log ("cli", GF_LOG_INFO, "Received resp to quota command"); if (rsp.op_errstr) snprintf (msg, sizeof (msg), "%s", rsp.op_errstr); else |