From df12073c4cc8340eb85b5d25c2da84fc21ec1f38 Mon Sep 17 00:00:00 2001 From: Rajesh Amaravathi Date: Tue, 31 Jan 2012 17:04:37 +0530 Subject: cli/glusterd: volume status modification * Method of getting mount details of brick has been changed from direct reading of /etc/mtab to using libc's , providing a fairly portable version independent of different linux distributions. It is only supported on Linux though. * Wrong fs type (rootfs for /) in fedora-based distributions has been fixed. * Allows options (detail, mem, fd, et al) to "all" volumes. * Use of the fnmatch's GNU extension flag, FNM_LEADING_DIR is restricted to Linux hosts only. In case of non-Linux hosts, partial match functionality is absent. Change-Id: I102ce808c192ef635c2536a2167101be0aa0fc50 BUG: 786367 Signed-off-by: Rajesh Amaravathi Reviewed-on: http://review.gluster.com/2705 Tested-by: Gluster Build System Reviewed-by: Jeff Darcy Reviewed-by: Vijay Bellur --- cli/src/cli-cmd-parser.c | 128 ++++++++++++++++------------- cli/src/cli-cmd-volume.c | 24 ++++-- cli/src/cli-rpc-ops.c | 6 +- cli/src/cli.h | 4 +- rpc/xdr/src/cli1-xdr.h | 1 - rpc/xdr/src/cli1-xdr.x | 1 - xlators/mgmt/glusterd/src/glusterd-utils.c | 71 ++++++++-------- xlators/mgmt/glusterd/src/glusterd-utils.h | 3 - 8 files changed, 124 insertions(+), 114 deletions(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index b4c86bf1a..e483a1bd4 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1839,39 +1839,42 @@ out: return ret; } -gf_boolean_t -cli_cmd_validate_statusop (const char *arg) +uint32_t +cli_cmd_get_statusop (const char *arg) { - char *opwords[] = {"misc-details", "mem", "clients", "fd", "inode", - "callpool", NULL}; - char *w = NULL; + int i = 0; + uint32_t ret = GF_CLI_STATUS_NONE; + char *w = NULL; + char *opwords[] = {"detail", "mem", "clients", "fd", + "inode", "callpool", NULL}; + struct { + char *opname; + uint32_t opcode; + } optable[] = { + { "detail", GF_CLI_STATUS_DETAIL }, + { "mem", GF_CLI_STATUS_MEM }, + { "clients", GF_CLI_STATUS_CLIENTS }, + { "fd", GF_CLI_STATUS_FD }, + { "inode", GF_CLI_STATUS_INODE }, + { "callpool", GF_CLI_STATUS_CALLPOOL }, + { NULL } + }; w = str_getunamb (arg, opwords); if (!w) { - gf_log ("cli", GF_LOG_ERROR, "Unknown status op %s", - arg); - return _gf_false; + gf_log ("cli", GF_LOG_DEBUG, + "Not a status op %s", arg); + goto out; } - return _gf_true; -} -int -cli_cmd_get_statusop (const char *arg) -{ - int ret = GF_CLI_STATUS_INVAL; - if (!strcmp (arg, "misc-details")) - ret = GF_CLI_STATUS_DETAIL; - else if (!strcmp (arg, "mem")) - ret = GF_CLI_STATUS_MEM; - else if (!strcmp (arg, "clients")) - ret = GF_CLI_STATUS_CLIENTS; - else if (!strcmp (arg, "inode")) - ret = GF_CLI_STATUS_INODE; - else if (!strcmp (arg, "fd")) - ret = GF_CLI_STATUS_FD; - else if (!strcmp (arg, "callpool")) - ret = GF_CLI_STATUS_CALLPOOL; + for (i = 0; optable[i].opname; i++) { + if (!strcmp (w, optable[i].opname)) { + ret = optable[i].opcode; + break; + } + } + out: return ret; } @@ -1879,9 +1882,9 @@ int cli_cmd_volume_status_parse (const char **words, int wordcount, dict_t **options) { - dict_t *dict = NULL; - int ret = -1; - int cmd = 0; + dict_t *dict = NULL; + int ret = -1; + uint32_t cmd = 0; GF_ASSERT (options); @@ -1898,60 +1901,69 @@ cli_cmd_volume_status_parse (const char **words, int wordcount, case 3: if (!strcmp (words[2], "all")) { - cmd = GF_CLI_STATUS_ALL; ret = 0; + } else { cmd = GF_CLI_STATUS_VOL; ret = dict_set_str (dict, "volname", (char *)words[2]); } + break; case 4: + cmd = cli_cmd_get_statusop (words[3]); + if (!strcmp (words[2], "all")) { - cli_out ("Cannot specify brick/status-type for \"all\""); - ret = -1; - goto out; + if (cmd == GF_CLI_STATUS_NONE) { + cli_out ("%s is not a valid status option", + words[3]); + ret = -1; + goto out; + } + cmd |= GF_CLI_STATUS_ALL; + ret = 0; + } else { - cmd = GF_CLI_STATUS_VOL; - ret = dict_set_str (dict, "volname", (char *)words[2]); + ret = dict_set_str (dict, "volname", + (char *)words[2]); if (ret) goto out; - } - if (cli_cmd_validate_statusop (words[3])) { - ret = cli_cmd_get_statusop (words[3]); - if (GF_CLI_STATUS_INVAL == ret) - goto out; - cmd |= ret; - ret = 0; - } else { - cmd = GF_CLI_STATUS_BRICK; - ret = dict_set_str (dict, "brick", (char *)words[3]); + if (cmd == GF_CLI_STATUS_NONE) { + cmd = GF_CLI_STATUS_BRICK; + ret = dict_set_str (dict, "brick", + (char *)words[3]); + + } else { + cmd |= GF_CLI_STATUS_VOL; + ret = 0; + } } + break; case 5: - if (!cli_cmd_validate_statusop (words[4])) { + if (!strcmp (words[2], "all")) { + cli_out ("Cannot specify brick for \"all\""); ret = -1; goto out; } - cmd = GF_CLI_STATUS_BRICK; - ret = cli_cmd_get_statusop (words[4]); - if (GF_CLI_STATUS_INVAL == ret) - goto out; - cmd |= ret; - - if (!strcmp (words[2], "all")) { - cli_out ("Cannot specify brick/status-type for \"all\""); + cmd = cli_cmd_get_statusop (words[4]); + if (cmd == GF_CLI_STATUS_NONE) { + cli_out ("%s is not a valid status option", + words[4]); ret = -1; goto out; - } else { - ret = dict_set_str (dict, "volname", (char *)words[2]); - if (ret) - goto out; } + + cmd |= GF_CLI_STATUS_BRICK; + + ret = dict_set_str (dict, "volname", (char *)words[2]); + if (ret) + goto out; + ret = dict_set_str (dict, "brick", (char *)words[3]); break; diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 41007cb7b..6bea948e9 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1431,6 +1431,7 @@ cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status) if (ret) goto out; +#ifdef GF_LINUX_HOST_OS memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.mnt_options", i); ret = dict_get_str (dict, key, &(status->mount_options)); @@ -1442,19 +1443,23 @@ cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status) ret = dict_get_str (dict, key, &(status->fs_name)); if (ret) goto out; +#endif if (IS_EXT_FS(status->fs_name) || !strcmp (status->fs_name, "xfs")) { +#ifdef GF_LINUX_HOST_OS memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.inode_size", i); ret = dict_get_str (dict, key, &(status->inode_size)); if (ret) status->inode_size = NULL; +#endif memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "brick%d.total_inodes", i); - ret = dict_get_uint64 (dict, key, &(status->total_inodes)); + ret = dict_get_uint64 (dict, key, + &(status->total_inodes)); if (ret) goto out; @@ -1463,9 +1468,10 @@ cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status) ret = dict_get_uint64 (dict, key, &(status->free_inodes)); if (ret) goto out; - } else { +#ifdef GF_LINUX_HOST_OS status->inode_size = NULL; +#endif status->total_inodes = 0; status->free_inodes = 0; } @@ -1481,6 +1487,8 @@ cli_print_detailed_status (cli_volume_status_t *status) cli_out ("%-20s : %-20d", "Port", status->port); cli_out ("%-20s : %-20c", "Online", (status->online) ? 'Y' : 'N'); cli_out ("%-20s : %-20s", "Pid", status->pid_str); + +#ifdef GF_LINUX_HOST_OS cli_out ("%-20s : %-20s", "File System", status->fs_name); cli_out ("%-20s : %-20s", "Device", status->device); @@ -1491,15 +1499,15 @@ cli_print_detailed_status (cli_volume_status_t *status) cli_out ("%-20s : %-20s", "Mount Options", "N/A"); } - cli_out ("%-20s : %-20s", "Disk Space Free", status->free); - cli_out ("%-20s : %-20s", "Total Disk Space", status->total); - if (status->inode_size) { cli_out ("%-20s : %-20s", "Inode Size", status->inode_size); } else { cli_out ("%-20s : %-20s", "Inode Size", "N/A"); } +#endif + cli_out ("%-20s : %-20s", "Disk Space Free", status->free); + cli_out ("%-20s : %-20s", "Total Disk Space", status->total); if (status->total_inodes) { cli_out ("%-20s : %-20ld", "Inode Count", @@ -1821,10 +1829,10 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_top_cbk, "volume top operations"}, - { "volume status [all|{ [] " - "[misc-details|clients|mem|inode|fd|callpool]}]", + { "volume status [all | []]" + " [detail|clients|mem|inode|fd|callpool]", cli_cmd_volume_status_cbk, - "display status of specified volume"}, + "display status of all or specified volume(s)/brick"}, { "volume heal ", cli_cmd_volume_heal_cbk, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 07a2f9fc7..6ed380bff 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -4956,7 +4956,7 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, char *volname = NULL; dict_t *dict = NULL; gf_cli_rsp rsp = {0,}; - cli_volume_status_t status = {0}; + cli_volume_status_t status = {0}; if (req->rpc_status == -1) goto out; @@ -5044,10 +5044,10 @@ gf_cli3_1_status_cbk (struct rpc_req *req, struct iovec *iov, if (ret) goto out; - cli_out ("\nSTATUS OF VOLUME: %s", volname); + cli_out ("\nStatus of volume: %s", volname); if ((cmd & GF_CLI_STATUS_DETAIL) == 0) - cli_out ("BRICK\t\t\t\t\t\t\tPORT\tONLINE\tPID"); + cli_out ("Brick\t\t\t\t\t\t\tPort\tOnline\tPid"); for (i = 0; i < count; i++) { diff --git a/cli/src/cli.h b/cli/src/cli.h index 25b17da49..74e1423f5 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -132,12 +132,14 @@ struct cli_volume_status { uint64_t free_inodes; char *brick; char *pid_str; - char *fs_name; char *free; char *total; +#ifdef GF_LINUX_HOST_OS + char *fs_name; char *mount_options; char *device; char *inode_size; +#endif }; typedef struct cli_volume_status cli_volume_status_t; diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index ea8ab02b6..d136ec255 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -161,7 +161,6 @@ enum gf1_cli_top_op { typedef enum gf1_cli_top_op gf1_cli_top_op; enum gf_cli_status_type { - GF_CLI_STATUS_INVAL = -1, GF_CLI_STATUS_NONE = 0x000, GF_CLI_STATUS_MEM = 0x001, GF_CLI_STATUS_CLIENTS = 0x002, diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index a2edc57eb..5f491c7b4 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -106,7 +106,6 @@ enum gf1_cli_top_op { /* The unconventional hex numbers help us perform bit-wise operations which reduces complexity */ enum gf_cli_status_type { - GF_CLI_STATUS_INVAL = -1, GF_CLI_STATUS_NONE = 0x000, GF_CLI_STATUS_MEM = 0x001, /*000000000001*/ GF_CLI_STATUS_CLIENTS = 0x002, /*000000000010*/ diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 864467fd3..42924a5f6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -60,6 +60,9 @@ #include #include +#ifdef GF_LINUX_HOST_OS +#include +#endif #ifdef GF_SOLARIS_HOST_OS #include @@ -744,9 +747,11 @@ glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path, *brickinfo = brickiter; break; } + if (path_match != GF_PATH_PARTIAL) continue; +#ifdef GF_LINUX_HOST_OS if (!fnmatch (path, brickiter->path, FNM_LEADING_DIR) || !fnmatch (brickiter->path, path, FNM_LEADING_DIR)) { gf_log (THIS->name, GF_LOG_ERROR, @@ -756,6 +761,7 @@ glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path, ret = 0; break; } +#endif } out: @@ -3109,7 +3115,8 @@ out: return -1; } -int +#ifdef GF_LINUX_HOST_OS +static int glusterd_get_brick_root (char *path, char **mount_point) { char *ptr = NULL; @@ -3257,16 +3264,14 @@ glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo, dict_t *dict, int count) { int ret = -1; - int fd = -1; char key[1024] = {0}; char base_key[1024] = {0}; - char buffer[4096] = {0}; - char cmd_str[1024] = {0}; char *mnt_pt = NULL; char *fs_name = NULL; char *mnt_options = NULL; char *device = NULL; - runner_t runner = {0}; + FILE *mtab = NULL; + struct mntent *entry = NULL; snprintf (base_key, sizeof (base_key), "brick%d", count); @@ -3274,33 +3279,25 @@ glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo, if (ret) goto out; - /* get mount details of brick in back-end */ - snprintf (cmd_str, sizeof (cmd_str), " %s ", mnt_pt); - - runinit (&runner); - runner_add_args (&runner, "grep", cmd_str, "/etc/mtab", NULL); - runner_redir (&runner, STDOUT_FILENO, RUN_PIPE); + mtab = setmntent (_PATH_MNTTAB, "r"); + entry = getmntent (mtab); - ret = runner_start (&runner); - if (ret) - goto out; - - if (!fgets (buffer, sizeof(buffer), - runner_chio (&runner, STDOUT_FILENO))) { - ret = -1; - goto out; + while (1) { + if (!entry) { + ret = -1; + goto out; + } + if (!strcmp (entry->mnt_dir, mnt_pt) && + strcmp (entry->mnt_type, "rootfs")) + break; + entry = getmntent (mtab); } - runner_end (&runner); - /* get device file */ memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "%s.device", base_key); - device = get_nth_word (buffer, 1); - if (!device) - goto out; - + device = gf_strdup (entry->mnt_fsname); ret = dict_set_dynstr (dict, key, device); if (ret) goto out; @@ -3309,10 +3306,7 @@ glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo, memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "%s.fs_name", base_key); - fs_name = get_nth_word (buffer, 3); - if (!fs_name) - goto out; - + fs_name = gf_strdup (entry->mnt_type); ret = dict_set_dynstr (dict, key, fs_name); if (ret) goto out; @@ -3321,18 +3315,15 @@ glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo, memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "%s.mnt_options", base_key); - mnt_options = get_nth_word (buffer, 4); - if (!mnt_options) - goto out; + mnt_options = gf_strdup (entry->mnt_opts); ret = dict_set_dynstr (dict, key, mnt_options); out: if (mnt_pt) GF_FREE (mnt_pt); - if (fd >= 0) - close (fd); return ret; } +#endif int glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, @@ -3348,7 +3339,9 @@ glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, char key[1024] = {0}; char base_key[1024] = {0}; struct statvfs brickstat = {0}; + xlator_t *this = NULL; + this = THIS; GF_ASSERT (volinfo); GF_ASSERT (brickinfo); GF_ASSERT (dict); @@ -3357,7 +3350,7 @@ glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, ret = statvfs (brickinfo->path, &brickstat); if (ret) { - gf_log (THIS->name, GF_LOG_ERROR, "statfs error: %s ", + gf_log (this->name, GF_LOG_ERROR, "statfs error: %s ", strerror (errno)); goto out; } @@ -3404,16 +3397,16 @@ glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, if (ret) goto out; } - +#ifdef GF_LINUX_HOST_OS ret = glusterd_add_brick_mount_details (brickinfo, dict, count); if (ret) goto out; ret = glusterd_add_inode_size_to_dict (dict, count); - +#endif out: if (ret) - gf_log (THIS->name, GF_LOG_DEBUG, "Error adding brick" + gf_log (this->name, GF_LOG_DEBUG, "Error adding brick" " detail to dict: %s", strerror (errno)); return ret; } @@ -3481,7 +3474,7 @@ glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo, out: if (ret) - gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index b8c65cbb0..6f9a5e14d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -348,9 +348,6 @@ glusterd_recreate_bricks (glusterd_conf_t *conf); int32_t glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf); -int -glusterd_get_brick_root (char *path, char **mount_point); - int glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo, -- cgit