static int _pvcreate_restore_params_from_backup(struct cmd_context *cmd, struct pvcreate_params *pp) { struct volume_group *vg; struct pv_list *existing_pvl; /* * When restoring a PV, params need to be read from a backup file. */ if (!pp->restorefile) return 1; if (!(vg = backup_read_vg(cmd, NULL, pp->restorefile))) { log_error("Unable to read volume group from %s", pp->restorefile); return 0; } if (!(existing_pvl = find_pv_in_vg_by_uuid(vg, &pp->pva.id))) { release_vg(vg); log_error("Can't find uuid %s in backup file %s", pp->uuid_str, pp->restorefile); return 0; } pp->pva.ba_start = pv_ba_start(existing_pvl->pv); pp->pva.ba_size = pv_ba_size(existing_pvl->pv); pp->pva.pe_start = pv_pe_start(existing_pvl->pv); pp->pva.extent_size = pv_pe_size(existing_pvl->pv); pp->pva.extent_count = pv_pe_count(existing_pvl->pv); release_vg(vg); return 1; }
static struct volume_group *_get_old_vg_for_rename(struct cmd_context *cmd, const char *vg_name_old, const char *vgid) { struct volume_group *vg; /* FIXME we used to print an error about EXPORTED, but proceeded nevertheless. */ vg = vg_read_for_update(cmd, vg_name_old, vgid, READ_ALLOW_EXPORTED); if (vg_read_error(vg)) { release_vg(vg); return_NULL; } return vg; }
/* * lvrename command implementation. * Check arguments and call lv_rename() to execute the request. */ int lvrename(struct cmd_context *cmd, int argc, char **argv) { size_t maxlen; char *lv_name_old, *lv_name_new; const char *vg_name, *vg_name_new, *vg_name_old; char *st; int r = ECMD_FAILED; struct volume_group *vg = NULL; struct lv_list *lvl; if (argc == 3) { vg_name = skip_dev_dir(cmd, argv[0], NULL); lv_name_old = argv[1]; lv_name_new = argv[2]; if (strchr(lv_name_old, '/') && (vg_name_old = extract_vgname(cmd, lv_name_old)) && strcmp(vg_name_old, vg_name)) { log_error("Please use a single volume group name " "(\"%s\" or \"%s\")", vg_name, vg_name_old); return EINVALID_CMD_LINE; } } else if (argc == 2) { lv_name_old = argv[0]; lv_name_new = argv[1]; vg_name = extract_vgname(cmd, lv_name_old); } else { log_error("Old and new logical volume names required"); return EINVALID_CMD_LINE; } if (!validate_name(vg_name)) { log_error("Please provide a valid volume group name"); return EINVALID_CMD_LINE; } if (strchr(lv_name_new, '/') && (vg_name_new = extract_vgname(cmd, lv_name_new)) && strcmp(vg_name, vg_name_new)) { log_error("Logical volume names must " "have the same volume group (\"%s\" or \"%s\")", vg_name, vg_name_new); return EINVALID_CMD_LINE; } if ((st = strrchr(lv_name_old, '/'))) lv_name_old = st + 1; if ((st = strrchr(lv_name_new, '/'))) lv_name_new = st + 1; /* Check sanity of new name */ maxlen = NAME_LEN - strlen(vg_name) - strlen(cmd->dev_dir) - 3; if (strlen(lv_name_new) > maxlen) { log_error("New logical volume path exceeds maximum length " "of %" PRIsize_t "!", maxlen); return ECMD_FAILED; } if (!*lv_name_new) { log_error("New logical volume name may not be blank"); return ECMD_FAILED; } if (!apply_lvname_restrictions(lv_name_new)) { stack; return ECMD_FAILED; } if (!validate_name(lv_name_new)) { log_error("New logical volume name \"%s\" is invalid", lv_name_new); return EINVALID_CMD_LINE; } if (!strcmp(lv_name_old, lv_name_new)) { log_error("Old and new logical volume names must differ"); return EINVALID_CMD_LINE; } log_verbose("Checking for existing volume group \"%s\"", vg_name); vg = vg_read_for_update(cmd, vg_name, NULL, 0); if (vg_read_error(vg)) { release_vg(vg); stack; return ECMD_FAILED; } if (!(lvl = find_lv_in_vg(vg, lv_name_old))) { log_error("Existing logical volume \"%s\" not found in " "volume group \"%s\"", lv_name_old, vg_name); goto error; } if (!lv_rename(cmd, lvl->lv, lv_name_new)) goto error; log_print("Renamed \"%s\" to \"%s\" in volume group \"%s\"", lv_name_old, lv_name_new, vg_name); r = ECMD_PROCESSED; error: unlock_and_release_vg(cmd, vg, vg_name); return r; }
/* * Intial sanity checking of recovery-related command-line arguments. * These args are: --restorefile, --uuid, and --physicalvolumesize * * Output arguments: * pp: structure allocated by caller, fields written / validated here */ static int pvcreate_restore_params_validate(struct cmd_context *cmd, int argc, char **argv, struct pvcreate_params *pp) { const char *uuid = NULL; struct volume_group *vg; struct pv_list *existing_pvl; if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) { log_error("--uuid is required with --restorefile"); return 0; } if (!arg_count(cmd, restorefile_ARG) && arg_count(cmd, uuidstr_ARG)) { if (!arg_count(cmd, norestorefile_ARG) && find_config_tree_bool(cmd, devices_require_restorefile_with_uuid_CFG, NULL)) { log_error("--restorefile is required with --uuid"); return 0; } } if (arg_count(cmd, uuidstr_ARG) && argc != 1) { log_error("Can only set uuid on one volume at once"); return 0; } if (arg_count(cmd, uuidstr_ARG)) { uuid = arg_str_value(cmd, uuidstr_ARG, ""); if (!id_read_format(&pp->rp.id, uuid)) return 0; pp->rp.idp = &pp->rp.id; lvmcache_seed_infos_from_lvmetad(cmd); /* need to check for UUID dups */ } if (arg_count(cmd, restorefile_ARG)) { pp->rp.restorefile = arg_str_value(cmd, restorefile_ARG, ""); /* The uuid won't already exist */ if (!(vg = backup_read_vg(cmd, NULL, pp->rp.restorefile))) { log_error("Unable to read volume group from %s", pp->rp.restorefile); return 0; } if (!(existing_pvl = find_pv_in_vg_by_uuid(vg, pp->rp.idp))) { release_vg(vg); log_error("Can't find uuid %s in backup file %s", uuid, pp->rp.restorefile); return 0; } pp->rp.ba_start = pv_ba_start(existing_pvl->pv); pp->rp.ba_size = pv_ba_size(existing_pvl->pv); pp->rp.pe_start = pv_pe_start(existing_pvl->pv); pp->rp.extent_size = pv_pe_size(existing_pvl->pv); pp->rp.extent_count = pv_pe_count(existing_pvl->pv); release_vg(vg); } if (arg_sign_value(cmd, physicalvolumesize_ARG, SIGN_NONE) == SIGN_MINUS) { log_error("Physical volume size may not be negative"); return 0; } pp->size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0)); if (arg_count(cmd, restorefile_ARG) || arg_count(cmd, uuidstr_ARG)) pp->zero = 0; return 1; }
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; if (!argc) { log_error("Please enter volume group name and " "physical volume(s)"); 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)) { return EINVALID_CMD_LINE; } /* * It is always ok to add new PVs to a VG - even if there are * missing PVs. No LVs are affected by this operation, but * repair processes - particularly for RAID segtypes - can * be facilitated. */ 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 */ 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) && 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; } /* 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); } /* 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; }