diff options
Diffstat (limited to 'tools/vgextend.c')
-rw-r--r-- | tools/vgextend.c | 167 |
1 files changed, 96 insertions, 71 deletions
diff --git a/tools/vgextend.c b/tools/vgextend.c index 2dc169980..afe67f575 100644 --- a/tools/vgextend.c +++ b/tools/vgextend.c @@ -15,7 +15,13 @@ #include "tools.h" -static int _restore_pv(struct volume_group *vg, char *pv_name) +struct pvcreate_params_args { + struct pvcreate_params pp; + int pv_count; + const char *const *pv_names; +}; + +static int _restore_pv(struct volume_group *vg, const char *pv_name) { struct pv_list *pvl = NULL; pvl = find_pv_in_vg(vg, pv_name); @@ -38,13 +44,81 @@ static int _restore_pv(struct volume_group *vg, char *pv_name) return 1; } +static int vgextend_restore(struct cmd_context *cmd __attribute__((unused)), const char *vg_name, + struct volume_group *vg, void *handle) +{ + struct pvcreate_params_args *ppa = handle; + int fixed = 0; + int i; + + for (i = 0; i < ppa->pv_count; i++) { + if (_restore_pv(vg, ppa->pv_names[i])) + fixed++; + } + + if (!fixed) { + log_error("No PV has been restored."); + return ECMD_FAILED; + } + + if (!vg_write(vg) || !vg_commit(vg)) + return ECMD_FAILED; + + backup(vg); + + log_print_unless_silent("Volume group \"%s\" successfully extended", vg_name); + + return ECMD_PROCESSED; +} + +static int vgextend_single(struct cmd_context *cmd, const char *vg_name, + struct volume_group *vg, void *handle) +{ + struct pvcreate_params_args *ppa = handle; + struct pvcreate_params *pp = &ppa->pp; + uint32_t mda_copies; + uint32_t mda_used; + + if (arg_count(cmd, metadataignore_ARG) && + (pp->force == PROMPT) && !pp->yes && + (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) && + (yes_no_prompt("Override preferred number of copies of VG %s metadata? [y/n]: ", vg_name) == 'n')) { + log_error("Volume group %s not changed", vg_name); + return ECMD_FAILED; + } + + if (!vg_extend(vg, ppa->pv_count, ppa->pv_names, pp)) + return ECMD_FAILED; + + if (arg_count(cmd, metadataignore_ARG)) { + mda_copies = vg_mda_copies(vg); + mda_used = vg_mda_used_count(vg); + + if ((mda_copies != VGMETADATACOPIES_UNMANAGED) && + (mda_copies != mda_used)) { + log_warn("WARNING: Changing preferred number of copies of VG %s metadata from %"PRIu32" to %"PRIu32, + vg_name, mda_copies, mda_used); + vg_set_mda_copies(vg, mda_used); + } + + } + + log_verbose("Volume group \"%s\" will be extended by %d new physical volumes", vg_name, ppa->pv_count); + + if (!vg_write(vg) || !vg_commit(vg)) + return ECMD_FAILED; + + backup(vg); + + log_print_unless_silent("Volume group \"%s\" successfully extended", vg_name); + + return ECMD_PROCESSED; +} + int vgextend(struct cmd_context *cmd, int argc, char **argv) { - const char *vg_name; - struct volume_group *vg = NULL; - int r = ECMD_FAILED; - struct pvcreate_params pp; - int fixed = 0, i = 0; + struct pvcreate_params_args ppa; + int ret; if (!argc) { log_error("Please enter volume group name and " @@ -52,19 +126,18 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } - vg_name = skip_dev_dir(cmd, argv[0], NULL); - argc--; - argv++; - if (arg_count(cmd, metadatacopies_ARG)) { log_error("Invalid option --metadatacopies, " "use --pvmetadatacopies instead."); return EINVALID_CMD_LINE; } - pvcreate_params_set_defaults(&pp); - if (!pvcreate_params_validate(cmd, argc, argv, &pp)) { + + pvcreate_params_set_defaults(&ppa.pp); + ppa.pv_count = argc - 1; + ppa.pv_names = (const char* const*)(argv + 1); + + if (!pvcreate_params_validate(cmd, ppa.pv_count, &ppa.pp)) return EINVALID_CMD_LINE; - } /* * It is always ok to add new PVs to a VG - even if there are @@ -74,71 +147,23 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) */ cmd->handles_missing_pvs = 1; - log_verbose("Checking for volume group \"%s\"", vg_name); - vg = vg_read_for_update(cmd, vg_name, NULL, 0); - if (vg_read_error(vg)) { - release_vg(vg); - return_ECMD_FAILED; - } - - if (!archive(vg)) - goto_bad; - if (arg_count(cmd, restoremissing_ARG)) { - for (i = 0; i < argc; ++i) { - if (_restore_pv(vg, argv[i])) - ++ fixed; - } - if (!fixed) { - log_error("No PV has been restored."); - goto bad; - } - } else { /* no --restore, normal vgextend */ + ret = process_each_vg(cmd, argc, argv, + READ_FOR_UPDATE | ONLY_FIRST_NAME, &ppa, + &vgextend_restore); + + } else { if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) { log_error("Can't get lock for orphan PVs"); - unlock_and_release_vg(cmd, vg, vg_name); return ECMD_FAILED; } - if (arg_count(cmd, metadataignore_ARG) && - (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) && - (pp.force == PROMPT) && !pp.yes && - yes_no_prompt("Override preferred number of copies " - "of VG %s metadata? [y/n]: ", - vg_name) == 'n') { - log_error("Volume group %s not changed", vg_name); - goto bad; - } + ret = process_each_vg(cmd, argc, argv, + READ_FOR_UPDATE | ONLY_FIRST_NAME, &ppa, + &vgextend_single); - /* extend vg */ - if (!vg_extend(vg, argc, (const char* const*)argv, &pp)) - goto_bad; - - if (arg_count(cmd, metadataignore_ARG) && - (vg_mda_copies(vg) != VGMETADATACOPIES_UNMANAGED) && - (vg_mda_copies(vg) != vg_mda_used_count(vg))) { - log_warn("WARNING: Changing preferred number of copies of VG %s " - "metadata from %"PRIu32" to %"PRIu32, vg_name, - vg_mda_copies(vg), vg_mda_used_count(vg)); - vg_set_mda_copies(vg, vg_mda_used_count(vg)); - } - - /* ret > 0 */ - log_verbose("Volume group \"%s\" will be extended by %d new " - "physical volumes", vg_name, argc); + unlock_vg(cmd, VG_ORPHANS); } - /* store vg on disk(s) */ - if (!vg_write(vg) || !vg_commit(vg)) - goto_bad; - - backup(vg); - log_print_unless_silent("Volume group \"%s\" successfully extended", vg_name); - r = ECMD_PROCESSED; - -bad: - if (!arg_count(cmd, restoremissing_ARG)) - unlock_vg(cmd, VG_ORPHANS); - unlock_and_release_vg(cmd, vg, vg_name); - return r; + return ret; } |