diff options
| -rw-r--r-- | cli/src/cli-xml-output.c | 96 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 43 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 126 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | 
4 files changed, 260 insertions, 7 deletions
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c index 5218e19e91d..4daf83e1dbf 100644 --- a/cli/src/cli-xml-output.c +++ b/cli/src/cli-xml-output.c @@ -1383,6 +1383,86 @@ out:  #if (HAVE_LIB_XML)  int +cli_xml_output_remove_brick_task_params (xmlTextWriterPtr writer, dict_t *dict, +                                         char *prefix) +{ +        int             ret = -1; +        char            key[1024] = {0,}; +        int             count = 0; +        int             i = 0; +        char            *brick = NULL; + +        /* <params> */ +        ret = xmlTextWriterStartElement (writer, (xmlChar *)"params"); +        XML_RET_CHECK_AND_GOTO (ret, out); + +        snprintf (key, sizeof (key), "%s.count", prefix); +        ret = dict_get_int32 (dict, key, &count); +        if (ret) +                goto out; + +        for (i = 1; i <= count; i++) { +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "%s.brick%d", prefix, i); +                ret = dict_get_str (dict, key, &brick); +                if (ret) +                        goto out; +                ret = xmlTextWriterWriteFormatElement (writer, +                                                       (xmlChar *)"brick", +                                                       "%s", brick); +                XML_RET_CHECK_AND_GOTO (ret, out); +                brick = NULL; +        } + +        /* </param> */ +        ret = xmlTextWriterEndElement (writer); + +out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int +cli_xml_output_replace_brick_task_params (xmlTextWriterPtr writer, dict_t *dict, +                                          char *prefix) +{ + +        int             ret = -1; +        char            key[1024] = {0,}; +        char            *brick = NULL; + +        /* <params> */ +        ret = xmlTextWriterStartElement (writer, (xmlChar *)"params"); +        XML_RET_CHECK_AND_GOTO (ret, out); + +        snprintf (key, sizeof (key), "%s.src-brick", prefix); +        ret = dict_get_str (dict, key, &brick); +        if (ret) +                goto out; +        ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"srcBrick", +                                               "%s", brick); +        XML_RET_CHECK_AND_GOTO (ret, out); + + +        memset (key, 0, sizeof (key)); +        snprintf (key, sizeof (key), "%s.dst-brick", prefix); +        ret = dict_get_str (dict, key, &brick); +        if (ret) +                goto out; +        ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"dstBrick", +                                               "%s", brick); +        XML_RET_CHECK_AND_GOTO (ret, out); + + +        /* </param> */ +        ret = xmlTextWriterEndElement (writer); + +out: +        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int  cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {          int                     ret = -1;          char                    *task_type = NULL; @@ -1451,6 +1531,21 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {                  XML_RET_CHECK_AND_GOTO (ret, out); +                memset (key, 0, sizeof (key)); +                snprintf (key, sizeof (key), "task%d", i); +                if (!strcmp (task_type, "Replace brick")) { +                        ret = cli_xml_output_replace_brick_task_params +                                (local->writer, dict, key); +                        if (ret) +                                goto out; +                } else if (!strcmp (task_type, "Remove brick")) { +                        ret = cli_xml_output_remove_brick_task_params +                                (local->writer, dict, key); +                        if (ret) +                                goto out; +                } + +                  /* </task> */                  ret = xmlTextWriterEndElement (local->writer);                  XML_RET_CHECK_AND_GOTO (ret, out); @@ -1459,7 +1554,6 @@ cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {          /* </tasks> */          ret = xmlTextWriterEndElement (local->writer); -  out:          gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);          return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 81ba31bfeec..3088f21949d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -1684,6 +1684,8 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)          glusterd_brickinfo_t    *tmp           = NULL;          char                    *task_id_str   = NULL;          xlator_t                *this          = NULL; +        dict_t                  *bricks_dict   = NULL; +        char                    *brick_tmpstr  = NULL;          this = THIS;          GF_ASSERT (this); @@ -1724,10 +1726,13 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                  }          } -        /* Clear task-id & rebal.op on commmitting/stopping remove-brick */ +        /* Clear task-id, rebal.op and stored bricks on commmitting/stopping +         * remove-brick */          if ((cmd != GF_OP_CMD_START) || (cmd != GF_OP_CMD_STATUS)) {                  uuid_clear (volinfo->rebal.rebalance_id);                  volinfo->rebal.op = GD_OP_NONE; +                dict_unref (volinfo->rebal.dict); +                volinfo->rebal.dict = NULL;          }          ret = -1; @@ -1812,7 +1817,20 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                  goto out;          } - +        /* Save the list of bricks for later usage. Right now this is required +         * for displaying the task parameters with task status in volume status. +         */ +        bricks_dict = dict_new (); +        if (!bricks_dict) { +                ret = -1; +                goto out; +        } +        ret = dict_set_int32 (bricks_dict, "count", count); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Failed to save remove-brick count"); +                goto out; +        }          while ( i <= count) {                  snprintf (key, 256, "brick%d", i);                  ret = dict_get_str (dict, key, &brick); @@ -1822,6 +1840,21 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                          goto out;                  } +                brick_tmpstr = gf_strdup (brick); +                if (!brick_tmpstr) { +                        ret = -1; +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to duplicate brick name"); +                        goto out; +                } +                ret = dict_set_dynstr (bricks_dict, key, brick_tmpstr); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to add brick to dict"); +                        goto out; +                } +                brick_tmpstr = NULL; +                  ret = glusterd_op_perform_remove_brick (volinfo, brick, force,                                                          &need_rebalance);                  if (ret) @@ -1852,6 +1885,8 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                          }                  }          } +        volinfo->rebal.dict = bricks_dict; +        bricks_dict = NULL;          ret = glusterd_create_volfiles_and_notify_services (volinfo);          if (ret) { @@ -1896,5 +1931,9 @@ out:          if (ret && err_str[0] && op_errstr)                  *op_errstr = gf_strdup (err_str); +        GF_FREE (brick_tmpstr); +        if (bricks_dict) +                dict_unref (bricks_dict); +          return ret;  } diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index f1e1e0652a2..01f19164041 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1901,6 +1901,105 @@ out:  }  static int +_add_brick_name_to_dict (dict_t *dict, char *key, glusterd_brickinfo_t *brick) +{ +        int     ret = -1; +        char    tmp[1024] = {0,}; +        char    *brickname = NULL; +        xlator_t *this = NULL; + +        GF_ASSERT (dict); +        GF_ASSERT (key); +        GF_ASSERT (brick); + +        this = THIS; +        GF_ASSERT (this); + +        snprintf (tmp, sizeof (tmp), "%s:%s", brick->hostname, brick->path); +        brickname = gf_strdup (tmp); +        if (!brickname) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to dup brick name"); +                goto out; +        } + +        ret = dict_set_dynstr (dict, key, brickname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Failed to add brick name to dict"); +                goto out; +        } +        brickname = NULL; +out: +        if (brickname) +                GF_FREE (brickname); +        return ret; +} + +static int +_add_remove_bricks_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, +                            char *prefix) +{ +        int             ret = -1; +        int             count = 0; +        int             i = 0; +        char            brick_key[1024] = {0,}; +        char            dict_key[1024] ={0,}; +        char            *brick = NULL; +        xlator_t        *this = NULL; + +        GF_ASSERT (dict); +        GF_ASSERT (volinfo); +        GF_ASSERT (prefix); + +        this = THIS; +        GF_ASSERT (this); + +        ret = dict_get_int32 (volinfo->rebal.dict, "count", &count); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Failed to get brick count"); +                goto out; +        } + +        snprintf (dict_key, sizeof (dict_key), "%s.count", prefix); +        ret = dict_set_int32 (dict, dict_key, count); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Failed to set brick count in dict"); +                goto out; +        } + +        for (i = 1; i <= count; i++) { +                memset (brick_key, 0, sizeof (brick_key)); +                snprintf (brick_key, sizeof (brick_key), "brick%d", i); + +                ret = dict_get_str (volinfo->rebal.dict, brick_key, &brick); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Unable to get %s", brick_key); +                        goto out; +                } + +                memset (dict_key, 0, sizeof (dict_key)); +                snprintf (dict_key, sizeof (dict_key), "%s.%s", prefix, +                          brick_key); +                ret = dict_set_str (dict, dict_key, brick); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to add brick to dict"); +                        goto out; +                } +                brick = NULL; +        } + +out: +        return ret; +} + +/* This adds the respective task-id and all available parameters of a task into + * a dictionary + */ +static int  _add_task_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index)  { @@ -1917,13 +2016,34 @@ _add_task_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index)          GF_ASSERT (this);          switch (op) { -        case GD_OP_REBALANCE:          case GD_OP_REMOVE_BRICK: +                snprintf (key, sizeof (key), "task%d", index); +                ret = _add_remove_bricks_to_dict (dict, volinfo, key); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "Failed to add remove bricks to dict"); +                        goto out; +                } +        case GD_OP_REBALANCE:                  uuid_str = gf_strdup (uuid_utoa (volinfo->rebal.rebalance_id));                  status = volinfo->rebal.defrag_status;                  break;          case GD_OP_REPLACE_BRICK: +                snprintf (key, sizeof (key), "task%d.src-brick", index); +                ret = _add_brick_name_to_dict (dict, key, +                                               volinfo->rep_brick.src_brick); +                if (ret) +                        goto out; +                memset (key, 0, sizeof (key)); + +                snprintf (key, sizeof (key), "task%d.dst-brick", index); +                ret = _add_brick_name_to_dict (dict, key, +                                               volinfo->rep_brick.dst_brick); +                if (ret) +                        goto out; +                memset (key, 0, sizeof (key)); +                  uuid_str = gf_strdup (uuid_utoa (volinfo->rep_brick.rb_id));                  status = volinfo->rep_brick.rb_status;                  break; @@ -1936,8 +2056,7 @@ _add_task_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index)          }          snprintf (key, sizeof (key), "task%d.type", index); -        ret = dict_set_str (dict, key, -                            (char *)gd_op_list[op]); +        ret = dict_set_str (dict, key, (char *)gd_op_list[op]);          if (ret) {                  gf_log (this->name, GF_LOG_ERROR,                          "Error setting task type in dict"); @@ -1947,7 +2066,6 @@ _add_task_to_dict (dict_t *dict, glusterd_volinfo_t *volinfo, int op, int index)          memset (key, 0, sizeof (key));          snprintf (key, sizeof (key), "task%d.id", index); -          if (!uuid_str)                  goto out;          ret = dict_set_dynstr (dict, key, uuid_str); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 18367d7c91d..227efdd6bd3 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -247,6 +247,8 @@ struct glusterd_rebalance_ {          uuid_t                  rebalance_id;          double                  rebalance_time;          glusterd_op_t           op; +        dict_t                  *dict; /* Dict to store misc information +                                        * like list of bricks being removed */  };  typedef struct glusterd_rebalance_ glusterd_rebalance_t;  | 
