]> sourceware.org Git - lvm2.git/commitdiff
Fix lv_count when manipulating with snapshots and max_lv is set.
authorMilan Broz <mbroz@redhat.com>
Mon, 16 Mar 2009 14:34:57 +0000 (14:34 +0000)
committerMilan Broz <mbroz@redhat.com>
Mon, 16 Mar 2009 14:34:57 +0000 (14:34 +0000)
Patch fixes these problems:
 - during the snapshot creation process, it needs create 2 LVs,
   one is cow, second becomes snapshot.
   If the code fails in vg_add_snapshot, code lvcreate will not remove
   LV cow volume.

 - if max_lv is set and VG contains snapshot, it can happen that
   during the activation lv_count is temporarily increased over the limit
   and VG metadata are not properly processed
   see https://bugzilla.redhat.com/show_bug.cgi?id=490298

 - vgcfgrestore alows restore with max_lv set to lower valuer that actual
   LV count. This later leads to situation that max_lv is completely ignored.

 - vgck doesn't call vg_validate(). It should at least try:-)

Signed-off-by: Milan Broz <mbroz@redhat.com>
WHATS_NEW
lib/metadata/metadata.c
lib/metadata/snapshot_manip.c
test/t-lvcreate-usage.sh
tools/lvcreate.c
tools/vgck.c

index 9bdaf81a4c2f0097b23cbdf530908160631fea32..1df0fe9bfbc7b3f59ee68f1ce19f068b8b0758bf 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
 Version 2.02.46 - 
 ================================
+  Fix maximal volume count check for snapshots if max_lv set for volume group.
+  Fix lvcreate to remove cow volume if the snapshot creation fails.
   Fix error messages when PV uuid or pe_start reading fails.
   Rename liblvm.a to liblvm-internal.a and build new application library.
   Flush memory pool and fix locking in clvmd refresh and backup command.
index 81a7fe28049054ddfc0d1e861012e2f6d6a60168..7848d829d5afc816168eac0edb20f442da3320a8 100644 (file)
@@ -1461,6 +1461,13 @@ int vg_validate(struct volume_group *vg)
                r = 0;
        }
 
+       if (vg->max_lv && (vg->max_lv < vg->lv_count)) {
+               log_error("Internal error: Volume group %s contains %u volumes"
+                         " but the limit is set to %u.",
+                         vg->name, vg->lv_count, vg->max_lv);
+               r = 0;
+       }
+
        return r;
 }
 
index 9531c921d1f887190f68dcf8778ca5300caeb9b7..39553820564c131849152537b5f6d789b7c296b2 100644 (file)
@@ -76,10 +76,18 @@ int vg_add_snapshot(const char *name, struct logical_volume *origin,
                return 0;
        }
 
+       /*
+        * Set origin lv count in advance to prevent fail because
+        * of temporary violation of LV limits.
+        */
+       origin->vg->lv_count--;
+
        if (!(snap = lv_create_empty(name ? name : "snapshot%d",
                                     lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
-                                    ALLOC_INHERIT, 1, origin->vg)))
+                                    ALLOC_INHERIT, 1, origin->vg))) {
+               origin->vg->lv_count++;
                return_0;
+       }
 
        snap->le_count = extent_count;
 
@@ -93,7 +101,6 @@ int vg_add_snapshot(const char *name, struct logical_volume *origin,
 
        origin->origin_count++;
        origin->vg->snapshot_count++;
-       origin->vg->lv_count--;
        cow->snapshot = seg;
 
        cow->status &= ~VISIBLE_LV;
index 4e78e9e59160fbd18cf6530664b42436e30621fe..13abbdf0dfc3be1655763e3e3e481c729ad478d4 100755 (executable)
@@ -58,3 +58,12 @@ not lvcreate -L 64M -n $lv -i2 --stripesize 3 $vg 2>err
 grep "^  Invalid stripe size 3\.00 KB\$" err
 case $(lvdisplay $vg) in "") true ;; *) false ;; esac
 
+# Setting max_lv works. (bz490298)
+vgchange -l 4 $vg
+lvcreate -l1 -n $lv1 $vg
+lvcreate -l1 -s -n $lv2 $vg/$lv1
+lvcreate -l1 -n $lv3 $vg
+not lvcreate -l1 -n $lv4 $vg
+vgs $vg
+lvremove -ff $vg
+vgchange -l 0 $vg
index 1f14eb1de80a45db7ea43aa14f01a25f8cd32af2..e25ecdd5612d20d1729aeef0a9a4c99bfd439175 100644 (file)
@@ -836,7 +836,7 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
                if (!vg_add_snapshot(NULL, org, lv, NULL,
                                     org->le_count, lp->chunk_size)) {
                        log_error("Couldn't create snapshot.");
-                       return 0;
+                       goto deactivate_and_revert_new_lv;
                }
 
                /* store vg on disk(s) */
index 1fb6c03c6bb4519e507eae3cb4c0c70f2f2ca6f2..26eab99a8f9a8c32441e2050a40f08e9dc8c3e1d 100644 (file)
@@ -33,6 +33,9 @@ static int vgck_single(struct cmd_context *cmd __attribute((unused)),
        if (!vg_check_status(vg, EXPORTED_VG))
                return ECMD_FAILED;
 
+       if (!vg_validate(vg))
+               return ECMD_FAILED;
+
        return ECMD_PROCESSED;
 }
 
This page took 0.074449 seconds and 5 git commands to generate.