From 19c865437a8c661045e61389dd6953047e2b9c82 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 7 Nov 2007 16:33:12 +0000 Subject: [PATCH] Prevent lvconvert -s from using same LV as origin and snapshot. --- WHATS_NEW | 1 + lib/metadata/merge.c | 9 +++++++++ lib/metadata/snapshot_manip.c | 5 +++++ tools/lvconvert.c | 6 ++++++ 4 files changed, 21 insertions(+) diff --git a/WHATS_NEW b/WHATS_NEW index 58fe520c4..e140b773e 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.29 - ================================== + Prevent lvconvert -s from using same LV as origin and snapshot. Fix human-readable output of odd numbers of sectors. Add pv_mda_free and vg_mda_free fields to reports for raw text format. Add LVM2 version to 'Generated by' comment in metadata. diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c index 8b65fad14..eb88ad73c 100644 --- a/lib/metadata/merge.c +++ b/lib/metadata/merge.c @@ -119,6 +119,15 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg) } } + if (seg_is_snapshot(seg)) { + if (seg->cow && seg->cow == seg->origin) { + log_error("LV %s: segment %u has same LV %s for " + "both origin and snapshot", + lv->name, seg_count, seg->cow->name); + r = 0; + } + } + for (s = 0; s < seg->area_count; s++) { if (seg_type(seg, s) == AREA_UNASSIGNED) { log_error("LV %s: segment %u has unassigned " diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c index 9e84a2a05..aab85ef70 100644 --- a/lib/metadata/snapshot_manip.c +++ b/lib/metadata/snapshot_manip.c @@ -63,6 +63,11 @@ int vg_add_snapshot(const char *name, struct logical_volume *origin, return 0; } + if (cow == origin) { + log_error("Snapshot and origin LVs must differ."); + return 0; + } + if (!(snap = lv_create_empty(name ? name : "snapshot%d", lvid, LVM_READ | LVM_WRITE | VISIBLE_LV, ALLOC_INHERIT, 1, origin->vg))) { diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 2864ea8e3..293f49b13 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -495,6 +495,12 @@ static int lvconvert_snapshot(struct cmd_context *cmd, return 0; } + if (org == lv) { + log_error("Unable to use \"%s\" as both snapshot and origin.", + lv->name); + return 0; + } + if (org->status & (LOCKED|PVMOVE) || lv_is_cow(org)) { log_error("Unable to create a snapshot of a %s LV.", org->status & LOCKED ? "locked" :