master - add flags to keep track of bad metadata
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=aeafdc1f45a5963290a...
Commit: aeafdc1f45a5963290a5bc3ea1661018b072d817
Parent: db98a6e3629aaf6bf42d0e840273b4328f930c89
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Feb 5 12:08:00 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jun 7 15:54:04 2019 -0500
add flags to keep track of bad metadata
When reading metadata headers and text, use a new set
of flags to identify specific errors that are seen.
These will be used for more advanced repair in a
subsequent commit.
---
lib/format_text/format-text.c | 44 +++++++++++++++++++++++++++--------------
lib/format_text/layout.h | 4 ++-
lib/format_text/text_label.c | 3 +-
lib/metadata/metadata.h | 14 +++++++++++++
4 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 2831a53..f5e08fa 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -161,7 +161,8 @@ static void _xlate_mdah(struct mda_header *mdah)
}
}
-static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev_area, int primary_mda)
+static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev_area,
+ int primary_mda, uint32_t ignore_bad_fields, uint32_t *bad_fields)
{
log_debug_metadata("Reading mda header sector from %s at %llu",
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
@@ -169,53 +170,62 @@ static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev
if (!dev_read_bytes(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
log_error("Failed to read metadata area header on %s at %llu",
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
+ *bad_fields |= BAD_MDA_READ;
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 checksum in metadata area header on %s at %llu",
+ log_warn("WARNING: wrong checksum %x in mda header on %s at %llu",
+ mdah->checksum_xl,
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
- return 0;
+ *bad_fields |= BAD_MDA_CHECKSUM;
}
_xlate_mdah(mdah);
if (memcmp(mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
- log_error("Wrong magic number in metadata area header on %s at %llu",
+ log_warn("WARNING: wrong magic number in mda header on %s at %llu",
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
- return 0;
+ *bad_fields |= BAD_MDA_MAGIC;
}
if (mdah->version != FMTT_VERSION) {
- log_error("Incompatible version %u metadata area header on %s at %llu",
+ log_warn("WARNING: wrong version %u in mda header on %s at %llu",
mdah->version,
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
- return 0;
+ *bad_fields |= BAD_MDA_VERSION;
}
if (mdah->start != dev_area->start) {
- log_error("Incorrect start sector %llu in metadata area header on %s at %llu",
+ log_warn("WARNING: wrong start sector %llu in mda header on %s at %llu",
(unsigned long long)mdah->start,
dev_name(dev_area->dev), (unsigned long long)dev_area->start);
- return 0;
+ *bad_fields |= BAD_MDA_START;
}
+ *bad_fields &= ~ignore_bad_fields;
+
+ if (*bad_fields)
+ return 0;
+
return 1;
}
struct mda_header *raw_read_mda_header(const struct format_type *fmt,
- struct device_area *dev_area, int primary_mda)
+ struct device_area *dev_area,
+ int primary_mda, uint32_t ignore_bad_fields, uint32_t *bad_fields)
{
struct mda_header *mdah;
if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
log_error("struct mda_header allocation failed");
+ *bad_fields |= BAD_MDA_INTERNAL;
return NULL;
}
- if (!_raw_read_mda_header(mdah, dev_area, primary_mda)) {
+ if (!_raw_read_mda_header(mdah, dev_area, primary_mda, ignore_bad_fields, bad_fields)) {
dm_pool_free(fmt->cmd->mem, mdah);
return NULL;
}
@@ -413,8 +423,9 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
time_t when;
char *desc;
uint32_t wrap = 0;
+ uint32_t bad_fields = 0;
- if (!(mdah = raw_read_mda_header(fid->fmt, area, primary_mda))) {
+ if (!(mdah = raw_read_mda_header(fid->fmt, area, primary_mda, 0, &bad_fields))) {
log_error("Failed to read vg %s from %s", vgname, dev_name(area->dev));
goto out;
}
@@ -535,6 +546,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
uint64_t old_start = 0, old_last = 0, old_size = 0, old_wrap = 0;
uint64_t new_start = 0, new_last = 0, new_size = 0, new_wrap = 0;
uint64_t max_size;
+ uint32_t bad_fields = 0;
char *new_buf = NULL;
int overlap;
int found = 0;
@@ -550,7 +562,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!found)
return 1;
- if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
+ if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda), mda->ignore_bad_fields, &bad_fields)))
goto_out;
/*
@@ -821,6 +833,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
struct raw_locn *rlocn_slot1;
struct raw_locn *rlocn_new;
struct pv_list *pvl;
+ uint32_t bad_fields = 0;
int r = 0;
int found = 0;
@@ -841,7 +854,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
* mdah buffer, but the mdah buffer is not modified and mdac->rlocn is
* modified.
*/
- if (!(mdab = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
+ if (!(mdab = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda), mda->ignore_bad_fields, &bad_fields)))
goto_out;
/*
@@ -1033,6 +1046,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
struct mda_header *mdah;
struct raw_locn *rlocn_slot0;
struct raw_locn *rlocn_slot1;
+ uint32_t bad_fields = 0;
int r = 0;
if (!(mdah = dm_pool_alloc(fid->fmt->cmd->mem, MDA_HEADER_SIZE))) {
@@ -1046,7 +1060,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
* Just to print the warning?
*/
- if (!_raw_read_mda_header(mdah, &mdac->area, mda_is_primary(mda)))
+ if (!_raw_read_mda_header(mdah, &mdac->area, mda_is_primary(mda), 0, &bad_fields))
log_warn("WARNING: Removing metadata location on %s with bad mda header.",
dev_name(mdac->area.dev));
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index e1462f1..7320d9c 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -81,7 +81,9 @@ struct mda_header {
} __attribute__ ((packed));
struct mda_header *raw_read_mda_header(const struct format_type *fmt,
- struct device_area *dev_area, int primary_mda);
+ struct device_area *dev_area, int primary_mda,
+ uint32_t ignore_bad_fields,
+ uint32_t *bad_fields);
struct mda_lists {
struct metadata_area_ops *file_ops;
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index ef2f6c7..6eca3c1 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -331,8 +331,9 @@ static int _read_mda_header_and_metadata(struct metadata_area *mda, void *baton)
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct mda_header *mdah;
struct lvmcache_vgsummary vgsummary = { 0 };
+ uint32_t bad_fields = 0;
- if (!(mdah = raw_read_mda_header(fmt, &mdac->area, mda_is_primary(mda)))) {
+ if (!(mdah = raw_read_mda_header(fmt, &mdac->area, mda_is_primary(mda), 0, &bad_fields))) {
log_error("Failed to read mda header from %s", dev_name(mdac->area.dev));
goto fail;
}
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index a140c29..d904aa6 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -168,11 +168,25 @@ struct metadata_area_ops {
#define MDA_CONTENT_REASON(primary_mda) ((primary_mda) ? DEV_IO_MDA_CONTENT : DEV_IO_MDA_EXTRA_CONTENT)
#define MDA_HEADER_REASON(primary_mda) ((primary_mda) ? DEV_IO_MDA_HEADER : DEV_IO_MDA_EXTRA_HEADER)
+/*
+ * Flags describing errors found while reading.
+ */
+#define BAD_MDA_INTERNAL 0x00000001 /* internal lvm error */
+#define BAD_MDA_READ 0x00000002 /* read io failed */
+#define BAD_MDA_HEADER 0x00000004 /* general problem with header */
+#define BAD_MDA_TEXT 0x00000008 /* general problem with text */
+#define BAD_MDA_CHECKSUM 0x00000010
+#define BAD_MDA_MAGIC 0x00000020
+#define BAD_MDA_VERSION 0x00000040
+#define BAD_MDA_START 0x00000080
+
struct metadata_area {
struct dm_list list;
struct metadata_area_ops *ops;
void *metadata_locn;
uint32_t status;
+ uint32_t bad_fields; /* BAD_MDA_ flags are set to indicate errors found when reading */
+ uint32_t ignore_bad_fields; /* BAD_MDA_ flags are set to indicate errors to ignore */
};
struct metadata_area *mda_copy(struct dm_pool *mem,
struct metadata_area *mda);
3 years, 9 months
master - Additional MD component checking
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=db98a6e3629aaf6bf42...
Commit: db98a6e3629aaf6bf42d0e840273b4328f930c89
Parent: 24bd35b4ce77a5111ee234f554ca139df4b7dd99
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 21 12:06:34 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jun 7 13:27:16 2019 -0500
Additional MD component checking
If udev info is missing for a device, (which would indicate
if it's an MD component), then do an end-of-device read to
check if a PV is an MD component. (This is skipped when
using hints since we already know devs in hints are good.)
A new config setting md_component_checks can be used to
disable the additional end-of-device MD checks, or to
always enable end-of-device MD checks.
When both hints and udev info are disabled/unavailable,
the end of PVs will now be scanned by default. If md
devices with end-of-device superblocks are not being
used, the extra I/O overhead can be avoided by setting
md_component_checks="start".
---
lib/cache/lvmcache.c | 7 +++-
lib/commands/toolcontext.h | 2 +
lib/config/config_settings.h | 25 +++++++++++++-
lib/config/defaults.h | 2 +
lib/device/dev-md.c | 5 ++-
lib/device/dev-type.c | 5 ++-
lib/device/device.h | 1 +
lib/label/label.c | 27 +++++++++++++++
test/shell/lvm-on-md.sh | 75 +++++++++++++++++++++++++++++------------
tools/lvmcmdline.c | 55 ++++++++++++++++++++++++------
10 files changed, 166 insertions(+), 38 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 8a29bf4..b62e5e2 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -555,8 +555,11 @@ next:
*/
if (!(info = lvmcache_info_from_pvid(alt->dev->pvid, NULL, 0))) {
- /* This shouldn't happen */
- log_warn("WARNING: PV %s on duplicate device %s not found in cache.",
+ /*
+ * This will happen if a duplicate dev has been dropped already,
+ * e.g. it was found to be an md component.
+ */
+ log_debug("PVID %s on duplicate device %s not found in cache.",
alt->dev->pvid, dev_name(alt->dev));
goto next;
}
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 0ea2132..7d373ab 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -172,6 +172,7 @@ struct cmd_context {
unsigned pvscan_cache_single:1;
unsigned can_use_one_scan:1;
unsigned is_clvmd:1;
+ unsigned md_component_detection:1;
unsigned use_full_md_check:1;
unsigned is_activating:1;
unsigned enable_hints:1; /* hints are enabled for cmds in general */
@@ -184,6 +185,7 @@ struct cmd_context {
*/
struct dev_filter *filter;
struct dm_list hints;
+ const char *md_component_checks;
/*
* Configuration.
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index efa86e7..e718dec 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -368,7 +368,30 @@ cfg(devices_multipath_component_detection_CFG, "multipath_component_detection",
"Ignore devices that are components of DM multipath devices.\n")
cfg(devices_md_component_detection_CFG, "md_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_COMPONENT_DETECTION, vsn(1, 0, 18), NULL, 0, NULL,
- "Ignore devices that are components of software RAID (md) devices.\n")
+ "Enable detection and exclusion of MD component devices.\n"
+ "An MD component device is a block device that MD uses as part\n"
+ "of a software RAID virtual device. When an LVM PV is created\n"
+ "on an MD device, LVM must only use the top level MD device as\n"
+ "the PV, and should ignore the underlying component devices.\n"
+ "In cases where the MD superblock is located at the end of the\n"
+ "component devices, it is more difficult for LVM to consistently\n"
+ "identify an MD component, see the md_component_checks setting.\n")
+
+cfg(devices_md_component_checks_CFG, "md_component_checks", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_MD_COMPONENT_CHECKS, vsn(2, 3, 2), NULL, 0, NULL,
+ "The checks LVM should use to detect MD component devices.\n"
+ "MD component devices are block devices used by MD software RAID.\n"
+ "#\n"
+ "Accepted values:\n"
+ " auto\n"
+ " LVM will skip scanning the end of devices when it has other\n"
+ " indications that the device is not an MD component.\n"
+ " start\n"
+ " LVM will only scan the start of devices for MD superblocks.\n"
+ " This does not incur extra I/O by LVM.\n"
+ " full\n"
+ " LVM will scan the start and end of devices for MD superblocks.\n"
+ " This requires an extra read at the end of devices.\n"
+ "#\n")
cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FW_RAID_COMPONENT_DETECTION, vsn(2, 2, 112), NULL, 0, NULL,
"Ignore devices that are components of firmware RAID devices.\n"
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index fac5b75..6a0d686 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -318,4 +318,6 @@
#define DEFAULT_IO_MEMORY_SIZE_KB 8192
+#define DEFAULT_MD_COMPONENT_CHECKS "auto"
+
#endif /* _LVM_DEFAULTS_H */
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 261f3f1..08143b7 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -110,14 +110,17 @@ static int _udev_dev_is_md_component(struct device *dev)
if (!(ext = dev_ext_get(dev)))
return_0;
- if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE)))
+ if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE))) {
+ dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
+ }
return !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID);
}
#else
static int _udev_dev_is_md_component(struct device *dev)
{
+ dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}
#endif
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index 73e55ca..4e35220 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -1170,8 +1170,10 @@ int udev_dev_is_md_component(struct device *dev)
const char *value;
int ret = 0;
- if (!obtain_device_list_from_udev())
+ if (!obtain_device_list_from_udev()) {
+ dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
+ }
if (!(udev_device = _udev_get_dev(dev)))
return 0;
@@ -1198,6 +1200,7 @@ int udev_dev_is_mpath_component(struct device *dev)
int udev_dev_is_md_component(struct device *dev)
{
+ dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}
diff --git a/lib/device/device.h b/lib/device/device.h
index 395405a..30e1e79 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -37,6 +37,7 @@
#define DEV_BCACHE_WRITE 0x00008000 /* bcache_fd is open with RDWR */
#define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
+#define DEV_UDEV_INFO_MISSING 0x00040000 /* we have no udev info for this device */
/*
* Support for external device info.
diff --git a/lib/label/label.c b/lib/label/label.c
index 10c1c4c..f6ba2d8 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1022,6 +1022,33 @@ int label_scan(struct cmd_context *cmd)
}
}
+ /*
+ * Stronger exclusion of md components that might have been
+ * misidentified as PVs due to having an end-of-device md superblock.
+ * If we're not using hints, and are not already doing a full md check
+ * on devs being scanned, then if udev info is missing for a PV, scan
+ * the end of the PV to verify it's not an md component. The full
+ * dev_is_md_component call will do new reads at the end of the dev.
+ */
+ if (cmd->md_component_detection && !cmd->use_full_md_check && !using_hints &&
+ !strcmp(cmd->md_component_checks, "auto")) {
+ int once = 0;
+ dm_list_iterate_items(devl, &scan_devs) {
+ if (!(devl->dev->flags & DEV_SCAN_FOUND_LABEL))
+ continue;
+ if (!(devl->dev->flags & DEV_UDEV_INFO_MISSING))
+ continue;
+ if (!once++)
+ log_debug_devs("Scanning end of PVs with no udev info for MD components");
+
+ if (dev_is_md_component(devl->dev, NULL, 1)) {
+ log_debug_devs("Drop PV from MD component %s", dev_name(devl->dev));
+ devl->dev->flags &= ~DEV_SCAN_FOUND_LABEL;
+ lvmcache_del_dev(devl->dev);
+ }
+ }
+ }
+
dm_list_iterate_items_safe(devl, devl2, &all_devs) {
dm_list_del(&devl->list);
free(devl);
diff --git a/test/shell/lvm-on-md.sh b/test/shell/lvm-on-md.sh
index 41649be..22cbee8 100644
--- a/test/shell/lvm-on-md.sh
+++ b/test/shell/lvm-on-md.sh
@@ -31,6 +31,10 @@ test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \
aux lvmconf 'devices/md_component_detection = 1'
+# This stops lvm from taking advantage of hints which
+# will have already excluded md components.
+aux lvmconf 'devices/hints = "none"'
+
# This stops lvm from asking udev if a dev is an md component.
# LVM will ask udev if a dev is an md component, but we don't
# want to rely on that ability in this test.
@@ -61,6 +65,10 @@ check lv_field $vg/$lv1 lv_active "active"
pvs "$mddev"
not pvs "$dev1"
not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
+
sleep 1
vgchange -an $vg
@@ -72,12 +80,14 @@ sleep 1
mdadm --stop "$mddev"
aux udev_wait
-# with md superblock 1.0 this pvs will report duplicates
-# for the two md legs since the md device itself is not
-# started
-pvs 2>&1 |tee out
-cat out
-grep "prefers device" out
+# The md components should still be detected and excluded.
+not pvs "$dev1"
+not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
+
+pvs -vvvv
# should not activate from the md legs
not vgchange -ay $vg
@@ -104,16 +114,20 @@ not grep "active" out
mdadm --assemble "$mddev" "$dev1" "$dev2"
aux udev_wait
-# Now that the md dev is online, pvs can see it and
-# ignore the two legs, so there's no duplicate warning
+# Now that the md dev is online, pvs can see it
+# and check for components even if
+# md_component_checks is "start" (which disables
+# most default end-of-device scans)
+aux lvmconf 'devices/md_component_checks = "start"'
-pvs 2>&1 |tee out
-cat out
-not grep "prefers device" out
+not pvs "$dev1"
+not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
-vgchange -ay $vg 2>&1 |tee out
-cat out
-not grep "prefers device" out
+
+vgchange -ay $vg
check lv_field $vg/$lv1 lv_active "active"
@@ -124,6 +138,9 @@ vgremove -f $vg
aux cleanup_md_dev
+# Put this setting back to the default
+aux lvmconf 'devices/md_component_checks = "auto"'
+
# create 2 disk MD raid0 array
# by default using metadata format 1.0 with data at the end of device
# When a raid0 md array is stopped, the components will not look like
@@ -149,6 +166,10 @@ check lv_field $vg/$lv1 lv_active "active"
pvs "$mddev"
not pvs "$dev1"
not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
+
sleep 1
vgchange -an $vg
@@ -160,7 +181,14 @@ sleep 1
mdadm --stop "$mddev"
aux udev_wait
-pvs 2>&1 |tee pvs.out
+# The md components should still be detected and excluded.
+not pvs "$dev1"
+not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
+
+pvs -vvvv
# should not activate from the md legs
not vgchange -ay $vg
@@ -187,16 +215,19 @@ not grep "active" out
mdadm --assemble "$mddev" "$dev1" "$dev2"
aux udev_wait
-# Now that the md dev is online, pvs can see it and
-# ignore the two legs, so there's no duplicate warning
+# Now that the md dev is online, pvs can see it
+# and check for components even if
+# md_component_checks is "start" (which disables
+# most default end-of-device scans)
+aux lvmconf 'devices/md_component_checks = "start"'
-pvs 2>&1 |tee out
-cat out
-not grep "prefers device" out
+not pvs "$dev1"
+not pvs "$dev2"
+pvs > out
+not grep "$dev1" out
+not grep "$dev2" out
vgchange -ay $vg 2>&1 |tee out
-cat out
-not grep "prefers device" out
check lv_field $vg/$lv1 lv_active "active"
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 79de85b..30f54e6 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -2766,20 +2766,53 @@ static int _init_lvmlockd(struct cmd_context *cmd)
return 1;
}
+/*
+ * md_component_check full: always set use_full_md_check
+ * which causes filter-md to read the start+end of every
+ * device on the system (this could be optimized to only
+ * read the end of PVs.)
+ *
+ * md_component_check start: the end of devices will
+ * not generally be read to check for an md superblock
+ * (lvm may still scan for end-of-device md superblocks
+ * if it knows that some exists.)
+ *
+ * md_component_check auto: lvm will use some built-in
+ * heuristics to decide when it should scan the end of
+ * devices to look for md superblocks, e.g. commands
+ * like pvcreate that could clobber a component, or if
+ * udev info is not available and hints are not available.
+ */
static void _init_md_checks(struct cmd_context *cmd)
{
- /*
- * use_full_md_check can also be set later.
- * These commands are chosen to always perform
- * a full md component check because they initialize
- * a new device that could be an md component,
- * and they are not run frequently during normal
- * operation.
- */
- if (!strcmp(cmd->name, "pvcreate") ||
- !strcmp(cmd->name, "vgcreate") ||
- !strcmp(cmd->name, "vgextend"))
+ const char *md_check;
+
+ cmd->md_component_detection = find_config_tree_bool(cmd, devices_md_component_detection_CFG, NULL);
+
+ md_check = find_config_tree_str(cmd, devices_md_component_checks_CFG, NULL);
+ if (!md_check)
+ cmd->md_component_checks = "auto";
+ else if (!strcmp(md_check, "auto") ||
+ !strcmp(md_check, "start") ||
+ !strcmp(md_check, "full"))
+ cmd->md_component_checks = md_check;
+ else {
+ log_warn("Ignoring unknown md_component_checks setting, using auto.");
+ cmd->md_component_checks = "auto";
+ }
+
+ if (!strcmp(cmd->md_component_checks, "full"))
cmd->use_full_md_check = 1;
+ else if (!strcmp(cmd->md_component_checks, "auto")) {
+ /* use_full_md_check can also be set later */
+ if (!strcmp(cmd->name, "pvcreate") ||
+ !strcmp(cmd->name, "vgcreate") ||
+ !strcmp(cmd->name, "vgextend"))
+ cmd->use_full_md_check = 1;
+ }
+
+ log_debug("Using md_component_checks %s use_full_md_check %d",
+ cmd->md_component_checks, cmd->use_full_md_check);
}
static int _cmd_no_meta_proc(struct cmd_context *cmd)
3 years, 9 months
v2_03_03 annotated tag has been created
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b97b215be1e22c0b621...
Commit: b97b215be1e22c0b621ee7092359ce827e0a0d82
Parent: 0000000000000000000000000000000000000000
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: 2019-06-07 15:25 +0000
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: 2019-06-07 15:25 +0000
annotated tag: v2_03_03 has been created
at b97b215be1e22c0b621ee7092359ce827e0a0d82 (tag)
tagging cb6277aa8a1f6d0dedf2082995b1673da1eb46f9 (commit)
replaces v2_03_01
Release 2.03.03
Bugfix and Feature Release
Notable changes:
- Add pvck --dump option to extract metadata from disk.
- New scan_lvs option, defaultingo to 0 so LVs are not scanned for PVs.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAABAgAGBQJc+oHSAAoJELkRJDHlCQOfYCgP+wcaZnBOECd/3mcsiMK9fu5u
zl/+akrGmJhWvvreLOXD5gP8ayLJpTx+8lx8FdHbp1Vt/0nFRrBixMv8TAlsw1Kk
5UcEx3HPv6p5lgKBOIFojgG40KrV48IazRUhF0B002lHuqxqi4ArzvXGaGn0hngR
zEg/948fgsfRDnvUlc2aUmKl2OKK1m5kCciwvihjDX7eL4xWa6ZfGf9ibeZ8JMqk
w10MJdDqs727TgDDCQtrnLpdLjrKf+QMx2O4Tl//73ygw45EQ4sCtwd4q9VF+RPB
+AxAuRiPGlEQc2BntLEru5Qr6cAR5ne8JphIlb2Hs7yuQgzttPBRwkaR+A00HahI
w6STjKFSlnWeY3QNfo/hMc+MSWoEt6tgBNqvckf3Hhny4Wu3L2tznlRRSnpThxKj
+Haq7DznR3i1Zm2gzfQ9IMNkdu673i0HWFj1fkt53pJBCcjkRmZw6ld4jmgQaR5g
nIfeAsDE9L2T6vn8x3TFCouw3bCX1PcgpNGyUT6b9zy/BkDjPdSLy0yeX3vhHiD4
Gt5htIKgo1Rk3n7vlOL8IN19vSbHUiNf1RAFPZjexznlbf3h9GM54PYpxmvXf1gF
gwG0L3C9iAec9r5kooQ2IzizFBTVw+OadthYKoTdWotYAWEaa/cJ7opgfJlikscb
W/c0EZGXVo63pqJOR7Px
=gYZd
-----END PGP SIGNATURE-----
Alasdair G Kergon (1):
dmsetup: Fix multi-line concise table parsing
Bryn M. Reeves (2):
libdm-stats: move no regions warning after dm_stats_list()
dmsetup: fix stats report command output
David Teigland (150):
lvmlockd: use new sanlock sector/align interface
lvmlockd: fix size/resizing of internal lvmlock LV for sanlock
lvmlockd: deactivate lvmlock LV in vgchange
lvmlockd: fix handling of sanlock release error
lvmlockd: use standard major minor functions
cache: add cache_mode_num_to_str
cache: factor settings text import export
cache: factor getting cache mode
cache: clean up segment line creation
cache: rename variable in _cache_display
cache: rename variable in _cache_add_target_line
cache: improve warning message about cached thin data
cache: improve error message about flush
cache: reorganize cache_set_policy
cache: factor report functions
cache: factor lvchange_cache
Allow dm-cache cache device to be standard LV
Add dm-writecache support
devices: reuse bcache fd when getting block size
tests: fix dd option in cache-single-options
tests: enable writeback in cache-single-options
tests: enable cachepolicy cleaner in cache-single-options
tests: add lvchange cachemode passthrough in cache-single-options
tests: specify m1 for raid1 in cache-single-types
man: lvmcache update
man: remove cluster references
man: remove clvmd man page
man lvmdump: remove clvm reference
man: remove lvmetad
man pvscan: replace lvmetad text
pvscan: background option is not used
man: pvscan updates
remove unused backgroundfork option
man: remove scattered lvmetad references
man: remove some clvmd references
lvm2-monitoring service shouldn't refer to lvmetad
scripts: remove lvmetad from makefile
io: use sync io if aio fails
bcache: sync io fixes
WHATS_NEW: sync io
writecache: set block_size using --cachesettings
pvscan systemd service for event based activation
blk_availability service drop lvmetad
Place the first PE at 1 MiB for all defaults
lvmlockctl: wait by default when stopping
lvmlockd: vgchange locktype with yes option
config settings: fix version 3.0.0
devs: use udev info to improve md component detection
pvscan: use correct dev filters
remove unused lvmetad filter
remove unused full filter
man lvmlockd: lvextend with gfs2
tests: lvm-on-md udev issues
lvmlockd: fix missing LV lock for lvconvert repair
unit test: use_lvmetad replaced by event_activation
Revert "lvconvert: use standard wiping code"
writecache: prompt before using an LV to hold cache
writecache: use wipe_lv to warn about specific signatures
add device hints to reduce scanning
WHATS_NEW: device hints
hints: fix hint flock when using lvm shell
lvmlockd: make lockstart wait for existing start
move init_use_aio
lvmlockd: fix make lockstart wait
hints: invalidate when pvscan --cache sees a new PV
vgscan: drop 'take a while' message
tests: use pvscan after enable_dev in process-each-duplicate-vgnames
apply obtain_device_list_from_udev to all libudev usage
hints: fix recreating hints from pvscan
config: change scan_lvs default to 0
tests: set scan_lvs=1 in tests that stack PVs on LVs
WHATS_NEW: scan_lvs default change
pvscan: fix autoactivation from concurrent pvscans
pvscan: autoactivate a VG once
WHATS_NEW: concurrent pvscan autoactivation
logging: add command[pid] and timestamp to file and verbose output
pvscan: fix hint recreation
logging: new config settings to specify debug fields
config: make hints setting commented
Use "cachevol" to refer to cache on a single LV
pvscan service: use StartLimitIntervalSec
logging: remove unused code
remove unused io functions
config: add new setting io_memory_size
io: warn when metadata size approaches io memory size
io: increase the default io memory from 4 to 8 MiB
WHATS_NEW: io_memory_size
pvscan: ignore online for unused PV
pvscan: ignore online for shared and foreign PVs
tests: check that pvscan --cache ignores certain PVs
config: improve scan_lvs description
pvscan: fix ignoring foreign PVs
warn about changes to an active lv with shared lock
lvextend: allow on LV active with a shared lock
lvextend: refresh shared LV remotely using dlm/corosync
lvextend: refresh shared LV using select option
lvextend: refresh shared LV with vgname as arg
lvresize: fix when compiled without lvmlockd
lvextend: refresh shared LV without using select
lvmlockd: do not allow mirror LV to be activated shared
man: updates to lvmlockd
pvscan: reorganize code
pvscan: for init only autoactivate vg for named dev
pvscan: remove initialization case
pvscan: don't print warning about lvmlockd not running
tests: update pvscan-autoactivate for init change
pvscan: print more reasons for ignoring devices
pvscan: ignore device with incorrect size
WHATS_NEW: add several recent changes
hints: fix case of error getting device size
hints: fix non-empty hints list when not using hints
tests: disable unworking pvscan case
pvscan: handle case of scanning PV without metadata last
wipe_lv: initially open LV in writable mode
locking: unify global lock for flock and lockd
remove retry for missed PVs in process_each_pv
hints: skip hint flock if nolocking option is set
pvscan: remove fixme comment that is fixed
pvcreate: call label scan prior to pvcreate_each_device
vgcreate: remove the lvmcache locking workaround
lvmcache: remove unused flag
remove unused string writecache
use memcpy for constant ondisk strings
lvmlockd: fix snprintf warnings
scan: remove comments about lvmetad
add md component check in vg_read based on size
pvscan: don't record PV online after error reading metadata
tests: expand lvm-on-md
pvs: remove unnecessary label scan
pvscan: fix segfault in recent commit
devs: rename dev_is_md dev_is_md_component
move the setting of use_full_md_check flag
hints: exclude md components
scan: expand and update label scan comments
tests: hints check if strace exists
tests: pvscan-autoactivate.sh switch system_id_source
tests: fsadm-crypt.sh update mkfs parameter
tests: pvscan-cache try to fix teardown problems
tests: fix error detection in lvconvert-raid-takeover.sh
tests: change mkfs usage in lvconvert raid tests
pvck: new dump option to extract metadata
WHATS_NEW: pvck --dump
separate code for setting devices from metadata parsing
tests: pvscan-cache more attempts to fix
tests: add debug to pvscan-cache deactivation
pvck: dump headers and metadata
pvck: dump metadata_all
tests: pvck-dump
pvck: use new dump routines for old output
tests: pvscan-autoactivate check for machine-id
Heinz Mauelshagen (5):
lvcreate/lvconvert: prohibit creation of/conversion to mirrored mirror logs
WHATS_NEW
raid: fix (de)activation of RaidLVs with visible SubLVs
man: document 's' RAID attribute bit
lvcreate/lvconvert: optionally reenable mirrored mirror log for testing purposes only
Marian Csontos (13):
post-release
build: Upse PYTHON_CONFIG env.variable when set
udev: 69-dm-lvm-metad.rules is still needed
dmeventd: Fix libdevmapper-event linking
tests: Remove unsupported mirrored mirrorlog
build: Remove reference to undefined @BUILD_LVMETAD@
build: Remove badly placed `@`
Revert "tests: Remove unsupported mirrored mirrorlog"
lvmlockd: Fix arguments when built without sanlock
cov: Close a FD on error
test: Restore testing of D-Bus API
test: Increase latency in pvmove-resume-multiseg
pre-release
Ming-Hung Tsai (1):
lvmanip: uninitialized members in struct pv_list (#10)
Peter Rajnoha (4):
scan: md metadata version 0.90 is at the end of disk
scripts: lvm2-activation-generator fix lvmconfig call
systemd: add missing Before=shutdown.target to LVM2 services to fix shutdown ordering
systemd: put back DefaultDependencies=no for lvmpolld socket unit
Tony Asleson (13):
lvmdbusd: Dump blackbox newest first
lvmdbusd: Handle missing lv_attr table lookups
lvmdbusd: Update table lookup for health lv_attr
lvmdbusd: Update table lookup for state lv_attr
lvmdbusd: Exit daemon when unable to retrieve state
lvmdbusd: Handle exported VG(s)
tests/dbus: Re-enable nesting and pvcreate via symlink
lvmdbusd: Ensure all paths return value
lvmdbusd: LookUpByLvmId: Add doc for cb, cbe
lvmdbusd: Spelling correction
lvmdbusd: Correct object manager lookups
lvmdbusd: Handle duplicate VG names
lvmdbusd: Use UUID instead of name for VG rename
Zdenek Kabelac (206):
label: add stack trace for failing dev_set_last_byte
cov: remove uneeded code
cov: split check for type assignment
cov: explicit ignore if failures
cov: overflow before widen
cov: add missing check for dm_strncpy
cov: trace failing pthread_kill
cov: mark warning as expected one
cov: hide intentionaly ptr arithmetic report
cov: remove unused assigns
cov: avoid unsing unchecked label_scan_open
cleanup: move cast to det_t into MKDEV macro
debug: tracing fclose failure
debug: missing backtrace
pvscan: add error checking for write of online files
tests: add wait for udev
tests: fix shell quoting
activation: trimming string is expected
devicemapper: retry remove even for subLVs
configure: update
tests: keep results configurable
tests: updates
tests: futher test tunning
devicemapper: retry mirror leg deactivation
tests: add wait loop
libdm: do not add params for resume and remove
libdm: add DM_DEVICE_ARM_POLL
libdm: print params only for ioctls using them
libdm: add memory barrier
tests: secure data erase
tests: extend
tests: raise minsize of xfs
tests: drop unwanted backup
tests: makefile fixes
tests: still more libs needs
tests: correcting header file enclosure
tests: prefer internal header
tests: skip when gcore from gdb package is missing
tests: skip portion of test for lvmpolld
tests: create whole path with mkdir
tests: skip part of test
tests: update parm for new kernel
tests: speed-up testing full of lvm2 metadata
tests: generate slightly less volumes
sanlock: update headers
tests: missing copyright
tests: update required raid target
base: use calloc
makefiles: improve lcov generator
makefiles: updates for less verbosity
makefiles: avoid dependency calcs for base dir
makefiles: improving cleaning rules
makefiles: add missing srcdir
make: generate config update
make: generate man update
tests: add mising udev_wait
tests: use select with dmsetup
tests: requires at least 2 iterations
tests: updates
tests: reduce memory footprint
tests: drop use_lvmetad from unit test
configure: update
makefiles: ignore missing files
makefiles: clean unit-test
tests: extend sleep
rpm: install lvm2-pvscan again
device_mapper: fix incorrect dm_strncpy usage
device_mapper: optimize dm_pool_strndup
libdm: optimize dm_pool_strndup
device_mapper: move internal header to front
makefiles: avoid clustering out
makefiles: ensure test dir can run unit-test
gcc: avoid shadowing index
gcc: avoid shadowing activate_lv
gcc: avoid shadowing use_aio
gcc: ensure sector is initilized
libdm: use libdm header
headers: use configure.h as 1st. header
headers: use full path header instead of -I directive
makefiles: correct libdm dependency
makefiles: drop unneeded include path
makefiles: local headers first
makefiles: some leftovers from lvmetad
cleanup: some local headers first
debug: drop extra tracing
lvconvert: ensure proper init of pv_list
dmfilemapd: avoid linking with DL_LIBS
dmeventd: fix linking with libdevmapper
dmeventd: do not link internal libraries to plugins
lvm: drop usage of dl library
cmirror: link with libdm
makefiles: sort
makefiles: drop unneeded LIBS add
makefiles: quite install
makefiles: missing cleaning
makefiles: no longer used define
makefiles: allow to set LIBS in Makefiles
makefiles: dm-tools improve Makefile
makefiles: correcting login of makefile
makefile: fixes build for older system
makefiles: also fix build of unit test
dmeventd: resolve compilation of vdo status parsing
lib: move towards v2 version of VDO format
configure: avoid repeative inclusion of configure.h
lvmpolld: improve makefile deps
lvmlockd: fix error return code for _init_vg_sanlock
lvmlockd: use commonly used define NOTIFYDBUS_SUPPORT
lvmlockd: drop superfluous defines
scripts: avoid voiding write result
scripts: simplify including for generator
stats: fix error path when region is NULL
cleanup: missing copyright header
lvconvert: use standard wiping code
lvconvert: writecache fix return code
dmeventd: unlock lvm2 lock on error path
bcache: fix memory leak on error path
debug: drop some extra backtraces
debug: tracing close errors
mangenerator: check strdup was successfull
cov: ensure lock_type is not NULL
cov: looks like cut&paste error
cov: drop unneeded header file
cov: extent_size cannot be 0
Revert "lvmlockd: Fix arguments when built without sanlock"
stats: initilize regions to NULL
cov: fix memleak on error path
cleanup: use zalloc
debug: drop some unneeded backtraces
tests: testing mirrorred mirror log
tests: fix unit test
tests: indent
generators: avoid contacting syslog with generators
config: drop extra spaces
vdo: regenerate config
mirror: regenerate config
raid: man regenerated
vdo: fix archived metadata comment
vdo: update vdo profile
man: missed --zero option for thin-pool creation
man: initial man page for VDO support
man: document dD attrs for VDO lvs
dm: ensure migration_threshold is big enough
dm: migration_threshold for old linked tools
lv_manip: better work with PERCENT_VG modifier
vdo: introduce function for estimation of virtual size
vdo: estimate virtual size after resize
vdo: discard reduced area
vdo: size reduction requires VDO to be active
vdo: allow resize of VDO and VDO pool volumes
cleanup: better naming
vdo: man documenting resize
tests: update cache test
tests: aux fix testing for kvdo
tests: initial test for vdo resize
vdo: add simple wrapper for getting pool percentage
vdo: enable dmeventd resize
tests: vdo dmeventd resize
vdo: minor API cleanup
lv_manip: better work with PERCENT_VG modifier with lvresize
vdo: some formating updates
rpm: package lvmvdo man page
cache: select chunk size as power of 2
thin: select chunk size as power of 2
tests: rounding for pools changed to power of 2
lvconvert: pass force and yes options for vdo conversion
vdo: complete matching with thin syntax
vdo: document types vdo and vdo-pool
vdo: add some basic example
man: vdo regenerated
man: lvmvdo component activation description
cleanup: indent
gitignore: update
dev_manager: add dev_manager_remove_dm_major_minor
filter: enhance mpath detection
debug: use log_warn
thin: max thin
cache: support vgsplit
tests: check vgsplit works with cache
lv_manip: insert remove layer skips pools
vdo: enable caching for vdopool LV and vdo LV
activation: synchronize before removing devices
man: basic vdo stacking support
man: dmeventd vdo plugin
tests: vdo dmevent autoresize
tests: vdo caching tests
filter: fix mpath test
thin: introduce estimate_thin_pool_metadata_size
thin: resize metadata with data
thin: fix maintenance of _pmspare
tests: check auto-growth of thin-pool meta
configure: check for pselect
libdaemon: use pselect to avoid condition checking race
cleanup: missed string specifier
clean: avoid cleaning iterator on error path
locking: validate locking mode
build: fix compilation without lvmlockd
cleanup: use unsigned type
tests: update resize value
tests: use luks1 for test
tests: drop call of wipefs
tests: split args
metadata: allow reading metadata with invalid creation_time
tests: check accepting out-of-range creation_time
cache: support no_discard_passdown
tests: automatically set scan_lvs when using extend_filter
tests: check no_discard_passdown
3 years, 9 months
master - Merge remote-tracking branch 'origin/master'
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=24bd35b4ce77a5111ee...
Commit: 24bd35b4ce77a5111ee234f554ca139df4b7dd99
Parent: 4d11bf8d50e72476c09e813ffc1144150f0552e0 2bcd43c683eec3a07d4b7833445856c9aad9963c
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Fri Jun 7 17:29:45 2019 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Fri Jun 7 17:29:45 2019 +0200
Merge remote-tracking branch 'origin/master'
* origin/master:
lvmcache: remove unused_duplicate_devs list from cmd
lib/cache/lvmcache.c | 16 +++++++++-------
lib/commands/toolcontext.c | 2 --
lib/commands/toolcontext.h | 1 -
3 files changed, 9 insertions(+), 10 deletions(-)
3 years, 9 months
master - post-release
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4d11bf8d50e72476c09...
Commit: 4d11bf8d50e72476c09e813ffc1144150f0552e0
Parent: cb6277aa8a1f6d0dedf2082995b1673da1eb46f9
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Fri Jun 7 16:33:29 2019 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Fri Jun 7 17:24:51 2019 +0200
post-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 3 +++
WHATS_NEW_DM | 5 ++++-
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/VERSION b/VERSION
index d2f613b..3a0456f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.03.03(2) (2019-06-07)
+2.03.04(2)-git (2019-06-07)
diff --git a/VERSION_DM b/VERSION_DM
index 78eb98d..79067a8 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.159 (2019-06-07)
+1.02.161-git (2019-06-07)
diff --git a/WHATS_NEW b/WHATS_NEW
index 1062c27..c2d3600 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,6 @@
+Version 2.03.04 -
+================================
+
Version 2.03.03 - 07th June 2019
================================
Report no_discard_passdown for cache LVs with lvs -o+kernel_discards.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 8edd76c..49b9a7e 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,8 @@
-Version 1.02.159 - 07th June 2019
+Version 1.02.161 -
====================================
+
+Version 1.02.159 - 07th June 2019
+=================================
Parsing of cache status understand no_discard_passdown.
Ensure migration_threshold for cache is at least 8 chunks.
3 years, 9 months
master - pre-release
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=cb6277aa8a1f6d0dedf...
Commit: cb6277aa8a1f6d0dedf2082995b1673da1eb46f9
Parent: c315112a3b7d01e56cbd2ecb3d05f55d44a50e12
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Fri Jun 7 16:32:02 2019 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Fri Jun 7 17:24:51 2019 +0200
pre-release
---
VERSION | 2 +-
VERSION_DM | 2 +-
WHATS_NEW | 12 ++++++++----
WHATS_NEW_DM | 6 +++++-
4 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/VERSION b/VERSION
index 83eb504..d2f613b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.03.02(2)-git (2018-10-31)
+2.03.03(2) (2019-06-07)
diff --git a/VERSION_DM b/VERSION_DM
index 4866208..78eb98d 100644
--- a/VERSION_DM
+++ b/VERSION_DM
@@ -1 +1 @@
-1.02.155-git (2018-10-31)
+1.02.159 (2019-06-07)
diff --git a/WHATS_NEW b/WHATS_NEW
index b5deceb..1062c27 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,5 @@
-Version 2.03.02 -
-===================================
+Version 2.03.03 - 07th June 2019
+================================
Report no_discard_passdown for cache LVs with lvs -o+kernel_discards.
Add pvck --dump option to extract metadata.
Fix signal delivery checking race in libdaemon (lvmetad).
@@ -35,10 +35,14 @@ Version 2.03.02 -
Fix missing unlock on lvm2 dmeventd plugin error path initialization.
Improve Makefile dependency tracking.
Move VDO support towards V2 target (6.2) support.
+
+Version 2.03.02 - 18th December 2018
+====================================
Fix missing proper initialization of pv_list struct when adding pv.
- Fix (de)activation of RaidLVs with visible SubLVs
- Prohibit mirrored 'mirror' log via lvcreate and lvconvert
+ Fix (de)activation of RaidLVs with visible SubLVs.
+ Prohibit mirrored 'mirror' log via lvcreate and lvconvert.
Use sync io if async io_setup fails, or use_aio=0 is set in config.
+ Fix more issues reported by coverity scan.
Version 2.03.01 - 31st October 2018
===================================
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 8a2146d..8edd76c 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,11 +1,15 @@
-Version 1.02.155 -
+Version 1.02.159 - 07th June 2019
====================================
Parsing of cache status understand no_discard_passdown.
Ensure migration_threshold for cache is at least 8 chunks.
+
+Version 1.02.155 - 18th December 2018
+=====================================
Include correct internal header inside libdm list.c.
Enhance ioctl flattening and add parameters only when needed.
Add DM_DEVICE_ARM_POLL for API completness matching kernel.
Do not add parameters for RESUME with DM_DEVICE_CREATE dm task.
+ Fix dmstats report printing no output.
Version 1.02.153 - 31st October 2018
====================================
3 years, 9 months
stable-2.02 - lvmcache: remove unused_duplicate_devs list from cmd
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c31e6b0acad339ec3cd...
Commit: c31e6b0acad339ec3cdc0c8d7e0e01f8d816ed10
Parent: cb7766bc1411c3350e79241122a974dac7fcc902
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jun 6 14:12:19 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Jun 6 14:12:19 2019 -0500
lvmcache: remove unused_duplicate_devs list from cmd
Save the previous duplicate PVs in a global list instead
of a list on the cmd struct. dmeventd reuses the cmd struct
for multiple commands, and the list entries between commands
were being freed (apparently), causing a segfault in dmeventd
when it tried to use items in cmd->unused_duplicate_devs
that had been saved there by the previous command.
---
lib/cache/lvmcache.c | 16 +++++++++-------
lib/commands/toolcontext.c | 2 --
lib/commands/toolcontext.h | 1 -
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index ad40d4c..0ce5df0 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -100,6 +100,7 @@ static struct dm_hash_table *_saved_vg_hash = NULL;
static DM_LIST_INIT(_vginfos);
static DM_LIST_INIT(_found_duplicate_devs);
static DM_LIST_INIT(_unused_duplicate_devs);
+static DM_LIST_INIT(_prev_unused_duplicate_devs);
static int _scanning_in_progress = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
@@ -118,6 +119,7 @@ int lvmcache_init(struct cmd_context *cmd)
dm_list_init(&_vginfos);
dm_list_init(&_found_duplicate_devs);
dm_list_init(&_unused_duplicate_devs);
+ dm_list_init(&_prev_unused_duplicate_devs);
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
@@ -1152,14 +1154,14 @@ next:
if (!prev_unchosen1 && !prev_unchosen2) {
/*
- * The cmd list saves the unchosen preference across
+ * The prev list saves the unchosen preference across
* lvmcache_destroy. Sometimes a single command will
* fill lvmcache, destroy it, and refill it, and we
* want the same duplicate preference to be preserved
* in each instance of lvmcache for a single command.
*/
- prev_unchosen1 = _dev_in_device_list(dev1, &cmd->unused_duplicate_devs);
- prev_unchosen2 = _dev_in_device_list(dev2, &cmd->unused_duplicate_devs);
+ prev_unchosen1 = _dev_in_device_list(dev1, &_prev_unused_duplicate_devs);
+ prev_unchosen2 = _dev_in_device_list(dev2, &_prev_unused_duplicate_devs);
}
dev1_major = MAJOR(dev1->dev);
@@ -2575,8 +2577,8 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
dm_list_init(&_vginfos);
/*
- * Copy the current _unused_duplicate_devs into a cmd list before
- * destroying _unused_duplicate_devs.
+ * Move the current _unused_duplicate_devs to _prev_unused_duplicate_devs
+ * before destroying _unused_duplicate_devs.
*
* One command can init/populate/destroy lvmcache multiple times. Each
* time it will encounter duplicates and choose the preferrred devs.
@@ -2584,8 +2586,8 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
* the unpreferred devs here so that _choose_preferred_devs can use
* this to make the same choice each time.
*/
- dm_list_init(&cmd->unused_duplicate_devs);
- lvmcache_get_unused_duplicate_devs(cmd, &cmd->unused_duplicate_devs);
+ _destroy_duplicate_device_list(&_prev_unused_duplicate_devs);
+ dm_list_splice(&_prev_unused_duplicate_devs, &_unused_duplicate_devs);
_destroy_duplicate_device_list(&_unused_duplicate_devs);
_destroy_duplicate_device_list(&_found_duplicate_devs); /* should be empty anyway */
_found_duplicate_pvs = 0;
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 25e8b87..38e382f 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1983,8 +1983,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
if (!init_lvmcache_orphans(cmd))
goto_out;
- dm_list_init(&cmd->unused_duplicate_devs);
-
if (!_init_segtypes(cmd))
goto_out;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 485dca9..6e262e8 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -231,7 +231,6 @@ struct cmd_context {
const char *report_list_item_separator;
const char *time_format;
unsigned rand_seed;
- struct dm_list unused_duplicate_devs; /* save preferences between lvmcache instances */
};
/*
3 years, 9 months
master - lvmcache: remove unused_duplicate_devs list from cmd
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2bcd43c683eec3a07d4...
Commit: 2bcd43c683eec3a07d4b7833445856c9aad9963c
Parent: c315112a3b7d01e56cbd2ecb3d05f55d44a50e12
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jun 7 10:12:52 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jun 7 10:14:33 2019 -0500
lvmcache: remove unused_duplicate_devs list from cmd
Save the previous duplicate PVs in a global list instead
of a list on the cmd struct. dmeventd reuses the cmd struct
for multiple commands, and the list entries between commands
were being freed (apparently), causing a segfault in dmeventd
when it tried to use items in cmd->unused_duplicate_devs
that had been saved there by the previous command.
---
lib/cache/lvmcache.c | 16 +++++++++-------
lib/commands/toolcontext.c | 2 --
lib/commands/toolcontext.h | 1 -
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index a4037a5..8a29bf4 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -66,6 +66,7 @@ static struct dm_hash_table *_vgname_hash = NULL;
static DM_LIST_INIT(_vginfos);
static DM_LIST_INIT(_found_duplicate_devs);
static DM_LIST_INIT(_unused_duplicate_devs);
+static DM_LIST_INIT(_prev_unused_duplicate_devs);
static int _vgs_locked = 0;
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
static int _found_duplicate_vgnames = 0;
@@ -81,6 +82,7 @@ int lvmcache_init(struct cmd_context *cmd)
dm_list_init(&_vginfos);
dm_list_init(&_found_duplicate_devs);
dm_list_init(&_unused_duplicate_devs);
+ dm_list_init(&_prev_unused_duplicate_devs);
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
@@ -581,14 +583,14 @@ next:
if (!prev_unchosen1 && !prev_unchosen2) {
/*
- * The cmd list saves the unchosen preference across
+ * The prev list saves the unchosen preference across
* lvmcache_destroy. Sometimes a single command will
* fill lvmcache, destroy it, and refill it, and we
* want the same duplicate preference to be preserved
* in each instance of lvmcache for a single command.
*/
- prev_unchosen1 = dev_in_device_list(dev1, &cmd->unused_duplicate_devs);
- prev_unchosen2 = dev_in_device_list(dev2, &cmd->unused_duplicate_devs);
+ prev_unchosen1 = dev_in_device_list(dev1, &_prev_unused_duplicate_devs);
+ prev_unchosen2 = dev_in_device_list(dev2, &_prev_unused_duplicate_devs);
}
dev1_major = MAJOR(dev1->dev);
@@ -1828,8 +1830,8 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
dm_list_init(&_vginfos);
/*
- * Copy the current _unused_duplicate_devs into a cmd list before
- * destroying _unused_duplicate_devs.
+ * Move the current _unused_duplicate_devs to _prev_unused_duplicate_devs
+ * before destroying _unused_duplicate_devs.
*
* One command can init/populate/destroy lvmcache multiple times. Each
* time it will encounter duplicates and choose the preferrred devs.
@@ -1837,8 +1839,8 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
* the unpreferred devs here so that _choose_preferred_devs can use
* this to make the same choice each time.
*/
- dm_list_init(&cmd->unused_duplicate_devs);
- lvmcache_get_unused_duplicate_devs(cmd, &cmd->unused_duplicate_devs);
+ _destroy_duplicate_device_list(&_prev_unused_duplicate_devs);
+ dm_list_splice(&_prev_unused_duplicate_devs, &_unused_duplicate_devs);
_destroy_duplicate_device_list(&_unused_duplicate_devs);
_destroy_duplicate_device_list(&_found_duplicate_devs); /* should be empty anyway */
_found_duplicate_pvs = 0;
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 2642d23..1e03ea2 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1715,8 +1715,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
if (!init_lvmcache_orphans(cmd))
goto_out;
- dm_list_init(&cmd->unused_duplicate_devs);
-
if (!_init_segtypes(cmd))
goto_out;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index c9def87..0ea2132 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -234,7 +234,6 @@ struct cmd_context {
const char *report_list_item_separator;
const char *time_format;
unsigned rand_seed;
- struct dm_list unused_duplicate_devs; /* save preferences between lvmcache instances */
};
/*
3 years, 9 months
master - tests: pvscan-autoactivate check for machine-id
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c315112a3b7d01e56cb...
Commit: c315112a3b7d01e56cbd2ecb3d05f55d44a50e12
Parent: 2b241eb1f666e93f47917f2495e900bf80c9d5ff
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jun 6 15:32:42 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Jun 6 15:32:42 2019 -0500
tests: pvscan-autoactivate check for machine-id
---
test/shell/pvscan-autoactivate.sh | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/test/shell/pvscan-autoactivate.sh b/test/shell/pvscan-autoactivate.sh
index 362a4ff..d674dc5 100644
--- a/test/shell/pvscan-autoactivate.sh
+++ b/test/shell/pvscan-autoactivate.sh
@@ -134,6 +134,8 @@ not ls "$RUNDIR/lvm/pvs_online/$PVID3"
# pvscan cache ignores pv in a foreign vg
+if [ -e "/etc/machine-id" ]; then
+
aux lvmconf "global/system_id_source = machineid"
_clear_online_files
@@ -168,6 +170,8 @@ cat tmp
grep $lv2 tmp
check lv_field $vg2/$lv2 lv_active "" --foreign
+fi
+
# Test the case where pvscan --cache -aay (with no devs)
# gets the final PV to complete the VG, where that final PV
3 years, 9 months
master - pvck: use new dump routines for old output
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2b241eb1f666e93f479...
Commit: 2b241eb1f666e93f47917f2495e900bf80c9d5ff
Parent: 356ea897ccfca5a80b00a0a6b2479042f6efd144
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 5 16:23:23 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jun 5 16:28:52 2019 -0500
pvck: use new dump routines for old output
Use the recently added dump routines to produce the
old/traditional pvck output, and remove the code that
had been used for that.
The validation/checking done by the new routines means
that new lines prefixed with CHECK are printed for
incorrect values.
---
lib/format_text/format-text.c | 152 -----------------------------------------
lib/label/label.c | 60 ----------------
lib/metadata/metadata.c | 35 ----------
tools/pvck.c | 151 +++++++++++++++++++++++++----------------
4 files changed, 92 insertions(+), 306 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 3828d5f..2831a53 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -121,157 +121,6 @@ static struct device *_mda_get_device_raw(struct metadata_area *mda)
return mdac->area.dev;
}
-/*
- * For circular region between region_start and region_start + region_size,
- * back up one SECTOR_SIZE from 'region_ptr' and return the value.
- * This allows reverse traversal through text metadata area to find old
- * metadata.
- *
- * Parameters:
- * region_start: start of the region (bytes)
- * region_size: size of the region (bytes)
- * region_ptr: pointer within the region (bytes)
- * NOTE: region_start <= region_ptr <= region_start + region_size
- */
-static uint64_t _get_prev_sector_circular(uint64_t region_start,
- uint64_t region_size,
- uint64_t region_ptr)
-{
- if (region_ptr >= region_start + SECTOR_SIZE)
- return region_ptr - SECTOR_SIZE;
-
- return (region_start + region_size - SECTOR_SIZE);
-}
-
-/*
- * Analyze a metadata area for old metadata records in the circular buffer.
- * This function just looks through and makes a first pass at the data in
- * the sectors for particular things.
- * FIXME: do something with each metadata area (try to extract vg, write
- * raw data to file, etc)
- */
-static int _pv_analyze_mda_raw (const struct format_type * fmt,
- struct metadata_area *mda)
-{
- struct mda_header *mdah;
- struct raw_locn *rlocn;
- uint64_t area_start;
- uint64_t area_size;
- uint64_t prev_sector, prev_sector2;
- uint64_t latest_mrec_offset;
- uint64_t offset;
- uint64_t offset2;
- size_t size;
- size_t size2;
- char *buf=NULL;
- struct device_area *area;
- struct mda_context *mdac;
- int r=0;
-
- mdac = (struct mda_context *) mda->metadata_locn;
-
- log_print("Found text metadata area: offset=" FMTu64 ", size="
- FMTu64, mdac->area.start, mdac->area.size);
- area = &mdac->area;
-
- if (!(mdah = raw_read_mda_header(fmt, area, mda_is_primary(mda))))
- goto_out;
-
- rlocn = mdah->raw_locns;
-
- /*
- * The device area includes the metadata header as well as the
- * records, so remove the metadata header from the start and size
- */
- area_start = area->start + MDA_HEADER_SIZE;
- area_size = area->size - MDA_HEADER_SIZE;
- latest_mrec_offset = rlocn->offset + area->start;
-
- /*
- * Start searching at rlocn (point of live metadata) and go
- * backwards.
- */
- prev_sector = _get_prev_sector_circular(area_start, area_size,
- latest_mrec_offset);
- offset = prev_sector;
- size = SECTOR_SIZE;
- offset2 = size2 = 0;
-
- while (prev_sector != latest_mrec_offset) {
- prev_sector2 = prev_sector;
- prev_sector = _get_prev_sector_circular(area_start, area_size,
- prev_sector);
- if (prev_sector > prev_sector2)
- goto_out;
- /*
- * FIXME: for some reason, the whole metadata region from
- * area->start to area->start+area->size is not used.
- * Only ~32KB seems to contain valid metadata records
- * (LVM2 format - format_text). As a result, I end up with
- * "dm_config_maybe_section" returning true when there's no valid
- * metadata in a sector (sectors with all nulls).
- */
- if (!(buf = malloc(size + size2)))
- goto_out;
-
- if (!dev_read_bytes(area->dev, offset, size, buf)) {
- log_error("Failed to read dev %s offset %llu size %llu",
- dev_name(area->dev),
- (unsigned long long)offset,
- (unsigned long long)size);
- goto out;
- }
-
- if (size2) {
- if (!dev_read_bytes(area->dev, offset2, size2, buf + size)) {
- log_error("Failed to read dev %s offset %llu size %llu",
- dev_name(area->dev),
- (unsigned long long)offset2,
- (unsigned long long)size2);
- goto out;
- }
- }
-
- /*
- * FIXME: We could add more sophisticated metadata detection
- */
- if (dm_config_maybe_section(buf, size + size2)) {
- /* FIXME: Validate region, pull out timestamp?, etc */
- /* FIXME: Do something with this region */
- log_verbose ("Found LVM2 metadata record at "
- "offset=" FMTu64 ", size=" FMTsize_t ", "
- "offset2=" FMTu64 " size2=" FMTsize_t,
- offset, size, offset2, size2);
- offset = prev_sector;
- size = SECTOR_SIZE;
- offset2 = size2 = 0;
- } else {
- /*
- * Not a complete metadata record, assume we have
- * metadata and just increase the size and offset.
- * Start the second region if the previous sector is
- * wrapping around towards the end of the disk.
- */
- if (prev_sector > offset) {
- offset2 = prev_sector;
- size2 += SECTOR_SIZE;
- } else {
- offset = prev_sector;
- size += SECTOR_SIZE;
- }
- }
- free(buf);
- buf = NULL;
- }
-
- r = 1;
- out:
- free(buf);
- return r;
-}
-
-
-
static int _text_lv_setup(struct format_instance *fid __attribute__((unused)),
struct logical_volume *lv)
{
@@ -1962,7 +1811,6 @@ static struct metadata_area_ops _metadata_text_raw_ops = {
.mda_free_sectors = _mda_free_sectors_raw,
.mda_total_sectors = _mda_total_sectors_raw,
.mda_in_vg = _mda_in_vg_raw,
- .pv_analyze_mda = _pv_analyze_mda_raw,
.mda_locns_match = _mda_locns_match_raw,
.mda_get_device = _mda_get_device_raw,
};
diff --git a/lib/label/label.c b/lib/label/label.c
index 43b05a2..10c1c4c 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1198,66 +1198,6 @@ int label_read(struct device *dev)
return 1;
}
-/*
- * Read a label from a specfic, non-zero sector. This is used in only
- * one place: pvck/pv_analyze.
- */
-
-int label_read_sector(struct device *dev, uint64_t read_sector)
-{
- struct block *bb = NULL;
- uint64_t block_num;
- uint64_t block_sector;
- uint64_t start_sector;
- int is_lvm_device = 0;
- int result;
- int ret;
-
- block_num = read_sector / BCACHE_BLOCK_SIZE_IN_SECTORS;
- block_sector = block_num * BCACHE_BLOCK_SIZE_IN_SECTORS;
- start_sector = read_sector % BCACHE_BLOCK_SIZE_IN_SECTORS;
-
- if (!label_scan_open(dev)) {
- log_error("Error opening device %s for prefetch %llu sector.",
- dev_name(dev), (unsigned long long)block_num);
- return false;
- }
-
- bcache_prefetch(scan_bcache, dev->bcache_fd, block_num);
-
- if (!bcache_get(scan_bcache, dev->bcache_fd, block_num, 0, &bb)) {
- log_error("Scan failed to read %s at %llu",
- dev_name(dev), (unsigned long long)block_num);
- ret = 0;
- goto out;
- }
-
- /*
- * TODO: check if scan_sector is larger than the bcache block size.
- * If it is, we need to fetch a later block from bcache.
- */
-
- result = _process_block(NULL, NULL, dev, bb, block_sector, start_sector, &is_lvm_device);
-
- if (!result && is_lvm_device) {
- log_error("Scan failed to process %s", dev_name(dev));
- ret = 0;
- goto out;
- }
-
- if (!result || !is_lvm_device) {
- log_error("Could not find LVM label on %s", dev_name(dev));
- ret = 0;
- goto out;
- }
-
- ret = 1;
-out:
- if (bb)
- bcache_put(bb);
- return ret;
-}
-
int label_scan_setup_bcache(void)
{
if (!scan_bcache) {
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 8f6de26..65da7e1 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4664,41 +4664,6 @@ int is_real_vg(const char *vg_name)
return (vg_name && *vg_name != '#');
}
-static int _analyze_mda(struct metadata_area *mda, void *baton)
-{
- const struct format_type *fmt = baton;
- mda->ops->pv_analyze_mda(fmt, mda);
- return 1;
-}
-
-/*
- * Returns:
- * 0 - fail
- * 1 - success
- */
-int pv_analyze(struct cmd_context *cmd, struct device *dev,
- uint64_t label_sector)
-{
- struct label *label;
- struct lvmcache_info *info;
-
- if (!(label = lvmcache_get_dev_label(dev))) {
- log_error("Could not find LVM label on %s", dev_name(dev));
- return 0;
- }
-
- log_print("Found label on %s, sector %"PRIu64", type=%.8s",
- dev_name(dev), label->sector, label->type);
-
- /*
- * Next, loop through metadata areas
- */
- info = label->info;
- lvmcache_foreach_mda(info, _analyze_mda, (void *)lvmcache_fmt(info));
-
- return 1;
-}
-
/* FIXME: remove / combine this with locking? */
int vg_check_write_mode(struct volume_group *vg)
{
diff --git a/tools/pvck.c b/tools/pvck.c
index c9b833a..3437164 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -83,13 +83,16 @@ static char *_chars_to_hexstr(void *in, void *out, int num, int max, const char
return out;
}
-static int _check_label_header(struct label_header *lh, uint64_t labelsector)
+static int _check_label_header(struct label_header *lh, uint64_t labelsector,
+ int *found_label)
{
uint32_t crc;
+ int good_id = 1, good_type = 1;
int bad = 0;
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
log_print("CHECK: label_header.id expected %s", LABEL_ID);
+ good_id = 0;
bad++;
}
@@ -113,9 +116,14 @@ static int _check_label_header(struct label_header *lh, uint64_t labelsector)
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
log_print("CHECK: label_header.type expected %s", LVM2_LABEL);
+ good_type = 0;
bad++;
}
+ /* Report a label is found if at least id and type are correct. */
+ if (found_label && good_id && good_type)
+ *found_label = 1;
+
if (bad)
return 0;
return 1;
@@ -140,10 +148,11 @@ static int _check_pv_header(struct pv_header *ph)
* mda_offset/mda_size are from the pv_header/disk_locn and could
* be incorrect.
*/
-static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_offset, uint64_t mda_size)
+static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_offset, uint64_t mda_size, int *found_header)
{
char str[256];
uint32_t crc;
+ int good_magic = 1;
int bad = 0;
crc = calc_crc(INITIAL_CRC, (uint8_t *)mh->magic,
@@ -156,6 +165,7 @@ static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_of
if (memcmp(mh->magic, FMTT_MAGIC, sizeof(mh->magic))) {
log_print("CHECK: mda_header_%d.magic expected 0x%s", mda_num, _chars_to_hexstr((void *)&FMTT_MAGIC, str, 16, 256, "mda_header.magic"));
+ good_magic = 0;
bad++;
}
@@ -174,6 +184,10 @@ static int _check_mda_header(struct mda_header *mh, int mda_num, uint64_t mda_of
bad++;
}
+ /* Report a header is found if at least magic is correct. */
+ if (found_header && good_magic)
+ *found_header = 1;
+
if (bad)
return 0;
return 1;
@@ -684,9 +698,10 @@ static int _dump_meta_text(struct device *dev,
config_destroy(cft);
}
- log_print("metadata text at %llu crc 0x%x # vgname %s seqno %u",
- (unsigned long long)(mda_offset + meta_offset), crc,
- vgname ? vgname : "?", seqno);
+ if (print_fields || print_metadata)
+ log_print("metadata text at %llu crc 0x%x # vgname %s seqno %u",
+ (unsigned long long)(mda_offset + meta_offset), crc,
+ vgname ? vgname : "?", seqno);
if (!print_metadata)
goto out;
@@ -720,6 +735,7 @@ static int _dump_meta_text(struct device *dev,
static int _dump_label_and_pv_header(struct cmd_context *cmd, int print_fields,
struct device *dev,
+ int *found_label,
uint64_t *mda1_offset, uint64_t *mda1_size,
uint64_t *mda2_offset, uint64_t *mda2_size)
{
@@ -771,7 +787,7 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, int print_fields,
log_print("label_header.type %s", _chars_to_str(lh->type, str, 8, 256, "label_header.type"));
}
- if (!_check_label_header(lh, labelsector))
+ if (!_check_label_header(lh, labelsector, found_label))
bad++;
/*
@@ -972,7 +988,8 @@ static int _dump_mda_header(struct cmd_context *cmd,
const char *tofile,
struct device *dev,
uint64_t mda_offset, uint64_t mda_size,
- uint32_t *checksum0_ret)
+ uint32_t *checksum0_ret,
+ int *found_header)
{
char str[256];
char *buf;
@@ -1018,7 +1035,7 @@ static int _dump_mda_header(struct cmd_context *cmd,
log_print("mda_header_%d.size %llu", mda_num, (unsigned long long)xlate64(mh->size));
}
- if (!_check_mda_header(mh, mda_num, mda_offset, mda_size))
+ if (!_check_mda_header(mh, mda_num, mda_offset, mda_size, found_header))
bad++;
if (print_area) {
@@ -1108,7 +1125,7 @@ static int _dump_headers(struct cmd_context *cmd,
label_scan_setup_bcache();
- if (!_dump_label_and_pv_header(cmd, 1, dev,
+ if (!_dump_label_and_pv_header(cmd, 1, dev, NULL,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
bad++;
@@ -1125,7 +1142,7 @@ static int _dump_headers(struct cmd_context *cmd,
* which may have been corrupted.
*/
- if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum))
+ if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, NULL))
bad++;
/*
@@ -1136,7 +1153,7 @@ static int _dump_headers(struct cmd_context *cmd,
* but there is a valid header elsewhere.
*/
if (mda2_offset) {
- if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum))
+ if (!_dump_mda_header(cmd, 1, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
bad++;
/* This probably indicates that one was committed and the other not. */
@@ -1181,7 +1198,7 @@ static int _dump_metadata(struct cmd_context *cmd,
label_scan_setup_bcache();
- if (!_dump_label_and_pv_header(cmd, 0, dev,
+ if (!_dump_label_and_pv_header(cmd, 0, dev, NULL,
&mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
bad++;
@@ -1204,14 +1221,14 @@ static int _dump_metadata(struct cmd_context *cmd,
*/
if (mda_num == 1) {
- if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, 4096, mda1_size, &mda1_checksum))
+ if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, 4096, mda1_size, &mda1_checksum, NULL))
bad++;
} else if (mda_num == 2) {
if (!mda2_offset) {
log_print("CHECK: second mda not found");
bad++;
} else {
- if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, mda2_offset, mda2_size, &mda2_checksum))
+ if (!_dump_mda_header(cmd, 0, print_metadata, print_area, tofile, dev, mda2_offset, mda2_size, &mda2_checksum, NULL))
bad++;
}
}
@@ -1223,16 +1240,59 @@ static int _dump_metadata(struct cmd_context *cmd,
return ECMD_PROCESSED;
}
+static int _dump_found(struct cmd_context *cmd, struct device *dev,
+ uint64_t labelsector)
+{
+ uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0;
+ uint32_t mda1_checksum = 0, mda2_checksum = 0;
+ int found_label = 0, found_header1 = 0, found_header2 = 0;
+ int bad = 0;
+
+ if (!_dump_label_and_pv_header(cmd, 0, dev, &found_label,
+ &mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
+ bad++;
+
+ if (found_label && mda1_offset) {
+ if (!_dump_mda_header(cmd, 0, 0, 0, NULL, dev, 4096, mda1_size, &mda1_checksum, &found_header1))
+ bad++;
+ }
+
+ if (found_label && mda2_offset) {
+ if (!_dump_mda_header(cmd, 0, 0, 0, NULL, dev, mda2_offset, mda2_size, &mda2_checksum, &found_header2))
+ bad++;
+ }
+
+ if (found_label)
+ log_print("Found label on %s, sector %llu, type=LVM2 001",
+ dev_name(dev), (unsigned long long)labelsector);
+ else {
+ log_error("Could not find LVM label on %s", dev_name(dev));
+ return 0;
+ }
+
+ if (found_header1)
+ log_print("Found text metadata area: offset=%llu, size=%llu",
+ (unsigned long long)mda1_offset,
+ (unsigned long long)mda1_size);
+
+ if (found_header2)
+ log_print("Found text metadata area: offset=%llu, size=%llu",
+ (unsigned long long)mda2_offset,
+ (unsigned long long)mda2_size);
+
+ if (bad)
+ return 0;
+ return 1;
+}
+
int pvck(struct cmd_context *cmd, int argc, char **argv)
{
- struct dm_list devs;
- struct device_list *devl;
struct device *dev;
const char *dump;
const char *pv_name;
- uint64_t labelsector;
+ uint64_t labelsector = 1;
+ int bad = 0;
int i;
- int ret_max = ECMD_PROCESSED;
if (arg_is_set(cmd, dump_ARG)) {
dump = arg_str_value(cmd, dump_ARG, NULL);
@@ -1253,56 +1313,29 @@ int pvck(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
- labelsector = arg_uint64_value(cmd, labelsector_ARG, UINT64_C(0));
+ /*
+ * The old/original form of pvck, which did not do much,
+ * but this is here to preserve the historical output.
+ */
- dm_list_init(&devs);
+ if (arg_is_set(cmd, labelsector_ARG))
+ labelsector = arg_uint64_value(cmd, labelsector_ARG, UINT64_C(0));
- for (i = 0; i < argc; i++) {
- dm_unescape_colons_and_at_signs(argv[i], NULL, NULL);
+ label_scan_setup_bcache();
+ for (i = 0; i < argc; i++) {
pv_name = argv[i];
- dev = dev_cache_get(cmd, pv_name, cmd->filter);
-
- if (!dev) {
+ if (!(dev = dev_cache_get(cmd, argv[i], cmd->filter))) {
log_error("Device %s %s.", pv_name, dev_cache_filtered_reason(pv_name));
continue;
}
- if (!(devl = zalloc(sizeof(*devl))))
- continue;
-
- devl->dev = dev;
- dm_list_add(&devs, &devl->list);
- }
-
- label_scan_setup_bcache();
- label_scan_devs(cmd, cmd->filter, &devs);
-
- dm_list_iterate_items(devl, &devs) {
- /*
- * The scan above will populate lvmcache with any info from the
- * standard locations at the start of the device. Now populate
- * lvmcache with any info from non-standard offsets.
- *
- * FIXME: is it possible for a real lvm label sector to be
- * anywhere other than the first four sectors of the disk?
- * If not, drop the code in label_read_sector/find_lvm_header
- * that supports searching at any sector.
- */
- if (labelsector) {
- if (!label_read_sector(devl->dev, labelsector)) {
- stack;
- ret_max = ECMD_FAILED;
- continue;
- }
- }
-
- if (!pv_analyze(cmd, devl->dev, labelsector)) {
- stack;
- ret_max = ECMD_FAILED;
- }
+ if (!_dump_found(cmd, dev, labelsector))
+ bad++;
}
- return ret_max;
+ if (bad)
+ return ECMD_FAILED;
+ return ECMD_PROCESSED;
}
3 years, 9 months