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

[lvm-devel] [LVM2 PATCH] Add lv_is_internal() to check internal LVs



Internal LVs ("snapshotX", mirror logs and mimages) should
not be directly manipulated from commands.

Currently, it's allowed in some places, though.
# lvs -a
  LV               VG     Attr   LSize Origin Snap%  Move Log        Copy% 
  lvol0            testvg -wi-a- 4.00M                                     
  lvol2            testvg mwi-a- 4.00M                    lvol2_mlog 100.00
  [lvol2_mimage_0] testvg iwi-ao 4.00M                                     
  [lvol2_mimage_1] testvg iwi-ao 4.00M                                     
  [lvol2_mlog]     testvg lwi-ao 4.00M          
# lvresize -l+1 testvg/lvol2_mimage_1
  Extending logical volume lvol2_mimage_1 to 8.00 MB
# lvconvert -s testvg/lvol2_mimage_1 testvg/lvol0
  Logical volume lvol0 converted to snapshot.
# lvrename testvg/snapshot0 testvg/s
  Renamed "snapshot0" to "s" in volume group "testvg"
# lvconvert -m1 testvg/s
  Logical volume s converted.

Until the stacking of LVs are properly supported,
it's safer to disable them.

Attached patch adds lv_is_internal() to check internal LVs.
lv_is_visible() returns true for "snapshotX" so it can't
directly usable for this purpose.

Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America
Add lv_is_internal() to check if it's internal LV
and use it from tools which should not manipulate on them.

lv_is_visible() in lib/metadata/snapshot_manip.c could be used to
check whether the LV is internal one or not.
However, it returns true for internal LV of snapshots ("snapshot0",
"snapshot1", ..) due to the inversion of VISIBLE and visibility
for cow and snapshot.
  - "snapshotX"'s status has "SNAPSHOT" and "VISIBLE" but
    should not be manipulated from commands and also "not visible"
    in reporting commands either
  - cow store's status doesn't have "VISIBLE" but it's actually
    a target of commands

Index: LVM2.work/lib/metadata/lv_manip.c
===================================================================
--- LVM2.work.orig/lib/metadata/lv_manip.c
+++ LVM2.work/lib/metadata/lv_manip.c
@@ -42,6 +42,14 @@ struct seg_pvs {
 	uint32_t len;
 };
 
+int lv_is_internal(const struct logical_volume *lv)
+{
+	if (lv->status & SNAPSHOT)
+		return 0;
+
+	return lv_is_visible(lv);
+}
+
 /*
  * Find first unused LV number.
  */
@@ -1582,7 +1590,7 @@ int lv_rename(struct cmd_context *cmd, s
 	struct lv_names lv_names;
 
 	/* rename is not allowed on sub LVs */
-	if (!lv_is_visible(lv)) {
+	if (!lv_is_internal(lv)) {
 		log_error("Cannot rename internal LV \"%s\".", lv->name);
 		return 0;
 	}
Index: LVM2.work/lib/metadata/metadata-exported.h
===================================================================
--- LVM2.work.orig/lib/metadata/metadata-exported.h
+++ LVM2.work/lib/metadata/metadata-exported.h
@@ -381,6 +381,7 @@ struct lv_segment *first_seg(struct logi
 int lv_is_origin(const struct logical_volume *lv);
 int lv_is_cow(const struct logical_volume *lv);
 int lv_is_visible(const struct logical_volume *lv);
+int lv_is_internal(const struct logical_volume *lv);
 
 int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
 
Index: LVM2.work/tools/lvresize.c
===================================================================
--- LVM2.work.orig/tools/lvresize.c
+++ LVM2.work/tools/lvresize.c
@@ -206,6 +206,11 @@ static int _lvresize(struct cmd_context 
 
 	lv = lvl->lv;
 
+	if (!lv_is_internal(lv)) {
+		log_error("Can't resize internal LV %s", lv->name);
+		return ECMD_FAILED;
+	}
+
 	if (lv->status & LOCKED) {
 		log_error("Can't resize locked LV %s", lv->name);
 		return ECMD_FAILED;
Index: LVM2.work/tools/lvconvert.c
===================================================================
--- LVM2.work.orig/tools/lvconvert.c
+++ LVM2.work/tools/lvconvert.c
@@ -522,6 +522,11 @@ static int lvconvert_snapshot(struct cmd
 		return 0;
 	}
 
+	if (lv_is_internal(org)) {
+		log_error("Unable to create a snapshot of an internal LV");
+		return 0;
+	}
+
 	if (!lp->zero || !(lv->status & LVM_WRITE))
 		log_warn("WARNING: \"%s\" not zeroed", lv->name);
 	else if (!set_lv(cmd, lv, 0, 0)) {
@@ -634,6 +639,12 @@ int lvconvert(struct cmd_context * cmd, 
 		goto error;
 	}
 
+	if (lv_is_internal(lvl->lv)) {
+		log_error("Unable to convert internal LV \"%s\".",
+			  lvl->lv->name);
+		return 0;
+	}
+
 	if (lp.pv_count) {
 		if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
 					      lp.pvs, 1))) {

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