"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/cli/src/cli-rpc-ops.c" (16 Sep 2020, 306994 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cli-rpc-ops.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2    Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
    3    This file is part of GlusterFS.
    4 
    5    This file is licensed to you under your choice of the GNU Lesser
    6    General Public License, version 3 or any later version (LGPLv3 or
    7    later), or the GNU General Public License, version 2 (GPLv2), in all
    8    cases as published by the Free Software Foundation.
    9 */
   10 
   11 /* Widths of various columns in top read/write-perf output
   12  * Total width of top read/write-perf should be 80 chars
   13  * including one space between column
   14  */
   15 #define VOL_TOP_PERF_FILENAME_DEF_WIDTH 47
   16 #define VOL_TOP_PERF_FILENAME_ALT_WIDTH 44
   17 #define VOL_TOP_PERF_SPEED_WIDTH 4
   18 #define VOL_TOP_PERF_TIME_WIDTH 26
   19 
   20 #define INDENT_MAIN_HEAD "%-25s %s "
   21 
   22 #define RETURNING "Returning %d"
   23 #define XML_ERROR "Error outputting to xml"
   24 #define XDR_DECODE_FAIL "Failed to decode xdr response"
   25 #define DICT_SERIALIZE_FAIL "Failed to serialize to data to dictionary"
   26 #define DICT_UNSERIALIZE_FAIL "Failed to unserialize the dictionary"
   27 
   28 /* Do not show estimates if greater than this number */
   29 #define REBAL_ESTIMATE_SEC_UPPER_LIMIT (60 * 24 * 3600)
   30 #define REBAL_ESTIMATE_START_TIME 600
   31 
   32 #include "cli.h"
   33 #include <glusterfs/compat-errno.h>
   34 #include "cli-cmd.h"
   35 #include <sys/uio.h>
   36 #include <stdlib.h>
   37 #include <sys/mount.h>
   38 #include <glusterfs/compat.h>
   39 #include "cli-mem-types.h"
   40 #include <glusterfs/syscall.h>
   41 #include "glusterfs3.h"
   42 #include "portmap-xdr.h"
   43 #include <glusterfs/byte-order.h>
   44 
   45 #include <glusterfs/run.h>
   46 #include <glusterfs/events.h>
   47 
   48 enum gf_task_types { GF_TASK_TYPE_REBALANCE, GF_TASK_TYPE_REMOVE_BRICK };
   49 
   50 extern struct rpc_clnt *global_quotad_rpc;
   51 rpc_clnt_prog_t cli_quotad_clnt;
   52 extern rpc_clnt_prog_t *cli_rpc_prog;
   53 extern int connected;
   54 
   55 static int32_t
   56 gf_cli_remove_brick(call_frame_t *frame, xlator_t *this, void *data);
   57 
   58 char *cli_vol_status_str[] = {
   59     "Created",
   60     "Started",
   61     "Stopped",
   62 };
   63 
   64 char *cli_vol_task_status_str[] = {"not started",
   65                                    "in progress",
   66                                    "stopped",
   67                                    "completed",
   68                                    "failed",
   69                                    "fix-layout in progress",
   70                                    "fix-layout stopped",
   71                                    "fix-layout completed",
   72                                    "fix-layout failed",
   73                                    "unknown"};
   74 
   75 static int32_t
   76 gf_cli_snapshot(call_frame_t *frame, xlator_t *this, void *data);
   77 
   78 static int32_t
   79 gf_cli_get_volume(call_frame_t *frame, xlator_t *this, void *data);
   80 
   81 static int
   82 cli_to_glusterd(gf_cli_req *req, call_frame_t *frame, fop_cbk_fn_t cbkfn,
   83                 xdrproc_t xdrproc, dict_t *dict, int procnum, xlator_t *this,
   84                 rpc_clnt_prog_t *prog, struct iobref *iobref);
   85 
   86 static int
   87 add_cli_cmd_timeout_to_dict(dict_t *dict);
   88 
   89 static rpc_clnt_prog_t cli_handshake_prog = {
   90     .progname = "cli handshake",
   91     .prognum = GLUSTER_HNDSK_PROGRAM,
   92     .progver = GLUSTER_HNDSK_VERSION,
   93 };
   94 
   95 static rpc_clnt_prog_t cli_pmap_prog = {
   96     .progname = "cli portmap",
   97     .prognum = GLUSTER_PMAP_PROGRAM,
   98     .progver = GLUSTER_PMAP_VERSION,
   99 };
  100 
  101 static void
  102 gf_free_xdr_cli_rsp(gf_cli_rsp rsp)
  103 {
  104     if (rsp.dict.dict_val) {
  105         free(rsp.dict.dict_val);
  106     }
  107     if (rsp.op_errstr) {
  108         free(rsp.op_errstr);
  109     }
  110 }
  111 
  112 static void
  113 gf_free_xdr_getspec_rsp(gf_getspec_rsp rsp)
  114 {
  115     if (rsp.spec) {
  116         free(rsp.spec);
  117     }
  118     if (rsp.xdata.xdata_val) {
  119         free(rsp.xdata.xdata_val);
  120     }
  121 }
  122 
  123 static void
  124 gf_free_xdr_fsm_log_rsp(gf1_cli_fsm_log_rsp rsp)
  125 {
  126     if (rsp.op_errstr) {
  127         free(rsp.op_errstr);
  128     }
  129     if (rsp.fsm_log.fsm_log_val) {
  130         free(rsp.fsm_log.fsm_log_val);
  131     }
  132 }
  133 
  134 static int
  135 gf_cli_probe_cbk(struct rpc_req *req, struct iovec *iov, int count,
  136                  void *myframe)
  137 {
  138     gf_cli_rsp rsp = {
  139         0,
  140     };
  141     int ret = -1;
  142     char msg[1024] = "success";
  143 
  144     GF_ASSERT(myframe);
  145 
  146     if (-1 == req->rpc_status) {
  147         goto out;
  148     }
  149 
  150     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  151     if (ret < 0) {
  152         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
  153                XDR_DECODE_FAIL);
  154         // rsp.op_ret   = -1;
  155         // rsp.op_errno = EINVAL;
  156         goto out;
  157     }
  158 
  159     gf_log("cli", GF_LOG_INFO, "Received resp to probe");
  160 
  161     if (rsp.op_errstr && rsp.op_errstr[0] != '\0') {
  162         snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
  163         if (rsp.op_ret) {
  164             gf_log("cli", GF_LOG_ERROR, "%s", msg);
  165         }
  166     }
  167 
  168     if (global_state->mode & GLUSTER_MODE_XML) {
  169         ret = cli_xml_output_str(NULL, (rsp.op_ret) ? NULL : msg, rsp.op_ret,
  170                                  rsp.op_errno, (rsp.op_ret) ? msg : NULL);
  171         if (ret)
  172             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  173         goto out;
  174     }
  175 
  176     if (!rsp.op_ret)
  177         cli_out("peer probe: %s", msg);
  178     else
  179         cli_err("peer probe: failed: %s", msg);
  180 
  181     ret = rsp.op_ret;
  182 
  183 out:
  184     cli_cmd_broadcast_response(ret);
  185     gf_free_xdr_cli_rsp(rsp);
  186     return ret;
  187 }
  188 
  189 static int
  190 gf_cli_deprobe_cbk(struct rpc_req *req, struct iovec *iov, int count,
  191                    void *myframe)
  192 {
  193     gf_cli_rsp rsp = {
  194         0,
  195     };
  196     int ret = -1;
  197     char msg[1024] = "success";
  198 
  199     GF_ASSERT(myframe);
  200 
  201     if (-1 == req->rpc_status) {
  202         goto out;
  203     }
  204 
  205     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  206     if (ret < 0) {
  207         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
  208                XDR_DECODE_FAIL);
  209         // rsp.op_ret   = -1;
  210         // rsp.op_errno = EINVAL;
  211         goto out;
  212     }
  213 
  214     gf_log("cli", GF_LOG_INFO, "Received resp to deprobe");
  215 
  216     if (rsp.op_ret) {
  217         if (rsp.op_errstr[0] != '\0') {
  218             snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
  219             gf_log("cli", GF_LOG_ERROR, "%s", rsp.op_errstr);
  220         }
  221     }
  222 
  223     if (global_state->mode & GLUSTER_MODE_XML) {
  224         ret = cli_xml_output_str(NULL, (rsp.op_ret) ? NULL : msg, rsp.op_ret,
  225                                  rsp.op_errno, (rsp.op_ret) ? msg : NULL);
  226         if (ret)
  227             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  228         goto out;
  229     }
  230 
  231     if (!rsp.op_ret)
  232         cli_out("peer detach: %s", msg);
  233     else
  234         cli_err("peer detach: failed: %s", msg);
  235 
  236     ret = rsp.op_ret;
  237 
  238 out:
  239     cli_cmd_broadcast_response(ret);
  240     gf_free_xdr_cli_rsp(rsp);
  241     return ret;
  242 }
  243 
  244 static int
  245 gf_cli_output_peer_hostnames(dict_t *dict, int count, const char *prefix)
  246 {
  247     int ret = -1;
  248     char key[512] = {
  249         0,
  250     };
  251     int i = 0;
  252     char *hostname = NULL;
  253 
  254     cli_out("Other names:");
  255     /* Starting from friend.hostname1, as friend.hostname0 will be the same
  256      * as friend.hostname
  257      */
  258     for (i = 1; i < count; i++) {
  259         ret = snprintf(key, sizeof(key), "%s.hostname%d", prefix, i);
  260         ret = dict_get_strn(dict, key, ret, &hostname);
  261         if (ret)
  262             break;
  263         cli_out("%s", hostname);
  264         hostname = NULL;
  265     }
  266 
  267     return ret;
  268 }
  269 
  270 static int
  271 gf_cli_output_peer_status(dict_t *dict, int count)
  272 {
  273     int ret = -1;
  274     char *uuid_buf = NULL;
  275     char *hostname_buf = NULL;
  276     int32_t i = 1;
  277     char key[256] = {
  278         0,
  279     };
  280     int keylen;
  281     char *state = NULL;
  282     int32_t connected = 0;
  283     const char *connected_str = NULL;
  284     int hostname_count = 0;
  285 
  286     cli_out("Number of Peers: %d", count);
  287     i = 1;
  288     while (i <= count) {
  289         keylen = snprintf(key, sizeof(key), "friend%d.uuid", i);
  290         ret = dict_get_strn(dict, key, keylen, &uuid_buf);
  291         if (ret)
  292             goto out;
  293 
  294         keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
  295         ret = dict_get_strn(dict, key, keylen, &hostname_buf);
  296         if (ret)
  297             goto out;
  298 
  299         keylen = snprintf(key, sizeof(key), "friend%d.connected", i);
  300         ret = dict_get_int32n(dict, key, keylen, &connected);
  301         if (ret)
  302             goto out;
  303         if (connected)
  304             connected_str = "Connected";
  305         else
  306             connected_str = "Disconnected";
  307 
  308         keylen = snprintf(key, sizeof(key), "friend%d.state", i);
  309         ret = dict_get_strn(dict, key, keylen, &state);
  310         if (ret)
  311             goto out;
  312 
  313         cli_out("\nHostname: %s\nUuid: %s\nState: %s (%s)", hostname_buf,
  314                 uuid_buf, state, connected_str);
  315 
  316         keylen = snprintf(key, sizeof(key), "friend%d.hostname_count", i);
  317         ret = dict_get_int32n(dict, key, keylen, &hostname_count);
  318         /* Print other addresses only if there are more than 1.
  319          */
  320         if ((ret == 0) && (hostname_count > 1)) {
  321             snprintf(key, sizeof(key), "friend%d", i);
  322             ret = gf_cli_output_peer_hostnames(dict, hostname_count, key);
  323             if (ret) {
  324                 gf_log("cli", GF_LOG_WARNING,
  325                        "error outputting peer other names");
  326                 goto out;
  327             }
  328         }
  329         i++;
  330     }
  331 
  332     ret = 0;
  333 out:
  334     return ret;
  335 }
  336 
  337 static int
  338 gf_cli_output_pool_list(dict_t *dict, int count)
  339 {
  340     int ret = -1;
  341     char *uuid_buf = NULL;
  342     char *hostname_buf = NULL;
  343     int32_t hostname_len = 8; /*min len 8 chars*/
  344     int32_t i = 1;
  345     char key[64] = {
  346         0,
  347     };
  348     int keylen;
  349     int32_t connected = 0;
  350     const char *connected_str = NULL;
  351 
  352     if (count <= 0)
  353         goto out;
  354 
  355     while (i <= count) {
  356         keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
  357         ret = dict_get_strn(dict, key, keylen, &hostname_buf);
  358         if (ret)
  359             goto out;
  360 
  361         ret = strlen(hostname_buf);
  362         if (ret > hostname_len)
  363             hostname_len = ret;
  364 
  365         i++;
  366     }
  367 
  368     cli_out("UUID\t\t\t\t\t%-*s\tState", hostname_len, "Hostname");
  369 
  370     i = 1;
  371     while (i <= count) {
  372         keylen = snprintf(key, sizeof(key), "friend%d.uuid", i);
  373         ret = dict_get_strn(dict, key, keylen, &uuid_buf);
  374         if (ret)
  375             goto out;
  376 
  377         keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
  378         ret = dict_get_strn(dict, key, keylen, &hostname_buf);
  379         if (ret)
  380             goto out;
  381 
  382         keylen = snprintf(key, sizeof(key), "friend%d.connected", i);
  383         ret = dict_get_int32n(dict, key, keylen, &connected);
  384         if (ret)
  385             goto out;
  386         if (connected)
  387             connected_str = "Connected";
  388         else
  389             connected_str = "Disconnected";
  390 
  391         cli_out("%s\t%-*s\t%s ", uuid_buf, hostname_len, hostname_buf,
  392                 connected_str);
  393         i++;
  394     }
  395 
  396     ret = 0;
  397 out:
  398     return ret;
  399 }
  400 
  401 /* function pointer for gf_cli_output_{pool_list,peer_status} */
  402 typedef int (*cli_friend_output_fn)(dict_t *, int);
  403 
  404 static int
  405 gf_cli_list_friends_cbk(struct rpc_req *req, struct iovec *iov, int count,
  406                         void *myframe)
  407 {
  408     gf1_cli_peer_list_rsp rsp = {
  409         0,
  410     };
  411     int ret = -1;
  412     dict_t *dict = NULL;
  413     char msg[1024] = {
  414         0,
  415     };
  416     const char *cmd = NULL;
  417     cli_friend_output_fn friend_output_fn;
  418     call_frame_t *frame = NULL;
  419     unsigned long flags = 0;
  420 
  421     if (-1 == req->rpc_status) {
  422         goto out;
  423     }
  424 
  425     GF_ASSERT(myframe);
  426 
  427     frame = myframe;
  428 
  429     flags = (long)frame->local;
  430 
  431     if (flags == GF_CLI_LIST_POOL_NODES) {
  432         cmd = "pool list";
  433         friend_output_fn = &gf_cli_output_pool_list;
  434     } else {
  435         cmd = "peer status";
  436         friend_output_fn = &gf_cli_output_peer_status;
  437     }
  438 
  439     /* 'free' the flags set by gf_cli_list_friends */
  440     frame->local = NULL;
  441 
  442     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
  443     if (ret < 0) {
  444         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
  445         // rsp.op_ret   = -1;
  446         // rsp.op_errno = EINVAL;
  447         goto out;
  448     }
  449 
  450     gf_log("cli", GF_LOG_DEBUG, "Received resp to list: %d", rsp.op_ret);
  451 
  452     if (!rsp.op_ret) {
  453         if (!rsp.friends.friends_len) {
  454             snprintf(msg, sizeof(msg), "%s: No peers present", cmd);
  455             if (global_state->mode & GLUSTER_MODE_XML) {
  456                 ret = cli_xml_output_peer_status(dict, rsp.op_ret, rsp.op_errno,
  457                                                  msg);
  458                 if (ret)
  459                     gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  460                 goto out;
  461             }
  462             cli_err("%s", msg);
  463             ret = 0;
  464             goto out;
  465         }
  466 
  467         dict = dict_new();
  468 
  469         if (!dict) {
  470             ret = -1;
  471             goto out;
  472         }
  473 
  474         ret = dict_unserialize(rsp.friends.friends_val, rsp.friends.friends_len,
  475                                &dict);
  476 
  477         if (ret) {
  478             gf_log("", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
  479             goto out;
  480         }
  481 
  482         if (global_state->mode & GLUSTER_MODE_XML) {
  483             ret = cli_xml_output_peer_status(dict, rsp.op_ret, rsp.op_errno,
  484                                              msg);
  485             if (ret)
  486                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  487             goto out;
  488         }
  489 
  490         ret = dict_get_int32_sizen(dict, "count", &count);
  491         if (ret) {
  492             goto out;
  493         }
  494 
  495         ret = friend_output_fn(dict, count);
  496         if (ret) {
  497             goto out;
  498         }
  499     } else {
  500         if (global_state->mode & GLUSTER_MODE_XML) {
  501             ret = cli_xml_output_peer_status(dict, rsp.op_ret, rsp.op_errno,
  502                                              NULL);
  503             if (ret)
  504                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  505         } else {
  506             ret = -1;
  507         }
  508         goto out;
  509     }
  510 
  511     ret = 0;
  512 
  513 out:
  514     if (ret)
  515         cli_err("%s: failed", cmd);
  516 
  517     cli_cmd_broadcast_response(ret);
  518 
  519     if (dict)
  520         dict_unref(dict);
  521 
  522     if (rsp.friends.friends_val) {
  523         free(rsp.friends.friends_val);
  524     }
  525     return ret;
  526 }
  527 
  528 static int
  529 gf_cli_get_state_cbk(struct rpc_req *req, struct iovec *iov, int count,
  530                      void *myframe)
  531 {
  532     gf_cli_rsp rsp = {
  533         0,
  534     };
  535     int ret = -1;
  536     dict_t *dict = NULL;
  537     char *daemon_name = NULL;
  538     char *ofilepath = NULL;
  539 
  540     GF_VALIDATE_OR_GOTO("cli", myframe, out);
  541 
  542     if (-1 == req->rpc_status) {
  543         goto out;
  544     }
  545     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  546     if (ret < 0) {
  547         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
  548                XDR_DECODE_FAIL);
  549         goto out;
  550     }
  551 
  552     dict = dict_new();
  553 
  554     if (!dict) {
  555         ret = -1;
  556         goto out;
  557     }
  558 
  559     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  560     if (ret)
  561         goto out;
  562 
  563     if (rsp.op_ret) {
  564         if (strcmp(rsp.op_errstr, ""))
  565             cli_err("Failed to get daemon state: %s", rsp.op_errstr);
  566         else
  567             cli_err(
  568                 "Failed to get daemon state. Check glusterd"
  569                 " log file for more details");
  570     } else {
  571         ret = dict_get_str_sizen(dict, "daemon", &daemon_name);
  572         if (ret)
  573             gf_log("cli", GF_LOG_ERROR, "Couldn't get daemon name");
  574 
  575         ret = dict_get_str_sizen(dict, "ofilepath", &ofilepath);
  576         if (ret)
  577             gf_log("cli", GF_LOG_ERROR, "Couldn't get filepath");
  578 
  579         if (daemon_name && ofilepath)
  580             cli_out("%s state dumped to %s", daemon_name, ofilepath);
  581     }
  582 
  583     ret = rsp.op_ret;
  584 
  585 out:
  586     if (dict)
  587         dict_unref(dict);
  588 
  589     cli_cmd_broadcast_response(ret);
  590     gf_free_xdr_cli_rsp(rsp);
  591 
  592     return ret;
  593 }
  594 
  595 static void
  596 cli_out_options(char *substr, char *optstr, char *valstr)
  597 {
  598     char *ptr1 = NULL;
  599     char *ptr2 = NULL;
  600 
  601     ptr1 = substr;
  602     ptr2 = optstr;
  603 
  604     while (ptr1) {
  605         /* Avoiding segmentation fault. */
  606         if (!ptr2)
  607             return;
  608         if (*ptr1 != *ptr2)
  609             break;
  610         ptr1++;
  611         ptr2++;
  612     }
  613 
  614     if (*ptr2 == '\0')
  615         return;
  616     cli_out("%s: %s", ptr2, valstr);
  617 }
  618 
  619 static int
  620 _gf_cli_output_volinfo_opts(dict_t *d, char *k, data_t *v, void *tmp)
  621 {
  622     int ret = 0;
  623     char *key = NULL;
  624     char *ptr = NULL;
  625     data_t *value = NULL;
  626 
  627     key = tmp;
  628 
  629     ptr = strstr(k, "option.");
  630     if (ptr) {
  631         value = v;
  632         if (!value) {
  633             ret = -1;
  634             goto out;
  635         }
  636         cli_out_options(key, k, v->data);
  637     }
  638 out:
  639     return ret;
  640 }
  641 
  642 static int
  643 print_brick_details(dict_t *dict, int volcount, int start_index, int end_index,
  644                     int replica_count)
  645 {
  646     char key[64] = {
  647         0,
  648     };
  649     int keylen;
  650     int index = start_index;
  651     int isArbiter = 0;
  652     int ret = -1;
  653     char *brick = NULL;
  654 
  655     while (index <= end_index) {
  656         keylen = snprintf(key, sizeof(key), "volume%d.brick%d", volcount,
  657                           index);
  658         ret = dict_get_strn(dict, key, keylen, &brick);
  659         if (ret)
  660             goto out;
  661         keylen = snprintf(key, sizeof(key), "volume%d.brick%d.isArbiter",
  662                           volcount, index);
  663         if (dict_getn(dict, key, keylen))
  664             isArbiter = 1;
  665         else
  666             isArbiter = 0;
  667 
  668         if (isArbiter)
  669             cli_out("Brick%d: %s (arbiter)", index, brick);
  670         else
  671             cli_out("Brick%d: %s", index, brick);
  672         index++;
  673     }
  674     ret = 0;
  675 out:
  676     return ret;
  677 }
  678 
  679 static void
  680 gf_cli_print_number_of_bricks(int type, int brick_count, int dist_count,
  681                               int stripe_count, int replica_count,
  682                               int disperse_count, int redundancy_count,
  683                               int arbiter_count)
  684 {
  685     if (type == GF_CLUSTER_TYPE_NONE) {
  686         cli_out("Number of Bricks: %d", brick_count);
  687     } else if (type == GF_CLUSTER_TYPE_DISPERSE) {
  688         cli_out("Number of Bricks: %d x (%d + %d) = %d",
  689                 (brick_count / dist_count), disperse_count - redundancy_count,
  690                 redundancy_count, brick_count);
  691     } else {
  692         /* For both replicate and stripe, dist_count is
  693            good enough */
  694         if (arbiter_count == 0) {
  695             cli_out("Number of Bricks: %d x %d = %d",
  696                     (brick_count / dist_count), dist_count, brick_count);
  697         } else {
  698             cli_out("Number of Bricks: %d x (%d + %d) = %d",
  699                     (brick_count / dist_count), dist_count - arbiter_count,
  700                     arbiter_count, brick_count);
  701         }
  702     }
  703 }
  704 
  705 static int
  706 gf_cli_get_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
  707                       void *myframe)
  708 {
  709     int ret = -1;
  710     int opt_count = 0;
  711     int32_t i = 0;
  712     int32_t j = 1;
  713     int32_t status = 0;
  714     int32_t type = 0;
  715     int32_t brick_count = 0;
  716     int32_t dist_count = 0;
  717     int32_t stripe_count = 0;
  718     int32_t replica_count = 0;
  719     int32_t disperse_count = 0;
  720     int32_t redundancy_count = 0;
  721     int32_t arbiter_count = 0;
  722     int32_t snap_count = 0;
  723     int32_t thin_arbiter_count = 0;
  724     int32_t vol_type = 0;
  725     int32_t transport = 0;
  726     char *volume_id_str = NULL;
  727     char *volname = NULL;
  728     char *ta_brick = NULL;
  729     dict_t *dict = NULL;
  730     cli_local_t *local = NULL;
  731     char key[64] = {0};
  732     int keylen;
  733     char err_str[2048] = {0};
  734     gf_cli_rsp rsp = {0};
  735     char *caps __attribute__((unused)) = NULL;
  736     int k __attribute__((unused)) = 0;
  737     call_frame_t *frame = NULL;
  738 
  739     GF_ASSERT(myframe);
  740 
  741     if (-1 == req->rpc_status)
  742         goto out;
  743 
  744     frame = myframe;
  745 
  746     GF_ASSERT(frame->local);
  747 
  748     local = frame->local;
  749 
  750     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
  751     if (ret < 0) {
  752         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
  753         goto out;
  754     }
  755 
  756     gf_log("cli", GF_LOG_INFO, "Received resp to get vol: %d", rsp.op_ret);
  757 
  758     if (!rsp.dict.dict_len) {
  759         if (global_state->mode & GLUSTER_MODE_XML)
  760             goto xml_output;
  761         cli_err("No volumes present");
  762         ret = 0;
  763         goto out;
  764     }
  765 
  766     dict = dict_new();
  767 
  768     if (!dict) {
  769         ret = -1;
  770         goto out;
  771     }
  772 
  773     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
  774 
  775     if (ret) {
  776         gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
  777         goto out;
  778     }
  779 
  780     ret = dict_get_int32_sizen(dict, "count", &count);
  781     if (ret)
  782         goto out;
  783 
  784     if (!count) {
  785         switch (local->get_vol.flags) {
  786             case GF_CLI_GET_NEXT_VOLUME:
  787                 GF_FREE(local->get_vol.volname);
  788                 local->get_vol.volname = NULL;
  789                 ret = 0;
  790                 goto out;
  791 
  792             case GF_CLI_GET_VOLUME:
  793                 snprintf(err_str, sizeof(err_str), "Volume %s does not exist",
  794                          local->get_vol.volname);
  795                 ret = -1;
  796                 if (!(global_state->mode & GLUSTER_MODE_XML))
  797                     goto out;
  798         }
  799     }
  800 
  801     if (rsp.op_ret) {
  802         if (global_state->mode & GLUSTER_MODE_XML)
  803             goto xml_output;
  804         ret = -1;
  805         goto out;
  806     }
  807 
  808 xml_output:
  809     if (global_state->mode & GLUSTER_MODE_XML) {
  810         /* For GET_NEXT_VOLUME output is already begun in
  811          * and will also end in gf_cli_get_next_volume()
  812          */
  813         if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
  814             ret = cli_xml_output_vol_info_begin(local, rsp.op_ret, rsp.op_errno,
  815                                                 rsp.op_errstr);
  816             if (ret) {
  817                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  818                 goto out;
  819             }
  820         }
  821 
  822         if (dict) {
  823             ret = cli_xml_output_vol_info(local, dict);
  824             if (ret) {
  825                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  826                 goto out;
  827             }
  828         }
  829 
  830         if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
  831             ret = cli_xml_output_vol_info_end(local);
  832             if (ret)
  833                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
  834         }
  835         goto out;
  836     }
  837 
  838     while (i < count) {
  839         cli_out(" ");
  840         keylen = snprintf(key, sizeof(key), "volume%d.name", i);
  841         ret = dict_get_strn(dict, key, keylen, &volname);
  842         if (ret)
  843             goto out;
  844 
  845         keylen = snprintf(key, sizeof(key), "volume%d.type", i);
  846         ret = dict_get_int32n(dict, key, keylen, &type);
  847         if (ret)
  848             goto out;
  849 
  850         keylen = snprintf(key, sizeof(key), "volume%d.status", i);
  851         ret = dict_get_int32n(dict, key, keylen, &status);
  852         if (ret)
  853             goto out;
  854 
  855         keylen = snprintf(key, sizeof(key), "volume%d.brick_count", i);
  856         ret = dict_get_int32n(dict, key, keylen, &brick_count);
  857         if (ret)
  858             goto out;
  859 
  860         keylen = snprintf(key, sizeof(key), "volume%d.dist_count", i);
  861         ret = dict_get_int32n(dict, key, keylen, &dist_count);
  862         if (ret)
  863             goto out;
  864 
  865         keylen = snprintf(key, sizeof(key), "volume%d.stripe_count", i);
  866         ret = dict_get_int32n(dict, key, keylen, &stripe_count);
  867         if (ret)
  868             goto out;
  869 
  870         keylen = snprintf(key, sizeof(key), "volume%d.replica_count", i);
  871         ret = dict_get_int32n(dict, key, keylen, &replica_count);
  872         if (ret)
  873             goto out;
  874 
  875         keylen = snprintf(key, sizeof(key), "volume%d.disperse_count", i);
  876         ret = dict_get_int32n(dict, key, keylen, &disperse_count);
  877         if (ret)
  878             goto out;
  879 
  880         keylen = snprintf(key, sizeof(key), "volume%d.redundancy_count", i);
  881         ret = dict_get_int32n(dict, key, keylen, &redundancy_count);
  882         if (ret)
  883             goto out;
  884 
  885         keylen = snprintf(key, sizeof(key), "volume%d.arbiter_count", i);
  886         ret = dict_get_int32n(dict, key, keylen, &arbiter_count);
  887         if (ret)
  888             goto out;
  889 
  890         keylen = snprintf(key, sizeof(key), "volume%d.transport", i);
  891         ret = dict_get_int32n(dict, key, keylen, &transport);
  892         if (ret)
  893             goto out;
  894 
  895         keylen = snprintf(key, sizeof(key), "volume%d.volume_id", i);
  896         ret = dict_get_strn(dict, key, keylen, &volume_id_str);
  897         if (ret)
  898             goto out;
  899 
  900         keylen = snprintf(key, sizeof(key), "volume%d.snap_count", i);
  901         ret = dict_get_int32n(dict, key, keylen, &snap_count);
  902         if (ret)
  903             goto out;
  904 
  905         keylen = snprintf(key, sizeof(key), "volume%d.thin_arbiter_count", i);
  906         ret = dict_get_int32n(dict, key, keylen, &thin_arbiter_count);
  907         if (ret)
  908             goto out;
  909 
  910         // Distributed (stripe/replicate/stripe-replica) setups
  911         vol_type = get_vol_type(type, dist_count, brick_count);
  912 
  913         cli_out("Volume Name: %s", volname);
  914         cli_out("Type: %s", vol_type_str[vol_type]);
  915         cli_out("Volume ID: %s", volume_id_str);
  916         cli_out("Status: %s", cli_vol_status_str[status]);
  917         cli_out("Snapshot Count: %d", snap_count);
  918 
  919         gf_cli_print_number_of_bricks(
  920             type, brick_count, dist_count, stripe_count, replica_count,
  921             disperse_count, redundancy_count, arbiter_count);
  922 
  923         cli_out("Transport-type: %s",
  924                 ((transport == 0) ? "tcp"
  925                                   : (transport == 1) ? "rdma" : "tcp,rdma"));
  926         j = 1;
  927 
  928         GF_FREE(local->get_vol.volname);
  929         local->get_vol.volname = gf_strdup(volname);
  930 
  931         cli_out("Bricks:");
  932         ret = print_brick_details(dict, i, j, brick_count, replica_count);
  933         if (ret)
  934             goto out;
  935 
  936         if (thin_arbiter_count) {
  937             snprintf(key, sizeof(key), "volume%d.thin_arbiter_brick", i);
  938             ret = dict_get_str(dict, key, &ta_brick);
  939             if (ret)
  940                 goto out;
  941             cli_out("Thin-arbiter-path: %s", ta_brick);
  942         }
  943 
  944         snprintf(key, sizeof(key), "volume%d.opt_count", i);
  945         ret = dict_get_int32(dict, key, &opt_count);
  946         if (ret)
  947             goto out;
  948 
  949         if (!opt_count)
  950             goto out;
  951 
  952         cli_out("Options Reconfigured:");
  953 
  954         snprintf(key, sizeof(key), "volume%d.option.", i);
  955 
  956         ret = dict_foreach(dict, _gf_cli_output_volinfo_opts, key);
  957         if (ret)
  958             goto out;
  959 
  960         i++;
  961     }
  962 
  963     ret = 0;
  964 out:
  965     if (ret)
  966         cli_err("%s", err_str);
  967 
  968     cli_cmd_broadcast_response(ret);
  969 
  970     if (dict)
  971         dict_unref(dict);
  972 
  973     gf_free_xdr_cli_rsp(rsp);
  974 
  975     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
  976     return ret;
  977 }
  978 
  979 static int
  980 gf_cli_create_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
  981                          void *myframe)
  982 {
  983     gf_cli_rsp rsp = {
  984         0,
  985     };
  986     int ret = -1;
  987     cli_local_t *local = NULL;
  988     char *volname = NULL;
  989     dict_t *rsp_dict = NULL;
  990     call_frame_t *frame = NULL;
  991 
  992     GF_ASSERT(myframe);
  993 
  994     if (-1 == req->rpc_status) {
  995         goto out;
  996     }
  997 
  998     frame = myframe;
  999 
 1000     GF_ASSERT(frame->local);
 1001 
 1002     local = frame->local;
 1003 
 1004     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1005     if (ret < 0) {
 1006         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1007         goto out;
 1008     }
 1009 
 1010     gf_log("cli", GF_LOG_INFO, "Received resp to create volume");
 1011 
 1012     if (global_state->mode & GLUSTER_MODE_XML) {
 1013         if (rsp.op_ret == 0) {
 1014             rsp_dict = dict_new();
 1015             ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
 1016                                    &rsp_dict);
 1017             if (ret) {
 1018                 gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1019                 goto out;
 1020             }
 1021         }
 1022 
 1023         ret = cli_xml_output_vol_create(rsp_dict, rsp.op_ret, rsp.op_errno,
 1024                                         rsp.op_errstr);
 1025         if (ret)
 1026             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1027         goto out;
 1028     }
 1029 
 1030     ret = dict_get_str_sizen(local->dict, "volname", &volname);
 1031     if (ret)
 1032         goto out;
 1033 
 1034     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 1035         cli_err("volume create: %s: failed: %s", volname, rsp.op_errstr);
 1036     else if (rsp.op_ret)
 1037         cli_err("volume create: %s: failed", volname);
 1038     else
 1039         cli_out(
 1040             "volume create: %s: success: "
 1041             "please start the volume to access data",
 1042             volname);
 1043 
 1044     ret = rsp.op_ret;
 1045 
 1046 out:
 1047     cli_cmd_broadcast_response(ret);
 1048     gf_free_xdr_cli_rsp(rsp);
 1049 
 1050     if (rsp_dict)
 1051         dict_unref(rsp_dict);
 1052     return ret;
 1053 }
 1054 
 1055 static int
 1056 gf_cli_delete_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1057                          void *myframe)
 1058 {
 1059     gf_cli_rsp rsp = {
 1060         0,
 1061     };
 1062     int ret = -1;
 1063     cli_local_t *local = NULL;
 1064     char *volname = NULL;
 1065     call_frame_t *frame = NULL;
 1066     dict_t *rsp_dict = NULL;
 1067 
 1068     if (-1 == req->rpc_status) {
 1069         goto out;
 1070     }
 1071 
 1072     GF_ASSERT(myframe);
 1073     frame = myframe;
 1074 
 1075     GF_ASSERT(frame->local);
 1076 
 1077     local = frame->local;
 1078 
 1079     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1080     if (ret < 0) {
 1081         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1082         goto out;
 1083     }
 1084 
 1085     gf_log("cli", GF_LOG_INFO, "Received resp to delete volume");
 1086 
 1087     if (global_state->mode & GLUSTER_MODE_XML) {
 1088         if (rsp.op_ret == 0) {
 1089             rsp_dict = dict_new();
 1090             ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
 1091                                    &rsp_dict);
 1092             if (ret) {
 1093                 gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1094                 goto out;
 1095             }
 1096         }
 1097 
 1098         ret = cli_xml_output_generic_volume("volDelete", rsp_dict, rsp.op_ret,
 1099                                             rsp.op_errno, rsp.op_errstr);
 1100         if (ret)
 1101             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1102         goto out;
 1103     }
 1104 
 1105     ret = dict_get_str_sizen(local->dict, "volname", &volname);
 1106     if (ret) {
 1107         gf_log(frame->this->name, GF_LOG_ERROR, "dict get failed");
 1108         goto out;
 1109     }
 1110 
 1111     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 1112         cli_err("volume delete: %s: failed: %s", volname, rsp.op_errstr);
 1113     else if (rsp.op_ret)
 1114         cli_err("volume delete: %s: failed", volname);
 1115     else
 1116         cli_out("volume delete: %s: success", volname);
 1117 
 1118     ret = rsp.op_ret;
 1119 
 1120 out:
 1121     cli_cmd_broadcast_response(ret);
 1122     gf_free_xdr_cli_rsp(rsp);
 1123 
 1124     if (rsp_dict)
 1125         dict_unref(rsp_dict);
 1126     gf_log("", GF_LOG_DEBUG, RETURNING, ret);
 1127     return ret;
 1128 }
 1129 
 1130 static int
 1131 gf_cli3_1_uuid_get_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1132                        void *myframe)
 1133 {
 1134     char *uuid_str = NULL;
 1135     gf_cli_rsp rsp = {
 1136         0,
 1137     };
 1138     int ret = -1;
 1139     cli_local_t *local = NULL;
 1140     call_frame_t *frame = NULL;
 1141     dict_t *dict = NULL;
 1142 
 1143     GF_ASSERT(myframe);
 1144 
 1145     if (-1 == req->rpc_status)
 1146         goto out;
 1147 
 1148     frame = myframe;
 1149 
 1150     GF_ASSERT(frame->local);
 1151 
 1152     local = frame->local;
 1153 
 1154     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1155     if (ret < 0) {
 1156         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1157         goto out;
 1158     }
 1159 
 1160     frame->local = NULL;
 1161 
 1162     gf_log("cli", GF_LOG_INFO, "Received resp to uuid get");
 1163 
 1164     dict = dict_new();
 1165     if (!dict) {
 1166         ret = -1;
 1167         goto out;
 1168     }
 1169 
 1170     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 1171     if (ret) {
 1172         gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1173         goto out;
 1174     }
 1175 
 1176     if (global_state->mode & GLUSTER_MODE_XML) {
 1177         ret = cli_xml_output_dict("uuidGenerate", dict, rsp.op_ret,
 1178                                   rsp.op_errno, rsp.op_errstr);
 1179         if (ret)
 1180             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1181         goto out;
 1182     }
 1183 
 1184     if (rsp.op_ret) {
 1185         if (strcmp(rsp.op_errstr, "") == 0)
 1186             cli_err("Get uuid was unsuccessful");
 1187         else
 1188             cli_err("%s", rsp.op_errstr);
 1189 
 1190     } else {
 1191         ret = dict_get_str_sizen(dict, "uuid", &uuid_str);
 1192         if (ret) {
 1193             gf_log("cli", GF_LOG_ERROR, "Failed to get uuid from dictionary");
 1194             goto out;
 1195         }
 1196         cli_out("UUID: %s", uuid_str);
 1197     }
 1198     ret = rsp.op_ret;
 1199 
 1200 out:
 1201     cli_cmd_broadcast_response(ret);
 1202     cli_local_wipe(local);
 1203     gf_free_xdr_cli_rsp(rsp);
 1204 
 1205     if (dict)
 1206         dict_unref(dict);
 1207 
 1208     gf_log("", GF_LOG_DEBUG, RETURNING, ret);
 1209     return ret;
 1210 }
 1211 
 1212 static int
 1213 gf_cli3_1_uuid_reset_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1214                          void *myframe)
 1215 {
 1216     gf_cli_rsp rsp = {
 1217         0,
 1218     };
 1219     int ret = -1;
 1220     cli_local_t *local = NULL;
 1221     call_frame_t *frame = NULL;
 1222 
 1223     GF_ASSERT(myframe);
 1224 
 1225     if (-1 == req->rpc_status) {
 1226         goto out;
 1227     }
 1228 
 1229     frame = myframe;
 1230 
 1231     GF_ASSERT(frame->local);
 1232 
 1233     local = frame->local;
 1234 
 1235     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1236     if (ret < 0) {
 1237         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1238         goto out;
 1239     }
 1240 
 1241     frame->local = NULL;
 1242 
 1243     gf_log("cli", GF_LOG_INFO, "Received resp to uuid reset");
 1244 
 1245     if (global_state->mode & GLUSTER_MODE_XML) {
 1246         ret = cli_xml_output_dict("uuidReset", NULL, rsp.op_ret, rsp.op_errno,
 1247                                   rsp.op_errstr);
 1248         if (ret)
 1249             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1250         goto out;
 1251     }
 1252 
 1253     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 1254         cli_err("%s", rsp.op_errstr);
 1255     else
 1256         cli_out("resetting the peer uuid has been %s",
 1257                 (rsp.op_ret) ? "unsuccessful" : "successful");
 1258     ret = rsp.op_ret;
 1259 
 1260 out:
 1261     cli_cmd_broadcast_response(ret);
 1262     cli_local_wipe(local);
 1263     gf_free_xdr_cli_rsp(rsp);
 1264 
 1265     gf_log("", GF_LOG_DEBUG, RETURNING, ret);
 1266     return ret;
 1267 }
 1268 
 1269 static int
 1270 gf_cli_start_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1271                         void *myframe)
 1272 {
 1273     gf_cli_rsp rsp = {
 1274         0,
 1275     };
 1276     int ret = -1;
 1277     cli_local_t *local = NULL;
 1278     char *volname = NULL;
 1279     call_frame_t *frame = NULL;
 1280     dict_t *rsp_dict = NULL;
 1281 
 1282     GF_ASSERT(myframe);
 1283 
 1284     if (-1 == req->rpc_status) {
 1285         goto out;
 1286     }
 1287 
 1288     frame = myframe;
 1289 
 1290     GF_ASSERT(frame->local);
 1291 
 1292     local = frame->local;
 1293 
 1294     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1295     if (ret < 0) {
 1296         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1297         goto out;
 1298     }
 1299 
 1300     gf_log("cli", GF_LOG_INFO, "Received resp to start volume");
 1301 
 1302     if (global_state->mode & GLUSTER_MODE_XML) {
 1303         if (rsp.op_ret == 0) {
 1304             rsp_dict = dict_new();
 1305             ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
 1306                                    &rsp_dict);
 1307             if (ret) {
 1308                 gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1309                 goto out;
 1310             }
 1311         }
 1312 
 1313         ret = cli_xml_output_generic_volume("volStart", rsp_dict, rsp.op_ret,
 1314                                             rsp.op_errno, rsp.op_errstr);
 1315         if (ret)
 1316             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1317         goto out;
 1318     }
 1319 
 1320     ret = dict_get_str_sizen(local->dict, "volname", &volname);
 1321     if (ret) {
 1322         gf_log("cli", GF_LOG_ERROR, "dict get failed");
 1323         goto out;
 1324     }
 1325 
 1326     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 1327         cli_err("volume start: %s: failed: %s", volname, rsp.op_errstr);
 1328     else if (rsp.op_ret)
 1329         cli_err("volume start: %s: failed", volname);
 1330     else
 1331         cli_out("volume start: %s: success", volname);
 1332 
 1333     ret = rsp.op_ret;
 1334 
 1335 out:
 1336     cli_cmd_broadcast_response(ret);
 1337     gf_free_xdr_cli_rsp(rsp);
 1338 
 1339     if (rsp_dict)
 1340         dict_unref(rsp_dict);
 1341     return ret;
 1342 }
 1343 
 1344 static int
 1345 gf_cli_stop_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1346                        void *myframe)
 1347 {
 1348     gf_cli_rsp rsp = {
 1349         0,
 1350     };
 1351     int ret = -1;
 1352     cli_local_t *local = NULL;
 1353     char *volname = NULL;
 1354     call_frame_t *frame = NULL;
 1355     dict_t *rsp_dict = NULL;
 1356 
 1357     GF_ASSERT(myframe);
 1358 
 1359     if (-1 == req->rpc_status) {
 1360         goto out;
 1361     }
 1362 
 1363     frame = myframe;
 1364 
 1365     GF_ASSERT(frame->local);
 1366 
 1367     local = frame->local;
 1368 
 1369     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1370     if (ret < 0) {
 1371         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1372         goto out;
 1373     }
 1374 
 1375     gf_log("cli", GF_LOG_INFO, "Received resp to stop volume");
 1376 
 1377     if (global_state->mode & GLUSTER_MODE_XML) {
 1378         if (rsp.op_ret == 0) {
 1379             rsp_dict = dict_new();
 1380             ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
 1381                                    &rsp_dict);
 1382             if (ret) {
 1383                 gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1384                 goto out;
 1385             }
 1386         }
 1387 
 1388         ret = cli_xml_output_generic_volume("volStop", rsp_dict, rsp.op_ret,
 1389                                             rsp.op_errno, rsp.op_errstr);
 1390         if (ret)
 1391             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1392         goto out;
 1393     }
 1394 
 1395     ret = dict_get_str_sizen(local->dict, "volname", &volname);
 1396     if (ret) {
 1397         gf_log(frame->this->name, GF_LOG_ERROR,
 1398                "Unable to get volname from dict");
 1399         goto out;
 1400     }
 1401 
 1402     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 1403         cli_err("volume stop: %s: failed: %s", volname, rsp.op_errstr);
 1404     else if (rsp.op_ret)
 1405         cli_err("volume stop: %s: failed", volname);
 1406     else
 1407         cli_out("volume stop: %s: success", volname);
 1408 
 1409     ret = rsp.op_ret;
 1410 
 1411 out:
 1412     cli_cmd_broadcast_response(ret);
 1413     gf_free_xdr_cli_rsp(rsp);
 1414 
 1415     if (rsp_dict)
 1416         dict_unref(rsp_dict);
 1417 
 1418     return ret;
 1419 }
 1420 
 1421 static int
 1422 gf_cli_print_rebalance_status(dict_t *dict, enum gf_task_types task_type)
 1423 {
 1424     int ret = -1;
 1425     int count = 0;
 1426     int i = 1;
 1427     char key[64] = {
 1428         0,
 1429     };
 1430     int keylen;
 1431     gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
 1432     uint64_t files = 0;
 1433     uint64_t size = 0;
 1434     uint64_t lookup = 0;
 1435     char *node_name = NULL;
 1436     uint64_t failures = 0;
 1437     uint64_t skipped = 0;
 1438     double elapsed = 0;
 1439     char *status_str = NULL;
 1440     char *size_str = NULL;
 1441     int32_t hrs = 0;
 1442     uint32_t min = 0;
 1443     uint32_t sec = 0;
 1444     gf_boolean_t fix_layout = _gf_false;
 1445     uint64_t max_time = 0;
 1446     uint64_t max_elapsed = 0;
 1447     uint64_t time_left = 0;
 1448     gf_boolean_t show_estimates = _gf_false;
 1449 
 1450     ret = dict_get_int32_sizen(dict, "count", &count);
 1451     if (ret) {
 1452         gf_log("cli", GF_LOG_ERROR, "count not set");
 1453         goto out;
 1454     }
 1455 
 1456     for (i = 1; i <= count; i++) {
 1457         keylen = snprintf(key, sizeof(key), "status-%d", i);
 1458         ret = dict_get_int32n(dict, key, keylen, (int32_t *)&status_rcd);
 1459         /* If information from a node is missing we should skip
 1460          * the node and try to fetch information of other nodes.
 1461          * If information is not found for all nodes, we should
 1462          * error out.
 1463          */
 1464         if (!ret)
 1465             break;
 1466         if (ret && i == count) {
 1467             gf_log("cli", GF_LOG_TRACE, "failed to get status");
 1468             goto out;
 1469         }
 1470     }
 1471 
 1472     /* Fix layout will be sent to all nodes for the volume
 1473        so every status should be of type
 1474        GF_DEFRAG_STATUS_LAYOUT_FIX*
 1475     */
 1476 
 1477     if ((task_type == GF_TASK_TYPE_REBALANCE) &&
 1478         (status_rcd >= GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED)) {
 1479         fix_layout = _gf_true;
 1480     }
 1481 
 1482     if (fix_layout) {
 1483         cli_out("%35s %41s %27s", "Node", "status", "run time in h:m:s");
 1484         cli_out("%35s %41s %27s", "---------", "-----------", "------------");
 1485     } else {
 1486         cli_out("%40s %16s %13s %13s %13s %13s %20s %18s", "Node",
 1487                 "Rebalanced-files", "size", "scanned", "failures", "skipped",
 1488                 "status",
 1489                 "run time in"
 1490                 " h:m:s");
 1491         cli_out("%40s %16s %13s %13s %13s %13s %20s %18s", "---------",
 1492                 "-----------", "-----------", "-----------", "-----------",
 1493                 "-----------", "------------", "--------------");
 1494     }
 1495 
 1496     for (i = 1; i <= count; i++) {
 1497         /* Reset the variables to prevent carryover of values */
 1498         node_name = NULL;
 1499         files = 0;
 1500         size = 0;
 1501         lookup = 0;
 1502         skipped = 0;
 1503         status_str = NULL;
 1504         elapsed = 0;
 1505         time_left = 0;
 1506 
 1507         /* Check if status is NOT_STARTED, and continue early */
 1508         keylen = snprintf(key, sizeof(key), "status-%d", i);
 1509 
 1510         ret = dict_get_int32n(dict, key, keylen, (int32_t *)&status_rcd);
 1511         if (ret == -ENOENT) {
 1512             gf_log("cli", GF_LOG_TRACE, "count %d %d", count, i);
 1513             gf_log("cli", GF_LOG_TRACE, "failed to get status");
 1514             gf_log("cli", GF_LOG_ERROR, "node down and has failed to set dict");
 1515             continue;
 1516             /* skip this node if value not available*/
 1517         } else if (ret) {
 1518             gf_log("cli", GF_LOG_TRACE, "count %d %d", count, i);
 1519             gf_log("cli", GF_LOG_TRACE, "failed to get status");
 1520             continue;
 1521             /* skip this node if value not available*/
 1522         }
 1523 
 1524         if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)
 1525             continue;
 1526 
 1527         if (GF_DEFRAG_STATUS_STARTED == status_rcd)
 1528             show_estimates = _gf_true;
 1529 
 1530         keylen = snprintf(key, sizeof(key), "node-name-%d", i);
 1531         ret = dict_get_strn(dict, key, keylen, &node_name);
 1532         if (ret)
 1533             gf_log("cli", GF_LOG_TRACE, "failed to get node-name");
 1534 
 1535         snprintf(key, sizeof(key), "files-%d", i);
 1536         ret = dict_get_uint64(dict, key, &files);
 1537         if (ret)
 1538             gf_log("cli", GF_LOG_TRACE, "failed to get file count");
 1539 
 1540         snprintf(key, sizeof(key), "size-%d", i);
 1541         ret = dict_get_uint64(dict, key, &size);
 1542         if (ret)
 1543             gf_log("cli", GF_LOG_TRACE, "failed to get size of xfer");
 1544 
 1545         snprintf(key, sizeof(key), "lookups-%d", i);
 1546         ret = dict_get_uint64(dict, key, &lookup);
 1547         if (ret)
 1548             gf_log("cli", GF_LOG_TRACE, "failed to get lookedup file count");
 1549 
 1550         snprintf(key, sizeof(key), "failures-%d", i);
 1551         ret = dict_get_uint64(dict, key, &failures);
 1552         if (ret)
 1553             gf_log("cli", GF_LOG_TRACE, "failed to get failures count");
 1554 
 1555         snprintf(key, sizeof(key), "skipped-%d", i);
 1556         ret = dict_get_uint64(dict, key, &skipped);
 1557         if (ret)
 1558             gf_log("cli", GF_LOG_TRACE, "failed to get skipped count");
 1559 
 1560         /* For remove-brick include skipped count into failure count*/
 1561         if (task_type != GF_TASK_TYPE_REBALANCE) {
 1562             failures += skipped;
 1563             skipped = 0;
 1564         }
 1565 
 1566         snprintf(key, sizeof(key), "run-time-%d", i);
 1567         ret = dict_get_double(dict, key, &elapsed);
 1568         if (ret)
 1569             gf_log("cli", GF_LOG_TRACE, "failed to get run-time");
 1570 
 1571         snprintf(key, sizeof(key), "time-left-%d", i);
 1572         ret = dict_get_uint64(dict, key, &time_left);
 1573         if (ret)
 1574             gf_log("cli", GF_LOG_TRACE, "failed to get time left");
 1575 
 1576         if (elapsed > max_elapsed)
 1577             max_elapsed = elapsed;
 1578 
 1579         if (time_left > max_time)
 1580             max_time = time_left;
 1581 
 1582         /* Check for array bound */
 1583         if (status_rcd >= GF_DEFRAG_STATUS_MAX)
 1584             status_rcd = GF_DEFRAG_STATUS_MAX;
 1585 
 1586         status_str = cli_vol_task_status_str[status_rcd];
 1587         size_str = gf_uint64_2human_readable(size);
 1588         hrs = elapsed / 3600;
 1589         min = ((uint64_t)elapsed % 3600) / 60;
 1590         sec = ((uint64_t)elapsed % 3600) % 60;
 1591 
 1592         if (fix_layout) {
 1593             cli_out("%35s %50s %8d:%d:%d", node_name, status_str, hrs, min,
 1594                     sec);
 1595         } else {
 1596             if (size_str) {
 1597                 cli_out("%40s %16" PRIu64
 1598                         " %13s"
 1599                         " %13" PRIu64 " %13" PRIu64 " %13" PRIu64
 1600                         " %20s "
 1601                         "%8d:%02d:%02d",
 1602                         node_name, files, size_str, lookup, failures, skipped,
 1603                         status_str, hrs, min, sec);
 1604             } else {
 1605                 cli_out("%40s %16" PRIu64 " %13" PRIu64 " %13" PRIu64
 1606                         " %13" PRIu64 " %13" PRIu64
 1607                         " %20s"
 1608                         " %8d:%02d:%02d",
 1609                         node_name, files, size, lookup, failures, skipped,
 1610                         status_str, hrs, min, sec);
 1611             }
 1612         }
 1613         GF_FREE(size_str);
 1614     }
 1615 
 1616     /* Max time will be non-zero if rebalance is still running */
 1617     if (max_time) {
 1618         hrs = max_time / 3600;
 1619         min = (max_time % 3600) / 60;
 1620         sec = (max_time % 3600) % 60;
 1621 
 1622         if (hrs < REBAL_ESTIMATE_SEC_UPPER_LIMIT) {
 1623             cli_out(
 1624                 "Estimated time left for rebalance to "
 1625                 "complete : %8d:%02d:%02d",
 1626                 hrs, min, sec);
 1627         } else {
 1628             cli_out(
 1629                 "Estimated time left for rebalance to "
 1630                 "complete : > 2 months. Please try again "
 1631                 "later.");
 1632         }
 1633     } else {
 1634         /* Rebalance will return 0 if it could not calculate the
 1635          * estimates or if it is complete.
 1636          */
 1637         if (!show_estimates) {
 1638             goto out;
 1639         }
 1640         if (max_elapsed <= REBAL_ESTIMATE_START_TIME) {
 1641             cli_out(
 1642                 "The estimated time for rebalance to complete "
 1643                 "will be unavailable for the first 10 "
 1644                 "minutes.");
 1645         } else {
 1646             cli_out(
 1647                 "Rebalance estimated time unavailable. Please "
 1648                 "try again later.");
 1649         }
 1650     }
 1651 out:
 1652     return ret;
 1653 }
 1654 
 1655 static int
 1656 gf_cli_defrag_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1657                          void *myframe)
 1658 {
 1659     gf_cli_rsp rsp = {
 1660         0,
 1661     };
 1662     cli_local_t *local = NULL;
 1663     char *volname = NULL;
 1664     call_frame_t *frame = NULL;
 1665     int cmd = 0;
 1666     int ret = -1;
 1667     dict_t *dict = NULL;
 1668     char msg[1024] = {
 1669         0,
 1670     };
 1671     char *task_id_str = NULL;
 1672 
 1673     if (-1 == req->rpc_status) {
 1674         goto out;
 1675     }
 1676 
 1677     GF_ASSERT(myframe);
 1678 
 1679     frame = myframe;
 1680 
 1681     GF_ASSERT(frame->local);
 1682 
 1683     local = frame->local;
 1684 
 1685     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1686     if (ret < 0) {
 1687         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 1688         goto out;
 1689     }
 1690 
 1691     ret = dict_get_str_sizen(local->dict, "volname", &volname);
 1692     if (ret) {
 1693         gf_log(frame->this->name, GF_LOG_ERROR, "Failed to get volname");
 1694         goto out;
 1695     }
 1696 
 1697     ret = dict_get_int32_sizen(local->dict, "rebalance-command",
 1698                                (int32_t *)&cmd);
 1699     if (ret) {
 1700         gf_log("cli", GF_LOG_ERROR, "Failed to get command");
 1701         goto out;
 1702     }
 1703 
 1704     if (rsp.dict.dict_len) {
 1705         /* Unserialize the dictionary */
 1706         dict = dict_new();
 1707 
 1708         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 1709         if (ret < 0) {
 1710             gf_log("glusterd", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 1711             goto out;
 1712         }
 1713     }
 1714 
 1715     if (!((cmd == GF_DEFRAG_CMD_STOP) || (cmd == GF_DEFRAG_CMD_STATUS)) &&
 1716         !(global_state->mode & GLUSTER_MODE_XML)) {
 1717         ret = dict_get_str_sizen(dict, GF_REBALANCE_TID_KEY, &task_id_str);
 1718         if (ret) {
 1719             gf_log("cli", GF_LOG_WARNING, "failed to get %s from dict",
 1720                    GF_REBALANCE_TID_KEY);
 1721         }
 1722         if (rsp.op_ret && strcmp(rsp.op_errstr, "")) {
 1723             snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 1724         } else {
 1725             if (!rsp.op_ret) {
 1726                 /* append errstr in the cli msg for successful
 1727                  * case since unlock failures can be highlighted
 1728                  * event though rebalance command was successful
 1729                  */
 1730                 snprintf(msg, sizeof(msg),
 1731                          "Rebalance on %s has been "
 1732                          "started successfully. Use "
 1733                          "rebalance status command to"
 1734                          " check status of the "
 1735                          "rebalance process.\nID: %s",
 1736                          volname, task_id_str);
 1737             } else {
 1738                 snprintf(msg, sizeof(msg),
 1739                          "Starting rebalance on volume %s has "
 1740                          "been unsuccessful.",
 1741                          volname);
 1742             }
 1743         }
 1744         goto done;
 1745     }
 1746 
 1747     if (cmd == GF_DEFRAG_CMD_STOP) {
 1748         if (rsp.op_ret == -1) {
 1749             if (strcmp(rsp.op_errstr, ""))
 1750                 snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 1751             else
 1752                 snprintf(msg, sizeof(msg), "rebalance volume %s stop failed",
 1753                          volname);
 1754             goto done;
 1755         } else {
 1756             /* append errstr in the cli msg for successful case
 1757              * since unlock failures can be highlighted event though
 1758              * rebalance command was successful */
 1759             snprintf(msg, sizeof(msg),
 1760                      "rebalance process may be in the middle of a "
 1761                      "file migration.\nThe process will be fully "
 1762                      "stopped once the migration of the file is "
 1763                      "complete.\nPlease check rebalance process "
 1764                      "for completion before doing any further "
 1765                      "brick related tasks on the volume.\n%s",
 1766                      rsp.op_errstr);
 1767         }
 1768     }
 1769     if (cmd == GF_DEFRAG_CMD_STATUS) {
 1770         if (rsp.op_ret == -1) {
 1771             if (strcmp(rsp.op_errstr, ""))
 1772                 snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 1773             else
 1774                 snprintf(msg, sizeof(msg),
 1775                          "Failed to get the status of rebalance process");
 1776             goto done;
 1777         } else {
 1778             snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 1779         }
 1780     }
 1781 
 1782     if (global_state->mode & GLUSTER_MODE_XML) {
 1783         ret = cli_xml_output_vol_rebalance(cmd, dict, rsp.op_ret, rsp.op_errno,
 1784                                            rsp.op_errstr);
 1785         goto out;
 1786     }
 1787 
 1788     ret = gf_cli_print_rebalance_status(dict, GF_TASK_TYPE_REBALANCE);
 1789     if (ret)
 1790         gf_log("cli", GF_LOG_ERROR, "Failed to print rebalance status");
 1791 
 1792 done:
 1793     if (global_state->mode & GLUSTER_MODE_XML)
 1794         cli_xml_output_str("volRebalance", msg, rsp.op_ret, rsp.op_errno,
 1795                            rsp.op_errstr);
 1796     else {
 1797         if (rsp.op_ret)
 1798             cli_err("volume rebalance: %s: failed%s%s", volname,
 1799                     strlen(msg) ? ": " : "", msg);
 1800         else
 1801             cli_out("volume rebalance: %s: success%s%s", volname,
 1802                     strlen(msg) ? ": " : "", msg);
 1803     }
 1804     ret = rsp.op_ret;
 1805 
 1806 out:
 1807     gf_free_xdr_cli_rsp(rsp);
 1808     if (dict)
 1809         dict_unref(dict);
 1810     cli_cmd_broadcast_response(ret);
 1811     return ret;
 1812 }
 1813 
 1814 static int
 1815 gf_cli_rename_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1816                          void *myframe)
 1817 {
 1818     gf_cli_rsp rsp = {
 1819         0,
 1820     };
 1821     int ret = -1;
 1822     char msg[1024] = {
 1823         0,
 1824     };
 1825 
 1826     GF_ASSERT(myframe);
 1827 
 1828     if (-1 == req->rpc_status) {
 1829         goto out;
 1830     }
 1831 
 1832     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1833     if (ret < 0) {
 1834         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 1835                XDR_DECODE_FAIL);
 1836         goto out;
 1837     }
 1838 
 1839     gf_log("cli", GF_LOG_INFO, "Received resp to probe");
 1840     snprintf(msg, sizeof(msg), "Rename volume %s",
 1841              (rsp.op_ret) ? "unsuccessful" : "successful");
 1842 
 1843     if (global_state->mode & GLUSTER_MODE_XML) {
 1844         ret = cli_xml_output_str("volRename", msg, rsp.op_ret, rsp.op_errno,
 1845                                  rsp.op_errstr);
 1846         if (ret)
 1847             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1848         goto out;
 1849     }
 1850 
 1851     if (rsp.op_ret)
 1852         cli_err("volume rename: failed");
 1853     else
 1854         cli_out("volume rename: success");
 1855 
 1856     ret = rsp.op_ret;
 1857 
 1858 out:
 1859     cli_cmd_broadcast_response(ret);
 1860     gf_free_xdr_cli_rsp(rsp);
 1861     return ret;
 1862 }
 1863 
 1864 static int
 1865 gf_cli_reset_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1866                         void *myframe)
 1867 {
 1868     gf_cli_rsp rsp = {
 1869         0,
 1870     };
 1871     int ret = -1;
 1872     char msg[1024] = {
 1873         0,
 1874     };
 1875 
 1876     GF_ASSERT(myframe);
 1877 
 1878     if (-1 == req->rpc_status) {
 1879         goto out;
 1880     }
 1881 
 1882     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1883     if (ret < 0) {
 1884         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 1885                XDR_DECODE_FAIL);
 1886         goto out;
 1887     }
 1888 
 1889     gf_log("cli", GF_LOG_INFO, "Received resp to reset");
 1890 
 1891     if (strcmp(rsp.op_errstr, ""))
 1892         snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 1893     else
 1894         snprintf(msg, sizeof(msg), "reset volume %s",
 1895                  (rsp.op_ret) ? "unsuccessful" : "successful");
 1896 
 1897     if (global_state->mode & GLUSTER_MODE_XML) {
 1898         ret = cli_xml_output_str("volReset", msg, rsp.op_ret, rsp.op_errno,
 1899                                  rsp.op_errstr);
 1900         if (ret)
 1901             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 1902         goto out;
 1903     }
 1904 
 1905     if (rsp.op_ret)
 1906         cli_err("volume reset: failed: %s", msg);
 1907     else
 1908         cli_out("volume reset: success: %s", msg);
 1909 
 1910     ret = rsp.op_ret;
 1911 
 1912 out:
 1913     cli_cmd_broadcast_response(ret);
 1914     gf_free_xdr_cli_rsp(rsp);
 1915     return ret;
 1916 }
 1917 
 1918 static int
 1919 gf_cli_ganesha_cbk(struct rpc_req *req, struct iovec *iov, int count,
 1920                    void *myframe)
 1921 {
 1922     gf_cli_rsp rsp = {
 1923         0,
 1924     };
 1925     int ret = -1;
 1926     dict_t *dict = NULL;
 1927 
 1928     GF_ASSERT(myframe);
 1929 
 1930     if (-1 == req->rpc_status) {
 1931         goto out;
 1932     }
 1933 
 1934     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 1935     if (ret < 0) {
 1936         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 1937                XDR_DECODE_FAIL);
 1938         goto out;
 1939     }
 1940 
 1941     gf_log("cli", GF_LOG_DEBUG, "Received resp to ganesha");
 1942 
 1943     dict = dict_new();
 1944 
 1945     if (!dict) {
 1946         ret = -1;
 1947         goto out;
 1948     }
 1949 
 1950     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 1951     if (ret)
 1952         goto out;
 1953 
 1954     if (rsp.op_ret) {
 1955         if (strcmp(rsp.op_errstr, ""))
 1956             cli_err("nfs-ganesha: failed: %s", rsp.op_errstr);
 1957         else
 1958             cli_err("nfs-ganesha: failed");
 1959     }
 1960 
 1961     else {
 1962         cli_out("nfs-ganesha : success ");
 1963     }
 1964 
 1965     ret = rsp.op_ret;
 1966 
 1967 out:
 1968     if (dict)
 1969         dict_unref(dict);
 1970     cli_cmd_broadcast_response(ret);
 1971     return ret;
 1972 }
 1973 
 1974 static char *
 1975 is_server_debug_xlator(void *myframe)
 1976 {
 1977     call_frame_t *frame = NULL;
 1978     cli_local_t *local = NULL;
 1979     char **words = NULL;
 1980     char *key = NULL;
 1981     char *value = NULL;
 1982     char *debug_xlator = NULL;
 1983 
 1984     frame = myframe;
 1985     local = frame->local;
 1986     words = (char **)local->words;
 1987 
 1988     while (*words != NULL) {
 1989         if (strstr(*words, "trace") == NULL &&
 1990             strstr(*words, "error-gen") == NULL) {
 1991             words++;
 1992             continue;
 1993         }
 1994 
 1995         key = *words;
 1996         words++;
 1997         value = *words;
 1998         if (value == NULL)
 1999             break;
 2000         if (strstr(value, "client")) {
 2001             words++;
 2002             continue;
 2003         } else {
 2004             if (!(strstr(value, "posix") || strstr(value, "acl") ||
 2005                   strstr(value, "locks") || strstr(value, "io-threads") ||
 2006                   strstr(value, "marker") || strstr(value, "index"))) {
 2007                 words++;
 2008                 continue;
 2009             } else {
 2010                 debug_xlator = gf_strdup(key);
 2011                 break;
 2012             }
 2013         }
 2014     }
 2015 
 2016     return debug_xlator;
 2017 }
 2018 
 2019 static int
 2020 gf_cli_set_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2021                       void *myframe)
 2022 {
 2023     gf_cli_rsp rsp = {
 2024         0,
 2025     };
 2026     int ret = -1;
 2027     dict_t *dict = NULL;
 2028     char *help_str = NULL;
 2029     char msg[1024] = {
 2030         0,
 2031     };
 2032     char *debug_xlator = NULL;
 2033     char tmp_str[512] = {
 2034         0,
 2035     };
 2036 
 2037     GF_ASSERT(myframe);
 2038 
 2039     if (-1 == req->rpc_status) {
 2040         goto out;
 2041     }
 2042 
 2043     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2044     if (ret < 0) {
 2045         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 2046                XDR_DECODE_FAIL);
 2047         goto out;
 2048     }
 2049 
 2050     gf_log("cli", GF_LOG_INFO, "Received resp to set");
 2051 
 2052     dict = dict_new();
 2053 
 2054     if (!dict) {
 2055         ret = -1;
 2056         goto out;
 2057     }
 2058 
 2059     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 2060     if (ret) {
 2061         gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 2062         goto out;
 2063     }
 2064 
 2065     /* For brick processes graph change does not happen on the fly.
 2066      * The process has to be restarted. So this is a check from the
 2067      * volume set option such that if debug xlators such as trace/errorgen
 2068      * are provided in the set command, warn the user.
 2069      */
 2070     debug_xlator = is_server_debug_xlator(myframe);
 2071 
 2072     if (dict_get_str_sizen(dict, "help-str", &help_str) && !msg[0])
 2073         snprintf(msg, sizeof(msg), "Set volume %s",
 2074                  (rsp.op_ret) ? "unsuccessful" : "successful");
 2075     if (rsp.op_ret == 0 && debug_xlator) {
 2076         snprintf(tmp_str, sizeof(tmp_str),
 2077                  "\n%s translator has been "
 2078                  "added to the server volume file. Please restart the"
 2079                  " volume for enabling the translator",
 2080                  debug_xlator);
 2081     }
 2082 
 2083     if ((global_state->mode & GLUSTER_MODE_XML) && (help_str == NULL)) {
 2084         ret = cli_xml_output_str("volSet", msg, rsp.op_ret, rsp.op_errno,
 2085                                  rsp.op_errstr);
 2086         if (ret)
 2087             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2088         goto out;
 2089     }
 2090 
 2091     if (rsp.op_ret) {
 2092         if (strcmp(rsp.op_errstr, ""))
 2093             cli_err("volume set: failed: %s", rsp.op_errstr);
 2094         else
 2095             cli_err("volume set: failed");
 2096     } else {
 2097         if (help_str == NULL) {
 2098             if (debug_xlator == NULL)
 2099                 cli_out("volume set: success");
 2100             else
 2101                 cli_out("volume set: success%s", tmp_str);
 2102         } else {
 2103             cli_out("%s", help_str);
 2104         }
 2105     }
 2106 
 2107     ret = rsp.op_ret;
 2108 
 2109 out:
 2110     if (dict)
 2111         dict_unref(dict);
 2112     GF_FREE(debug_xlator);
 2113     cli_cmd_broadcast_response(ret);
 2114     gf_free_xdr_cli_rsp(rsp);
 2115     return ret;
 2116 }
 2117 
 2118 int
 2119 gf_cli_add_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2120                      void *myframe)
 2121 {
 2122     gf_cli_rsp rsp = {
 2123         0,
 2124     };
 2125     int ret = -1;
 2126     char msg[1024] = {
 2127         0,
 2128     };
 2129 
 2130     GF_ASSERT(myframe);
 2131 
 2132     if (-1 == req->rpc_status) {
 2133         goto out;
 2134     }
 2135 
 2136     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2137     if (ret < 0) {
 2138         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 2139                XDR_DECODE_FAIL);
 2140         goto out;
 2141     }
 2142 
 2143     gf_log("cli", GF_LOG_INFO, "Received resp to add brick");
 2144 
 2145     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 2146         snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 2147     else
 2148         snprintf(msg, sizeof(msg), "Add Brick %s",
 2149                  (rsp.op_ret) ? "unsuccessful" : "successful");
 2150 
 2151     if (global_state->mode & GLUSTER_MODE_XML) {
 2152         ret = cli_xml_output_str("volAddBrick", msg, rsp.op_ret, rsp.op_errno,
 2153                                  rsp.op_errstr);
 2154         if (ret)
 2155             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2156         goto out;
 2157     }
 2158 
 2159     if (rsp.op_ret)
 2160         cli_err("volume add-brick: failed: %s", rsp.op_errstr);
 2161     else
 2162         cli_out("volume add-brick: success");
 2163     ret = rsp.op_ret;
 2164 
 2165 out:
 2166     cli_cmd_broadcast_response(ret);
 2167     gf_free_xdr_cli_rsp(rsp);
 2168     return ret;
 2169 }
 2170 
 2171 static int
 2172 gf_cli3_remove_brick_status_cbk(struct rpc_req *req, struct iovec *iov,
 2173                                 int count, void *myframe)
 2174 {
 2175     gf_cli_rsp rsp = {
 2176         0,
 2177     };
 2178     int ret = -1;
 2179     dict_t *dict = NULL;
 2180     char msg[1024] = {
 2181         0,
 2182     };
 2183     int32_t command = 0;
 2184     gf1_op_commands cmd = GF_OP_CMD_NONE;
 2185     cli_local_t *local = NULL;
 2186     call_frame_t *frame = NULL;
 2187     const char *cmd_str;
 2188 
 2189     GF_ASSERT(myframe);
 2190 
 2191     if (-1 == req->rpc_status) {
 2192         goto out;
 2193     }
 2194 
 2195     frame = myframe;
 2196 
 2197     GF_ASSERT(frame->local);
 2198 
 2199     local = frame->local;
 2200 
 2201     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2202     if (ret < 0) {
 2203         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 2204         goto out;
 2205     }
 2206 
 2207     ret = dict_get_int32_sizen(local->dict, "command", &command);
 2208     if (ret)
 2209         goto out;
 2210 
 2211     cmd = command;
 2212 
 2213     switch (cmd) {
 2214         case GF_OP_CMD_STOP:
 2215             cmd_str = "stop";
 2216             break;
 2217         case GF_OP_CMD_STATUS:
 2218             cmd_str = "status";
 2219             break;
 2220         default:
 2221             cmd_str = "unknown";
 2222             break;
 2223     }
 2224 
 2225     ret = rsp.op_ret;
 2226     if (rsp.op_ret == -1) {
 2227         if (strcmp(rsp.op_errstr, ""))
 2228             snprintf(msg, sizeof(msg), "volume remove-brick %s: failed: %s",
 2229                      cmd_str, rsp.op_errstr);
 2230         else
 2231             snprintf(msg, sizeof(msg), "volume remove-brick %s: failed",
 2232                      cmd_str);
 2233 
 2234         if (global_state->mode & GLUSTER_MODE_XML)
 2235             goto xml_output;
 2236 
 2237         cli_err("%s", msg);
 2238         goto out;
 2239     }
 2240 
 2241     if (rsp.dict.dict_len) {
 2242         /* Unserialize the dictionary */
 2243         dict = dict_new();
 2244 
 2245         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 2246         if (ret < 0) {
 2247             strncpy(msg, DICT_UNSERIALIZE_FAIL, sizeof(msg));
 2248 
 2249             if (global_state->mode & GLUSTER_MODE_XML) {
 2250                 rsp.op_ret = -1;
 2251                 goto xml_output;
 2252             }
 2253 
 2254             gf_log("cli", GF_LOG_ERROR, "%s", msg);
 2255             goto out;
 2256         }
 2257     }
 2258 
 2259 xml_output:
 2260     if (global_state->mode & GLUSTER_MODE_XML) {
 2261         if (strcmp(rsp.op_errstr, "")) {
 2262             ret = cli_xml_output_vol_remove_brick(_gf_true, dict, rsp.op_ret,
 2263                                                   rsp.op_errno, rsp.op_errstr,
 2264                                                   "volRemoveBrick");
 2265         } else {
 2266             ret = cli_xml_output_vol_remove_brick(_gf_true, dict, rsp.op_ret,
 2267                                                   rsp.op_errno, msg,
 2268                                                   "volRemoveBrick");
 2269         }
 2270         goto out;
 2271     }
 2272 
 2273     ret = gf_cli_print_rebalance_status(dict, GF_TASK_TYPE_REMOVE_BRICK);
 2274     if (ret) {
 2275         gf_log("cli", GF_LOG_ERROR,
 2276                "Failed to print remove-brick rebalance status");
 2277         goto out;
 2278     }
 2279 
 2280     if ((cmd == GF_OP_CMD_STOP) && (rsp.op_ret == 0)) {
 2281         cli_out(
 2282             "'remove-brick' process may be in the middle of a "
 2283             "file migration.\nThe process will be fully stopped "
 2284             "once the migration of the file is complete.\nPlease "
 2285             "check remove-brick process for completion before "
 2286             "doing any further brick related tasks on the "
 2287             "volume.");
 2288     }
 2289 
 2290 out:
 2291     if (dict)
 2292         dict_unref(dict);
 2293     cli_cmd_broadcast_response(ret);
 2294     gf_free_xdr_cli_rsp(rsp);
 2295     return ret;
 2296 }
 2297 
 2298 static int
 2299 gf_cli_remove_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2300                         void *myframe)
 2301 {
 2302     gf_cli_rsp rsp = {
 2303         0,
 2304     };
 2305     int ret = -1;
 2306     char msg[1024] = {
 2307         0,
 2308     };
 2309     gf1_op_commands cmd = GF_OP_CMD_NONE;
 2310     char *cmd_str = "unknown";
 2311     cli_local_t *local = NULL;
 2312     call_frame_t *frame = NULL;
 2313     char *task_id_str = NULL;
 2314     dict_t *rsp_dict = NULL;
 2315 
 2316     GF_ASSERT(myframe);
 2317 
 2318     if (-1 == req->rpc_status) {
 2319         goto out;
 2320     }
 2321 
 2322     frame = myframe;
 2323 
 2324     GF_ASSERT(frame->local);
 2325 
 2326     local = frame->local;
 2327 
 2328     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2329     if (ret < 0) {
 2330         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 2331         goto out;
 2332     }
 2333 
 2334     ret = dict_get_int32_sizen(local->dict, "command", (int32_t *)&cmd);
 2335     if (ret) {
 2336         gf_log("", GF_LOG_ERROR, "failed to get command");
 2337         goto out;
 2338     }
 2339 
 2340     if (rsp.dict.dict_len) {
 2341         rsp_dict = dict_new();
 2342         if (!rsp_dict) {
 2343             ret = -1;
 2344             goto out;
 2345         }
 2346 
 2347         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &rsp_dict);
 2348         if (ret) {
 2349             gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 2350             goto out;
 2351         }
 2352     }
 2353 
 2354     switch (cmd) {
 2355         case GF_OP_CMD_DETACH_START:
 2356         case GF_OP_CMD_START:
 2357             cmd_str = "start";
 2358 
 2359             ret = dict_get_str_sizen(rsp_dict, GF_REMOVE_BRICK_TID_KEY,
 2360                                      &task_id_str);
 2361             if (ret) {
 2362                 gf_log("cli", GF_LOG_ERROR,
 2363                        "remove-brick-id is not present in dict");
 2364             }
 2365             break;
 2366         case GF_OP_CMD_COMMIT:
 2367             cmd_str = "commit";
 2368             break;
 2369         case GF_OP_CMD_COMMIT_FORCE:
 2370             cmd_str = "commit force";
 2371             break;
 2372         default:
 2373             cmd_str = "unknown";
 2374             break;
 2375     }
 2376 
 2377     gf_log("cli", GF_LOG_INFO, "Received resp to remove brick");
 2378 
 2379     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 2380         snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 2381     else
 2382         snprintf(msg, sizeof(msg), "Remove Brick %s %s", cmd_str,
 2383                  (rsp.op_ret) ? "unsuccessful" : "successful");
 2384 
 2385     if (global_state->mode & GLUSTER_MODE_XML) {
 2386         ret = cli_xml_output_vol_remove_brick(_gf_false, rsp_dict, rsp.op_ret,
 2387                                               rsp.op_errno, msg,
 2388                                               "volRemoveBrick");
 2389         if (ret)
 2390             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2391         goto out;
 2392     }
 2393 
 2394     if (rsp.op_ret) {
 2395         cli_err("volume remove-brick %s: failed: %s", cmd_str, msg);
 2396     } else {
 2397         cli_out("volume remove-brick %s: success", cmd_str);
 2398         if (GF_OP_CMD_START == cmd && task_id_str != NULL)
 2399             cli_out("ID: %s", task_id_str);
 2400         if (GF_OP_CMD_COMMIT == cmd)
 2401             cli_out(
 2402                 "Check the removed bricks to ensure all files "
 2403                 "are migrated.\nIf files with data are "
 2404                 "found on the brick path, copy them via a "
 2405                 "gluster mount point before re-purposing the "
 2406                 "removed brick. ");
 2407     }
 2408 
 2409     ret = rsp.op_ret;
 2410 
 2411 out:
 2412     cli_cmd_broadcast_response(ret);
 2413     gf_free_xdr_cli_rsp(rsp);
 2414 
 2415     if (rsp_dict)
 2416         dict_unref(rsp_dict);
 2417 
 2418     return ret;
 2419 }
 2420 
 2421 static int
 2422 gf_cli_reset_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2423                        void *myframe)
 2424 {
 2425     gf_cli_rsp rsp = {
 2426         0,
 2427     };
 2428     int ret = -1;
 2429     cli_local_t *local = NULL;
 2430     call_frame_t *frame = NULL;
 2431     const char *rb_operation_str = NULL;
 2432     dict_t *rsp_dict = NULL;
 2433     char msg[1024] = {
 2434         0,
 2435     };
 2436     char *reset_op = NULL;
 2437 
 2438     GF_ASSERT(myframe);
 2439 
 2440     if (-1 == req->rpc_status) {
 2441         goto out;
 2442     }
 2443 
 2444     frame = myframe;
 2445 
 2446     GF_ASSERT(frame->local);
 2447 
 2448     local = frame->local;
 2449 
 2450     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2451     if (ret < 0) {
 2452         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 2453         goto out;
 2454     }
 2455 
 2456     ret = dict_get_str_sizen(local->dict, "operation", &reset_op);
 2457     if (ret) {
 2458         gf_log(frame->this->name, GF_LOG_ERROR, "dict_get on operation failed");
 2459         goto out;
 2460     }
 2461 
 2462     if (strcmp(reset_op, "GF_RESET_OP_START") &&
 2463         strcmp(reset_op, "GF_RESET_OP_COMMIT") &&
 2464         strcmp(reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
 2465         ret = -1;
 2466         goto out;
 2467     }
 2468 
 2469     if (rsp.dict.dict_len) {
 2470         /* Unserialize the dictionary */
 2471         rsp_dict = dict_new();
 2472 
 2473         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &rsp_dict);
 2474         if (ret < 0) {
 2475             gf_log(frame->this->name, GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 2476             goto out;
 2477         }
 2478     }
 2479 
 2480     if (rsp.op_ret && (strcmp(rsp.op_errstr, ""))) {
 2481         rb_operation_str = rsp.op_errstr;
 2482     } else {
 2483         if (!strcmp(reset_op, "GF_RESET_OP_START")) {
 2484             if (rsp.op_ret)
 2485                 rb_operation_str = "reset-brick start operation failed";
 2486             else
 2487                 rb_operation_str = "reset-brick start operation successful";
 2488         } else if (!strcmp(reset_op, "GF_RESET_OP_COMMIT")) {
 2489             if (rsp.op_ret)
 2490                 rb_operation_str = "reset-brick commit operation failed";
 2491             else
 2492                 rb_operation_str = "reset-brick commit operation successful";
 2493         } else if (!strcmp(reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
 2494             if (rsp.op_ret)
 2495                 rb_operation_str = "reset-brick commit force operation failed";
 2496             else
 2497                 rb_operation_str =
 2498                     "reset-brick commit force operation successful";
 2499         }
 2500     }
 2501 
 2502     gf_log("cli", GF_LOG_INFO, "Received resp to reset brick");
 2503     snprintf(msg, sizeof(msg), "%s",
 2504              rb_operation_str ? rb_operation_str : "Unknown operation");
 2505 
 2506     if (global_state->mode & GLUSTER_MODE_XML) {
 2507         ret = cli_xml_output_vol_replace_brick(rsp_dict, rsp.op_ret,
 2508                                                rsp.op_errno, msg);
 2509         if (ret)
 2510             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2511         goto out;
 2512     }
 2513 
 2514     if (rsp.op_ret)
 2515         cli_err("volume reset-brick: failed: %s", msg);
 2516     else
 2517         cli_out("volume reset-brick: success: %s", msg);
 2518     ret = rsp.op_ret;
 2519 
 2520 out:
 2521     if (frame)
 2522         frame->local = NULL;
 2523 
 2524     if (local)
 2525         cli_local_wipe(local);
 2526 
 2527     cli_cmd_broadcast_response(ret);
 2528     gf_free_xdr_cli_rsp(rsp);
 2529     if (rsp_dict)
 2530         dict_unref(rsp_dict);
 2531 
 2532     return ret;
 2533 }
 2534 static int
 2535 gf_cli_replace_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2536                          void *myframe)
 2537 {
 2538     gf_cli_rsp rsp = {
 2539         0,
 2540     };
 2541     int ret = -1;
 2542     cli_local_t *local = NULL;
 2543     call_frame_t *frame = NULL;
 2544     const char *rb_operation_str = NULL;
 2545     dict_t *rsp_dict = NULL;
 2546     char msg[1024] = {
 2547         0,
 2548     };
 2549     char *replace_op = NULL;
 2550 
 2551     GF_ASSERT(myframe);
 2552 
 2553     if (-1 == req->rpc_status) {
 2554         goto out;
 2555     }
 2556 
 2557     frame = myframe;
 2558 
 2559     GF_ASSERT(frame->local);
 2560 
 2561     local = frame->local;
 2562 
 2563     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2564     if (ret < 0) {
 2565         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 2566         goto out;
 2567     }
 2568 
 2569     ret = dict_get_str_sizen(local->dict, "operation", &replace_op);
 2570     if (ret) {
 2571         gf_log(frame->this->name, GF_LOG_ERROR, "dict_get on operation failed");
 2572         goto out;
 2573     }
 2574 
 2575     if (rsp.dict.dict_len) {
 2576         /* Unserialize the dictionary */
 2577         rsp_dict = dict_new();
 2578 
 2579         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &rsp_dict);
 2580         if (ret < 0) {
 2581             gf_log(frame->this->name, GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 2582             goto out;
 2583         }
 2584     }
 2585 
 2586     if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
 2587         if (rsp.op_ret || ret)
 2588             rb_operation_str = "replace-brick commit force operation failed";
 2589         else
 2590             rb_operation_str =
 2591                 "replace-brick commit force operation successful";
 2592     } else {
 2593         gf_log(frame->this->name, GF_LOG_DEBUG, "Unknown operation");
 2594     }
 2595 
 2596     if (rsp.op_ret && (strcmp(rsp.op_errstr, ""))) {
 2597         rb_operation_str = rsp.op_errstr;
 2598     }
 2599 
 2600     gf_log("cli", GF_LOG_INFO, "Received resp to replace brick");
 2601     snprintf(msg, sizeof(msg), "%s",
 2602              rb_operation_str ? rb_operation_str : "Unknown operation");
 2603 
 2604     if (global_state->mode & GLUSTER_MODE_XML) {
 2605         ret = cli_xml_output_vol_replace_brick(rsp_dict, rsp.op_ret,
 2606                                                rsp.op_errno, msg);
 2607         if (ret)
 2608             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2609         goto out;
 2610     }
 2611 
 2612     if (rsp.op_ret)
 2613         cli_err("volume replace-brick: failed: %s", msg);
 2614     else
 2615         cli_out("volume replace-brick: success: %s", msg);
 2616     ret = rsp.op_ret;
 2617 
 2618 out:
 2619     if (frame)
 2620         frame->local = NULL;
 2621 
 2622     if (local)
 2623         cli_local_wipe(local);
 2624 
 2625     cli_cmd_broadcast_response(ret);
 2626     gf_free_xdr_cli_rsp(rsp);
 2627     if (rsp_dict)
 2628         dict_unref(rsp_dict);
 2629 
 2630     return ret;
 2631 }
 2632 
 2633 static int
 2634 gf_cli_log_rotate_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2635                       void *myframe)
 2636 {
 2637     gf_cli_rsp rsp = {
 2638         0,
 2639     };
 2640     int ret = -1;
 2641     char msg[1024] = {
 2642         0,
 2643     };
 2644 
 2645     GF_ASSERT(myframe);
 2646 
 2647     if (-1 == req->rpc_status) {
 2648         goto out;
 2649     }
 2650 
 2651     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2652     if (ret < 0) {
 2653         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 2654                XDR_DECODE_FAIL);
 2655         goto out;
 2656     }
 2657 
 2658     gf_log("cli", GF_LOG_DEBUG, "Received resp to log rotate");
 2659 
 2660     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 2661         snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
 2662     else
 2663         snprintf(msg, sizeof(msg), "log rotate %s",
 2664                  (rsp.op_ret) ? "unsuccessful" : "successful");
 2665 
 2666     if (global_state->mode & GLUSTER_MODE_XML) {
 2667         ret = cli_xml_output_str("volLogRotate", msg, rsp.op_ret, rsp.op_errno,
 2668                                  rsp.op_errstr);
 2669         if (ret)
 2670             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2671         goto out;
 2672     }
 2673 
 2674     if (rsp.op_ret)
 2675         cli_err("volume log-rotate: failed: %s", msg);
 2676     else
 2677         cli_out("volume log-rotate: success");
 2678     ret = rsp.op_ret;
 2679 
 2680 out:
 2681     cli_cmd_broadcast_response(ret);
 2682     gf_free_xdr_cli_rsp(rsp);
 2683 
 2684     return ret;
 2685 }
 2686 
 2687 static int
 2688 gf_cli_sync_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
 2689                        void *myframe)
 2690 {
 2691     gf_cli_rsp rsp = {
 2692         0,
 2693     };
 2694     int ret = -1;
 2695     char msg[1024] = {
 2696         0,
 2697     };
 2698 
 2699     GF_ASSERT(myframe);
 2700 
 2701     if (-1 == req->rpc_status) {
 2702         goto out;
 2703     }
 2704 
 2705     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 2706     if (ret < 0) {
 2707         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 2708                XDR_DECODE_FAIL);
 2709         goto out;
 2710     }
 2711 
 2712     gf_log("cli", GF_LOG_DEBUG, "Received resp to sync");
 2713 
 2714     if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
 2715         snprintf(msg, sizeof(msg), "volume sync: failed: %s", rsp.op_errstr);
 2716     else
 2717         snprintf(msg, sizeof(msg), "volume sync: %s",
 2718                  (rsp.op_ret) ? "failed" : "success");
 2719 
 2720     if (global_state->mode & GLUSTER_MODE_XML) {
 2721         ret = cli_xml_output_str("volSync", msg, rsp.op_ret, rsp.op_errno,
 2722                                  rsp.op_errstr);
 2723         if (ret)
 2724             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 2725         goto out;
 2726     }
 2727 
 2728     if (rsp.op_ret)
 2729         cli_err("%s", msg);
 2730     else
 2731         cli_out("%s", msg);
 2732     ret = rsp.op_ret;
 2733 
 2734 out:
 2735     cli_cmd_broadcast_response(ret);
 2736     gf_free_xdr_cli_rsp(rsp);
 2737     return ret;
 2738 }
 2739 
 2740 static int
 2741 print_quota_list_usage_output(cli_local_t *local, char *path, int64_t avail,
 2742                               char *sl_str, quota_limits_t *limits,
 2743                               quota_meta_t *used_space, gf_boolean_t sl,
 2744                               gf_boolean_t hl, double sl_num,
 2745                               gf_boolean_t limit_set)
 2746 {
 2747     int32_t ret = -1;
 2748     char *used_str = NULL;
 2749     char *avail_str = NULL;
 2750     char *hl_str = NULL;
 2751     char *sl_val = NULL;
 2752 
 2753     if (global_state->mode & GLUSTER_MODE_XML) {
 2754         ret = cli_quota_xml_output(local, path, limits->hl, sl_str, sl_num,
 2755                                    used_space->size, avail, sl ? "Yes" : "No",
 2756                                    hl ? "Yes" : "No", limit_set);
 2757         if (ret) {
 2758             gf_log("cli", GF_LOG_ERROR,
 2759                    "Failed to output in xml format for quota list command");
 2760         }
 2761         goto out;
 2762     }
 2763 
 2764     used_str = gf_uint64_2human_readable(used_space->size);
 2765 
 2766     if (limit_set) {
 2767         hl_str = gf_uint64_2human_readable(limits->hl);
 2768         sl_val = gf_uint64_2human_readable(sl_num);
 2769 
 2770         if (!used_str) {
 2771             cli_out("%-40s %7s %7s(%s) %8" PRIu64 "%9" PRIu64
 2772                     ""
 2773                     "%15s %18s",
 2774                     path, hl_str, sl_str, sl_val, used_space->size, avail,
 2775                     sl ? "Yes" : "No", hl ? "Yes" : "No");
 2776         } else {
 2777             avail_str = gf_uint64_2human_readable(avail);
 2778             cli_out("%-40s %7s %7s(%s) %8s %7s %15s %20s", path, hl_str, sl_str,
 2779                     sl_val, used_str, avail_str, sl ? "Yes" : "No",
 2780                     hl ? "Yes" : "No");
 2781         }
 2782     } else {
 2783         cli_out("%-36s %10s %10s %14s %9s %15s %18s", path, "N/A", "N/A",
 2784                 used_str, "N/A", "N/A", "N/A");
 2785     }
 2786 
 2787     ret = 0;
 2788 out:
 2789     GF_FREE(hl_str);
 2790     GF_FREE(used_str);
 2791     GF_FREE(avail_str);
 2792     GF_FREE(sl_val);
 2793 
 2794     return ret;
 2795 }
 2796 
 2797 static int
 2798 print_quota_list_object_output(cli_local_t *local, char *path, int64_t avail,
 2799                                char *sl_str, quota_limits_t *limits,
 2800                                quota_meta_t *used_space, gf_boolean_t sl,
 2801                                gf_boolean_t hl, double sl_num,
 2802                                gf_boolean_t limit_set)
 2803 {
 2804     int32_t ret = -1;
 2805     int64_t sl_val = sl_num;
 2806 
 2807     if (global_state->mode & GLUSTER_MODE_XML) {
 2808         ret = cli_quota_object_xml_output(local, path, sl_str, sl_val, limits,
 2809                                           used_space, avail, sl ? "Yes" : "No",
 2810                                           hl ? "Yes" : "No", limit_set);
 2811         if (ret) {
 2812             gf_log("cli", GF_LOG_ERROR,
 2813                    "Failed to output in xml format for quota list command");
 2814         }
 2815         goto out;
 2816     }
 2817 
 2818     if (limit_set) {
 2819         cli_out("%-40s %9" PRIu64 " %9s(%" PRId64 ") %10" PRIu64
 2820                 ""
 2821                 "%10" PRIu64 " %11" PRIu64 " %15s %20s",
 2822                 path, limits->hl, sl_str, sl_val, used_space->file_count,
 2823                 used_space->dir_count, avail, sl ? "Yes" : "No",
 2824                 hl ? "Yes" : "No");
 2825     } else {
 2826         cli_out("%-40s %9s %9s %10" PRIu64 " %10" PRIu64 " %11s %15s %20s",
 2827                 path, "N/A", "N/A", used_space->file_count,
 2828                 used_space->dir_count, "N/A", "N/A", "N/A");
 2829     }
 2830     ret = 0;
 2831 
 2832 out:
 2833 
 2834     return ret;
 2835 }
 2836 
 2837 static int
 2838 print_quota_list_output(cli_local_t *local, char *path, char *default_sl,
 2839                         quota_limits_t *limits, quota_meta_t *used_space,
 2840                         int type, gf_boolean_t limit_set)
 2841 {
 2842     int64_t avail = 0;
 2843     char percent_str[20] = {0};
 2844     char *sl_final = NULL;
 2845     int ret = -1;
 2846     double sl_num = 0;
 2847     gf_boolean_t sl = _gf_false;
 2848     gf_boolean_t hl = _gf_false;
 2849     int64_t used_size = 0;
 2850 
 2851     GF_ASSERT(local);
 2852     GF_ASSERT(path);
 2853 
 2854     if (limit_set) {
 2855         if (limits->sl < 0) {
 2856             ret = gf_string2percent(default_sl, &sl_num);
 2857             if (ret) {
 2858                 gf_log("cli", GF_LOG_ERROR,
 2859                        "could not convert default soft limit to percent");
 2860                 goto out;
 2861             }
 2862             sl_num = (sl_num * limits->hl) / 100;
 2863             sl_final = default_sl;
 2864         } else {
 2865             sl_num = (limits->sl * limits->hl) / 100;
 2866             ret = snprintf(percent_str, sizeof(percent_str), "%" PRIu64 "%%",
 2867                            limits->sl);
 2868             if (ret < 0)
 2869                 goto out;
 2870             sl_final = percent_str;
 2871         }
 2872         if (type == GF_QUOTA_OPTION_TYPE_LIST)
 2873             used_size = used_space->size;
 2874         else
 2875             used_size = used_space->file_count + used_space->dir_count;
 2876 
 2877         if (limits->hl > used_size) {
 2878             avail = limits->hl - used_size;
 2879             hl = _gf_false;
 2880             if (used_size > sl_num)
 2881                 sl = _gf_true;
 2882             else
 2883                 sl = _gf_false;
 2884         } else {
 2885             avail = 0;
 2886             hl = sl = _gf_true;
 2887         }
 2888     }
 2889 
 2890     if (type == GF_QUOTA_OPTION_TYPE_LIST)
 2891         ret = print_quota_list_usage_output(local, path, avail, sl_final,
 2892                                             limits, used_space, sl, hl, sl_num,
 2893                                             limit_set);
 2894     else
 2895         ret = print_quota_list_object_output(local, path, avail, sl_final,
 2896                                              limits, used_space, sl, hl, sl_num,
 2897                                              limit_set);
 2898 out:
 2899     return ret;
 2900 }
 2901 
 2902 static int
 2903 print_quota_list_from_mountdir(cli_local_t *local, char *mountdir,
 2904                                char *default_sl, char *path, int type)
 2905 {
 2906     int ret = -1;
 2907     ssize_t xattr_size = 0;
 2908     quota_limits_t limits = {
 2909         0,
 2910     };
 2911     quota_meta_t used_space = {
 2912         0,
 2913     };
 2914     char *key = NULL;
 2915     gf_boolean_t limit_set = _gf_true;
 2916 
 2917     GF_ASSERT(local);
 2918     GF_ASSERT(mountdir);
 2919     GF_ASSERT(path);
 2920 
 2921     if (type == GF_QUOTA_OPTION_TYPE_LIST)
 2922         key = QUOTA_LIMIT_KEY;
 2923     else
 2924         key = QUOTA_LIMIT_OBJECTS_KEY;
 2925 
 2926     ret = sys_lgetxattr(mountdir, key, (void *)&limits, sizeof(limits));
 2927     if (ret < 0) {
 2928         gf_log("cli", GF_LOG_ERROR,
 2929                "Failed to get the xattr %s on %s. Reason : %s", key, mountdir,
 2930                strerror(errno));
 2931 
 2932         switch (errno) {
 2933 #if defined(ENODATA)
 2934             case ENODATA:
 2935 #endif
 2936 #if defined(ENOATTR) && (ENOATTR != ENODATA)
 2937             case ENOATTR:
 2938 #endif
 2939                 /* If it's an ENOATTR, quota/inode-quota is
 2940                  * configured(limit is set at least for one directory).
 2941                  * The user is trying to issue 'list/list-objects'
 2942                  * command for a directory on which quota limit is
 2943                  * not set and we are showing the used-space in case
 2944                  * of list-usage and showing (dir_count, file_count)
 2945                  * in case of list-objects. Other labels are
 2946                  * shown "N/A".
 2947                  */
 2948 
 2949                 limit_set = _gf_false;
 2950                 goto enoattr;
 2951                 break;
 2952 
 2953             default:
 2954                 cli_err("%-40s %s", path, strerror(errno));
 2955                 break;
 2956         }
 2957 
 2958         goto out;
 2959     }
 2960 
 2961     limits.hl = ntoh64(limits.hl);
 2962     limits.sl = ntoh64(limits.sl);
 2963 
 2964 enoattr:
 2965     xattr_size = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, NULL, 0);
 2966     if (xattr_size < (sizeof(int64_t) * 2) &&
 2967         type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) {
 2968         ret = -1;
 2969 
 2970         /* This can happen when glusterfs is upgraded from 3.6 to 3.7
 2971          * and the xattr healing is not completed.
 2972          */
 2973     } else if (xattr_size > (sizeof(int64_t) * 2)) {
 2974         ret = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, &used_space,
 2975                             sizeof(used_space));
 2976     } else if (xattr_size > 0) {
 2977         /* This is for compatibility.
 2978          * Older version had only file usage
 2979          */
 2980         ret = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, &(used_space.size),
 2981                             sizeof(used_space.size));
 2982         used_space.file_count = 0;
 2983         used_space.dir_count = 0;
 2984     } else {
 2985         ret = -1;
 2986     }
 2987 
 2988     if (ret < 0) {
 2989         gf_log("cli", GF_LOG_ERROR, "Failed to get quota size on path %s: %s",
 2990                mountdir, strerror(errno));
 2991         print_quota_list_empty(path, type);
 2992         goto out;
 2993     }
 2994 
 2995     used_space.size = ntoh64(used_space.size);
 2996     used_space.file_count = ntoh64(used_space.file_count);
 2997     used_space.dir_count = ntoh64(used_space.dir_count);
 2998 
 2999     ret = print_quota_list_output(local, path, default_sl, &limits, &used_space,
 3000                                   type, limit_set);
 3001 out:
 3002     return ret;
 3003 }
 3004 
 3005 static int
 3006 gluster_remove_auxiliary_mount(char *volname)
 3007 {
 3008     int ret = -1;
 3009     char mountdir[PATH_MAX] = {
 3010         0,
 3011     };
 3012     xlator_t *this = NULL;
 3013 
 3014     this = THIS;
 3015     GF_ASSERT(this);
 3016 
 3017     GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(mountdir, volname, "/");
 3018     ret = gf_umount_lazy(this->name, mountdir, 1);
 3019     if (ret) {
 3020         gf_log("cli", GF_LOG_ERROR, "umount on %s failed, reason : %s",
 3021                mountdir, strerror(errno));
 3022     }
 3023 
 3024     return ret;
 3025 }
 3026 
 3027 static int
 3028 gf_cli_print_limit_list_from_dict(cli_local_t *local, char *volname,
 3029                                   dict_t *dict, char *default_sl, int count,
 3030                                   int op_ret, int op_errno, char *op_errstr)
 3031 {
 3032     int ret = -1;
 3033     int i = 0;
 3034     char key[32] = {
 3035         0,
 3036     };
 3037     int keylen;
 3038     char mountdir[PATH_MAX] = {
 3039         0,
 3040     };
 3041     char *path = NULL;
 3042     int type = -1;
 3043 
 3044     if (!dict || count <= 0)
 3045         goto out;
 3046 
 3047     ret = dict_get_int32_sizen(dict, "type", &type);
 3048     if (ret) {
 3049         gf_log("cli", GF_LOG_ERROR, "Failed to get quota type");
 3050         goto out;
 3051     }
 3052 
 3053     if (global_state->mode & GLUSTER_MODE_XML) {
 3054         ret = cli_xml_output_vol_quota_limit_list_begin(local, op_ret, op_errno,
 3055                                                         op_errstr);
 3056         if (ret) {
 3057             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3058             goto out;
 3059         }
 3060     } else {
 3061         print_quota_list_header(type);
 3062     }
 3063 
 3064     while (count--) {
 3065         keylen = snprintf(key, sizeof(key), "path%d", i++);
 3066 
 3067         ret = dict_get_strn(dict, key, keylen, &path);
 3068         if (ret < 0) {
 3069             gf_log("cli", GF_LOG_DEBUG, "Path not present in limit list");
 3070             continue;
 3071         }
 3072 
 3073         ret = gf_canonicalize_path(path);
 3074         if (ret)
 3075             goto out;
 3076         GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(mountdir, volname, path);
 3077         ret = print_quota_list_from_mountdir(local, mountdir, default_sl, path,
 3078                                              type);
 3079     }
 3080 
 3081 out:
 3082     return ret;
 3083 }
 3084 
 3085 static int
 3086 print_quota_list_from_quotad(call_frame_t *frame, dict_t *rsp_dict)
 3087 {
 3088     char *path = NULL;
 3089     char *default_sl = NULL;
 3090     int ret = -1;
 3091     cli_local_t *local = NULL;
 3092     dict_t *gd_rsp_dict = NULL;
 3093     quota_meta_t used_space = {
 3094         0,
 3095     };
 3096     quota_limits_t limits = {
 3097         0,
 3098     };
 3099     quota_limits_t *size_limits = NULL;
 3100     int32_t type = 0;
 3101     int32_t success_count = 0;
 3102 
 3103     GF_ASSERT(frame);
 3104 
 3105     local = frame->local;
 3106     gd_rsp_dict = local->dict;
 3107 
 3108     ret = dict_get_int32_sizen(rsp_dict, "type", &type);
 3109     if (ret) {
 3110         gf_log("cli", GF_LOG_ERROR, "Failed to get type");
 3111         goto out;
 3112     }
 3113 
 3114     ret = dict_get_str_sizen(rsp_dict, GET_ANCESTRY_PATH_KEY, &path);
 3115     if (ret) {
 3116         gf_log("cli", GF_LOG_WARNING, "path key is not present in dict");
 3117         goto out;
 3118     }
 3119 
 3120     ret = dict_get_str_sizen(gd_rsp_dict, "default-soft-limit", &default_sl);
 3121     if (ret) {
 3122         gf_log(frame->this->name, GF_LOG_ERROR,
 3123                "failed to get default soft limit");
 3124         goto out;
 3125     }
 3126 
 3127     if (type == GF_QUOTA_OPTION_TYPE_LIST) {
 3128         ret = dict_get_bin(rsp_dict, QUOTA_LIMIT_KEY, (void **)&size_limits);
 3129         if (ret) {
 3130             gf_log("cli", GF_LOG_WARNING, "limit key not present in dict on %s",
 3131                    path);
 3132             goto out;
 3133         }
 3134     } else {
 3135         ret = dict_get_bin(rsp_dict, QUOTA_LIMIT_OBJECTS_KEY,
 3136                            (void **)&size_limits);
 3137         if (ret) {
 3138             gf_log("cli", GF_LOG_WARNING,
 3139                    "object limit key not present in dict on %s", path);
 3140             goto out;
 3141         }
 3142     }
 3143 
 3144     limits.hl = ntoh64(size_limits->hl);
 3145     limits.sl = ntoh64(size_limits->sl);
 3146 
 3147     if (type == GF_QUOTA_OPTION_TYPE_LIST)
 3148         ret = quota_dict_get_meta(rsp_dict, QUOTA_SIZE_KEY,
 3149                                   SLEN(QUOTA_SIZE_KEY), &used_space);
 3150     else
 3151         ret = quota_dict_get_inode_meta(rsp_dict, QUOTA_SIZE_KEY,
 3152                                         SLEN(QUOTA_SIZE_KEY), &used_space);
 3153 
 3154     if (ret < 0) {
 3155         gf_log("cli", GF_LOG_WARNING, "size key not present in dict");
 3156         print_quota_list_empty(path, type);
 3157         goto out;
 3158     }
 3159 
 3160     LOCK(&local->lock);
 3161     {
 3162         ret = dict_get_int32_sizen(gd_rsp_dict, "quota-list-success-count",
 3163                                    &success_count);
 3164         if (ret)
 3165             success_count = 0;
 3166 
 3167         ret = dict_set_int32_sizen(gd_rsp_dict, "quota-list-success-count",
 3168                                    success_count + 1);
 3169     }
 3170     UNLOCK(&local->lock);
 3171     if (ret) {
 3172         gf_log("cli", GF_LOG_ERROR,
 3173                "Failed to set quota-list-success-count in dict");
 3174         goto out;
 3175     }
 3176 
 3177     if (success_count == 0) {
 3178         if (!(global_state->mode & GLUSTER_MODE_XML)) {
 3179             print_quota_list_header(type);
 3180         } else {
 3181             ret = cli_xml_output_vol_quota_limit_list_begin(local, 0, 0, NULL);
 3182             if (ret) {
 3183                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3184                 goto out;
 3185             }
 3186         }
 3187     }
 3188 
 3189     ret = print_quota_list_output(local, path, default_sl, &limits, &used_space,
 3190                                   type, _gf_true);
 3191 out:
 3192     return ret;
 3193 }
 3194 
 3195 static void *
 3196 cli_cmd_broadcast_response_detached(void *opaque)
 3197 {
 3198     int32_t ret = 0;
 3199 
 3200     ret = (intptr_t)opaque;
 3201     cli_cmd_broadcast_response(ret);
 3202 
 3203     return NULL;
 3204 }
 3205 
 3206 static int32_t
 3207 cli_quota_compare_path(struct list_head *list1, struct list_head *list2)
 3208 {
 3209     struct list_node *node1 = NULL;
 3210     struct list_node *node2 = NULL;
 3211     dict_t *dict1 = NULL;
 3212     dict_t *dict2 = NULL;
 3213     char *path1 = NULL;
 3214     char *path2 = NULL;
 3215     int ret = 0;
 3216 
 3217     node1 = list_entry(list1, struct list_node, list);
 3218     node2 = list_entry(list2, struct list_node, list);
 3219 
 3220     dict1 = node1->ptr;
 3221     dict2 = node2->ptr;
 3222 
 3223     ret = dict_get_str_sizen(dict1, GET_ANCESTRY_PATH_KEY, &path1);
 3224     if (ret < 0)
 3225         return 0;
 3226 
 3227     ret = dict_get_str_sizen(dict2, GET_ANCESTRY_PATH_KEY, &path2);
 3228     if (ret < 0)
 3229         return 0;
 3230 
 3231     return strcmp(path1, path2);
 3232 }
 3233 
 3234 static int
 3235 cli_quotad_getlimit_cbk(struct rpc_req *req, struct iovec *iov, int count,
 3236                         void *myframe)
 3237 {
 3238     /*TODO: we need to gather the path, hard-limit, soft-limit and used space*/
 3239     gf_cli_rsp rsp = {
 3240         0,
 3241     };
 3242     int ret = -1;
 3243     dict_t *dict = NULL;
 3244     struct list_node *node = NULL;
 3245     struct list_node *tmpnode = NULL;
 3246     call_frame_t *frame = NULL;
 3247     cli_local_t *local = NULL;
 3248     int32_t list_count = 0;
 3249     pthread_t th_id = {
 3250         0,
 3251     };
 3252     int32_t max_count = 0;
 3253 
 3254     GF_ASSERT(myframe);
 3255 
 3256     frame = myframe;
 3257 
 3258     GF_ASSERT(frame->local);
 3259 
 3260     local = frame->local;
 3261 
 3262     LOCK(&local->lock);
 3263     {
 3264         ret = dict_get_int32_sizen(local->dict, "quota-list-count",
 3265                                    &list_count);
 3266         if (ret)
 3267             list_count = 0;
 3268 
 3269         list_count++;
 3270         ret = dict_set_int32_sizen(local->dict, "quota-list-count", list_count);
 3271     }
 3272     UNLOCK(&local->lock);
 3273 
 3274     if (ret) {
 3275         gf_log("cli", GF_LOG_ERROR, "Failed to set quota-list-count in dict");
 3276         goto out;
 3277     }
 3278 
 3279     if (-1 == req->rpc_status) {
 3280         if (list_count == 0)
 3281             cli_err(
 3282                 "Connection failed. Please check if quota "
 3283                 "daemon is operational.");
 3284         ret = -1;
 3285         goto out;
 3286     }
 3287 
 3288     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 3289     if (ret < 0) {
 3290         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 3291         goto out;
 3292     }
 3293 
 3294     if (rsp.op_ret) {
 3295         ret = -1;
 3296         if (strcmp(rsp.op_errstr, ""))
 3297             cli_err("quota command failed : %s", rsp.op_errstr);
 3298         else
 3299             cli_err("quota command : failed");
 3300         goto out;
 3301     }
 3302 
 3303     if (rsp.dict.dict_len) {
 3304         /* Unserialize the dictionary */
 3305         dict = dict_new();
 3306 
 3307         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 3308         if (ret < 0) {
 3309             gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 3310             goto out;
 3311         }
 3312 
 3313         node = list_node_add_order(dict, &local->dict_list,
 3314                                    cli_quota_compare_path);
 3315         if (node == NULL) {
 3316             gf_log("cli", GF_LOG_ERROR, "failed to add node to the list");
 3317             dict_unref(dict);
 3318             ret = -1;
 3319             goto out;
 3320         }
 3321     }
 3322 
 3323     ret = dict_get_int32_sizen(local->dict, "max_count", &max_count);
 3324     if (ret < 0) {
 3325         gf_log("cli", GF_LOG_ERROR, "failed to get max_count");
 3326         goto out;
 3327     }
 3328 
 3329     if (list_count == max_count) {
 3330         list_for_each_entry_safe(node, tmpnode, &local->dict_list, list)
 3331         {
 3332             dict = node->ptr;
 3333             print_quota_list_from_quotad(frame, dict);
 3334             list_node_del(node);
 3335             dict_unref(dict);
 3336         }
 3337     }
 3338 
 3339 out:
 3340     /* Bad Fix: CLI holds the lock to process a command.
 3341      * When processing quota list command, below sequence of steps executed
 3342      * in the same thread and causing deadlock
 3343      *
 3344      * 1) CLI holds the lock
 3345      * 2) Send rpc_clnt_submit request to quotad for quota usage
 3346      * 3) If quotad is down, rpc_clnt_submit invokes cbk function with error
 3347      * 4) cbk function cli_quotad_getlimit_cbk invokes
 3348      *    cli_cmd_broadcast_response which tries to hold lock to broadcast
 3349      *    the results and hangs, because same thread has already holding
 3350      *    the lock
 3351      *
 3352      * Broadcasting response in a separate thread which is not a
 3353      * good fix. This needs to be re-visted with better solution
 3354      */
 3355     if (ret == -1) {
 3356         ret = pthread_create(&th_id, NULL, cli_cmd_broadcast_response_detached,
 3357                              (void *)-1);
 3358         if (ret)
 3359             gf_log("cli", GF_LOG_ERROR, "pthread_create failed: %s",
 3360                    strerror(errno));
 3361     } else {
 3362         cli_cmd_broadcast_response(ret);
 3363     }
 3364     gf_free_xdr_cli_rsp(rsp);
 3365 
 3366     return ret;
 3367 }
 3368 
 3369 static int
 3370 cli_quotad_getlimit(call_frame_t *frame, xlator_t *this, void *data)
 3371 {
 3372     gf_cli_req req = {{
 3373         0,
 3374     }};
 3375     int ret = 0;
 3376     dict_t *dict = NULL;
 3377 
 3378     if (!frame || !this || !data) {
 3379         ret = -1;
 3380         goto out;
 3381     }
 3382 
 3383     dict = data;
 3384     ret = add_cli_cmd_timeout_to_dict(dict);
 3385 
 3386     ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
 3387                                       &req.dict.dict_len);
 3388     if (ret < 0) {
 3389         gf_log(this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
 3390 
 3391         goto out;
 3392     }
 3393 
 3394     ret = cli_cmd_submit(global_quotad_rpc, &req, frame, &cli_quotad_clnt,
 3395                          GF_AGGREGATOR_GETLIMIT, NULL, this,
 3396                          cli_quotad_getlimit_cbk, (xdrproc_t)xdr_gf_cli_req);
 3397 
 3398 out:
 3399     GF_FREE(req.dict.dict_val);
 3400     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3401     return ret;
 3402 }
 3403 
 3404 static void
 3405 gf_cli_quota_list(cli_local_t *local, char *volname, dict_t *dict,
 3406                   char *default_sl, int count, int op_ret, int op_errno,
 3407                   char *op_errstr)
 3408 {
 3409     if (!connected)
 3410         goto out;
 3411 
 3412     if (count > 0) {
 3413         GF_VALIDATE_OR_GOTO("cli", volname, out);
 3414 
 3415         gf_cli_print_limit_list_from_dict(local, volname, dict, default_sl,
 3416                                           count, op_ret, op_errno, op_errstr);
 3417     }
 3418 out:
 3419     return;
 3420 }
 3421 
 3422 static int
 3423 gf_cli_quota_cbk(struct rpc_req *req, struct iovec *iov, int count,
 3424                  void *myframe)
 3425 {
 3426     gf_cli_rsp rsp = {
 3427         0,
 3428     };
 3429     int ret = -1;
 3430     dict_t *dict = NULL;
 3431     char *volname = NULL;
 3432     int32_t type = 0;
 3433     call_frame_t *frame = NULL;
 3434     char *default_sl = NULL;
 3435     cli_local_t *local = NULL;
 3436     char *default_sl_dup = NULL;
 3437     int32_t entry_count = 0;
 3438 
 3439     GF_ASSERT(myframe);
 3440 
 3441     if (-1 == req->rpc_status) {
 3442         goto out;
 3443     }
 3444 
 3445     frame = myframe;
 3446 
 3447     GF_ASSERT(frame->local);
 3448 
 3449     local = frame->local;
 3450 
 3451     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 3452     if (ret < 0) {
 3453         gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
 3454         goto out;
 3455     }
 3456 
 3457     if (rsp.op_ret) {
 3458         ret = -1;
 3459         if (global_state->mode & GLUSTER_MODE_XML)
 3460             goto xml_output;
 3461 
 3462         if (strcmp(rsp.op_errstr, "")) {
 3463             cli_err("quota command failed : %s", rsp.op_errstr);
 3464             if (rsp.op_ret == -ENOENT)
 3465                 cli_err("please enter the path relative to the volume");
 3466         } else {
 3467             cli_err("quota command : failed");
 3468         }
 3469 
 3470         goto out;
 3471     }
 3472 
 3473     if (rsp.dict.dict_len) {
 3474         /* Unserialize the dictionary */
 3475         dict = dict_new();
 3476 
 3477         ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 3478         if (ret < 0) {
 3479             gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
 3480             goto out;
 3481         }
 3482     }
 3483 
 3484     gf_log("cli", GF_LOG_DEBUG, "Received resp to quota command");
 3485 
 3486     ret = dict_get_str_sizen(dict, "default-soft-limit", &default_sl);
 3487     if (ret)
 3488         gf_log(frame->this->name, GF_LOG_TRACE,
 3489                "failed to get default soft limit");
 3490 
 3491     // default-soft-limit is part of rsp_dict only iff we sent
 3492     // GLUSTER_CLI_QUOTA with type being GF_QUOTA_OPTION_TYPE_LIST
 3493     if (default_sl) {
 3494         default_sl_dup = gf_strdup(default_sl);
 3495         if (!default_sl_dup) {
 3496             ret = -1;
 3497             goto out;
 3498         }
 3499         ret = dict_set_dynstr_sizen(local->dict, "default-soft-limit",
 3500                                     default_sl_dup);
 3501         if (ret) {
 3502             gf_log(frame->this->name, GF_LOG_TRACE,
 3503                    "failed to set default soft limit");
 3504             GF_FREE(default_sl_dup);
 3505         }
 3506     }
 3507 
 3508     ret = dict_get_str_sizen(dict, "volname", &volname);
 3509     if (ret)
 3510         gf_log(frame->this->name, GF_LOG_ERROR, "failed to get volname");
 3511 
 3512     ret = dict_get_int32_sizen(dict, "type", &type);
 3513     if (ret)
 3514         gf_log(frame->this->name, GF_LOG_TRACE, "failed to get type");
 3515 
 3516     ret = dict_get_int32_sizen(dict, "count", &entry_count);
 3517     if (ret)
 3518         gf_log(frame->this->name, GF_LOG_TRACE, "failed to get count");
 3519 
 3520     if ((type == GF_QUOTA_OPTION_TYPE_LIST) ||
 3521         (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
 3522         gf_cli_quota_list(local, volname, dict, default_sl, entry_count,
 3523                           rsp.op_ret, rsp.op_errno, rsp.op_errstr);
 3524 
 3525         if (global_state->mode & GLUSTER_MODE_XML) {
 3526             ret = cli_xml_output_vol_quota_limit_list_end(local);
 3527             if (ret < 0) {
 3528                 ret = -1;
 3529                 gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3530             }
 3531             goto out;
 3532         }
 3533     }
 3534 
 3535 xml_output:
 3536 
 3537     if (global_state->mode & GLUSTER_MODE_XML) {
 3538         ret = cli_xml_output_str("volQuota", NULL, rsp.op_ret, rsp.op_errno,
 3539                                  rsp.op_errstr);
 3540         if (ret)
 3541             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3542         goto out;
 3543     }
 3544 
 3545     if (!rsp.op_ret && type != GF_QUOTA_OPTION_TYPE_LIST &&
 3546         type != GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)
 3547         cli_out("volume quota : success");
 3548 
 3549     ret = rsp.op_ret;
 3550 out:
 3551 
 3552     if ((type == GF_QUOTA_OPTION_TYPE_LIST) ||
 3553         (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
 3554         gluster_remove_auxiliary_mount(volname);
 3555     }
 3556 
 3557     cli_cmd_broadcast_response(ret);
 3558     if (dict)
 3559         dict_unref(dict);
 3560 
 3561     gf_free_xdr_cli_rsp(rsp);
 3562 
 3563     return ret;
 3564 }
 3565 
 3566 static int
 3567 gf_cli_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count,
 3568                    void *myframe)
 3569 {
 3570     gf_getspec_rsp rsp = {
 3571         0,
 3572     };
 3573     int ret = -1;
 3574     char *spec = NULL;
 3575 
 3576     GF_ASSERT(myframe);
 3577 
 3578     if (-1 == req->rpc_status) {
 3579         goto out;
 3580     }
 3581 
 3582     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
 3583     if (ret < 0) {
 3584         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 3585                XDR_DECODE_FAIL);
 3586         goto out;
 3587     }
 3588 
 3589     if (rsp.op_ret == -1) {
 3590         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 3591                "getspec failed");
 3592         ret = -1;
 3593         goto out;
 3594     }
 3595 
 3596     gf_log("cli", GF_LOG_INFO, "Received resp to getspec");
 3597 
 3598     spec = GF_MALLOC(rsp.op_ret + 1, cli_mt_char);
 3599     if (!spec) {
 3600         gf_log("", GF_LOG_ERROR, "out of memory");
 3601         ret = -1;
 3602         goto out;
 3603     }
 3604     memcpy(spec, rsp.spec, rsp.op_ret);
 3605     spec[rsp.op_ret] = '\0';
 3606     cli_out("%s", spec);
 3607     GF_FREE(spec);
 3608 
 3609     ret = 0;
 3610 
 3611 out:
 3612     cli_cmd_broadcast_response(ret);
 3613     gf_free_xdr_getspec_rsp(rsp);
 3614     return ret;
 3615 }
 3616 
 3617 static int
 3618 gf_cli_pmap_b2p_cbk(struct rpc_req *req, struct iovec *iov, int count,
 3619                     void *myframe)
 3620 {
 3621     pmap_port_by_brick_rsp rsp = {
 3622         0,
 3623     };
 3624     int ret = -1;
 3625     char *spec = NULL;
 3626 
 3627     GF_ASSERT(myframe);
 3628 
 3629     if (-1 == req->rpc_status) {
 3630         goto out;
 3631     }
 3632 
 3633     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
 3634     if (ret < 0) {
 3635         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 3636                XDR_DECODE_FAIL);
 3637         goto out;
 3638     }
 3639 
 3640     if (rsp.op_ret == -1) {
 3641         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 3642                "pump_b2p failed");
 3643         ret = -1;
 3644         goto out;
 3645     }
 3646 
 3647     gf_log("cli", GF_LOG_INFO, "Received resp to pmap b2p");
 3648 
 3649     cli_out("%d", rsp.port);
 3650     GF_FREE(spec);
 3651 
 3652     ret = rsp.op_ret;
 3653 
 3654 out:
 3655     cli_cmd_broadcast_response(ret);
 3656     return ret;
 3657 }
 3658 
 3659 static int32_t
 3660 gf_cli_probe(call_frame_t *frame, xlator_t *this, void *data)
 3661 {
 3662     gf_cli_req req = {
 3663         {
 3664             0,
 3665         },
 3666     };
 3667     int ret = 0;
 3668     dict_t *dict = NULL;
 3669     int port = 0;
 3670 
 3671     if (!frame || !this || !data) {
 3672         ret = -1;
 3673         goto out;
 3674     }
 3675 
 3676     dict = data;
 3677 
 3678     ret = dict_get_int32_sizen(dict, "port", &port);
 3679     if (ret) {
 3680         ret = dict_set_int32_sizen(dict, "port", CLI_GLUSTERD_PORT);
 3681         if (ret)
 3682             goto out;
 3683     }
 3684 
 3685     ret = cli_to_glusterd(&req, frame, gf_cli_probe_cbk,
 3686                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_PROBE,
 3687                           this, cli_rpc_prog, NULL);
 3688 
 3689 out:
 3690     GF_FREE(req.dict.dict_val);
 3691     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3692 
 3693     return ret;
 3694 }
 3695 
 3696 static int32_t
 3697 gf_cli_deprobe(call_frame_t *frame, xlator_t *this, void *data)
 3698 {
 3699     gf_cli_req req = {
 3700         {
 3701             0,
 3702         },
 3703     };
 3704     int ret = 0;
 3705     dict_t *dict = NULL;
 3706     int port = 0;
 3707     int flags = 0;
 3708 
 3709     if (!frame || !this || !data) {
 3710         ret = -1;
 3711         goto out;
 3712     }
 3713 
 3714     dict = data;
 3715     ret = dict_get_int32_sizen(dict, "port", &port);
 3716     if (ret) {
 3717         ret = dict_set_int32_sizen(dict, "port", CLI_GLUSTERD_PORT);
 3718         if (ret)
 3719             goto out;
 3720     }
 3721 
 3722     ret = dict_get_int32_sizen(dict, "flags", &flags);
 3723     if (ret) {
 3724         ret = dict_set_int32_sizen(dict, "flags", 0);
 3725         if (ret)
 3726             goto out;
 3727     }
 3728 
 3729     ret = cli_to_glusterd(&req, frame, gf_cli_deprobe_cbk,
 3730                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_DEPROBE,
 3731                           this, cli_rpc_prog, NULL);
 3732 
 3733 out:
 3734     GF_FREE(req.dict.dict_val);
 3735     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3736 
 3737     return ret;
 3738 }
 3739 
 3740 static int32_t
 3741 gf_cli_list_friends(call_frame_t *frame, xlator_t *this, void *data)
 3742 {
 3743     gf1_cli_peer_list_req req = {
 3744         0,
 3745     };
 3746     int ret = 0;
 3747     unsigned long flags = 0;
 3748 
 3749     if (!frame || !this) {
 3750         ret = -1;
 3751         goto out;
 3752     }
 3753 
 3754     GF_ASSERT(frame->local == NULL);
 3755 
 3756     flags = (long)data;
 3757     req.flags = flags;
 3758     frame->local = (void *)flags;
 3759     ret = cli_cmd_submit(
 3760         NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_LIST_FRIENDS, NULL, this,
 3761         gf_cli_list_friends_cbk, (xdrproc_t)xdr_gf1_cli_peer_list_req);
 3762 
 3763 out:
 3764     if (ret && frame) {
 3765         /*
 3766          * If everything goes fine, gf_cli_list_friends_cbk()
 3767          * [invoked through cli_cmd_submit()]resets the
 3768          * frame->local to NULL. In case cli_cmd_submit()
 3769          * fails in between, RESET frame->local here.
 3770          */
 3771         frame->local = NULL;
 3772     }
 3773     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3774     return ret;
 3775 }
 3776 
 3777 static int32_t
 3778 gf_cli_get_state(call_frame_t *frame, xlator_t *this, void *data)
 3779 {
 3780     gf_cli_req req = {
 3781         {
 3782             0,
 3783         },
 3784     };
 3785     int ret = 0;
 3786     dict_t *dict = NULL;
 3787 
 3788     dict = data;
 3789 
 3790     ret = cli_to_glusterd(&req, frame, gf_cli_get_state_cbk,
 3791                           (xdrproc_t)xdr_gf_cli_req, dict,
 3792                           GLUSTER_CLI_GET_STATE, this, cli_rpc_prog, NULL);
 3793     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3794     GF_FREE(req.dict.dict_val);
 3795 
 3796     return ret;
 3797 }
 3798 
 3799 static int32_t
 3800 gf_cli_get_next_volume(call_frame_t *frame, xlator_t *this, void *data)
 3801 {
 3802     int ret = 0;
 3803     cli_cmd_volume_get_ctx_t *ctx = NULL;
 3804     cli_local_t *local = NULL;
 3805 
 3806     if (!frame || !this || !data) {
 3807         ret = -1;
 3808         goto out;
 3809     }
 3810 
 3811     ctx = data;
 3812     local = frame->local;
 3813 
 3814     if (global_state->mode & GLUSTER_MODE_XML) {
 3815         ret = cli_xml_output_vol_info_begin(local, 0, 0, "");
 3816         if (ret) {
 3817             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3818             goto out;
 3819         }
 3820     }
 3821 
 3822     ret = gf_cli_get_volume(frame, this, data);
 3823 
 3824     if (!local || !local->get_vol.volname) {
 3825         if ((global_state->mode & GLUSTER_MODE_XML))
 3826             goto end_xml;
 3827 
 3828         cli_err("No volumes present");
 3829         goto out;
 3830     }
 3831 
 3832     ctx->volname = local->get_vol.volname;
 3833 
 3834     while (ctx->volname) {
 3835         ret = gf_cli_get_volume(frame, this, ctx);
 3836         if (ret)
 3837             goto out;
 3838         ctx->volname = local->get_vol.volname;
 3839     }
 3840 
 3841 end_xml:
 3842     if (global_state->mode & GLUSTER_MODE_XML) {
 3843         ret = cli_xml_output_vol_info_end(local);
 3844         if (ret)
 3845             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 3846     }
 3847 
 3848 out:
 3849     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3850     return ret;
 3851 }
 3852 
 3853 static int32_t
 3854 gf_cli_get_volume(call_frame_t *frame, xlator_t *this, void *data)
 3855 {
 3856     gf_cli_req req = {{
 3857         0,
 3858     }};
 3859     int ret = 0;
 3860     cli_cmd_volume_get_ctx_t *ctx = NULL;
 3861     dict_t *dict = NULL;
 3862     int32_t flags = 0;
 3863 
 3864     if (!this || !data) {
 3865         ret = -1;
 3866         goto out;
 3867     }
 3868 
 3869     ctx = data;
 3870 
 3871     dict = dict_new();
 3872     if (!dict) {
 3873         gf_log(THIS->name, GF_LOG_ERROR, "Failed to create the dict");
 3874         ret = -1;
 3875         goto out;
 3876     }
 3877 
 3878     if (ctx->volname) {
 3879         ret = dict_set_str_sizen(dict, "volname", ctx->volname);
 3880         if (ret)
 3881             goto out;
 3882     }
 3883 
 3884     flags = ctx->flags;
 3885     ret = dict_set_int32_sizen(dict, "flags", flags);
 3886     if (ret) {
 3887         gf_log(frame->this->name, GF_LOG_ERROR, "failed to set flags");
 3888         goto out;
 3889     }
 3890 
 3891     ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
 3892                                       &req.dict.dict_len);
 3893     if (ret) {
 3894         gf_log(frame->this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
 3895         goto out;
 3896     }
 3897 
 3898     ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog,
 3899                          GLUSTER_CLI_GET_VOLUME, NULL, this,
 3900                          gf_cli_get_volume_cbk, (xdrproc_t)xdr_gf_cli_req);
 3901 
 3902 out:
 3903     if (dict)
 3904         dict_unref(dict);
 3905 
 3906     GF_FREE(req.dict.dict_val);
 3907 
 3908     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3909     return ret;
 3910 }
 3911 
 3912 static int32_t
 3913 gf_cli3_1_uuid_get(call_frame_t *frame, xlator_t *this, void *data)
 3914 {
 3915     gf_cli_req req = {{
 3916         0,
 3917     }};
 3918     int ret = 0;
 3919     dict_t *dict = NULL;
 3920 
 3921     dict = data;
 3922     ret = cli_to_glusterd(&req, frame, gf_cli3_1_uuid_get_cbk,
 3923                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_UUID_GET,
 3924                           this, cli_rpc_prog, NULL);
 3925     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3926     GF_FREE(req.dict.dict_val);
 3927     return ret;
 3928 }
 3929 
 3930 static int32_t
 3931 gf_cli3_1_uuid_reset(call_frame_t *frame, xlator_t *this, void *data)
 3932 {
 3933     gf_cli_req req = {{
 3934         0,
 3935     }};
 3936     int ret = 0;
 3937     dict_t *dict = NULL;
 3938 
 3939     dict = data;
 3940     ret = cli_to_glusterd(&req, frame, gf_cli3_1_uuid_reset_cbk,
 3941                           (xdrproc_t)xdr_gf_cli_req, dict,
 3942                           GLUSTER_CLI_UUID_RESET, this, cli_rpc_prog, NULL);
 3943     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3944     GF_FREE(req.dict.dict_val);
 3945     return ret;
 3946 }
 3947 
 3948 static int32_t
 3949 gf_cli_create_volume(call_frame_t *frame, xlator_t *this, void *data)
 3950 {
 3951     gf_cli_req req = {{
 3952         0,
 3953     }};
 3954     int ret = 0;
 3955     dict_t *dict = NULL;
 3956 
 3957     dict = data;
 3958 
 3959     ret = cli_to_glusterd(&req, frame, gf_cli_create_volume_cbk,
 3960                           (xdrproc_t)xdr_gf_cli_req, dict,
 3961                           GLUSTER_CLI_CREATE_VOLUME, this, cli_rpc_prog, NULL);
 3962     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3963 
 3964     GF_FREE(req.dict.dict_val);
 3965 
 3966     return ret;
 3967 }
 3968 
 3969 static int32_t
 3970 gf_cli_delete_volume(call_frame_t *frame, xlator_t *this, void *data)
 3971 {
 3972     gf_cli_req req = {{
 3973         0,
 3974     }};
 3975     int ret = 0;
 3976     dict_t *dict = NULL;
 3977 
 3978     dict = data;
 3979 
 3980     ret = cli_to_glusterd(&req, frame, gf_cli_delete_volume_cbk,
 3981                           (xdrproc_t)xdr_gf_cli_req, dict,
 3982                           GLUSTER_CLI_DELETE_VOLUME, this, cli_rpc_prog, NULL);
 3983     GF_FREE(req.dict.dict_val);
 3984     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 3985 
 3986     return ret;
 3987 }
 3988 
 3989 static int32_t
 3990 gf_cli_start_volume(call_frame_t *frame, xlator_t *this, void *data)
 3991 {
 3992     gf_cli_req req = {{
 3993         0,
 3994     }};
 3995     int ret = 0;
 3996     dict_t *dict = NULL;
 3997 
 3998     dict = data;
 3999 
 4000     ret = cli_to_glusterd(&req, frame, gf_cli_start_volume_cbk,
 4001                           (xdrproc_t)xdr_gf_cli_req, dict,
 4002                           GLUSTER_CLI_START_VOLUME, this, cli_rpc_prog, NULL);
 4003 
 4004     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4005     GF_FREE(req.dict.dict_val);
 4006 
 4007     return ret;
 4008 }
 4009 
 4010 static int32_t
 4011 gf_cli_stop_volume(call_frame_t *frame, xlator_t *this, void *data)
 4012 {
 4013     gf_cli_req req = {{
 4014         0,
 4015     }};
 4016     int ret = 0;
 4017     dict_t *dict = data;
 4018 
 4019     dict = data;
 4020 
 4021     ret = cli_to_glusterd(&req, frame, gf_cli_stop_volume_cbk,
 4022                           (xdrproc_t)xdr_gf_cli_req, dict,
 4023                           GLUSTER_CLI_STOP_VOLUME, this, cli_rpc_prog, NULL);
 4024     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4025     GF_FREE(req.dict.dict_val);
 4026 
 4027     return ret;
 4028 }
 4029 
 4030 static int32_t
 4031 gf_cli_defrag_volume(call_frame_t *frame, xlator_t *this, void *data)
 4032 {
 4033     gf_cli_req req = {{
 4034         0,
 4035     }};
 4036     int ret = 0;
 4037     dict_t *dict = NULL;
 4038 
 4039     dict = data;
 4040 
 4041     ret = cli_to_glusterd(&req, frame, gf_cli_defrag_volume_cbk,
 4042                           (xdrproc_t)xdr_gf_cli_req, dict,
 4043                           GLUSTER_CLI_DEFRAG_VOLUME, this, cli_rpc_prog, NULL);
 4044     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4045     GF_FREE(req.dict.dict_val);
 4046 
 4047     return ret;
 4048 }
 4049 
 4050 static int32_t
 4051 gf_cli_rename_volume(call_frame_t *frame, xlator_t *this, void *data)
 4052 {
 4053     gf_cli_req req = {{
 4054         0,
 4055     }};
 4056     int ret = 0;
 4057     dict_t *dict = NULL;
 4058 
 4059     if (!frame || !this || !data) {
 4060         ret = -1;
 4061         goto out;
 4062     }
 4063 
 4064     dict = data;
 4065 
 4066     ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
 4067                                       &req.dict.dict_len);
 4068     if (ret < 0) {
 4069         gf_log(this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
 4070 
 4071         goto out;
 4072     }
 4073 
 4074     ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog,
 4075                          GLUSTER_CLI_RENAME_VOLUME, NULL, this,
 4076                          gf_cli_rename_volume_cbk, (xdrproc_t)xdr_gf_cli_req);
 4077 
 4078 out:
 4079     GF_FREE(req.dict.dict_val);
 4080     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4081 
 4082     return ret;
 4083 }
 4084 
 4085 static int32_t
 4086 gf_cli_reset_volume(call_frame_t *frame, xlator_t *this, void *data)
 4087 {
 4088     gf_cli_req req = {{
 4089         0,
 4090     }};
 4091     int ret = 0;
 4092     dict_t *dict = NULL;
 4093 
 4094     dict = data;
 4095 
 4096     ret = cli_to_glusterd(&req, frame, gf_cli_reset_volume_cbk,
 4097                           (xdrproc_t)xdr_gf_cli_req, dict,
 4098                           GLUSTER_CLI_RESET_VOLUME, this, cli_rpc_prog, NULL);
 4099     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4100     GF_FREE(req.dict.dict_val);
 4101     return ret;
 4102 }
 4103 
 4104 static int32_t
 4105 gf_cli_ganesha(call_frame_t *frame, xlator_t *this, void *data)
 4106 {
 4107     gf_cli_req req = {{
 4108         0,
 4109     }};
 4110     int ret = 0;
 4111     dict_t *dict = NULL;
 4112 
 4113     dict = data;
 4114 
 4115     ret = cli_to_glusterd(&req, frame, gf_cli_ganesha_cbk,
 4116                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_GANESHA,
 4117                           this, cli_rpc_prog, NULL);
 4118     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4119 
 4120     return ret;
 4121 }
 4122 
 4123 static int32_t
 4124 gf_cli_set_volume(call_frame_t *frame, xlator_t *this, void *data)
 4125 {
 4126     gf_cli_req req = {{
 4127         0,
 4128     }};
 4129     int ret = 0;
 4130     dict_t *dict = NULL;
 4131 
 4132     dict = data;
 4133 
 4134     ret = cli_to_glusterd(&req, frame, gf_cli_set_volume_cbk,
 4135                           (xdrproc_t)xdr_gf_cli_req, dict,
 4136                           GLUSTER_CLI_SET_VOLUME, this, cli_rpc_prog, NULL);
 4137     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4138     GF_FREE(req.dict.dict_val);
 4139 
 4140     return ret;
 4141 }
 4142 
 4143 int32_t
 4144 gf_cli_add_brick(call_frame_t *frame, xlator_t *this, void *data)
 4145 {
 4146     gf_cli_req req = {{
 4147         0,
 4148     }};
 4149     int ret = 0;
 4150     dict_t *dict = NULL;
 4151 
 4152     dict = data;
 4153 
 4154     ret = cli_to_glusterd(&req, frame, gf_cli_add_brick_cbk,
 4155                           (xdrproc_t)xdr_gf_cli_req, dict,
 4156                           GLUSTER_CLI_ADD_BRICK, this, cli_rpc_prog, NULL);
 4157 
 4158     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4159 
 4160     GF_FREE(req.dict.dict_val);
 4161 
 4162     return ret;
 4163 }
 4164 
 4165 static int32_t
 4166 gf_cli_remove_brick(call_frame_t *frame, xlator_t *this, void *data)
 4167 {
 4168     gf_cli_req req = {{
 4169         0,
 4170     }};
 4171     ;
 4172     gf_cli_req status_req = {{
 4173         0,
 4174     }};
 4175     ;
 4176     int ret = 0;
 4177     dict_t *dict = NULL;
 4178     int32_t command = 0;
 4179     int32_t cmd = 0;
 4180 
 4181     if (!frame || !this) {
 4182         ret = -1;
 4183         goto out;
 4184     }
 4185 
 4186     dict = data;
 4187 
 4188     ret = dict_get_int32_sizen(dict, "command", &command);
 4189     if (ret)
 4190         goto out;
 4191 
 4192     if ((command != GF_OP_CMD_STATUS) && (command != GF_OP_CMD_STOP)) {
 4193         ret = cli_to_glusterd(
 4194             &req, frame, gf_cli_remove_brick_cbk, (xdrproc_t)xdr_gf_cli_req,
 4195             dict, GLUSTER_CLI_REMOVE_BRICK, this, cli_rpc_prog, NULL);
 4196     } else {
 4197         /* Need rebalance status to be sent :-) */
 4198         if (command == GF_OP_CMD_STATUS)
 4199             cmd |= GF_DEFRAG_CMD_STATUS;
 4200         else
 4201             cmd |= GF_DEFRAG_CMD_STOP;
 4202 
 4203         ret = dict_set_int32_sizen(dict, "rebalance-command", (int32_t)cmd);
 4204         if (ret) {
 4205             gf_log(this->name, GF_LOG_ERROR, "Failed to set dict");
 4206             goto out;
 4207         }
 4208 
 4209         ret = cli_to_glusterd(
 4210             &status_req, frame, gf_cli3_remove_brick_status_cbk,
 4211             (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_DEFRAG_VOLUME, this,
 4212             cli_rpc_prog, NULL);
 4213     }
 4214 
 4215 out:
 4216     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4217 
 4218     GF_FREE(req.dict.dict_val);
 4219 
 4220     GF_FREE(status_req.dict.dict_val);
 4221 
 4222     return ret;
 4223 }
 4224 
 4225 static int32_t
 4226 gf_cli_reset_brick(call_frame_t *frame, xlator_t *this, void *data)
 4227 {
 4228     gf_cli_req req = {{
 4229         0,
 4230     }};
 4231     int ret = 0;
 4232     dict_t *dict = NULL;
 4233     char *dst_brick = NULL;
 4234     char *op = NULL;
 4235 
 4236     if (!frame || !this || !data) {
 4237         ret = -1;
 4238         goto out;
 4239     }
 4240 
 4241     dict = data;
 4242 
 4243     ret = dict_get_str_sizen(dict, "operation", &op);
 4244     if (ret) {
 4245         gf_log(this->name, GF_LOG_DEBUG, "dict_get on operation failed");
 4246         goto out;
 4247     }
 4248 
 4249     if (!strcmp(op, "GF_RESET_OP_COMMIT") ||
 4250         !strcmp(op, "GF_RESET_OP_COMMIT_FORCE")) {
 4251         ret = dict_get_str_sizen(dict, "dst-brick", &dst_brick);
 4252         if (ret) {
 4253             gf_log(this->name, GF_LOG_DEBUG, "dict_get on dst-brick failed");
 4254             goto out;
 4255         }
 4256     }
 4257 
 4258     ret = cli_to_glusterd(&req, frame, gf_cli_reset_brick_cbk,
 4259                           (xdrproc_t)xdr_gf_cli_req, dict,
 4260                           GLUSTER_CLI_RESET_BRICK, this, cli_rpc_prog, NULL);
 4261 
 4262 out:
 4263     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4264 
 4265     GF_FREE(req.dict.dict_val);
 4266 
 4267     return ret;
 4268 }
 4269 
 4270 static int32_t
 4271 gf_cli_replace_brick(call_frame_t *frame, xlator_t *this, void *data)
 4272 {
 4273     gf_cli_req req = {{
 4274         0,
 4275     }};
 4276     int ret = 0;
 4277     dict_t *dict = NULL;
 4278     int32_t op = 0;
 4279 
 4280     if (!frame || !this || !data) {
 4281         ret = -1;
 4282         goto out;
 4283     }
 4284 
 4285     dict = data;
 4286 
 4287     ret = dict_get_int32_sizen(dict, "operation", &op);
 4288     if (ret) {
 4289         gf_log(this->name, GF_LOG_DEBUG, "dict_get on operation failed");
 4290         goto out;
 4291     }
 4292 
 4293     ret = cli_to_glusterd(&req, frame, gf_cli_replace_brick_cbk,
 4294                           (xdrproc_t)xdr_gf_cli_req, dict,
 4295                           GLUSTER_CLI_REPLACE_BRICK, this, cli_rpc_prog, NULL);
 4296 
 4297 out:
 4298     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4299 
 4300     GF_FREE(req.dict.dict_val);
 4301 
 4302     return ret;
 4303 }
 4304 
 4305 static int32_t
 4306 gf_cli_log_rotate(call_frame_t *frame, xlator_t *this, void *data)
 4307 {
 4308     gf_cli_req req = {{
 4309         0,
 4310     }};
 4311     int ret = 0;
 4312     dict_t *dict = NULL;
 4313 
 4314     dict = data;
 4315 
 4316     ret = cli_to_glusterd(&req, frame, gf_cli_log_rotate_cbk,
 4317                           (xdrproc_t)xdr_gf_cli_req, dict,
 4318                           GLUSTER_CLI_LOG_ROTATE, this, cli_rpc_prog, NULL);
 4319     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4320 
 4321     GF_FREE(req.dict.dict_val);
 4322     return ret;
 4323 }
 4324 
 4325 static int32_t
 4326 gf_cli_sync_volume(call_frame_t *frame, xlator_t *this, void *data)
 4327 {
 4328     int ret = 0;
 4329     gf_cli_req req = {{
 4330         0,
 4331     }};
 4332     dict_t *dict = NULL;
 4333 
 4334     dict = data;
 4335 
 4336     ret = cli_to_glusterd(&req, frame, gf_cli_sync_volume_cbk,
 4337                           (xdrproc_t)xdr_gf_cli_req, dict,
 4338                           GLUSTER_CLI_SYNC_VOLUME, this, cli_rpc_prog, NULL);
 4339     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4340     GF_FREE(req.dict.dict_val);
 4341 
 4342     return ret;
 4343 }
 4344 
 4345 static int32_t
 4346 gf_cli_getspec(call_frame_t *frame, xlator_t *this, void *data)
 4347 {
 4348     gf_getspec_req req = {
 4349         0,
 4350     };
 4351     int ret = 0;
 4352     dict_t *dict = NULL;
 4353     dict_t *op_dict = NULL;
 4354 
 4355     if (!frame || !this) {
 4356         ret = -1;
 4357         goto out;
 4358     }
 4359 
 4360     dict = data;
 4361 
 4362     ret = dict_get_str_sizen(dict, "volid", &req.key);
 4363     if (ret)
 4364         goto out;
 4365 
 4366     op_dict = dict_new();
 4367     if (!op_dict) {
 4368         ret = -1;
 4369         goto out;
 4370     }
 4371 
 4372     // Set the supported min and max op-versions, so glusterd can make a
 4373     // decision
 4374     ret = dict_set_int32_sizen(op_dict, "min-op-version", GD_OP_VERSION_MIN);
 4375     if (ret) {
 4376         gf_log(THIS->name, GF_LOG_ERROR,
 4377                "Failed to set min-op-version in request dict");
 4378         goto out;
 4379     }
 4380 
 4381     ret = dict_set_int32_sizen(op_dict, "max-op-version", GD_OP_VERSION_MAX);
 4382     if (ret) {
 4383         gf_log(THIS->name, GF_LOG_ERROR,
 4384                "Failed to set max-op-version in request dict");
 4385         goto out;
 4386     }
 4387 
 4388     ret = dict_allocate_and_serialize(op_dict, &req.xdata.xdata_val,
 4389                                       &req.xdata.xdata_len);
 4390     if (ret < 0) {
 4391         gf_log(THIS->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
 4392         goto out;
 4393     }
 4394 
 4395     ret = cli_cmd_submit(NULL, &req, frame, &cli_handshake_prog,
 4396                          GF_HNDSK_GETSPEC, NULL, this, gf_cli_getspec_cbk,
 4397                          (xdrproc_t)xdr_gf_getspec_req);
 4398 
 4399 out:
 4400     if (op_dict) {
 4401         dict_unref(op_dict);
 4402     }
 4403     GF_FREE(req.xdata.xdata_val);
 4404     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4405 
 4406     return ret;
 4407 }
 4408 
 4409 static int32_t
 4410 gf_cli_quota(call_frame_t *frame, xlator_t *this, void *data)
 4411 {
 4412     gf_cli_req req = {{
 4413         0,
 4414     }};
 4415     int ret = 0;
 4416     dict_t *dict = NULL;
 4417 
 4418     dict = data;
 4419 
 4420     ret = cli_to_glusterd(&req, frame, gf_cli_quota_cbk,
 4421                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_QUOTA,
 4422                           this, cli_rpc_prog, NULL);
 4423     GF_FREE(req.dict.dict_val);
 4424     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4425     return ret;
 4426 }
 4427 
 4428 static int32_t
 4429 gf_cli_pmap_b2p(call_frame_t *frame, xlator_t *this, void *data)
 4430 {
 4431     pmap_port_by_brick_req req = {
 4432         0,
 4433     };
 4434     int ret = 0;
 4435     dict_t *dict = NULL;
 4436 
 4437     if (!frame || !this) {
 4438         ret = -1;
 4439         goto out;
 4440     }
 4441 
 4442     dict = data;
 4443 
 4444     ret = dict_get_str_sizen(dict, "brick", &req.brick);
 4445     if (ret)
 4446         goto out;
 4447 
 4448     ret = cli_cmd_submit(NULL, &req, frame, &cli_pmap_prog, GF_PMAP_PORTBYBRICK,
 4449                          NULL, this, gf_cli_pmap_b2p_cbk,
 4450                          (xdrproc_t)xdr_pmap_port_by_brick_req);
 4451 
 4452 out:
 4453     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4454 
 4455     return ret;
 4456 }
 4457 
 4458 static int
 4459 gf_cli_fsm_log_cbk(struct rpc_req *req, struct iovec *iov, int count,
 4460                    void *myframe)
 4461 {
 4462     gf1_cli_fsm_log_rsp rsp = {
 4463         0,
 4464     };
 4465     int ret = -1;
 4466     dict_t *dict = NULL;
 4467     int tr_count = 0;
 4468     char key[64] = {0};
 4469     int keylen;
 4470     int i = 0;
 4471     char *old_state = NULL;
 4472     char *new_state = NULL;
 4473     char *event = NULL;
 4474     char *time = NULL;
 4475 
 4476     GF_ASSERT(myframe);
 4477 
 4478     if (-1 == req->rpc_status) {
 4479         goto out;
 4480     }
 4481 
 4482     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
 4483     if (ret < 0) {
 4484         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 4485                XDR_DECODE_FAIL);
 4486         goto out;
 4487     }
 4488 
 4489     if (rsp.op_ret) {
 4490         if (strcmp(rsp.op_errstr, ""))
 4491             cli_err("%s", rsp.op_errstr);
 4492         cli_err("fsm log unsuccessful");
 4493         ret = rsp.op_ret;
 4494         goto out;
 4495     }
 4496 
 4497     dict = dict_new();
 4498     if (!dict) {
 4499         ret = -1;
 4500         goto out;
 4501     }
 4502 
 4503     ret = dict_unserialize(rsp.fsm_log.fsm_log_val, rsp.fsm_log.fsm_log_len,
 4504                            &dict);
 4505 
 4506     if (ret) {
 4507         cli_err(DICT_UNSERIALIZE_FAIL);
 4508         goto out;
 4509     }
 4510 
 4511     ret = dict_get_int32_sizen(dict, "count", &tr_count);
 4512     if (!ret && tr_count)
 4513         cli_out("number of transitions: %d", tr_count);
 4514     else
 4515         cli_err("No transitions");
 4516     for (i = 0; i < tr_count; i++) {
 4517         keylen = snprintf(key, sizeof(key), "log%d-old-state", i);
 4518         ret = dict_get_strn(dict, key, keylen, &old_state);
 4519         if (ret)
 4520             goto out;
 4521 
 4522         keylen = snprintf(key, sizeof(key), "log%d-event", i);
 4523         ret = dict_get_strn(dict, key, keylen, &event);
 4524         if (ret)
 4525             goto out;
 4526 
 4527         keylen = snprintf(key, sizeof(key), "log%d-new-state", i);
 4528         ret = dict_get_strn(dict, key, keylen, &new_state);
 4529         if (ret)
 4530             goto out;
 4531 
 4532         keylen = snprintf(key, sizeof(key), "log%d-time", i);
 4533         ret = dict_get_strn(dict, key, keylen, &time);
 4534         if (ret)
 4535             goto out;
 4536         cli_out(
 4537             "Old State: [%s]\n"
 4538             "New State: [%s]\n"
 4539             "Event    : [%s]\n"
 4540             "timestamp: [%s]\n",
 4541             old_state, new_state, event, time);
 4542     }
 4543 
 4544     ret = rsp.op_ret;
 4545 
 4546 out:
 4547     cli_cmd_broadcast_response(ret);
 4548     if (dict) {
 4549         dict_unref(dict);
 4550     }
 4551     gf_free_xdr_fsm_log_rsp(rsp);
 4552 
 4553     return ret;
 4554 }
 4555 
 4556 static int32_t
 4557 gf_cli_fsm_log(call_frame_t *frame, xlator_t *this, void *data)
 4558 {
 4559     int ret = -1;
 4560     gf1_cli_fsm_log_req req = {
 4561         0,
 4562     };
 4563 
 4564     GF_ASSERT(frame);
 4565     GF_ASSERT(this);
 4566     GF_ASSERT(data);
 4567 
 4568     if (!frame || !this || !data)
 4569         goto out;
 4570     req.name = data;
 4571     ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_FSM_LOG,
 4572                          NULL, this, gf_cli_fsm_log_cbk,
 4573                          (xdrproc_t)xdr_gf1_cli_fsm_log_req);
 4574 
 4575 out:
 4576     gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
 4577 
 4578     return ret;
 4579 }
 4580 
 4581 static int
 4582 gf_cli_gsync_config_command(dict_t *dict)
 4583 {
 4584     runner_t runner = {
 4585         0,
 4586     };
 4587     char *subop = NULL;
 4588     char *gwd = NULL;
 4589     char *slave = NULL;
 4590     char *confpath = NULL;
 4591     char *master = NULL;
 4592     char *op_name = NULL;
 4593     int ret = -1;
 4594     char conf_path[PATH_MAX] = "";
 4595 
 4596     if (dict_get_str_sizen(dict, "subop", &subop) != 0)
 4597         return -1;
 4598 
 4599     if (strcmp(subop, "get") != 0 && strcmp(subop, "get-all") != 0) {
 4600         cli_out(GEOREP " config updated successfully");
 4601         return 0;
 4602     }
 4603 
 4604     if (dict_get_str_sizen(dict, "glusterd_workdir", &gwd) != 0 ||
 4605         dict_get_str_sizen(dict, "slave", &slave) != 0)
 4606         return -1;
 4607 
 4608     if (dict_get_str_sizen(dict, "master", &master) != 0)
 4609         master = NULL;
 4610     if (dict_get_str_sizen(dict, "op_name", &op_name) != 0)
 4611         op_name = NULL;
 4612 
 4613     ret = dict_get_str_sizen(dict, "conf_path", &confpath);
 4614     if (ret || !confpath) {
 4615         ret = snprintf(conf_path, sizeof(conf_path) - 1,
 4616                        "%s/" GEOREP "/gsyncd_template.conf", gwd);
 4617         conf_path[ret] = '\0';
 4618         confpath = conf_path;
 4619     }
 4620 
 4621     runinit(&runner);
 4622     runner_add_args(&runner, GSYNCD_PREFIX "/gsyncd", "-c", NULL);
 4623     runner_argprintf(&runner, "%s", confpath);
 4624     runner_argprintf(&runner, "--iprefix=%s", DATADIR);
 4625     if (master)
 4626         runner_argprintf(&runner, ":%s", master);
 4627     runner_add_arg(&runner, slave);
 4628     runner_argprintf(&runner, "--config-%s", subop);
 4629     if (op_name)
 4630         runner_add_arg(&runner, op_name);
 4631 
 4632     return runner_run(&runner);
 4633 }
 4634 
 4635 static int
 4636 gf_cli_print_status(char **title_values, gf_gsync_status_t **sts_vals,
 4637                     int *spacing, int gsync_count, int number_of_fields,
 4638                     int is_detail)
 4639 {
 4640     int i = 0;
 4641     int j = 0;
 4642     int ret = 0;
 4643     int status_fields = 8; /* Indexed at 0 */
 4644     int total_spacing = 0;
 4645     char **output_values = NULL;
 4646     char *tmp = NULL;
 4647     char *hyphens = NULL;
 4648 
 4649     /* calculating spacing for hyphens */
 4650     for (i = 0; i < number_of_fields; i++) {
 4651         /* Suppressing detail output for status */
 4652         if ((!is_detail) && (i > status_fields)) {
 4653             /* Suppressing detailed output for
 4654              * status */
 4655             continue;
 4656         }
 4657         spacing[i] += 3; /* Adding extra space to
 4658                             distinguish between fields */
 4659         total_spacing += spacing[i];
 4660     }
 4661     total_spacing += 4; /* For the spacing between the fields */
 4662 
 4663     /* char pointers for each field */
 4664     output_values = GF_MALLOC(number_of_fields * sizeof(char *),
 4665                               gf_common_mt_char);
 4666     if (!output_values) {
 4667         ret = -1;
 4668         goto out;
 4669     }
 4670     for (i = 0; i < number_of_fields; i++) {
 4671         output_values[i] = GF_CALLOC(spacing[i] + 1, sizeof(char),
 4672                                      gf_common_mt_char);
 4673         if (!output_values[i]) {
 4674             ret = -1;
 4675             goto out;
 4676         }
 4677     }
 4678 
 4679     cli_out(" ");
 4680 
 4681     /* setting the title "NODE", "MASTER", etc. from title_values[]
 4682        and printing the same */
 4683     for (j = 0; j < number_of_fields; j++) {
 4684         if ((!is_detail) && (j > status_fields)) {
 4685             /* Suppressing detailed output for
 4686              * status */
 4687             output_values[j][0] = '\0';
 4688             continue;
 4689         }
 4690         memset(output_values[j], ' ', spacing[j]);
 4691         memcpy(output_values[j], title_values[j], strlen(title_values[j]));
 4692         output_values[j][spacing[j]] = '\0';
 4693     }
 4694     cli_out("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", output_values[0],
 4695             output_values[1], output_values[2], output_values[3],
 4696             output_values[4], output_values[5], output_values[6],
 4697             output_values[7], output_values[8], output_values[9],
 4698             output_values[10], output_values[11], output_values[12],
 4699             output_values[13], output_values[14], output_values[15]);
 4700 
 4701     hyphens = GF_MALLOC((total_spacing + 1) * sizeof(char), gf_common_mt_char);
 4702     if (!hyphens) {
 4703         ret = -1;
 4704         goto out;
 4705     }
 4706 
 4707     /* setting and printing the hyphens */
 4708     memset(hyphens, '-', total_spacing);
 4709     hyphens[total_spacing] = '\0';
 4710     cli_out("%s", hyphens);
 4711 
 4712     for (i = 0; i < gsync_count; i++) {
 4713         for (j = 0; j < number_of_fields; j++) {
 4714             if ((!is_detail) && (j > status_fields)) {
 4715                 /* Suppressing detailed output for
 4716                  * status */
 4717                 output_values[j][0] = '\0';
 4718                 continue;
 4719             }
 4720             tmp = get_struct_variable(j, sts_vals[i]);
 4721             if (!tmp) {
 4722                 gf_log("", GF_LOG_ERROR, "struct member empty.");
 4723                 ret = -1;
 4724                 goto out;
 4725             }
 4726             memset(output_values[j], ' ', spacing[j]);
 4727             memcpy(output_values[j], tmp, strlen(tmp));
 4728             output_values[j][spacing[j]] = '\0';
 4729         }
 4730 
 4731         cli_out("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
 4732                 output_values[0], output_values[1], output_values[2],
 4733                 output_values[3], output_values[4], output_values[5],
 4734                 output_values[6], output_values[7], output_values[8],
 4735                 output_values[9], output_values[10], output_values[11],
 4736                 output_values[12], output_values[13], output_values[14],
 4737                 output_values[15]);
 4738     }
 4739 
 4740 out:
 4741     if (output_values) {
 4742         for (i = 0; i < number_of_fields; i++) {
 4743             if (output_values[i])
 4744                 GF_FREE(output_values[i]);
 4745         }
 4746         GF_FREE(output_values);
 4747     }
 4748 
 4749     if (hyphens)
 4750         GF_FREE(hyphens);
 4751 
 4752     return ret;
 4753 }
 4754 
 4755 int
 4756 gf_gsync_status_t_comparator(const void *p, const void *q)
 4757 {
 4758     char *slavekey1 = NULL;
 4759     char *slavekey2 = NULL;
 4760 
 4761     slavekey1 = get_struct_variable(20, (*(gf_gsync_status_t **)p));
 4762     slavekey2 = get_struct_variable(20, (*(gf_gsync_status_t **)q));
 4763     if (!slavekey1 || !slavekey2) {
 4764         gf_log("cli", GF_LOG_ERROR, "struct member empty.");
 4765         return 0;
 4766     }
 4767 
 4768     return strcmp(slavekey1, slavekey2);
 4769 }
 4770 
 4771 static int
 4772 gf_cli_read_status_data(dict_t *dict, gf_gsync_status_t **sts_vals,
 4773                         int *spacing, int gsync_count, int number_of_fields)
 4774 {
 4775     char *tmp = NULL;
 4776     char sts_val_name[PATH_MAX] = "";
 4777     int ret = 0;
 4778     int i = 0;
 4779     int j = 0;
 4780 
 4781     /* Storing per node status info in each object */
 4782     for (i = 0; i < gsync_count; i++) {
 4783         snprintf(sts_val_name, sizeof(sts_val_name), "status_value%d", i);
 4784 
 4785         /* Fetching the values from dict, and calculating
 4786            the max length for each field */
 4787         ret = dict_get_bin(dict, sts_val_name, (void **)&(sts_vals[i]));
 4788         if (ret)
 4789             goto out;
 4790 
 4791         for (j = 0; j < number_of_fields; j++) {
 4792             tmp = get_struct_variable(j, sts_vals[i]);
 4793             if (!tmp) {
 4794                 gf_log("", GF_LOG_ERROR, "struct member empty.");
 4795                 ret = -1;
 4796                 goto out;
 4797             }
 4798             if (strlen(tmp) > spacing[j])
 4799                 spacing[j] = strlen(tmp);
 4800         }
 4801     }
 4802 
 4803     /* Sort based on Session Slave */
 4804     qsort(sts_vals, gsync_count, sizeof(gf_gsync_status_t *),
 4805           gf_gsync_status_t_comparator);
 4806 
 4807 out:
 4808     return ret;
 4809 }
 4810 
 4811 static int
 4812 gf_cli_gsync_status_output(dict_t *dict, gf_boolean_t is_detail)
 4813 {
 4814     int gsync_count = 0;
 4815     int i = 0;
 4816     int ret = 0;
 4817     int spacing[16] = {0};
 4818     int num_of_fields = 16;
 4819     char errmsg[1024] = "";
 4820     char *master = NULL;
 4821     char *slave = NULL;
 4822     static char *title_values[] = {"MASTER NODE",
 4823                                    "MASTER VOL",
 4824                                    "MASTER BRICK",
 4825                                    "SLAVE USER",
 4826                                    "SLAVE",
 4827                                    "SLAVE NODE",
 4828                                    "STATUS",
 4829                                    "CRAWL STATUS",
 4830                                    "LAST_SYNCED",
 4831                                    "ENTRY",
 4832                                    "DATA",
 4833                                    "META",
 4834                                    "FAILURES",
 4835                                    "CHECKPOINT TIME",
 4836                                    "CHECKPOINT COMPLETED",
 4837                                    "CHECKPOINT COMPLETION TIME"};
 4838     gf_gsync_status_t **sts_vals = NULL;
 4839 
 4840     /* Checks if any session is active or not */
 4841     ret = dict_get_int32_sizen(dict, "gsync-count", &gsync_count);
 4842     if (ret) {
 4843         ret = dict_get_str_sizen(dict, "master", &master);
 4844 
 4845         ret = dict_get_str_sizen(dict, "slave", &slave);
 4846 
 4847         if (master) {
 4848             if (slave)
 4849                 snprintf(errmsg, sizeof(errmsg),
 4850                          "No active geo-replication sessions between %s"
 4851                          " and %s",
 4852                          master, slave);
 4853             else
 4854                 snprintf(errmsg, sizeof(errmsg),
 4855                          "No active geo-replication sessions for %s", master);
 4856         } else
 4857             snprintf(errmsg, sizeof(errmsg),
 4858                      "No active geo-replication sessions");
 4859 
 4860         gf_log("cli", GF_LOG_INFO, "%s", errmsg);
 4861         cli_out("%s", errmsg);
 4862         ret = -1;
 4863         goto out;
 4864     }
 4865 
 4866     for (i = 0; i < num_of_fields; i++)
 4867         spacing[i] = strlen(title_values[i]);
 4868 
 4869     /* gsync_count = number of nodes reporting output.
 4870        each sts_val object will store output of each
 4871        node */
 4872     sts_vals = GF_MALLOC(gsync_count * sizeof(gf_gsync_status_t *),
 4873                          gf_common_mt_char);
 4874     if (!sts_vals) {
 4875         ret = -1;
 4876         goto out;
 4877     }
 4878     for (i = 0; i < gsync_count; i++) {
 4879         sts_vals[i] = GF_CALLOC(1, sizeof(gf_gsync_status_t),
 4880                                 gf_common_mt_char);
 4881         if (!sts_vals[i]) {
 4882             ret = -1;
 4883             goto out;
 4884         }
 4885     }
 4886 
 4887     ret = gf_cli_read_status_data(dict, sts_vals, spacing, gsync_count,
 4888                                   num_of_fields);
 4889     if (ret) {
 4890         gf_log("", GF_LOG_ERROR, "Unable to read status data");
 4891         goto out;
 4892     }
 4893 
 4894     ret = gf_cli_print_status(title_values, sts_vals, spacing, gsync_count,
 4895                               num_of_fields, is_detail);
 4896     if (ret) {
 4897         gf_log("", GF_LOG_ERROR, "Unable to print status output");
 4898         goto out;
 4899     }
 4900 
 4901 out:
 4902     if (sts_vals)
 4903         GF_FREE(sts_vals);
 4904 
 4905     return ret;
 4906 }
 4907 
 4908 static int32_t
 4909 write_contents_to_common_pem_file(dict_t *dict, int output_count)
 4910 {
 4911     char *workdir = NULL;
 4912     char common_pem_file[PATH_MAX] = "";
 4913     char *output = NULL;
 4914     char output_name[32] = "";
 4915     int bytes_written = 0;
 4916     int fd = -1;
 4917     int ret = -1;
 4918     int i = -1;
 4919 
 4920     ret = dict_get_str_sizen(dict, "glusterd_workdir", &workdir);
 4921     if (ret || !workdir) {
 4922         gf_log("", GF_LOG_ERROR, "Unable to fetch workdir");
 4923         ret = -1;
 4924         goto out;
 4925     }
 4926 
 4927     snprintf(common_pem_file, sizeof(common_pem_file),
 4928              "%s/geo-replication/common_secret.pem.pub", workdir);
 4929 
 4930     sys_unlink(common_pem_file);
 4931 
 4932     fd = open(common_pem_file, O_WRONLY | O_CREAT, 0600);
 4933     if (fd == -1) {
 4934         gf_log("", GF_LOG_ERROR, "Failed to open %s Error : %s",
 4935                common_pem_file, strerror(errno));
 4936         ret = -1;
 4937         goto out;
 4938     }
 4939 
 4940     for (i = 1; i <= output_count; i++) {
 4941         ret = snprintf(output_name, sizeof(output_name), "output_%d", i);
 4942         ret = dict_get_strn(dict, output_name, ret, &output);
 4943         if (ret) {
 4944             gf_log("", GF_LOG_ERROR, "Failed to get %s.", output_name);
 4945             cli_out("Unable to fetch output.");
 4946         }
 4947         if (output) {
 4948             bytes_written = sys_write(fd, output, strlen(output));
 4949             if (bytes_written != strlen(output)) {
 4950                 gf_log("", GF_LOG_ERROR, "Failed to write to %s",
 4951                        common_pem_file);
 4952                 ret = -1;
 4953                 goto out;
 4954             }
 4955             /* Adding the new line character */
 4956             bytes_written = sys_write(fd, "\n", 1);
 4957             if (bytes_written != 1) {
 4958                 gf_log("", GF_LOG_ERROR, "Failed to add new line char");
 4959                 ret = -1;
 4960                 goto out;
 4961             }
 4962             output = NULL;
 4963         }
 4964     }
 4965 
 4966     cli_out("Common secret pub file present at %s", common_pem_file);
 4967     ret = 0;
 4968 out:
 4969     if (fd >= 0)
 4970         sys_close(fd);
 4971 
 4972     gf_log("", GF_LOG_DEBUG, RETURNING, ret);
 4973     return ret;
 4974 }
 4975 
 4976 static int
 4977 gf_cli_sys_exec_cbk(struct rpc_req *req, struct iovec *iov, int count,
 4978                     void *myframe)
 4979 {
 4980     int ret = -1;
 4981     int output_count = -1;
 4982     int i = -1;
 4983     char *output = NULL;
 4984     char *command = NULL;
 4985     char output_name[32] = "";
 4986     gf_cli_rsp rsp = {
 4987         0,
 4988     };
 4989     dict_t *dict = NULL;
 4990 
 4991     GF_ASSERT(myframe);
 4992 
 4993     if (req->rpc_status == -1) {
 4994         goto out;
 4995     }
 4996 
 4997     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 4998     if (ret < 0) {
 4999         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 5000                XDR_DECODE_FAIL);
 5001         goto out;
 5002     }
 5003 
 5004     dict = dict_new();
 5005 
 5006     if (!dict) {
 5007         ret = -1;
 5008         goto out;
 5009     }
 5010 
 5011     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 5012 
 5013     if (ret)
 5014         goto out;
 5015 
 5016     if (rsp.op_ret) {
 5017         cli_err("%s", rsp.op_errstr ? rsp.op_errstr : "Command failed.");
 5018         ret = rsp.op_ret;
 5019         goto out;
 5020     }
 5021 
 5022     ret = dict_get_int32_sizen(dict, "output_count", &output_count);
 5023     if (ret) {
 5024         cli_out("Command executed successfully.");
 5025         ret = 0;
 5026         goto out;
 5027     }
 5028 
 5029     ret = dict_get_str_sizen(dict, "command", &command);
 5030     if (ret) {
 5031         gf_log("", GF_LOG_ERROR, "Unable to get command from dict");
 5032         goto out;
 5033     }
 5034 
 5035     if (!strcmp(command, "gsec_create")) {
 5036         ret = write_contents_to_common_pem_file(dict, output_count);
 5037         if (!ret)
 5038             goto out;
 5039     }
 5040 
 5041     for (i = 1; i <= output_count; i++) {
 5042         ret = snprintf(output_name, sizeof(output_name), "output_%d", i);
 5043         ret = dict_get_strn(dict, output_name, ret, &output);
 5044         if (ret) {
 5045             gf_log("", GF_LOG_ERROR, "Failed to get %s.", output_name);
 5046             cli_out("Unable to fetch output.");
 5047         }
 5048         if (output) {
 5049             cli_out("%s", output);
 5050             output = NULL;
 5051         }
 5052     }
 5053 
 5054     ret = 0;
 5055 out:
 5056     if (dict)
 5057         dict_unref(dict);
 5058     cli_cmd_broadcast_response(ret);
 5059     gf_free_xdr_cli_rsp(rsp);
 5060     return ret;
 5061 }
 5062 
 5063 static int
 5064 gf_cli_copy_file_cbk(struct rpc_req *req, struct iovec *iov, int count,
 5065                      void *myframe)
 5066 {
 5067     int ret = -1;
 5068     gf_cli_rsp rsp = {
 5069         0,
 5070     };
 5071     dict_t *dict = NULL;
 5072 
 5073     GF_ASSERT(myframe);
 5074 
 5075     if (req->rpc_status == -1) {
 5076         goto out;
 5077     }
 5078 
 5079     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 5080     if (ret < 0) {
 5081         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 5082                XDR_DECODE_FAIL);
 5083         goto out;
 5084     }
 5085 
 5086     dict = dict_new();
 5087 
 5088     if (!dict) {
 5089         ret = -1;
 5090         goto out;
 5091     }
 5092 
 5093     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 5094 
 5095     if (ret)
 5096         goto out;
 5097 
 5098     if (rsp.op_ret) {
 5099         cli_err("%s", rsp.op_errstr ? rsp.op_errstr : "Copy unsuccessful");
 5100         ret = rsp.op_ret;
 5101         goto out;
 5102     }
 5103 
 5104     cli_out("Successfully copied file.");
 5105 
 5106 out:
 5107     if (dict)
 5108         dict_unref(dict);
 5109     cli_cmd_broadcast_response(ret);
 5110     gf_free_xdr_cli_rsp(rsp);
 5111     return ret;
 5112 }
 5113 
 5114 static int
 5115 gf_cli_gsync_set_cbk(struct rpc_req *req, struct iovec *iov, int count,
 5116                      void *myframe)
 5117 {
 5118     int ret = -1;
 5119     gf_cli_rsp rsp = {
 5120         0,
 5121     };
 5122     dict_t *dict = NULL;
 5123     char *gsync_status = NULL;
 5124     char *master = NULL;
 5125     char *slave = NULL;
 5126     int32_t type = 0;
 5127     gf_boolean_t status_detail = _gf_false;
 5128 
 5129     GF_ASSERT(myframe);
 5130 
 5131     if (req->rpc_status == -1) {
 5132         goto out;
 5133     }
 5134 
 5135     ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
 5136     if (ret < 0) {
 5137         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 5138                XDR_DECODE_FAIL);
 5139         goto out;
 5140     }
 5141 
 5142     dict = dict_new();
 5143 
 5144     if (!dict) {
 5145         ret = -1;
 5146         goto out;
 5147     }
 5148 
 5149     ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
 5150 
 5151     if (ret)
 5152         goto out;
 5153 
 5154     if (global_state->mode & GLUSTER_MODE_XML) {
 5155         ret = cli_xml_output_vol_gsync(dict, rsp.op_ret, rsp.op_errno,
 5156                                        rsp.op_errstr);
 5157         if (ret)
 5158             gf_log("cli", GF_LOG_ERROR, XML_ERROR);
 5159         goto out;
 5160     }
 5161 
 5162     if (rsp.op_ret) {
 5163         cli_err("%s",
 5164                 rsp.op_errstr ? rsp.op_errstr : GEOREP " command unsuccessful");
 5165         ret = rsp.op_ret;
 5166         goto out;
 5167     }
 5168 
 5169     ret = dict_get_str_sizen(dict, "gsync-status", &gsync_status);
 5170     if (!ret)
 5171         cli_out("%s", gsync_status);
 5172 
 5173     ret = dict_get_int32_sizen(dict, "type", &type);
 5174     if (ret) {
 5175         gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
 5176                "failed to get type");
 5177         goto out;
 5178     }
 5179 
 5180     switch (type) {
 5181         case GF_GSYNC_OPTION_TYPE_START:
 5182         case GF_GSYNC_OPTION_TYPE_STOP:
 5183             if (dict_get_str_sizen(dict, "master", &master) != 0)
 5184                 master = "???";
 5185             if (dict_get_str_sizen(dict, "slave", &slave) != 0)
 5186                 slave = "???";
 5187 
 5188             cli_out(
 5189                 "%s " GEOREP " session between %s & %s has been successful",
 5190                 type == GF_GSYNC_OPTION_TYPE_START ? "Starting" : "Stopping",
 5191                 master, slave);
 5192             break;
 5193 
 5194         case GF_GSYNC_OPTION_TYPE_PAUSE:
 5195         case GF_GSYNC_OPTION_TYPE_RESUME:
 5196             if (dict_get_str_sizen(dict, "master", &master) != 0)
 5197                 master = "???";
 5198             if (dict_get_str_sizen(dict, "slave", &slave) != 0)
 5199                 slave = "???";
 5200 
 5201             cli_out("%s " GEOREP " session between %s & %s has been successful",
 5202                     type == GF_GSYNC_OPTION_TYPE_PAUSE ? "Pausing" : "Resuming",
 5203                     master, slave);
 5204             break;
 5205 
 5206         case GF_GSYNC_OPTION_TYPE_CONFIG:
 5207             ret = gf_cli_gsync_config_command(dict);
 5208             break;
 5209 
 5210         case GF_GSYNC_OPTION_TYPE_STATUS:
 5211             status_detail = dict_get_str_boolean(dict, "status-detail",
 5212                                                  _gf_false);
 5213             ret = gf_cli_gsync_status_output(dict, status_detail);
 5214             break;
 5215 
 5216         case GF_GSYNC_OPTION_TYPE_DELETE:
 5217             if (dict_get_str_sizen(dict, "master", &master) != 0)
 5218                 master = "???";
 5219             if (dict_get_str_sizen(dict, "slave", &slave) != 0)
 5220                 slave = "???";
 5221             cli_out("Deleting " GEOREP
 5222                     " session between %s & %s has been successful",
 5223                     master, slave);
 5224             break;
 5225 
 5226         case GF_GSYNC_OPTION_TYPE_CREATE:
 5227             if (dict_get_str_sizen(dict, "master", &master) != 0)
 5228                 master = "???";
 5229             if (dict_get_str_sizen(dict, "slave", &slave) != 0)
 5230                 slave = "???";
 5231             cli_out("Creating " GEOREP
 5232                     " session between %s & %s has been successful",
 5233                     master, slave);
 5234             break;
 5235 
 5236         default:
 5237             cli_out(GEOREP " command executed successfully");
 5238     }
 5239 
 5240 out:
 5241     if (dict)
 5242         dict_unref(dict);
 5243     cli_cmd_broadcast_response(ret);
 5244     gf_free_xdr_cli_rsp(rsp);
 5245     return ret;
 5246 }
 5247 
 5248 static int32_t
 5249 gf_cli_sys_exec(call_frame_t *frame, xlator_t *this, void *data)
 5250 {
 5251     int ret = 0;
 5252     dict_t *dict = NULL;
 5253     gf_cli_req req = {{
 5254         0,
 5255     }};
 5256 
 5257     dict = data;
 5258 
 5259     ret = cli_to_glusterd(&req, frame, gf_cli_sys_exec_cbk,
 5260                           (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_SYS_EXEC,
 5261                           this, cli_rpc_prog, NULL);
 5262     if (ret)
 5263         if (!frame || !this || !data) {
 5264             ret = -1;
 5265             gf_log("cli", GF_LOG_ERROR, "Invalid data");
 5266         }
 5267 
 5268     GF_FREE(req.dict.dict_val);
 5269     return ret;
 5270 }
 5271 
 5272 static int32_t
 5273 gf_cli_copy_file(call_frame_t *frame, xlator_t *this, void *data)
 5274 {
 5275     int ret = 0;
 5276     dict_t *dict = NULL;
 5277     gf_cli_req req = {{
 5278         0,
 5279     }};
 5280 
 5281     dict = data;
 5282 
 5283     ret = cli_to_glusterd(&req, frame, gf_cli_copy_file_cbk,
 5284                           (xdrproc_t)xdr_gf_cli_req, dict,
 5285                           GLUSTER_CLI_COPY_FILE, this, cli_rpc_prog, NULL);
 5286     if (ret)
 5287         if (!frame || !this || !data) {
 5288             ret = -1;
 5289             gf_log("cli", GF_LOG_ERROR, "Invalid data");
 5290         }
 5291 
 5292     GF_FREE(req.dict.dict_val);
 5293     return ret;
 5294 }
 5295 
 5296 static int32_t
 5297 gf_cli_gsync_set(call_frame_t *frame, xlator_t *this, void *data)
 5298 {
 5299     int ret = 0;
 5300     dict_t *dict = NULL;
 5301     gf_cli_req req = {{
 5302         0,
 5303     }};
 5304 
 5305     dict = data;
 5306 
 5307     ret = cli_to_glusterd(&req, frame, gf_cli_gsync_set_cbk,
 5308                           (xdrproc_t)xdr_gf_cli_req, dict,
 5309                           GLUSTER_CLI_GSYNC_SET, this, cli_rpc_prog, NULL);
 5310