summaryrefslogtreecommitdiff
path: root/tools/pvchange.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pvchange.c')
-rw-r--r--tools/pvchange.c120
1 files changed, 49 insertions, 71 deletions
diff --git a/tools/pvchange.c b/tools/pvchange.c
index 28e71b8..70f1e62 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -15,8 +15,6 @@
#include "tools.h"
-/* FIXME Locking. PVs in VG. */
-
static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv,
void *handle __attribute__((unused)))
@@ -27,21 +25,14 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
uint64_t orig_pe_start;
const char *pv_name = pv_dev_name(pv);
- const char *tag = NULL;
const char *orig_vg_name;
char uuid[64] __attribute__((aligned(8)));
int allocatable = 0;
- int tagarg = 0;
- int r = 0;
+ int tagargs = 0;
int mda_ignore = 0;
- struct arg_value_group_list *current_group;
-
- if (arg_count(cmd, addtag_ARG))
- tagarg = addtag_ARG;
- else if (arg_count(cmd, deltag_ARG))
- tagarg = deltag_ARG;
+ tagargs = arg_count(cmd, addtag_ARG) + arg_count(cmd, deltag_ARG);
if (arg_count(cmd, allocatable_ARG))
allocatable = !strcmp(arg_str_value(cmd, allocatable_ARG, "n"),
@@ -52,20 +43,20 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
/* If in a VG, must change using volume group. */
if (!is_orphan(pv)) {
- if (tagarg && !(vg->fid->fmt->features & FMT_TAGS)) {
+ if (tagargs && !(vg->fid->fmt->features & FMT_TAGS)) {
log_error("Volume group containing %s does not "
"support tags", pv_name);
- goto out;
+ return 0;
}
if (arg_count(cmd, uuid_ARG) && lvs_in_vg_activated(vg)) {
log_error("Volume group containing %s has active "
"logical volumes", pv_name);
- goto out;
+ return 0;
}
if (!archive(vg))
- goto out;
+ return 0;
} else {
- if (tagarg) {
+ if (tagargs) {
log_error("Can't change tag on Physical Volume %s not "
"in volume group", pv_name);
return 0;
@@ -77,22 +68,20 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
!(pv->fmt->features & FMT_ORPHAN_ALLOCATABLE)) {
log_error("Allocatability not supported by orphan "
"%s format PV %s", pv->fmt->name, pv_name);
- goto out;
+ return 0;
}
/* change allocatability for a PV */
if (allocatable && (pv_status(pv) & ALLOCATABLE_PV)) {
log_error("Physical volume \"%s\" is already "
"allocatable", pv_name);
- r = 1;
- goto out;
+ return 1;
}
if (!allocatable && !(pv_status(pv) & ALLOCATABLE_PV)) {
log_error("Physical volume \"%s\" is already "
"unallocatable", pv_name);
- r = 1;
- goto out;
+ return 1;
}
if (allocatable) {
@@ -104,50 +93,41 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
"allocatable", pv_name);
pv->status &= ~ALLOCATABLE_PV;
}
- } else if (tagarg) {
- /* tag or deltag */
+ }
- dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
- if (!grouped_arg_is_set(current_group->arg_values, tagarg))
- continue;
+ if (tagargs) {
+ /* tag or deltag */
+ if (arg_count(cmd, addtag_ARG) && !change_tag(cmd, NULL, NULL, pv, addtag_ARG))
+ return_0;
- if (!(tag = grouped_arg_str_value(current_group->arg_values, tagarg, NULL))) {
- log_error("Failed to get tag");
- goto out;
- }
+ if (arg_count(cmd, deltag_ARG) && !change_tag(cmd, NULL, NULL, pv, deltag_ARG))
+ return_0;
+
+ }
- if ((tagarg == addtag_ARG)) {
- if (!str_list_add(cmd->mem, &pv->tags, tag)) {
- log_error("Failed to add tag %s to physical "
- "volume %s", tag, pv_name);
- goto out;
- }
- } else if (!str_list_del(&pv->tags, tag)) {
- log_error("Failed to remove tag %s from "
- "physical volume" "%s", tag, pv_name);
- goto out;
- }
- }
- } else if (arg_count(cmd, metadataignore_ARG)) {
+ if (arg_count(cmd, metadataignore_ARG)) {
if ((vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) &&
(arg_count(cmd, force_ARG) == PROMPT) &&
yes_no_prompt("Override preferred number of copies "
"of VG %s metadata? [y/n]: ",
pv_vg_name(pv)) == 'n') {
log_error("Physical volume %s not changed", pv_name);
- goto out;
+ return 0;
}
if (!pv_change_metadataignore(pv, mda_ignore))
- goto out;
- } else {
+ return_0;
+ }
+
+ if (arg_count(cmd, uuid_ARG)) {
/* --uuid: Change PV ID randomly */
+ memcpy(&pv->old_id, &pv->id, sizeof(pv->id));
if (!id_create(&pv->id)) {
log_error("Failed to generate new random UUID for %s.",
pv_name);
- goto out;
+ return 0;
}
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
- goto_out;
+ return 0;
log_verbose("Changing uuid of %s to %s.", pv_name, uuid);
if (!is_orphan(pv)) {
orig_vg_name = pv_vg_name(pv);
@@ -160,10 +140,10 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
pv->vg_name = pv->fmt->orphan_vg_name;
pv->pe_alloc_count = 0;
- if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+ if (!(pv_write(cmd, pv, 0))) {
log_error("pv_write with new uuid failed "
"for %s.", pv_name);
- goto out;
+ return 0;
}
pv->vg_name = orig_vg_name;
pv->pe_alloc_count = orig_pe_alloc_count;
@@ -179,20 +159,18 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
if (!vg_write(vg) || !vg_commit(vg)) {
log_error("Failed to store physical volume \"%s\" in "
"volume group \"%s\"", pv_name, vg->name);
- goto out;
+ return 0;
}
backup(vg);
- } else if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+ } else if (!(pv_write(cmd, pv, 0))) {
log_error("Failed to store physical volume \"%s\"",
pv_name);
- goto out;
+ return 0;
}
- log_print("Physical volume \"%s\" changed", pv_name);
- r = 1;
-out:
- return r;
+ log_print_unless_silent("Physical volume \"%s\" changed", pv_name);
+ return 1;
}
int pvchange(struct cmd_context *cmd, int argc, char **argv)
@@ -209,11 +187,11 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
struct dm_list *vgnames;
struct str_list *sll;
- if (arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) +
+ if (!(arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) +
arg_is_set(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
- arg_count(cmd, metadataignore_ARG) != 1) {
- log_error("Please give exactly one option of -x, -uuid, "
- "--addtag or --deltag");
+ arg_count(cmd, metadataignore_ARG))) {
+ log_error("Please give one or more of -x, -uuid, "
+ "--addtag, --deltag or --metadataignore");
return EINVALID_CMD_LINE;
}
@@ -231,7 +209,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
log_verbose("Using physical volume(s) on command line");
for (; opt < argc; opt++) {
pv_name = argv[opt];
- unescape_colons_and_at_signs(pv_name, NULL, NULL);
+ dm_unescape_colons_and_at_signs(pv_name, NULL, NULL);
vg_name = find_vgname_from_pvname(cmd, pv_name);
if (!vg_name) {
log_error("Failed to read physical volume %s",
@@ -240,7 +218,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
}
vg = vg_read_for_update(cmd, vg_name, NULL, 0);
if (vg_read_error(vg)) {
- free_vg(vg);
+ release_vg(vg);
stack;
continue;
}
@@ -254,7 +232,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
total++;
done += _pvchange_single(cmd, vg,
pvl->pv, NULL);
- unlock_and_free_vg(cmd, vg, vg_name);
+ unlock_and_release_vg(cmd, vg, vg_name);
}
} else {
log_verbose("Scanning for physical volume names");
@@ -275,7 +253,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
dm_list_iterate_items(sll, vgnames) {
vg = vg_read_for_update(cmd, sll->str, NULL, 0);
if (vg_read_error(vg)) {
- free_vg(vg);
+ release_vg(vg);
stack;
continue;
}
@@ -285,16 +263,16 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
pvl->pv,
NULL);
}
- unlock_and_free_vg(cmd, vg, sll->str);
+ unlock_and_release_vg(cmd, vg, sll->str);
}
}
+ unlock_vg(cmd, VG_GLOBAL);
}
- unlock_vg(cmd, VG_GLOBAL);
- log_print("%d physical volume%s changed / %d physical volume%s "
- "not changed",
- done, done == 1 ? "" : "s",
- total - done, (total - done) == 1 ? "" : "s");
+ log_print_unless_silent("%d physical volume%s changed / %d physical volume%s "
+ "not changed",
+ done, done == 1 ? "" : "s",
+ total - done, (total - done) == 1 ? "" : "s");
return (total == done) ? ECMD_PROCESSED : ECMD_FAILED;
}