mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
metadata: Avoid accessing ignored metadata.
When an ignored metadata area gets flagged for use again, make sure the code doesn't try to parse its old metadata. Firstly by trying to detect this situation and skipping the read (while still remembering the position reached in the circular buffer), and secondly by clearing the invalid live metadata location on disk as a precaution when subsequently writing out the precommitted metadata. Problems showed up when a metadata area in one VG got moved to another VG in ignored state (still holding metadata for the original VG) and then later got brought into use in the new VG - only the header should be read in this case, not any of the metadata content.
This commit is contained in:
parent
84aca4201e
commit
52fd66210b
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.176 -
|
Version 2.02.176 -
|
||||||
===================================
|
===================================
|
||||||
|
Avoid reading ignored metadata when mda gets used again.
|
||||||
Fix detection of moved PVs in vgsplit. (2.02.175)
|
Fix detection of moved PVs in vgsplit. (2.02.175)
|
||||||
Ignore --stripes/--stripesize on RAID takeover
|
Ignore --stripes/--stripesize on RAID takeover
|
||||||
Improve used paths for generated systemd units and init shells.
|
Improve used paths for generated systemd units and init shells.
|
||||||
|
@ -414,12 +414,15 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
|||||||
struct lvmcache_vgsummary vgsummary_orphan = {
|
struct lvmcache_vgsummary vgsummary_orphan = {
|
||||||
.vgname = FMT_TEXT_ORPHAN_VG_NAME,
|
.vgname = FMT_TEXT_ORPHAN_VG_NAME,
|
||||||
};
|
};
|
||||||
|
int rlocn_was_ignored;
|
||||||
|
|
||||||
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
|
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
|
||||||
|
|
||||||
rlocn = mdah->raw_locns; /* Slot 0 */
|
rlocn = mdah->raw_locns; /* Slot 0 */
|
||||||
rlocn_precommitted = rlocn + 1; /* Slot 1 */
|
rlocn_precommitted = rlocn + 1; /* Slot 1 */
|
||||||
|
|
||||||
|
rlocn_was_ignored = rlocn_is_ignored(rlocn);
|
||||||
|
|
||||||
/* Should we use precommitted metadata? */
|
/* Should we use precommitted metadata? */
|
||||||
if (*precommitted && rlocn_precommitted->size &&
|
if (*precommitted && rlocn_precommitted->size &&
|
||||||
(rlocn_precommitted->offset != rlocn->offset)) {
|
(rlocn_precommitted->offset != rlocn->offset)) {
|
||||||
@ -438,6 +441,12 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
|||||||
if (!*vgname)
|
if (!*vgname)
|
||||||
return rlocn;
|
return rlocn;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If live rlocn has ignored flag, data will be out-of-date so skip further checks.
|
||||||
|
*/
|
||||||
|
if (rlocn_was_ignored)
|
||||||
|
return rlocn;
|
||||||
|
|
||||||
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
|
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
|
||||||
/* FIXME Ignore if checksum incorrect!!! */
|
/* FIXME Ignore if checksum incorrect!!! */
|
||||||
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
|
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
|
||||||
@ -448,8 +457,9 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
|||||||
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
|
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{'))
|
||||||
return rlocn;
|
return rlocn;
|
||||||
|
|
||||||
log_debug_metadata("Volume group name found in metadata on %s at %" PRIu64 " does "
|
log_debug_metadata("Volume group name found in %smetadata on %s at %" PRIu64 " does "
|
||||||
"not match expected name %s.",
|
"not match expected name %s.",
|
||||||
|
*precommitted ? "precommitted " : "",
|
||||||
dev_name(dev_area->dev), dev_area->start + rlocn->offset, vgname);
|
dev_name(dev_area->dev), dev_area->start + rlocn->offset, vgname);
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
@ -750,6 +760,14 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
|||||||
mdah->raw_locns[2].size = 0;
|
mdah->raw_locns[2].size = 0;
|
||||||
mdah->raw_locns[2].checksum = 0;
|
mdah->raw_locns[2].checksum = 0;
|
||||||
rlocn = &mdah->raw_locns[0];
|
rlocn = &mdah->raw_locns[0];
|
||||||
|
} else if (precommit && rlocn_is_ignored(rlocn) && !mda_is_ignored(mda)) {
|
||||||
|
/*
|
||||||
|
* If precommitting into a previously-ignored mda, wipe the live rlocn
|
||||||
|
* as a precaution so that nothing can use it by mistake.
|
||||||
|
*/
|
||||||
|
mdah->raw_locns[0].offset = 0;
|
||||||
|
mdah->raw_locns[0].size = 0;
|
||||||
|
mdah->raw_locns[0].checksum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (precommit)
|
if (precommit)
|
||||||
@ -766,12 +784,14 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
|||||||
rlocn->offset = mdac->rlocn.offset;
|
rlocn->offset = mdac->rlocn.offset;
|
||||||
rlocn->size = mdac->rlocn.size;
|
rlocn->size = mdac->rlocn.size;
|
||||||
rlocn->checksum = mdac->rlocn.checksum;
|
rlocn->checksum = mdac->rlocn.checksum;
|
||||||
log_debug_metadata("%sCommitting %s metadata (%u) to %s header at %"
|
log_debug_metadata("%sCommitting %s %smetadata (%u) to %s header at %"
|
||||||
PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno,
|
PRIu64, precommit ? "Pre-" : "", vg->name,
|
||||||
|
mda_is_ignored(mda) ? "(ignored) " : "", vg->seqno,
|
||||||
dev_name(mdac->area.dev), mdac->area.start);
|
dev_name(mdac->area.dev), mdac->area.start);
|
||||||
} else
|
} else
|
||||||
log_debug_metadata("Wiping pre-committed %s metadata from %s "
|
log_debug_metadata("Wiping pre-committed %s %smetadata from %s "
|
||||||
"header at %" PRIu64, vg->name,
|
"header at %" PRIu64, vg->name,
|
||||||
|
mda_is_ignored(mda) ? "(ignored) " : "",
|
||||||
dev_name(mdac->area.dev), mdac->area.start);
|
dev_name(mdac->area.dev), mdac->area.start);
|
||||||
|
|
||||||
rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
|
rlocn_set_ignored(mdah->raw_locns, mda_is_ignored(mda));
|
||||||
|
Loading…
Reference in New Issue
Block a user