tools/virsh.c: New helper function vshStringToArray, use the helper
in cmdUndefine.
---
tools/virsh.c | 107 +++++++++++++++++++++++++++++++++++----------------------
1 files changed, 66 insertions(+), 41 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 40f3be3..9c3b565 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3014,6 +3014,51 @@ static const vshCmdOptDef opts_undefine[] = {
{NULL, 0, 0, NULL}
};
+/*
+ * Convert the strings separated by ',' into array. The caller
+ * must free the returned array after use.
+ *
+ * Returns the length of the filled array on success, or -1
+ * on error.
+ */
+static int
+vshStringToArray(char *str,
+ char ***array)
+{
+ char *str_tok = NULL;
+ unsigned int nstr_tokens = 0;
+ char **arr = NULL;
+
+ /* tokenize the string from user and save it's parts into an array */
+ if (str) {
+ nstr_tokens = 1;
+
+ /* count the delimiters */
+ str_tok = str;
+ while (*str_tok) {
+ if (*str_tok == ',')
+ nstr_tokens++;
+ str_tok++;
+ }
+
+ if (VIR_ALLOC_N(arr, nstr_tokens) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ /* tokenize the input string */
+ nstr_tokens = 0;
+ str_tok = str;
+ do {
+ arr[nstr_tokens] = strsep(&str_tok, ",");
+ nstr_tokens++;
+ } while (str_tok);
+ }
+
+ *array = arr;
+ return nstr_tokens;
+}
+
static bool
cmdUndefine(vshControl *ctl, const vshCmd *cmd)
{
@@ -3039,21 +3084,21 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
int running;
/* list of volumes to remove along with this domain */
const char *volumes_arg = NULL;
- char *volumes = NULL;
- char **volume_tokens = NULL;
- char *volume_tok = NULL;
- int nvolume_tokens = 0;
+ char *volumes_str = NULL;
+ char **volumes = NULL;
+ char *volume = NULL;
+ int volumes_len = 0;
char *def = NULL;
char *source = NULL;
char *target = NULL;
int vol_i;
- int tok_i;
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlNodePtr *vol_nodes = NULL;
int nvolumes = 0;
virStorageVolPtr vol = NULL;
bool vol_del_failed = false;
+ int i;
if (managed_save) {
flags |= VIR_DOMAIN_UNDEFINE_MANAGED_SAVE;
@@ -3072,7 +3117,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
/* check if a string that should contain list of volumes to remove is present */
if (vshCommandOptString(cmd, "storage", &volumes_arg) > 0) {
- volumes = vshStrdup(ctl, volumes_arg);
+ volumes_str = vshStrdup(ctl, volumes_arg);
if (remove_all_storage) {
vshError(ctl, _("Specified both --storage and
--remove-all-storage"));
@@ -3212,27 +3257,8 @@ out:
if (remove_storage || remove_all_storage) {
ret = false;
- /* tokenize the string from user and save it's parts into an array */
- if (volumes) {
- /* count the delimiters */
- volume_tok = volumes;
- nvolume_tokens = 1; /* we need at least one member */
- while (*volume_tok) {
- if (*volume_tok == ',')
- nvolume_tokens++;
- volume_tok++;
- }
-
- volume_tokens = vshCalloc(ctl, nvolume_tokens, sizeof(char *));
-
- /* tokenize the input string */
- nvolume_tokens = 0;
- volume_tok = volumes;
- do {
- volume_tokens[nvolume_tokens] = strsep(&volume_tok, ",");
- nvolume_tokens++;
- } while (volume_tok);
- }
+ if ((volumes_len = vshStringToArray(volumes_str, &volumes)) < 0)
+ goto cleanup;
doc = virXMLParseStringCtxt(def, _("(domain_definition)"), &ctxt);
if (!doc)
@@ -3268,17 +3294,17 @@ out:
/* lookup if volume was selected by user */
if (volumes) {
- volume_tok = NULL;
- for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) {
- if (volume_tokens[tok_i] &&
- (STREQ_NULLABLE(volume_tokens[tok_i], target) ||
- STREQ_NULLABLE(volume_tokens[tok_i], source))) {
- volume_tok = volume_tokens[tok_i];
- volume_tokens[tok_i] = NULL;
+ volume = NULL;
+ for (i = 0; i < volumes_len; i++) {
+ if (volumes[i] &&
+ (STREQ_NULLABLE(volumes[i], target) ||
+ STREQ_NULLABLE(volumes[i], source))) {
+ volume = volumes[i];
+ volumes[i] = NULL;
break;
}
}
- if (!volume_tok)
+ if (!volume)
continue;
}
@@ -3311,16 +3337,16 @@ out:
target, source);
vol_del_failed = true;
}
- vshPrint(ctl, _("Volume '%s' removed.\n"),
volume_tok?volume_tok:source);
+ vshPrint(ctl, _("Volume '%s' removed.\n"), volume ? volume
:source);
}
/* print volumes specified by user that were not found in domain definition */
if (volumes) {
- for (tok_i = 0; tok_i < nvolume_tokens; tok_i++) {
- if (volume_tokens[tok_i])
+ for (i = 0; i < volumes_len; i++) {
+ if (volumes[i])
vshPrint(ctl, _("Volume '%s' was not found in
domain's "
"definition.\n"),
- volume_tokens[tok_i]);
+ volumes[i]);
}
}
@@ -3331,8 +3357,8 @@ out:
cleanup:
VIR_FREE(source);
VIR_FREE(target);
+ VIR_FREE(volumes_str);
VIR_FREE(volumes);
- VIR_FREE(volume_tokens);
VIR_FREE(def);
VIR_FREE(vol_nodes);
if (vol)
@@ -3343,7 +3369,6 @@ cleanup:
return ret;
}
-
/*
* "start" command
*/
--
1.7.7.3