summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2019-10-08 14:44:24 -0500
committerDavid Teigland <teigland@redhat.com>2019-10-11 12:57:39 -0500
commitbd21736e8b082319e1a9a29e75badd906ee277f6 (patch)
treee18faeeb7a598362dc1d794d3158507230158b41
parentd6ffc990523468e46ae03a462ef1ec73067f9934 (diff)
downloadlvm2-bd21736e8b082319e1a9a29e75badd906ee277f6.tar.gz
vgck: let updatemetadata repair mismatched metadata
Let vgck --updatemetadata repair cases where different mdas hold indepedently valid but unmatching copies of the metadata, i.e. different text metadata checksums or text metadata sizes.
-rw-r--r--lib/cache/lvmcache.c1
-rw-r--r--lib/cache/lvmcache.h1
-rw-r--r--lib/format_text/text_label.c25
-rw-r--r--lib/metadata/metadata.c3
-rw-r--r--lib/metadata/metadata.h1
5 files changed, 25 insertions, 6 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 316624fe5..f6e792459 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1649,6 +1649,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
vgsummary->mda_checksum, vgsummary->mda_size,
vginfo->mda_checksum, vginfo->mda_size);
vginfo->scan_summary_mismatch = true;
+ vgsummary->mismatch = 1;
return 0;
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 1401974be..d614e5469 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -58,6 +58,7 @@ struct lvmcache_vgsummary {
int mda_num; /* 1 = summary from mda1, 2 = summary from mda2 */
unsigned mda_ignored:1;
unsigned zero_offset:1;
+ unsigned mismatch:1; /* lvmcache sets if this summary differs from previous values */
struct dm_list pvsummaries;
};
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 41276be73..246fb7b4a 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -507,10 +507,17 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
if (rv1 && !vgsummary.zero_offset && !vgsummary.mda_ignored) {
if (!lvmcache_update_vgname_and_id(info, &vgsummary)) {
/* I believe this is only an internal error. */
- log_warn("WARNING: Scanning %s mda1 failed to save internal summary.", dev_name(dev));
dm_list_del(&mda1->list);
- bad_fields |= BAD_MDA_INTERNAL;
+
+ /* Are there other cases besides mismatch and internal error? */
+ if (vgsummary.mismatch) {
+ log_warn("WARNING: Scanning %s mda1 found mismatch with other metadata.", dev_name(dev));
+ bad_fields |= BAD_MDA_MISMATCH;
+ } else {
+ log_warn("WARNING: Scanning %s mda1 failed to save internal summary.", dev_name(dev));
+ bad_fields |= BAD_MDA_INTERNAL;
+ }
mda1->bad_fields = bad_fields;
lvmcache_save_bad_mda(info, mda1);
mda1 = NULL;
@@ -550,11 +557,17 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
if (rv2 && !vgsummary.zero_offset && !vgsummary.mda_ignored) {
if (!lvmcache_update_vgname_and_id(info, &vgsummary)) {
- /* I believe this is only an internal error. */
- log_warn("WARNING: Scanning %s mda2 failed to save internal summary.", dev_name(dev));
-
dm_list_del(&mda2->list);
- bad_fields |= BAD_MDA_INTERNAL;
+
+ /* Are there other cases besides mismatch and internal error? */
+ if (vgsummary.mismatch) {
+ log_warn("WARNING: Scanning %s mda2 found mismatch with other metadata.", dev_name(dev));
+ bad_fields |= BAD_MDA_MISMATCH;
+ } else {
+ log_warn("WARNING: Scanning %s mda2 failed to save internal summary.", dev_name(dev));
+ bad_fields |= BAD_MDA_INTERNAL;
+ }
+
mda2->bad_fields = bad_fields;
lvmcache_save_bad_mda(info, mda2);
mda2 = NULL;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 39544e66a..b09f4b35e 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4518,6 +4518,9 @@ void vg_write_commit_bad_mdas(struct cmd_context *cmd, struct volume_group *vg)
* above.
*
* TEXT: general error related to text metadata, we can repair.
+ *
+ * MISMATCH: different values between instances of metadata,
+ * can repair.
*/
if (!mda->bad_fields ||
(mda->bad_fields & BAD_MDA_READ) ||
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 6516e627c..ac18879b0 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -179,6 +179,7 @@ struct metadata_area_ops {
#define BAD_MDA_MAGIC 0x00000020
#define BAD_MDA_VERSION 0x00000040
#define BAD_MDA_START 0x00000080
+#define BAD_MDA_MISMATCH 0x00000100 /* lvmcache found difference from prev metadata */
struct metadata_area {
struct dm_list list;