summaryrefslogtreecommitdiffstats
path: root/tools/pvcreate.c
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2002-11-18 14:04:08 +0000
committerAlasdair Kergon <agk@redhat.com>2002-11-18 14:04:08 +0000
commit5a52dca9c26ade9f233abcf5213300560d7a13a9 (patch)
tree9afbc621c07148c96a1ba1878a262dbd8aec613a /tools/pvcreate.c
parentd1d9800ef1c7ec38a5f72b8e2586f927ab68188c (diff)
downloadlvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.tar.gz
lvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.tar.xz
lvm2-5a52dca9c26ade9f233abcf5213300560d7a13a9.zip
Some new features.
Diffstat (limited to 'tools/pvcreate.c')
-rw-r--r--tools/pvcreate.c117
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);
}