diff options
author | Alasdair Kergon <agk@redhat.com> | 2002-11-18 14:04:08 +0000 |
---|---|---|
committer | Alasdair Kergon <agk@redhat.com> | 2002-11-18 14:04:08 +0000 |
commit | 5a52dca9c26ade9f233abcf5213300560d7a13a9 (patch) | |
tree | 9afbc621c07148c96a1ba1878a262dbd8aec613a /tools/pvcreate.c | |
parent | d1d9800ef1c7ec38a5f72b8e2586f927ab68188c (diff) | |
download | lvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.tar.gz lvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.tar.xz lvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.zip |
Some new features.
Diffstat (limited to 'tools/pvcreate.c')
-rw-r--r-- | tools/pvcreate.c | 117 |
1 files changed, 101 insertions, 16 deletions
diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 0cc1d95f..7ca11ede 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -19,6 +19,7 @@ */ #include "tools.h" +#include "defaults.h" const char _really_init[] = "Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? "; @@ -39,7 +40,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name) } /* is there a pv here already */ - if (!(pv = pv_read(cmd, name))) + if (!(pv = pv_read(cmd, name, NULL, NULL))) return 1; /* orphan ? */ @@ -72,20 +73,28 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name) return 1; } -static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) +static void pvcreate_single(struct cmd_context *cmd, const char *pv_name, + void *handle) { - struct physical_volume *pv; - struct format_instance *fid; + struct physical_volume *pv, *existing_pv; struct id id, *idp = NULL; char *uuid; uint64_t size = 0; struct device *dev; + struct list mdas; + int pvmetadatacopies; + uint64_t pvmetadatasize; + struct volume_group *vg; + char *restorefile; + uint64_t pe_start = 0; + uint32_t extent_count = 0, extent_size = 0; if (arg_count(cmd, uuidstr_ARG)) { uuid = arg_str_value(cmd, uuidstr_ARG, ""); if (!id_read_format(&id, uuid)) return; - if ((dev = uuid_map_lookup(cmd->um, &id))) { + if ((dev = device_from_pvid(cmd, &id)) && + (dev != dev_cache_get(pv_name, cmd->filter))) { log_error("uuid %s already in use on \"%s\"", uuid, dev_name(dev)); return; @@ -93,32 +102,84 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name) idp = &id; } - if (!pvcreate_check(cmd, pv_name)) + if (arg_count(cmd, restorefile_ARG)) { + restorefile = arg_str_value(cmd, restorefile_ARG, ""); + /* The uuid won't already exist */ + init_partial(1); + if (!(vg = backup_read_vg(cmd, NULL, restorefile))) { + log_error("Unable to read volume group from %s", + restorefile); + return; + } + init_partial(0); + if (!(existing_pv = find_pv_in_vg_by_uuid(vg, idp))) { + log_error("Can't find uuid %s in backup file %s", + uuid, restorefile); + return; + } + pe_start = existing_pv->pe_start; + extent_size = existing_pv->pe_size; + extent_count = existing_pv->pe_count; + } + + if (!lock_vol(cmd, "", LCK_VG_WRITE)) { + log_error("Can't get lock for orphan PVs"); return; + } + + if (!pvcreate_check(cmd, pv_name)) + goto error; size = arg_int64_value(cmd, physicalvolumesize_ARG, 0) * 2; - /* FIXME Use config file/cmd line to specify format */ - if (!(fid = cmd->fmt1->ops->create_instance(cmd->fmt1, NULL, NULL))) { - log_error("Failed to create format1 instance"); - return; + pvmetadatasize = arg_int64_value(cmd, metadatasize_ARG, 0) * 2; + if (!pvmetadatasize) + pvmetadatasize = find_config_int(cmd->cf->root, + "metadata/pvmetadatasize", + '/', DEFAULT_PVMETADATASIZE); + + pvmetadatacopies = arg_int_value(cmd, metadatacopies_ARG, -1); + if (pvmetadatacopies < 0) + pvmetadatacopies = find_config_int(cmd->cf->root, + "metadata/pvmetadatacopies", + '/', + DEFAULT_PVMETADATACOPIES); + + if (!(dev = dev_cache_get(pv_name, cmd->filter))) { + log_error("%s: Couldn't find device.", pv_name); + goto error; } - if (!(pv = pv_create(fid, pv_name, idp, size))) { + + list_init(&mdas); + if (!(pv = pv_create(cmd->fmt, dev, idp, size, pe_start, + extent_count, extent_size, + pvmetadatacopies, pvmetadatasize, &mdas))) { log_error("Failed to setup physical volume \"%s\"", pv_name); - return; + goto error; } log_verbose("Set up physical volume for \"%s\" with %" PRIu64 - " sectors", pv_name, pv->size); + " available sectors", pv_name, pv->size); + + /* Wipe existing label first */ + if (!label_remove(pv->dev)) { + log_error("Failed to wipe existing label on %s", pv_name); + goto error; + } log_very_verbose("Writing physical volume data to disk \"%s\"", pv_name); - if (!(pv_write(cmd, pv))) { + if (!(pv_write(cmd, pv, &mdas, arg_int_value(cmd, labelsector_ARG, + DEFAULT_LABELSECTOR)))) { log_error("Failed to write physical volume \"%s\"", pv_name); - return; + goto error; } log_print("Physical volume \"%s\" successfully created", pv_name); + + error: + unlock_vg(cmd, ""); + return; } int pvcreate(struct cmd_context *cmd, int argc, char **argv) @@ -130,6 +191,11 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } + if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) { + log_error("--uuid is required with --restorefile"); + return EINVALID_CMD_LINE; + } + if (arg_count(cmd, uuidstr_ARG) && argc != 1) { log_error("Can only set uuid on one volume at once"); return EINVALID_CMD_LINE; @@ -140,8 +206,27 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } + if (arg_int_value(cmd, labelsector_ARG, 0) >= LABEL_SCAN_SECTORS) { + log_error("labelsector must be less than %lu", + LABEL_SCAN_SECTORS); + return EINVALID_CMD_LINE; + } + + if (!(cmd->fmt->features & FMT_MDAS) && + (arg_count(cmd, metadatacopies_ARG) || + arg_count(cmd, metadatasize_ARG))) { + log_error("Metadata parameters only apply to text format"); + return EINVALID_CMD_LINE; + } + + if (arg_count(cmd, metadatacopies_ARG) && + arg_int_value(cmd, metadatacopies_ARG, -1) > 2) { + log_error("Metadatacopies may only be 0, 1 or 2"); + return EINVALID_CMD_LINE; + } + for (i = 0; i < argc; i++) { - pvcreate_single(cmd, argv[i]); + pvcreate_single(cmd, argv[i], NULL); pool_empty(cmd->mem); } |