]> sourceware.org Git - lvm2.git/commitdiff
Adjust auto-metadata repair and caching logic to try to cope with empty mdas.
authorAlasdair Kergon <agk@redhat.com>
Wed, 7 Jul 2010 02:53:16 +0000 (02:53 +0000)
committerAlasdair Kergon <agk@redhat.com>
Wed, 7 Jul 2010 02:53:16 +0000 (02:53 +0000)
- If a PV contained empty mdas, the auto-recovery code was not kicking in.
- The 'inconsistent' state was getting lost when metadata was cached so
  recovery didn't kick in.  But leave the behaviour alone when using
  precommitted metadata because of a warning in a confusing FIXME.

In my testing, pvs and vgs didn't repair inconsistent metadata like they
used to do.  (How many other tools fail similarly now?)

And there should be no need to cache inconsistent metadata because it is
supposed to get repaired under the protection of a write lock immediately it is
discovered.

This code is in need of a redesign based on first principles.
I still see bugs in this code and this commit is risky.

WHATS_NEW
lib/metadata/metadata.c
lib/metadata/metadata.h

index 0737da81db4565851be5153d7aa362c128633d2d..9c8fc554315062b7d56eba3bc9d19321f7987c76 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.71 -
 ===============================
+  Adjust auto-metadata repair and caching logic to try to cope with empty mdas.
 
 Version 2.02.70 - 6th July 2010
 ===============================
index f076b721b0946d1e015e67cb8f1f024d1c39e786..543ad83089c2140d691e653fcfc9b5ea9c6df920 100644 (file)
@@ -2899,6 +2899,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
        int inconsistent_vgid = 0;
        int inconsistent_pvs = 0;
        int inconsistent_seqno = 0;
+       int inconsistent_mdas = 0;
        unsigned use_precommitted = precommitted;
        unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
        struct dm_list *pvids;
@@ -2916,14 +2917,28 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
                return _vg_read_orphans(cmd, vgname);
        }
 
-       if ((correct_vg = lvmcache_get_vg(vgid, precommitted))) {
+       /*
+        * If cached metadata was inconsistent and *consistent is set
+        * then repair it now.  Otherwise just return it.
+        * Also return if use_precommitted is set due to the FIXME in
+        * the missing PV logic below.
+        */
+       if ((correct_vg = lvmcache_get_vg(vgid, precommitted)) &&
+           (use_precommitted || !*consistent || !(correct_vg->status & INCONSISTENT_VG))) {
+               if (!(correct_vg->status & INCONSISTENT_VG))
+                       *consistent = 1;
+               else    /* Inconsistent but we can't repair it */
+                       correct_vg->status &= ~INCONSISTENT_VG;
+
                if (vg_missing_pv_count(correct_vg)) {
                        log_verbose("There are %d physical volumes missing.",
                                    vg_missing_pv_count(correct_vg));
                        vg_mark_partial_lvs(correct_vg);
                }
-               *consistent = 1;
                return correct_vg;
+       } else {
+               vg_release(correct_vg);
+               correct_vg = NULL;
        }
 
        /* Find the vgname in the cache */
@@ -3009,14 +3024,29 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
                                 * not ignored.
                                 */
                                if (!(info = info_from_pvid(pvl->pv->dev->pvid, 1)) ||
-                                  !info->vginfo || !is_orphan_vg(info->vginfo->vgname) ||
-                                  !mdas_empty_or_ignored(&info->mdas)) {
+                                  !info->vginfo || !is_orphan_vg(info->vginfo->vgname)) {
                                        inconsistent_pvs = 1;
                                        break;
                                }
-                               if (dm_list_size(&info->mdas) &&
-                                   !fid_add_mdas(fid, &info->mdas))
-                                       return_NULL;
+                               if (dm_list_size(&info->mdas)) {
+                                       if (!fid_add_mdas(fid, &info->mdas))
+                                               return_NULL;
+                                        
+                                       log_debug("Empty mda found for VG %s.", vgname);
+
+                                       if (inconsistent_mdas)
+                                               continue;
+
+                                       /*
+                                        * If any newly-added mdas are in-use then their
+                                        * metadata needs updating.
+                                        */
+                                       dm_list_iterate_items(mda, &info->mdas)
+                                               if (!mda_is_ignored(mda)) {
+                                                       inconsistent_mdas = 1;
+                                                       break;
+                                               }
+                               }
                        }
 
                        /* If the check passed, let's update VG and recalculate pvids */
@@ -3056,6 +3086,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
                                break;
                        }
                }
+
+               if (correct_vg && inconsistent_mdas) {
+                       vg_release(correct_vg);
+                       correct_vg = NULL;
+               }
        }
 
        dm_list_init(&all_pvs);
@@ -3132,7 +3167,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
         * If there is no precommitted metadata, committed metadata
         * is read and stored in the cache even if use_precommitted is set
         */
-       lvmcache_update_vg(correct_vg, correct_vg->status & PRECOMMITTED);
+       lvmcache_update_vg(correct_vg, correct_vg->status & PRECOMMITTED &
+                          (inconsistent ? INCONSISTENT_VG : 0));
 
        if (inconsistent) {
                /* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
index 6a211c1e9cae539c5ad419e2fd1524b06bf20126..80701b53a122fe0422a8fdaadc31066662092db9 100644 (file)
@@ -76,6 +76,7 @@
 //#define CONVERTING           0x00400000U     /* LV */
 
 //#define MISSING_PV           0x00800000U     /* PV */
+#define INCONSISTENT_VG                0x00800000U     /* VG - internal use only */
 //#define PARTIAL_LV           0x01000000U     /* LV - derived flag, not
 //                                                written out in metadata*/
 
This page took 0.055938 seconds and 5 git commands to generate.