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 5218e19e..4daf83e1 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 81ba31bf..3088f219 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 f1e1e065..01f19164 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 18367d7c..227efdd6 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; |