[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [patch 1/3] Update vgsplit to take "-n LogicalVolumeName" on the commandline.



Signed-off-by: Dave Wysochanski <dwysocha redhat com>
---
 tools/commands.h |    5 ++-
 tools/vgsplit.c  |   80 +++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 73 insertions(+), 12 deletions(-)

diff --git a/tools/commands.h b/tools/commands.h
index ceaf0b3..9e9d6f1 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -927,16 +927,17 @@ xx(vgsplit,
    "\t[-h|--help] " "\n"
    "\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
    "\t[-M|--metadatatype 1|2] " "\n"
+   "\t[-n|--name LogicalVolumeName]\n"
    "\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
    "\t[-t|--test] " "\n"
    "\t[-v|--verbose] " "\n"
    "\t[--version]" "\n"
    "\tSourceVolumeGroupName DestinationVolumeGroupName" "\n"
-   "\tPhysicalVolumePath [PhysicalVolumePath...]\n",
+   "\t[PhysicalVolumePath...]\n",
 
    alloc_ARG, autobackup_ARG, clustered_ARG,
    maxlogicalvolumes_ARG, maxphysicalvolumes_ARG,
-   metadatatype_ARG, test_ARG)
+   metadatatype_ARG, name_ARG, test_ARG)
 
 xx(version,
    "Display software and driver version information",
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 30d7802..05c132f 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -15,10 +15,18 @@
 
 #include "tools.h"
 
-static void _move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
-		     struct pv_list *pvl)
+static int _move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
+		    const char *pv_name)
 {
 	struct physical_volume *pv;
+	struct pv_list *pvl;
+
+	/* FIXME: handle tags */
+	if (!(pvl = find_pv_in_vg(vg_from, pv_name))) {
+		log_error("Physical volume %s not in volume group %s",
+			  pv_name, vg_from->name);
+		return 0;
+	}
 
 	list_move(&pvl->list, &vg_to->pvs);
 
@@ -32,6 +40,45 @@ static void _move_pv(struct volume_group *vg_from, struct volume_group *vg_to,
 
 	vg_from->free_count -= pv_pe_count(pv) - pv_pe_alloc_count(pv);
 	vg_to->free_count += pv_pe_count(pv) - pv_pe_alloc_count(pv);
+
+	return 1;
+}
+
+static int _move_pvs_underlying_lv(struct volume_group *vg_from,
+				   struct volume_group *vg_to,
+				   const char *lv_name)
+{
+	struct lv_segment *lvseg;
+	unsigned s;
+	struct lv_list *lvl;
+	struct logical_volume *lv;
+
+	/* FIXME: handle tags */
+	if (!(lvl = find_lv_in_vg(vg_from, lv_name))) {
+		log_error("Logical volume %s not in volume group %s",
+			  lv_name, vg_from->name);
+		return 0;
+	}
+
+	list_iterate_items(lvseg, &lvl->lv->segments) {
+		if (lvseg->log_lv)
+			if (!_move_pvs_underlying_lv(vg_from, vg_to,
+						     lvseg->log_lv->name))
+				return 0;
+		for (s = 0; s < lvseg->area_count; s++) {
+			if (seg_type(lvseg, s) == AREA_PV) {
+				if (!_move_pv(vg_from, vg_to,
+					      pv_dev_name(seg_pv(lvseg, s))))
+					return 0;
+			} else if (seg_type(lvseg, s) == AREA_LV) {
+				lv = seg_lv(lvseg, s);
+				if (!_move_pvs_underlying_lv(vg_from, vg_to,
+							     lv->name))
+				    return 0;
+			}
+		}
+	}
+	return 1;
 }
 
 /* FIXME Why not (lv->vg == vg) ? */
@@ -220,14 +267,26 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
 	int opt;
 	int active;
 	int existing_vg;
-	struct pv_list *pvl;
 	int consistent;
+	const char *lv_name;
 
-	if (argc < 3) {
-		log_error("Existing VG, new VG and physical volumes required.");
+	if ((arg_count(cmd, name_ARG) + argc) < 3) {
+		log_error("Existing VG, new VG and either physical volumes "
+			  "or logical volume required.");
 		return EINVALID_CMD_LINE;
 	}
 
+	if (arg_count(cmd, name_ARG) && (argc > 2)) {
+		log_error("A logical volume name cannot be given with "
+			  "physical volumes.");
+		return ECMD_FAILED;
+	}
+
+	if (arg_count(cmd, name_ARG))
+		lv_name = arg_value(cmd, name_ARG);
+	else
+		lv_name = NULL;
+
 	vg_name_from = skip_dev_dir(cmd, argv[0], NULL);
 	vg_name_to = skip_dev_dir(cmd, argv[1], NULL);
 	argc -= 2;
@@ -311,13 +370,14 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
 
 	/* Move PVs across to new structure */
 	for (opt = 0; opt < argc; opt++) {
-		if (!(pvl = find_pv_in_vg(vg_from, argv[opt]))) {
-			log_error("Physical volume %s not in volume group %s",
-				  argv[opt], vg_from->name);
+		if (!_move_pv(vg_from, vg_to, argv[opt]))
 			goto error;
-		}
+	}
 
-		_move_pv(vg_from, vg_to, pvl);
+	/* If an LV given on the cmdline, move underlying PVs */
+	if (lv_name) {
+		if (!_move_pvs_underlying_lv(vg_from, vg_to, lv_name))
+			goto error;
 	}
 
 	/* Move required LVs across, checking consistency */
-- 
1.5.3.4

-- 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]