1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-04-19 06:50:42 +03:00

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.
This commit is contained in:
David Teigland 2019-10-08 14:44:24 -05:00
parent d6ffc99052
commit bd21736e8b
5 changed files with 25 additions and 6 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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) ||

View File

@ -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;