diff options
Diffstat (limited to 'tools/pvchange.c')
-rw-r--r-- | tools/pvchange.c | 120 |
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; } |