cli: add a command 'gluster pool list [--xml]'
* unlike 'gluster peer status', which lists only info about peers, this command lists localhost also in the list, so the sorted output from all the nodes should match. * made the output script friendly by keeping it one output per line. Change-Id: I853656753b35c617debbcceecbb71c8d6dd3c334 BUG: 764638 Original-review: http://review.gluster.org/4221 Original-author: Amar Tumballi <amarts@redhat.com> Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: http://review.gluster.org/4862 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
parent
5e0116109e
commit
e6b6d1235d
@ -184,7 +184,7 @@ cli_cmd_peer_status_cbk (struct cli_state *state, struct cli_cmd_word *word,
|
||||
goto out;
|
||||
|
||||
if (proc->fn) {
|
||||
ret = proc->fn (frame, THIS, (char *)words[1] );
|
||||
ret = proc->fn (frame, THIS, (void *)GF_CLI_LIST_PEERS);
|
||||
}
|
||||
|
||||
out:
|
||||
@ -199,6 +199,45 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
cli_cmd_pool_list_cbk (struct cli_state *state, struct cli_cmd_word *word,
|
||||
const char **words, int wordcount)
|
||||
{
|
||||
int ret = -1;
|
||||
rpc_clnt_procedure_t *proc = NULL;
|
||||
call_frame_t *frame = NULL;
|
||||
int sent = 0;
|
||||
int parse_error = 0;
|
||||
|
||||
if (wordcount != 2) {
|
||||
cli_usage_out (word->pattern);
|
||||
parse_error = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
|
||||
|
||||
frame = create_frame (THIS, THIS->ctx->pool);
|
||||
if (!frame)
|
||||
goto out;
|
||||
|
||||
if (proc->fn) {
|
||||
ret = proc->fn (frame, THIS,
|
||||
(void *)GF_CLI_LIST_POOL_NODES);
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
cli_cmd_sent_status_get (&sent);
|
||||
if ((sent == 0) && (parse_error == 0))
|
||||
cli_err ("pool list: command execution failed");
|
||||
}
|
||||
|
||||
CLI_STACK_DESTROY (frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct cli_cmd cli_probe_cmds[] = {
|
||||
{ "peer probe <HOSTNAME>",
|
||||
cli_cmd_peer_probe_cbk,
|
||||
@ -216,6 +255,10 @@ struct cli_cmd cli_probe_cmds[] = {
|
||||
cli_cmd_peer_help_cbk,
|
||||
"Help command for peer "},
|
||||
|
||||
{ "pool list",
|
||||
cli_cmd_pool_list_cbk,
|
||||
"list all the nodes in the pool (including localhost)"},
|
||||
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -295,12 +295,9 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
int count, void *myframe)
|
||||
gf_cli_output_peer_status (dict_t *dict, int count)
|
||||
{
|
||||
gf1_cli_peer_list_rsp rsp = {0,};
|
||||
int ret = -1;
|
||||
dict_t *dict = NULL;
|
||||
char *uuid_buf = NULL;
|
||||
char *hostname_buf = NULL;
|
||||
int32_t i = 1;
|
||||
@ -309,7 +306,130 @@ gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
int32_t port = 0;
|
||||
int32_t connected = 0;
|
||||
char *connected_str = NULL;
|
||||
|
||||
cli_out ("Number of Peers: %d", count);
|
||||
i = 1;
|
||||
while ( i <= count) {
|
||||
snprintf (key, 256, "friend%d.uuid", i);
|
||||
ret = dict_get_str (dict, key, &uuid_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.hostname", i);
|
||||
ret = dict_get_str (dict, key, &hostname_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.connected", i);
|
||||
ret = dict_get_int32 (dict, key, &connected);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (connected)
|
||||
connected_str = "Connected";
|
||||
else
|
||||
connected_str = "Disconnected";
|
||||
|
||||
snprintf (key, 256, "friend%d.port", i);
|
||||
ret = dict_get_int32 (dict, key, &port);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.state", i);
|
||||
ret = dict_get_str (dict, key, &state);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!port) {
|
||||
cli_out ("\nHostname: %s\nUuid: %s\nState: %s "
|
||||
"(%s)",
|
||||
hostname_buf, uuid_buf, state,
|
||||
connected_str);
|
||||
} else {
|
||||
cli_out ("\nHostname: %s\nPort: %d\nUuid: %s\n"
|
||||
"State: %s (%s)", hostname_buf, port,
|
||||
uuid_buf, state, connected_str);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
gf_cli_output_pool_list (dict_t *dict, int count)
|
||||
{
|
||||
int ret = -1;
|
||||
char *uuid_buf = NULL;
|
||||
char *hostname_buf = NULL;
|
||||
int32_t i = 1;
|
||||
char key[256] = {0,};
|
||||
int32_t connected = 0;
|
||||
char *connected_str = NULL;
|
||||
|
||||
if (count >= 1)
|
||||
cli_out ("UUID\t\t\t\t\tHostname\tState");
|
||||
|
||||
while ( i <= count) {
|
||||
snprintf (key, 256, "friend%d.uuid", i);
|
||||
ret = dict_get_str (dict, key, &uuid_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.hostname", i);
|
||||
ret = dict_get_str (dict, key, &hostname_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.connected", i);
|
||||
ret = dict_get_int32 (dict, key, &connected);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (connected)
|
||||
connected_str = "Connected";
|
||||
else
|
||||
connected_str = "Disconnected";
|
||||
|
||||
cli_out ("%s\t%s\t%s ", uuid_buf, hostname_buf,
|
||||
connected_str);
|
||||
i++;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* function pointer for gf_cli_output_{pool_list,peer_status} */
|
||||
typedef int (*cli_friend_output_fn) (dict_t*, int);
|
||||
|
||||
int
|
||||
gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
int count, void *myframe)
|
||||
{
|
||||
gf1_cli_peer_list_rsp rsp = {0,};
|
||||
int ret = -1;
|
||||
dict_t *dict = NULL;
|
||||
char msg[1024] = {0,};
|
||||
char *cmd = NULL;
|
||||
cli_friend_output_fn friend_output_fn;
|
||||
call_frame_t *frame = NULL;
|
||||
unsigned long flags = 0;
|
||||
|
||||
frame = myframe;
|
||||
flags = (long)frame->local;
|
||||
|
||||
if (flags == GF_CLI_LIST_POOL_NODES) {
|
||||
cmd = "pool list";
|
||||
friend_output_fn = &gf_cli_output_pool_list;
|
||||
} else {
|
||||
cmd = "peer status";
|
||||
friend_output_fn = &gf_cli_output_peer_status;
|
||||
}
|
||||
|
||||
/* 'free' the flags set by gf_cli_list_friends */
|
||||
frame->local = NULL;
|
||||
|
||||
if (-1 == req->rpc_status) {
|
||||
goto out;
|
||||
@ -324,7 +444,7 @@ gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gf_log ("cli", GF_LOG_INFO, "Received resp to list: %d",
|
||||
gf_log ("cli", GF_LOG_DEBUG, "Received resp to list: %d",
|
||||
rsp.op_ret);
|
||||
|
||||
ret = rsp.op_ret;
|
||||
@ -333,7 +453,7 @@ gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
|
||||
if (!rsp.friends.friends_len) {
|
||||
snprintf (msg, sizeof (msg),
|
||||
"peer status: No peers present");
|
||||
"%s: No peers present", cmd);
|
||||
if (global_state->mode & GLUSTER_MODE_XML) {
|
||||
ret = cli_xml_output_peer_status (dict,
|
||||
rsp.op_ret,
|
||||
@ -380,49 +500,9 @@ gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
goto out;
|
||||
}
|
||||
|
||||
cli_out ("Number of Peers: %d", count);
|
||||
i = 1;
|
||||
while ( i <= count) {
|
||||
snprintf (key, 256, "friend%d.uuid", i);
|
||||
ret = dict_get_str (dict, key, &uuid_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.hostname", i);
|
||||
ret = dict_get_str (dict, key, &hostname_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.connected", i);
|
||||
ret = dict_get_int32 (dict, key, &connected);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (connected)
|
||||
connected_str = "Connected";
|
||||
else
|
||||
connected_str = "Disconnected";
|
||||
|
||||
snprintf (key, 256, "friend%d.port", i);
|
||||
ret = dict_get_int32 (dict, key, &port);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.state", i);
|
||||
ret = dict_get_str (dict, key, &state);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!port) {
|
||||
cli_out ("\nHostname: %s\nUuid: %s\nState: %s "
|
||||
"(%s)",
|
||||
hostname_buf, uuid_buf, state,
|
||||
connected_str);
|
||||
} else {
|
||||
cli_out ("\nHostname: %s\nPort: %d\nUuid: %s\n"
|
||||
"State: %s (%s)", hostname_buf, port,
|
||||
uuid_buf, state, connected_str);
|
||||
}
|
||||
i++;
|
||||
ret = friend_output_fn (dict, count);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (global_state->mode & GLUSTER_MODE_XML) {
|
||||
@ -443,7 +523,7 @@ gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
|
||||
out:
|
||||
cli_cmd_broadcast_response (ret);
|
||||
if (ret)
|
||||
cli_err ("peer status: failed");
|
||||
cli_err ("%s: failed", cmd);
|
||||
|
||||
if (dict)
|
||||
dict_destroy (dict);
|
||||
@ -2676,18 +2756,22 @@ out:
|
||||
|
||||
int32_t
|
||||
gf_cli_list_friends (call_frame_t *frame, xlator_t *this,
|
||||
void *data)
|
||||
void *data)
|
||||
{
|
||||
gf1_cli_peer_list_req req = {0,};
|
||||
int ret = 0;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (!frame || !this) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
req.flags = GF_CLI_LIST_ALL;
|
||||
GF_ASSERT (frame->local == NULL);
|
||||
|
||||
flags = (long)data;
|
||||
req.flags = flags;
|
||||
frame->local = (void*)flags;
|
||||
ret = cli_cmd_submit (&req, frame, cli_rpc_prog,
|
||||
GLUSTER_CLI_LIST_FRIENDS, NULL,
|
||||
this, gf_cli_list_friends_cbk,
|
||||
|
@ -2801,29 +2801,30 @@ cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
|
||||
memset (key, 0, sizeof (key));
|
||||
snprintf (key, sizeof (key), "friend%d.stateId", i);
|
||||
ret = dict_get_int32 (dict, key, &state_id);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (!ret) {
|
||||
/* ignore */
|
||||
|
||||
ret = xmlTextWriterWriteFormatElement (writer,
|
||||
(xmlChar *)"state",
|
||||
"%d", state_id);
|
||||
XML_RET_CHECK_AND_GOTO (ret, out);
|
||||
ret = xmlTextWriterWriteFormatElement (writer,
|
||||
(xmlChar *)"state", "%d", state_id);
|
||||
XML_RET_CHECK_AND_GOTO (ret, out);
|
||||
}
|
||||
|
||||
memset (key, 0, sizeof (key));
|
||||
snprintf (key, sizeof (key), "friend%d.state", i);
|
||||
ret = dict_get_str (dict, key, &state_str);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (!ret) {
|
||||
/* ignore */
|
||||
|
||||
ret = xmlTextWriterWriteFormatElement (writer,
|
||||
(xmlChar *)"stateStr",
|
||||
"%s", state_str);
|
||||
XML_RET_CHECK_AND_GOTO (ret, out);
|
||||
ret = xmlTextWriterWriteFormatElement (writer,
|
||||
(xmlChar *)"stateStr", "%s", state_str);
|
||||
XML_RET_CHECK_AND_GOTO (ret, out);
|
||||
}
|
||||
|
||||
memset (key, 0, sizeof (key));
|
||||
snprintf (key, sizeof (key), "friend%d.port", i);
|
||||
ret = dict_get_int32 (dict, key, &port);
|
||||
if (port != 0) {
|
||||
if (!ret) {
|
||||
/* ignore */
|
||||
ret = xmlTextWriterWriteFormatElement
|
||||
(writer, (xmlChar *)"port", "%d", port);
|
||||
XML_RET_CHECK_AND_GOTO (ret, out);
|
||||
|
@ -92,7 +92,8 @@ enum gf_quota_type {
|
||||
typedef enum gf_quota_type gf_quota_type;
|
||||
|
||||
enum gf1_cli_friends_list {
|
||||
GF_CLI_LIST_ALL = 1,
|
||||
GF_CLI_LIST_PEERS = 1,
|
||||
GF_CLI_LIST_POOL_NODES = 2,
|
||||
};
|
||||
typedef enum gf1_cli_friends_list gf1_cli_friends_list;
|
||||
|
||||
|
13
tests/bugs/bug-764638.t
Normal file
13
tests/bugs/bug-764638.t
Normal file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
. $(dirname $0)/../include.rc
|
||||
|
||||
cleanup;
|
||||
|
||||
TEST glusterd
|
||||
TEST pidof glusterd
|
||||
|
||||
TEST $CLI pool list;
|
||||
TEST $CLI pool list --xml;
|
||||
|
||||
cleanup;
|
@ -2949,37 +2949,50 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
|
||||
int32_t count = 0;
|
||||
dict_t *friends = NULL;
|
||||
gf1_cli_peer_list_rsp rsp = {0,};
|
||||
char my_uuid_str[64] = {0,};
|
||||
char key[256] = {0,};
|
||||
|
||||
priv = THIS->private;
|
||||
GF_ASSERT (priv);
|
||||
|
||||
if (!list_empty (&priv->peers)) {
|
||||
friends = dict_new ();
|
||||
if (!friends) {
|
||||
gf_log ("", GF_LOG_WARNING, "Out of Memory");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
friends = dict_new ();
|
||||
if (!friends) {
|
||||
gf_log ("", GF_LOG_WARNING, "Out of Memory");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (flags == GF_CLI_LIST_ALL) {
|
||||
list_for_each_entry (entry, &priv->peers, uuid_list) {
|
||||
count++;
|
||||
ret = glusterd_add_peer_detail_to_dict (entry,
|
||||
if (!list_empty (&priv->peers)) {
|
||||
list_for_each_entry (entry, &priv->peers, uuid_list) {
|
||||
count++;
|
||||
ret = glusterd_add_peer_detail_to_dict (entry,
|
||||
friends, count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
ret = dict_set_int32 (friends, "count", count);
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags == GF_CLI_LIST_POOL_NODES) {
|
||||
count++;
|
||||
snprintf (key, 256, "friend%d.uuid", count);
|
||||
uuid_utoa_r (MY_UUID, my_uuid_str);
|
||||
ret = dict_set_str (friends, key, my_uuid_str);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.hostname", count);
|
||||
ret = dict_set_str (friends, key, "localhost");
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
snprintf (key, 256, "friend%d.connected", count);
|
||||
ret = dict_set_int32 (friends, key, 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = dict_set_int32 (friends, "count", count);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = dict_allocate_and_serialize (friends, &rsp.friends.friends_val,
|
||||
&rsp.friends.friends_len);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user