mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
lvmetad: Hide corrupt MDAs from the cache.
This is probably not optimal, but makes the lvmetad case mimic non-lvmetad code more closely. It also fixes vgremove of a partially corrupt VG with lvmetad, as _vg_write_raw (and consequently, entire vg_write) currently panics when it encounters a corrupt MDA. Ideally, we'd be able to explicitly control when it is safe to ignore them.
This commit is contained in:
parent
6b43db5804
commit
a368698672
@ -316,6 +316,49 @@ static void _xlate_mdah(struct mda_header *mdah)
|
||||
}
|
||||
}
|
||||
|
||||
static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev_area)
|
||||
{
|
||||
if (!dev_open(dev_area->dev))
|
||||
return_0;
|
||||
|
||||
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
|
||||
return_0;
|
||||
|
||||
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
|
||||
MDA_HEADER_SIZE -
|
||||
sizeof(mdah->checksum_xl)))) {
|
||||
log_error("Incorrect metadata area header checksum on %s"
|
||||
" at offset %"PRIu64, dev_name(dev_area->dev),
|
||||
dev_area->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_xlate_mdah(mdah);
|
||||
|
||||
if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
|
||||
log_error("Wrong magic number in metadata area header on %s"
|
||||
" at offset %"PRIu64, dev_name(dev_area->dev),
|
||||
dev_area->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mdah->version != FMTT_VERSION) {
|
||||
log_error("Incompatible metadata area header version: %d on %s"
|
||||
" at offset %"PRIu64, mdah->version,
|
||||
dev_name(dev_area->dev), dev_area->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mdah->start != dev_area->start) {
|
||||
log_error("Incorrect start sector in metadata area header: %"
|
||||
PRIu64" on %s at offset %"PRIu64, mdah->start,
|
||||
dev_name(dev_area->dev), dev_area->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct mda_header *raw_read_mda_header(const struct format_type *fmt,
|
||||
struct device_area *dev_area)
|
||||
{
|
||||
@ -326,46 +369,12 @@ struct mda_header *raw_read_mda_header(const struct format_type *fmt,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
|
||||
goto_bad;
|
||||
|
||||
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
|
||||
MDA_HEADER_SIZE -
|
||||
sizeof(mdah->checksum_xl)))) {
|
||||
log_error("Incorrect metadata area header checksum on %s"
|
||||
" at offset %"PRIu64, dev_name(dev_area->dev),
|
||||
dev_area->start);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
_xlate_mdah(mdah);
|
||||
|
||||
if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
|
||||
log_error("Wrong magic number in metadata area header on %s"
|
||||
" at offset %"PRIu64, dev_name(dev_area->dev),
|
||||
dev_area->start);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (mdah->version != FMTT_VERSION) {
|
||||
log_error("Incompatible metadata area header version: %d on %s"
|
||||
" at offset %"PRIu64, mdah->version,
|
||||
dev_name(dev_area->dev), dev_area->start);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (mdah->start != dev_area->start) {
|
||||
log_error("Incorrect start sector in metadata area header: %"
|
||||
PRIu64" on %s at offset %"PRIu64, mdah->start,
|
||||
dev_name(dev_area->dev), dev_area->start);
|
||||
goto bad;
|
||||
if (!_raw_read_mda_header(mdah, dev_area)) {
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mdah;
|
||||
|
||||
bad:
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
@ -1670,6 +1679,10 @@ static int _mda_export_text_raw(struct metadata_area *mda,
|
||||
struct dm_config_node *parent)
|
||||
{
|
||||
struct mda_context *mdc = (struct mda_context *) mda->metadata_locn;
|
||||
char mdah[MDA_HEADER_SIZE]; /* temporary */
|
||||
|
||||
if (!mdc || !_raw_read_mda_header(mdah, &mdc->area))
|
||||
return 1; /* pretend the MDA does not exist */
|
||||
|
||||
return config_make_nodes(cft, parent, NULL,
|
||||
"ignore = %" PRId64, (int64_t) mda_is_ignored(mda),
|
||||
|
20
test/shell/vgremove-corrupt-vg.sh
Normal file
20
test/shell/vgremove-corrupt-vg.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
. lib/test
|
||||
|
||||
aux prepare_vg 3
|
||||
lvcreate -n blabla -L 1 $vg -an --zero n
|
||||
|
||||
dd if=/dev/urandom bs=512 seek=2 count=32 of="$dev2"
|
||||
aux notify_lvmetad "$dev2"
|
||||
|
||||
vgremove -f $vg
|
Loading…
Reference in New Issue
Block a user