diff options
| -rw-r--r-- | cli/src/cli-cmd-peer.c | 45 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 188 | ||||
| -rw-r--r-- | cli/src/cli-xml-output.c | 27 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 3 | ||||
| -rw-r--r-- | tests/bugs/bug-764638.t | 13 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-handler.c | 51 | 
6 files changed, 241 insertions, 86 deletions
diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c index 08651e72f..263f419a6 100644 --- a/cli/src/cli-cmd-peer.c +++ b/cli/src/cli-cmd-peer.c @@ -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 }  }; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 66d79a284..536402615 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -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, diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 72e1264f7..168159b68 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -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); diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 58ce1101e..9aeee2a6c 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -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; diff --git a/tests/bugs/bug-764638.t b/tests/bugs/bug-764638.t new file mode 100644 index 000000000..816546524 --- /dev/null +++ b/tests/bugs/bug-764638.t @@ -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; diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index 09cab9d1e..faba30221 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -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; +                        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; -                        ret = dict_set_int32 (friends, "count", count); +                snprintf (key, 256, "friend%d.hostname", count); +                ret = dict_set_str (friends, key, "localhost"); +                if (ret) +                        goto out; -                        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);  | 
