]> sourceware.org Git - lvm2.git/commitdiff
cache: change cachevol flags for backward compat
authorDavid Teigland <teigland@redhat.com>
Mon, 14 Oct 2019 20:32:13 +0000 (15:32 -0500)
committerDavid Teigland <teigland@redhat.com>
Tue, 15 Oct 2019 14:05:52 +0000 (09:05 -0500)
A cachevol LV had the CACHE_VOL status flag in metadata,
and the cache LV using it had no new flag.  This caused
problems if the new metadata was used by an old version
of lvm.  An old version of lvm would have two problems
processing the new metadata:

. The old lvm would return an error when reading the VG
  metadata when it saw the unknown CACHE_VOL status flag.

. The old lvm would return an error when reading the VG
  metadata because it would not find an expected cache pool
  attached to the cache LV (since the cache LV had a
  cachevol attached instead.)

Change the use of flags:

. Change the CACHE_VOL flag to be a COMPATIBLE flag (instead
  of a STATUS flag) so that old versions will not fail when
  they see it.

. When a cache LV is using a cachevol, the cache LV gets
  a new SEGTYPE flag CACHE_USES_CACHEVOL.  This flag is
  appended to the segtype name, so that old lvm versions
  will fail to use the LV because of an unknown segtype,
  as opposed to failing to read the VG.

lib/format_text/flags.c
lib/metadata/metadata-exported.h
lib/metadata/pool_manip.c
tools/lvconvert.c

index 1ae64a213556811c979c3e37741a28190347b638..2873ba63251afde8fb26c48bf5a76582226b31f5 100644 (file)
@@ -72,7 +72,8 @@ static const struct flag _lv_flags[] = {
        {LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
        {LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
        {LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
-       {LV_CACHE_VOL, "CACHE_VOL", STATUS_FLAG},
+       {LV_CACHE_VOL, "CACHE_VOL", COMPATIBLE_FLAG},
+       {LV_CACHE_USES_CACHEVOL, "CACHE_USES_CACHEVOL", SEGTYPE_FLAG},
        {LV_NOSCAN, NULL, 0},
        {LV_TEMPORARY, NULL, 0},
        {POOL_METADATA_SPARE, NULL, 0},
@@ -192,12 +193,21 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
                        return 0;
                }
 
-               for (f = 0; flags[f].description; f++)
+               /*
+                * For a short time CACHE_VOL was a STATUS_FLAG, then it
+                * was changed to COMPATIBLE_FLAG, so we want to read it
+                * from either place.
+                */
+               if (type == LV_FLAGS && !strcmp(cv->v.str, "CACHE_VOL"))
+                       mask = (STATUS_FLAG | COMPATIBLE_FLAG);
+
+               for (f = 0; flags[f].description; f++) {
                        if ((flags[f].kind & mask) &&
                            !strcmp(flags[f].description, cv->v.str)) {
                                s |= flags[f].mask;
                                break;
                        }
+               }
 
                if (type == VG_FLAGS && !strcmp(cv->v.str, "PARTIAL")) {
                        /*
index 2d977532a116f4d91a0647003b7bfba15683eb12..66d85792939e7f7b083120278a45c33d1a64ef0d 100644 (file)
 #define LV_VDO_POOL_DATA       UINT64_C(0x8000000000000000)    /* LV - Internal user only */
 
 #define LV_CACHE_VOL           UINT64_C(0x0010000000000000)    /* LV - also a PV flag */
+#define LV_CACHE_USES_CACHEVOL UINT64_C(0x4000000000000000)    /* LV - also a PV flag */
 
 
 /* Format features flags */
index b9d04eade468b19fbe09e843751e81978dc32160..8d0aa83bf833b4c5acd5dde94f994eeabdbbfc39 100644 (file)
@@ -253,6 +253,7 @@ int detach_pool_lv(struct lv_segment *seg)
                if (!remove_seg_from_segs_using_this_lv(seg->pool_lv, seg))
                        return_0;
                seg->lv->status &= ~CACHE;
+               seg->lv->status &= ~LV_CACHE_USES_CACHEVOL;
                lv_set_visible(seg->pool_lv);
                seg->pool_lv->status &= ~LV_CACHE_VOL;
                seg->pool_lv = NULL;
index 3fa1b0441b594376f54264fe9b4429db00730c4e..9ab362b940efafec898d9e35d4004d91a58c2253 100644 (file)
@@ -4267,7 +4267,17 @@ static int _lvconvert_cachevol_attach_single(struct cmd_context *cmd,
        if (!lv_rename_update(cmd, cachevol_lv, cvol_name, 0))
                return_0;
 
+       /*
+        * This flag is added to the segtype name so that old versions of lvm
+        * (if they happen to be used with new metadata with a cache LV using a
+        * cachevol) will report an error when they see the unknown
+        * cache+CACHE_USES_CACHEVOL segment type.  Otherwise the old version
+        * would expect to find a cache pool and fail.
+        */
+       lv->status |= LV_CACHE_USES_CACHEVOL;
+
        cachevol_lv->status |= LV_CACHE_VOL;
+
        if (!_cache_vol_attach(cmd, lv, cachevol_lv))
                goto_out;
 
This page took 0.042906 seconds and 5 git commands to generate.