[lvm-devel] master - lvmetad: Hide corrupt MDAs from the cache.
Petr Rockai
mornfall at fedoraproject.org
Fri Feb 28 10:26:31 UTC 2014
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a36869867275b8ef0f6d324bc5a7f3e2b8e445e9
Commit: a36869867275b8ef0f6d324bc5a7f3e2b8e445e9
Parent: 6b43db580474ae96627c6b3784c136b56f30dde3
Author: Petr Rockai <me at mornfall.net>
AuthorDate: Thu Feb 27 23:06:42 2014 +0100
Committer: Petr Rockai <me at mornfall.net>
CommitterDate: Fri Feb 28 11:23:52 2014 +0100
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.
---
lib/format_text/format-text.c | 47 +++++++++++++++++++++++-------------
test/shell/vgremove-corrupt-vg.sh | 20 +++++++++++++++
2 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index b4f96f8..0d6483a 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -316,18 +316,13 @@ static void _xlate_mdah(struct mda_header *mdah)
}
}
-struct mda_header *raw_read_mda_header(const struct format_type *fmt,
- struct device_area *dev_area)
+static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev_area)
{
- struct mda_header *mdah;
-
- if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
- log_error("struct mda_header allocation failed");
- return NULL;
- }
+ if (!dev_open(dev_area->dev))
+ return_0;
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
- goto_bad;
+ return_0;
if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, (uint8_t *)mdah->magic,
MDA_HEADER_SIZE -
@@ -335,7 +330,7 @@ struct mda_header *raw_read_mda_header(const struct format_type *fmt,
log_error("Incorrect metadata area header checksum on %s"
" at offset %"PRIu64, dev_name(dev_area->dev),
dev_area->start);
- goto bad;
+ return 0;
}
_xlate_mdah(mdah);
@@ -344,28 +339,42 @@ struct mda_header *raw_read_mda_header(const struct format_type *fmt,
log_error("Wrong magic number in metadata area header on %s"
" at offset %"PRIu64, dev_name(dev_area->dev),
dev_area->start);
- goto bad;
+ 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);
- goto bad;
+ 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);
- goto bad;
+ return 0;
}
- return mdah;
+ return 1;
+}
-bad:
- dm_pool_free(fmt->cmd->mem, mdah);
- return NULL;
+struct mda_header *raw_read_mda_header(const struct format_type *fmt,
+ struct device_area *dev_area)
+{
+ struct mda_header *mdah;
+
+ if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
+ log_error("struct mda_header allocation failed");
+ return NULL;
+ }
+
+ if (!_raw_read_mda_header(mdah, dev_area)) {
+ dm_pool_free(fmt->cmd->mem, mdah);
+ return NULL;
+ }
+
+ return mdah;
}
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),
diff --git a/test/shell/vgremove-corrupt-vg.sh b/test/shell/vgremove-corrupt-vg.sh
new file mode 100644
index 0000000..9e750ac
--- /dev/null
+++ b/test/shell/vgremove-corrupt-vg.sh
@@ -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
More information about the lvm-devel
mailing list