summaryrefslogtreecommitdiff
path: root/tools/vgcreate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/vgcreate.c')
-rw-r--r--tools/vgcreate.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index fd7956382..17a649280 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -17,13 +17,13 @@
int vgcreate(struct cmd_context *cmd, int argc, char **argv)
{
+ struct pvcreate_each_params pp;
struct vgcreate_params vp_new;
struct vgcreate_params vp_def;
struct volume_group *vg;
const char *tag;
const char *clustered_message = "";
char *vg_name;
- struct pvcreate_params pp;
struct arg_value_group_list *current_group;
if (!argc) {
@@ -36,10 +36,19 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
argc--;
argv++;
- pvcreate_params_set_defaults(&pp);
- if (!pvcreate_params_validate(cmd, argc, &pp)) {
+ pvcreate_each_params_set_defaults(&pp);
+
+ if (!pvcreate_each_params_from_args(cmd, &pp))
return EINVALID_CMD_LINE;
- }
+
+ pp.pv_count = argc;
+ pp.pv_names = argv;
+
+ /* Don't create a new PV on top of an existing PV like pvcreate does. */
+ pp.preserve_existing = 1;
+
+ /* pvcreate within vgcreate cannot be forced. */
+ pp.force = 0;
if (!vgcreate_params_set_defaults(cmd, &vp_def, NULL))
return EINVALID_CMD_LINE;
@@ -48,14 +57,27 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
if (!vgcreate_params_validate(cmd, &vp_new))
- return EINVALID_CMD_LINE;
+ return EINVALID_CMD_LINE;
/*
* Needed to change the global VG namespace,
* and to change the set of orphan PVs.
*/
if (!lockd_gl_create(cmd, "ex", vp_new.lock_type))
- return ECMD_FAILED;
+ return_ECMD_FAILED;
+
+ if (!pvcreate_each_device(cmd, &pp))
+ return_ECMD_FAILED;
+
+ /*
+ * pvcreate_each_device returns with the VG_ORPHANS
+ * write lock held, which it used to do pvcreate.
+ * Now to create the VG using those PVs, the VG lock
+ * will be taken (with the orphan lock already held.)
+ * The lock ordering rules want the VG locked first,
+ * so the lock order check needs to be suppressed.
+ */
+ lvmcache_lock_ordering(0);
lvmcache_seed_infos_from_lvmetad(cmd);
@@ -66,8 +88,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
log_error("A volume group called %s already exists.", vp_new.vg_name);
else
log_error("Can't get lock for %s.", vp_new.vg_name);
- release_vg(vg);
- return ECMD_FAILED;
+ goto bad_read;
}
if (vg->fid->fmt->features & FMT_CONFIG_PROFILE)
@@ -80,15 +101,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
!vg_set_clustered(vg, vp_new.clustered) ||
!vg_set_system_id(vg, vp_new.system_id) ||
!vg_set_mda_copies(vg, vp_new.vgmetadatacopies))
- goto bad_orphan;
-
- if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
- log_error("Can't get lock for orphan PVs");
- goto bad_orphan;
- }
+ goto_bad;
/* attach the pv's */
- if (!vg_extend(vg, argc, (const char* const*)argv, &pp))
+ if (!vg_extend_each_pv(vg, &pp))
goto_bad;
if (vp_new.max_lv != vg->max_lv)
@@ -179,9 +195,9 @@ out:
return ECMD_PROCESSED;
bad:
+ unlock_vg(cmd, vp_new.vg_name);
+bad_read:
unlock_vg(cmd, VG_ORPHANS);
-bad_orphan:
release_vg(vg);
- unlock_vg(cmd, vp_new.vg_name);
return ECMD_FAILED;
}