master - pvck: handle PVs with zero metadata copies
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7368cf8e7df0218d61c...
Commit: 7368cf8e7df0218d61c9538fee68d0da634b5571
Parent: 1bfae5bf8e5905a72f7168562e1bbc074f23b791
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Sep 30 16:20:17 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 16:20:17 2019 -0500
pvck: handle PVs with zero metadata copies
---
test/shell/pvck-dump.sh | 14 +++++++++++++-
tools/pvck.c | 23 +++++++++++++++++++----
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/test/shell/pvck-dump.sh b/test/shell/pvck-dump.sh
index ed8766a..542fb49 100644
--- a/test/shell/pvck-dump.sh
+++ b/test/shell/pvck-dump.sh
@@ -12,30 +12,35 @@
. lib/inittest
-aux prepare_devs 3
+aux prepare_devs 4
get_devs
dd if=/dev/zero of="$dev1" || true
dd if=/dev/zero of="$dev2" || true
dd if=/dev/zero of="$dev3" || true
+dd if=/dev/zero of="$dev4" || true
pvcreate "$dev1"
pvcreate "$dev2"
pvcreate --pvmetadatacopies 2 "$dev3"
+pvcreate --pvmetadatacopies 0 "$dev4"
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
pvck --dump headers "$dev1" > h1
pvck --dump headers "$dev2" > h2
pvck --dump headers "$dev3" > h3
+pvck --dump headers "$dev4" > h4
grep "label_header at 512" h1
grep "label_header at 512" h2
grep "label_header at 512" h3
+grep "label_header at 512" h4
grep "pv_header at 544" h1
grep "pv_header at 544" h2
grep "pv_header at 544" h3
+grep "pv_header at 544" h4
grep "pv_header.disk_locn\[0\].offset 1048576" h1
grep "pv_header.disk_locn\[0\].offset 1048576" h2
@@ -49,6 +54,10 @@ grep "pv_header.disk_locn\[2\].size 1044480" h1
grep "pv_header.disk_locn\[2\].size 1044480" h2
grep "pv_header.disk_locn\[2\].size 1044480" h3
+not grep "pv_header.disk_locn\[3\].size" h4
+not grep "pv_header.disk_locn\[4\].size" h4
+not grep "mda_header" h4
+
grep "mda_header_1 at 4096" h1
grep "mda_header_1 at 4096" h2
grep "mda_header_1 at 4096" h3
@@ -75,8 +84,11 @@ not grep CHECK h3
pvck --dump metadata "$dev1" > m1
pvck --dump metadata "$dev2" > m2
pvck --dump metadata "$dev3" > m3
+pvck --dump metadata "$dev4" > m4
pvck --dump metadata --pvmetadatacopies 2 "$dev3" > m3b
+grep "zero metadata copies" m4
+
diff m1 m2
diff m1 m3
diff --git a/tools/pvck.c b/tools/pvck.c
index af2dd8e..2b5e63b 100644
--- a/tools/pvck.c
+++ b/tools/pvck.c
@@ -740,7 +740,8 @@ 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)
+ uint64_t *mda2_offset, uint64_t *mda2_size,
+ int *mda_count_out)
{
char str[256];
struct label_header *lh;
@@ -900,6 +901,8 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, int print_fields,
mda_count++;
}
+ *mda_count_out = mda_count;
+
/* all-zero dlocn struct is area list end */
if (print_fields) {
log_print("pv_header.disk_locn[%d] at %llu # location list end", di,
@@ -1117,6 +1120,7 @@ static int _dump_headers(struct cmd_context *cmd,
const char *pv_name;
uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0;
uint32_t mda1_checksum, mda2_checksum;
+ int mda_count = 0;
int bad = 0;
pv_name = argv[0];
@@ -1129,9 +1133,14 @@ static int _dump_headers(struct cmd_context *cmd,
label_scan_setup_bcache();
if (!_dump_label_and_pv_header(cmd, 1, dev, NULL,
- &mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
+ &mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
+ if (!mda_count) {
+ log_print("zero metadata copies");
+ return ECMD_PROCESSED;
+ }
+
/* N.B. mda1_size and mda2_size may be different */
/*
@@ -1180,6 +1189,7 @@ static int _dump_metadata(struct cmd_context *cmd,
const char *tofile = NULL;
uint64_t mda1_offset = 0, mda1_size = 0, mda2_offset = 0, mda2_size = 0;
uint32_t mda1_checksum, mda2_checksum;
+ int mda_count = 0;
int mda_num = 1;
int bad = 0;
@@ -1202,9 +1212,13 @@ static int _dump_metadata(struct cmd_context *cmd,
label_scan_setup_bcache();
if (!_dump_label_and_pv_header(cmd, 0, dev, NULL,
- &mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
+ &mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
+ if (!mda_count) {
+ log_print("zero metadata copies");
+ return ECMD_PROCESSED;
+ }
/*
* The first mda is always 4096 bytes from the start of the device.
@@ -1249,10 +1263,11 @@ static int _dump_found(struct cmd_context *cmd, struct device *dev,
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 mda_count = 0;
int bad = 0;
if (!_dump_label_and_pv_header(cmd, 0, dev, &found_label,
- &mda1_offset, &mda1_size, &mda2_offset, &mda2_size))
+ &mda1_offset, &mda1_size, &mda2_offset, &mda2_size, &mda_count))
bad++;
if (found_label && mda1_offset) {
4 years, 2 months
master - scan: use PV device name hint for choosing duplicate PV
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f836fe3836e990e41b2...
Commit: f836fe3836e990e41b2c2b59c2af7ef6b979097f
Parent: 4910a31f6d3a9e52e8be85c6409b5fa93895874a
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Sep 27 11:34:55 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
scan: use PV device name hint for choosing duplicate PV
Prefer a device if its name matches the PV device name hint.
---
lib/cache/lvmcache.c | 36 ++++++++++++++++++++++++++++++++++--
1 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index d45b6db..316624f 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -404,6 +404,23 @@ static uint64_t _get_pvsummary_size(char *pvid)
return 0;
}
+static const char *_get_pvsummary_device_hint(char *pvid)
+{
+ char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
+ struct lvmcache_vginfo *vginfo;
+ struct pv_list *pvl;
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ dm_list_iterate_items(pvl, &vginfo->pvsummaries) {
+ (void) dm_strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s));
+ if (!strcmp(pvid_s, pvid))
+ return pvl->pv->device_hint;
+ }
+ }
+
+ return NULL;
+}
+
/*
* Check if any PVs in vg->pvs have the same PVID as any
* entries in _unused_duplicates.
@@ -502,6 +519,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
{
char *pvid;
const char *reason;
+ const char *device_hint;
struct dm_list altdevs;
struct dm_list new_unused;
struct dev_types *dt = cmd->dev_types;
@@ -515,6 +533,7 @@ static void _choose_duplicates(struct cmd_context *cmd,
int has_fs1, has_fs2;
int has_lv1, has_lv2;
int same_size1, same_size2;
+ int same_name1 = 0, same_name2 = 0;
int prev_unchosen1, prev_unchosen2;
int change;
@@ -640,6 +659,11 @@ next:
same_size1 = (dev1_size == pv_size);
same_size2 = (dev2_size == pv_size);
+ if ((device_hint = _get_pvsummary_device_hint(devl->dev->pvid))) {
+ same_name1 = !strcmp(device_hint, dev_name(dev1));
+ same_name2 = !strcmp(device_hint, dev_name(dev2));
+ }
+
has_lv1 = (dev1->flags & DEV_USED_FOR_LV) ? 1 : 0;
has_lv2 = (dev2->flags & DEV_USED_FOR_LV) ? 1 : 0;
@@ -652,10 +676,11 @@ next:
has_fs1 = dm_device_has_mounted_fs(dev1_major, dev1_minor);
has_fs2 = dm_device_has_mounted_fs(dev2_major, dev2_minor);
- log_debug_cache("PV %s compare duplicates: %s %u:%u. %s %u:%u.",
+ log_debug_cache("PV %s compare duplicates: %s %u:%u. %s %u:%u. device_hint %s.",
devl->dev->pvid,
dev_name(dev1), dev1_major, dev1_minor,
- dev_name(dev2), dev2_major, dev2_minor);
+ dev_name(dev2), dev2_major, dev2_minor,
+ device_hint ?: "none");
log_debug_cache("PV %s: size %llu. %s is %llu. %s is %llu.",
devl->dev->pvid,
@@ -711,6 +736,13 @@ next:
/* change to 2 */
change = 1;
reason = "device size is correct";
+ } else if (same_name1 && !same_name2) {
+ /* keep 1 */
+ reason = "device name matches previous";
+ } else if (same_name2 && !same_name1) {
+ /* change to 2 */
+ change = 1;
+ reason = "device name matches previous";
} else if (has_fs1 && !has_fs2) {
/* keep 1 */
reason = "device has fs mounted";
4 years, 2 months
master - tests: update duplicate md tests
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1bfae5bf8e5905a72f7...
Commit: 1bfae5bf8e5905a72f7168562e1bbc074f23b791
Parent: f836fe3836e990e41b2c2b59c2af7ef6b979097f
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Sep 27 14:18:35 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
tests: update duplicate md tests
adjust to recent improvements in duplicate handling
---
test/shell/duplicate-pvs-md1.sh | 39 ++++++++++++++-------------------------
1 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/test/shell/duplicate-pvs-md1.sh b/test/shell/duplicate-pvs-md1.sh
index 626c55c..334ac41 100644
--- a/test/shell/duplicate-pvs-md1.sh
+++ b/test/shell/duplicate-pvs-md1.sh
@@ -190,18 +190,17 @@ lvs -o active $vg |tee out || true
grep "active" out
vgchange -an $vg
-# N.B. when the md dev (which is started) has not been scanned by
-# pvscan, then pvscan --cache on the md component does not detect it's
-# an md component, and marks the PVID online, then does activation,
-# but the activation using the component fails because the component
-# device is busy from being used in the md dev, and activation fails.
-# The default behavior in auto mode is preferrable.
+# The dev name and device_hint don't match so pvscan
+# skips quick activation and scans all devs during
+# activation. This means it sees the component and
+# the mddev as duplicates and chooses to use the mddev
+# for activation.
_clear_online_files
-not pvscan --cache -aay "$dev1"
+pvscan --cache -aay "$dev1"
ls "$RUNDIR/lvm/pvs_online/$PVIDMD"
ls "$RUNDIR/lvm/vgs_online/$vg"
lvs -o active $vg |tee out || true
-not grep "active" out
+grep "active" out
# pvscan activation from mddev first, then try from component which fails
_clear_online_files
@@ -332,27 +331,17 @@ pvscan --cache -aay
not ls "$RUNDIR/lvm/pvs_online/$PVIDMD"
not ls "$RUNDIR/lvm/vgs_online/$vg"
+# component dev name does not match device_hint in metadata so
+# quick activation is skipped and activation scans all devs.
+# this leads it to see both components as duplicates which
+# triggers full md check which means we see both devs are
+# md components and drop them, leaving no remaining devs
+# on which this vg is seen.
_clear_online_files
-pvscan --cache -aay "$dev1"
+not pvscan --cache -aay "$dev1"
ls "$RUNDIR/lvm/pvs_online/$PVIDMD"
ls "$RUNDIR/lvm/vgs_online/$vg"
-# N.B. not good to activate from component, but result of "start" setting
-# Other commands will not see the vg at this point because they'll
-# recognize the md components and ignore them (where pvscan is special due
-# to it not scanning all devs and not seeing the duplicates and not
-# detecting the components.)
-# disable dev2 so other cmds don't see dups and we can deactivate the vg
-aux disable_dev "$dev2"
-vgchange -an $vg
-
-aux enable_dev "$dev2"
-aux udev_wait
-cat /proc/mdstat
-# for some reason enabling dev2 starts an odd md dev
-mdadm --stop "$mddev" || true
-mdadm --stop --scan
-cat /proc/mdstat
wipefs -a "$dev1" || true
wipefs -a "$dev2" || true
4 years, 2 months
master - scan: use PV size for choosing duplicate PV
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4910a31f6d3a9e52e8b...
Commit: 4910a31f6d3a9e52e8be85c6409b5fa93895874a
Parent: f3084ee2e577abe05e4707730f3cb96f2cb5ec45
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Sep 27 11:11:57 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
scan: use PV size for choosing duplicate PV
Prefer a device if it matches the size of the PV.
---
lib/cache/lvmcache.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 7ee94c2..d45b6db 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -387,6 +387,23 @@ const char *lvmcache_vgname_from_info(struct lvmcache_info *info)
return NULL;
}
+static uint64_t _get_pvsummary_size(char *pvid)
+{
+ char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
+ struct lvmcache_vginfo *vginfo;
+ struct pv_list *pvl;
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ dm_list_iterate_items(pvl, &vginfo->pvsummaries) {
+ (void) dm_strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s));
+ if (!strcmp(pvid_s, pvid))
+ return pvl->pv->size;
+ }
+ }
+
+ return 0;
+}
+
/*
* Check if any PVs in vg->pvs have the same PVID as any
* entries in _unused_duplicates.
@@ -492,10 +509,12 @@ static void _choose_duplicates(struct cmd_context *cmd,
struct lvmcache_info *info;
struct device *dev1, *dev2;
uint32_t dev1_major, dev1_minor, dev2_major, dev2_minor;
+ uint64_t dev1_size, dev2_size, pv_size;
int in_subsys1, in_subsys2;
int is_dm1, is_dm2;
int has_fs1, has_fs2;
int has_lv1, has_lv2;
+ int same_size1, same_size2;
int prev_unchosen1, prev_unchosen2;
int change;
@@ -612,6 +631,15 @@ next:
dev2_major = MAJOR(dev2->dev);
dev2_minor = MINOR(dev2->dev);
+ if (!dev_get_size(dev1, &dev1_size))
+ dev1_size = 0;
+ if (!dev_get_size(dev2, &dev2_size))
+ dev2_size = 0;
+
+ pv_size = _get_pvsummary_size(devl->dev->pvid);
+ same_size1 = (dev1_size == pv_size);
+ same_size2 = (dev2_size == pv_size);
+
has_lv1 = (dev1->flags & DEV_USED_FOR_LV) ? 1 : 0;
has_lv2 = (dev2->flags & DEV_USED_FOR_LV) ? 1 : 0;
@@ -629,6 +657,12 @@ next:
dev_name(dev1), dev1_major, dev1_minor,
dev_name(dev2), dev2_major, dev2_minor);
+ log_debug_cache("PV %s: size %llu. %s is %llu. %s is %llu.",
+ devl->dev->pvid,
+ (unsigned long long)pv_size,
+ dev_name(dev1), (unsigned long long)dev1_size,
+ dev_name(dev2), (unsigned long long)dev2_size);
+
log_debug_cache("PV %s: %s was prev %s. %s was prev %s.",
devl->dev->pvid,
dev_name(dev1), prev_unchosen1 ? "not chosen" : "<none>",
@@ -670,6 +704,13 @@ next:
/* change to 2 */
change = 1;
reason = "device is used by LV";
+ } else if (same_size1 && !same_size2) {
+ /* keep 1 */
+ reason = "device size is correct";
+ } else if (same_size2 && !same_size1) {
+ /* change to 2 */
+ change = 1;
+ reason = "device size is correct";
} else if (has_fs1 && !has_fs2) {
/* keep 1 */
reason = "device has fs mounted";
4 years, 2 months
master - scan: add PV summary info to lvmcache
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f3084ee2e577abe05e4...
Commit: f3084ee2e577abe05e4707730f3cb96f2cb5ec45
Parent: 0c23d3fc8402e49e61c9c490d9c2c9c2d58596e8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Sep 26 11:27:38 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
scan: add PV summary info to lvmcache
Expand the lvmcache info that is saved by the scan to
include PV info from the metadata.
---
lib/cache/lvmcache.c | 16 +++++++
lib/cache/lvmcache.h | 12 ++---
lib/format_text/format-text.c | 2 +
lib/format_text/import_vsn1.c | 96 +++++++++++++++++++++++++++++++++-------
lib/format_text/text_label.c | 2 +
5 files changed, 103 insertions(+), 25 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 29d6446..7ee94c2 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -53,6 +53,7 @@ struct lvmcache_vginfo {
struct dm_list list; /* Join these vginfos together */
struct dm_list infos; /* List head for lvmcache_infos */
struct dm_list outdated_infos; /* vg_read moves info from infos to outdated_infos */
+ struct dm_list pvsummaries; /* pv_list taken directly from vgsummary */
const struct format_type *fmt;
char *vgname; /* "" == orphan */
uint32_t status;
@@ -1295,6 +1296,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
}
dm_list_init(&vginfo->infos);
dm_list_init(&vginfo->outdated_infos);
+ dm_list_init(&vginfo->pvsummaries);
/*
* A different VG (different uuid) can exist with the same name.
@@ -1418,6 +1420,18 @@ int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
+static void _lvmcache_update_pvsummaries(struct lvmcache_vginfo *vginfo, struct lvmcache_vgsummary *vgsummary)
+{
+ struct pv_list *pvl, *safe;
+
+ dm_list_init(&vginfo->pvsummaries);
+
+ dm_list_iterate_items_safe(pvl, safe, &vgsummary->pvsummaries) {
+ dm_list_del(&pvl->list);
+ dm_list_add(&vginfo->pvsummaries, &pvl->list);
+ }
+}
+
/*
* Returning 0 causes the caller to remove the info struct for this
* device from lvmcache, which will make it look like a missing device.
@@ -1582,6 +1596,8 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
log_error("Failed to update VG %s info in lvmcache.", vgname);
}
+ _lvmcache_update_pvsummaries(vginfo, vgsummary);
+
return 1;
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 89fbe6f..1401974 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -41,14 +41,9 @@ struct lvmcache_vginfo;
/*
* vgsummary represents a summary of the VG that is read
- * without a lock. The info does not come through vg_read(),
- * but through reading mdas. It provides information about
- * the VG that is needed to lock the VG and then read it fully
- * with vg_read(), after which the VG summary should be checked
- * against the full VG metadata to verify it was correct (since
- * it was read without a lock.)
- *
- * Once read, vgsummary information is saved in lvmcache_vginfo.
+ * without a lock during label scan. It's used to populate
+ * basic lvmcache vginfo/info during label scan prior to
+ * vg_read().
*/
struct lvmcache_vgsummary {
const char *vgname;
@@ -63,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;
+ struct dm_list pvsummaries;
};
int lvmcache_init(struct cmd_context *cmd);
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 2a5c8ec..be4730b 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -278,6 +278,8 @@ static struct raw_locn *_read_metadata_location_vg(struct device_area *dev_area,
};
int rlocn_was_ignored;
+ dm_list_init(&vgsummary_orphan.pvsummaries);
+
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
rlocn = mdah->raw_locns; /* Slot 0 */
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 2785ab3..d7ff786 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -31,10 +31,12 @@ typedef int (*section_fn) (struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid,
struct dm_pool *mem,
- struct volume_group * vg, const struct dm_config_node * pvn,
- const struct dm_config_node * vgn,
- struct dm_hash_table * pv_hash,
- struct dm_hash_table * lv_hash);
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *pvn,
+ const struct dm_config_node *vgn,
+ struct dm_hash_table *pv_hash,
+ struct dm_hash_table *lv_hash);
#define _read_int32(root, path, result) \
dm_config_get_uint32(root, path, (uint32_t *) (result))
@@ -176,7 +178,9 @@ static int _read_pv(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid,
struct dm_pool *mem,
- struct volume_group *vg, const struct dm_config_node *pvn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *pvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash __attribute__((unused)))
@@ -289,6 +293,49 @@ static int _read_pv(struct cmd_context *cmd,
return 1;
}
+static int _read_pvsummary(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *pvn,
+ const struct dm_config_node *vgn __attribute__((unused)),
+ struct dm_hash_table *pv_hash __attribute__((unused)),
+ struct dm_hash_table *lv_hash __attribute__((unused)))
+{
+ struct physical_volume *pv;
+ struct pv_list *pvl;
+ const char *device_hint;
+
+ if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
+ !(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
+ return_0;
+
+ pv = pvl->pv;
+
+ if (!(pvn = pvn->child)) {
+ log_error("Empty pv section.");
+ return 0;
+ }
+
+ if (!_read_id(&pv->id, pvn, "id"))
+ log_warn("Couldn't read uuid for physical volume.");
+
+ if (dm_config_has_node(pvn, "dev_size") &&
+ !_read_uint64(pvn, "dev_size", &pv->size))
+ log_warn("Couldn't read dev size for physical volume.");
+
+ if (dm_config_get_str(pvn, "device", &device_hint)) {
+ if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
+ log_error("Failed to allocate memory for device hint in read_pv.");
+ }
+
+ dm_list_add(&vgsummary->pvsummaries, &pvl->list);
+
+ return 1;
+}
+
static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
{
struct lv_segment *comp;
@@ -538,7 +585,9 @@ static int _read_lvnames(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid __attribute__((unused)),
struct dm_pool *mem,
- struct volume_group *vg, const struct dm_config_node *lvn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash)
@@ -695,7 +744,9 @@ static int _read_historical_lvnames(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid __attribute__((unused)),
struct dm_pool *mem,
- struct volume_group *vg, const struct dm_config_node *hlvn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
@@ -766,7 +817,9 @@ static int _read_historical_lvnames_interconnections(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid __attribute__((unused)),
struct dm_pool *mem,
- struct volume_group *vg, const struct dm_config_node *hlvn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
@@ -878,7 +931,9 @@ static int _read_lvsegs(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid,
struct dm_pool *mem,
- struct volume_group *vg, const struct dm_config_node *lvn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash)
@@ -942,7 +997,9 @@ static int _read_sections(struct cmd_context *cmd,
struct format_instance *fid,
struct dm_pool *mem,
const char *section, section_fn fn,
- struct volume_group *vg, const struct dm_config_node *vgn,
+ struct volume_group *vg,
+ struct lvmcache_vgsummary *vgsummary,
+ const struct dm_config_node *vgn,
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash,
int optional)
@@ -959,7 +1016,7 @@ static int _read_sections(struct cmd_context *cmd,
}
for (n = n->child; n; n = n->sib) {
- if (!fn(cmd, fmt, fid, mem, vg, n, vgn, pv_hash, lv_hash))
+ if (!fn(cmd, fmt, fid, mem, vg, vgsummary, n, vgn, pv_hash, lv_hash))
return_0;
}
@@ -971,7 +1028,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
unsigned allow_lvmetad_extensions)
{
struct cmd_context *cmd = fid->fmt->cmd;
- struct format_type *fmt = fid->fmt;
+ struct format_type *fmt = (struct format_type *)fid->fmt;
struct dm_pool *mem;
const struct dm_config_node *vgn;
const struct dm_config_value *cv;
@@ -1126,7 +1183,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
vg->mda_copies = DEFAULT_VGMETADATACOPIES;
}
- if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg, NULL,
vgn, pv_hash, lv_hash, 0)) {
log_error("Couldn't find all physical volumes for volume "
"group %s.", vg->name);
@@ -1140,21 +1197,21 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
- if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg, NULL,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all logical volume names for volume "
"group %s.", vg->name);
goto bad;
}
- if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg, NULL,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all historical logical volumes for volume "
"group %s.", vg->name);
goto bad;
}
- if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg, NULL,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all logical volumes for "
"volume group %s.", vg->name);
@@ -1162,7 +1219,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
}
if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames_interconnections,
- vg, vgn, pv_hash, lv_hash, 1)) {
+ vg, NULL, vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all removed logical volume interconnections "
"for volume group %s.", vg->name);
goto bad;
@@ -1270,6 +1327,11 @@ static int _read_vgsummary(const struct format_type *fmt, const struct dm_config
return 0;
}
+ if (!_read_sections(fmt->cmd, NULL, NULL, mem, "physical_volumes", _read_pvsummary, NULL, vgsummary,
+ vgn, NULL, NULL, 0)) {
+ log_debug("Couldn't read pv summaries");
+ }
+
return 1;
}
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index 934bc73..41276be 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -498,6 +498,7 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
if (mda1) {
log_debug_metadata("Scanning %s mda1 summary.", dev_name(dev));
memset(&vgsummary, 0, sizeof(vgsummary));
+ dm_list_init(&vgsummary.pvsummaries);
bad_fields = 0;
vgsummary.mda_num = 1;
@@ -541,6 +542,7 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
if (mda2) {
log_debug_metadata("Scanning %s mda2 summary.", dev_name(dev));
memset(&vgsummary, 0, sizeof(vgsummary));
+ dm_list_init(&vgsummary.pvsummaries);
bad_fields = 0;
vgsummary.mda_num = 2;
4 years, 2 months
master - pvscan: use quick activation only with matching PV device names
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0c23d3fc8402e49e61c...
Commit: 0c23d3fc8402e49e61c9c490d9c2c9c2d58596e8
Parent: 3a8e41a67b3f0edb0fcb27302351f7d58b6ef8c5
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 4 15:59:49 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
pvscan: use quick activation only with matching PV device names
When the PV device names in the VG metadata do not match the
current PV device names seen on the system, do not use the
optimized activation function (that avoids extra device scanning.)
When the device names do not match, it's a clue that there could
be duplicate PVs, in which case we want to scan all devicess to
find any duplicates and stop the activation if found.
This does not prevent autoactivating a VG from the incorrect
duplicate PV, because the incorrect duplicate may appear by itself
first. At that point its duplicate PV does not exist to be seen.
(A future enhancement could use the WWID to strengthen this
detection.)
---
tools/pvscan.c | 30 ++++++++++++++++++++++--------
1 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index b025ae3..96ef438 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -929,17 +929,19 @@ static int _online_vg_file_create(struct cmd_context *cmd, const char *vgname)
* scan/read in order to process/activate the VG.
*/
-static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
+static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
struct dm_list *saved_vgs,
struct dm_list *devs)
{
char path[PATH_MAX];
char file_vgname[NAME_LEN];
+ char uuidstr[64] __attribute__((aligned(8)));
struct pv_list *pvl;
struct device_list *devl;
struct device *dev;
struct volume_group *vg;
const char *pvid;
+ const char *name1, *name2;
dev_t devno;
int file_major = 0, file_minor = 0;
@@ -978,6 +980,16 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
return 0;
}
+ name1 = dev_name(dev);
+ name2 = pvl->pv->device_hint;
+
+ if (strcmp(name1, name2)) {
+ if (!id_write_format((const struct id *)pvid, uuidstr, sizeof(uuidstr)))
+ uuidstr[0] = '\0';
+ log_print("PVID %s read from %s last written to %s.", uuidstr, name1, name2);
+ return 0;
+ }
+
if (!(devl = zalloc(sizeof(*devl))))
return_0;
@@ -1024,8 +1036,8 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, char *vgname,
* is important when there are many devs.
*/
-static int _pvscan_aa_direct(struct cmd_context *cmd, struct pvscan_aa_params *pp, char *vgname,
- struct dm_list *saved_vgs)
+static int _pvscan_aa_quick(struct cmd_context *cmd, struct pvscan_aa_params *pp, const char *vgname,
+ struct dm_list *saved_vgs, int *no_quick)
{
struct dm_list devs; /* device_list */
struct volume_group *vg;
@@ -1044,7 +1056,8 @@ static int _pvscan_aa_direct(struct cmd_context *cmd, struct pvscan_aa_params *p
* The dev_cache gives us struct devices from the devnums.
*/
if (!_get_devs_from_saved_vg(cmd, vgname, saved_vgs, &devs)) {
- log_error("pvscan activation for VG %s failed to find devices.", vgname);
+ log_print("pvscan[%d] VG %s not using quick activation.", getpid(), vgname);
+ *no_quick = 1;
return ECMD_FAILED;
}
@@ -1132,6 +1145,7 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
{
struct processing_handle *handle = NULL;
struct dm_str_list *sl, *sl2;
+ int no_quick = 0;
int ret;
if (dm_list_empty(vgnames)) {
@@ -1169,12 +1183,12 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
if (dm_list_size(vgnames) == 1) {
dm_list_iterate_items(sl, vgnames)
- ret = _pvscan_aa_direct(cmd, pp, (char *)sl->str, saved_vgs);
- } else {
- /* FIXME: suppress label scan in process_each if label scan already done? */
- ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_ACTIVATE, 0, handle, _pvscan_aa_single);
+ ret = _pvscan_aa_quick(cmd, pp, sl->str, saved_vgs, &no_quick);
}
+ if ((dm_list_size(vgnames) > 1) || no_quick)
+ ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, READ_FOR_ACTIVATE, 0, handle, _pvscan_aa_single);
+
destroy_processing_handle(cmd, handle);
return ret;
4 years, 2 months
master - metadata: import device name hint from metadata
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3a8e41a67b3f0edb0fc...
Commit: 3a8e41a67b3f0edb0fcb27302351f7d58b6ef8c5
Parent: fcfabb26a535f9b967e96ad44300377598622c0d
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 4 14:13:14 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
metadata: import device name hint from metadata
Start by using it in a comment for a missing PV.
---
lib/format_text/import_vsn1.c | 6 ++++++
lib/metadata/metadata.c | 5 ++++-
lib/metadata/pv.h | 1 +
3 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index f29abce..2785ab3 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -184,6 +184,7 @@ static int _read_pv(struct cmd_context *cmd,
struct physical_volume *pv;
struct pv_list *pvl;
const struct dm_config_value *cv;
+ const char *device_hint;
uint64_t size, ba_start;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
@@ -228,6 +229,11 @@ static int _read_pv(struct cmd_context *cmd,
return 0;
}
+ if (dm_config_get_str(pvn, "device", &device_hint)) {
+ if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
+ log_error("Failed to allocate memory for device hint in read_pv.");
+ }
+
if (!_read_uint64(pvn, "pe_start", &pv->pe_start)) {
log_error("Couldn't read extent start value (pe_start) "
"for physical volume.");
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index b434967..cf5c563 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4971,7 +4971,10 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
if (!pvl->pv->dev) {
/* The obvious and common case of a missing device. */
- log_warn("WARNING: VG %s is missing PV %s.", vg_name, uuidstr);
+ if (pvl->pv->device_hint)
+ log_warn("WARNING: VG %s is missing PV %s (last written to %s).", vg_name, uuidstr, pvl->pv->device_hint);
+ else
+ log_warn("WARNING: VG %s is missing PV %s.", vg_name, uuidstr);
missing_pv_dev++;
} else if (pvl->pv->status & MISSING_PV) {
diff --git a/lib/metadata/pv.h b/lib/metadata/pv.h
index 3430c2e..efa13e0 100644
--- a/lib/metadata/pv.h
+++ b/lib/metadata/pv.h
@@ -26,6 +26,7 @@ struct physical_volume {
struct id id;
struct id old_id; /* Set during pvchange -u. */
struct device *dev;
+ const char *device_hint; /* primary name last time metadata was written */
const struct format_type *fmt;
struct format_instance *fid;
4 years, 2 months
master - metadata: add args to metadata import functions
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fcfabb26a535f9b967e...
Commit: fcfabb26a535f9b967e96ad44300377598622c0d
Parent: 8f02f8dcd72571ce3bc6538f1cd23807e2b6a64d
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Sep 26 11:50:51 2019 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Sep 30 11:38:10 2019 -0500
metadata: add args to metadata import functions
instead of getting them through fid arg
no functional change
---
lib/format_text/import_vsn1.c | 101 ++++++++++++++++++++++++++---------------
1 files changed, 65 insertions(+), 36 deletions(-)
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 43ec10b..f29abce 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -27,7 +27,10 @@
#include "lib/config/defaults.h"
#include "lib/datastruct/str_list.h"
-typedef int (*section_fn) (struct format_instance * fid,
+typedef int (*section_fn) (struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
struct volume_group * vg, const struct dm_config_node * pvn,
const struct dm_config_node * vgn,
struct dm_hash_table * pv_hash,
@@ -169,13 +172,15 @@ static int _read_str_list(struct dm_pool *mem, struct dm_list *list, const struc
return 1;
}
-static int _read_pv(struct format_instance *fid,
+static int _read_pv(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
struct volume_group *vg, const struct dm_config_node *pvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash,
struct dm_hash_table *lv_hash __attribute__((unused)))
{
- struct dm_pool *mem = vg->vgmem;
struct physical_volume *pv;
struct pv_list *pvl;
const struct dm_config_value *cv;
@@ -266,7 +271,7 @@ static int _read_pv(struct format_instance *fid,
pv->pe_alloc_count = 0;
pv->pe_align = 0;
- pv->fmt = fid->fmt;
+ pv->fmt = fmt;
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
@@ -293,10 +298,13 @@ static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
dm_list_add(&lv->segments, &seg->list);
}
-static int _read_segment(struct logical_volume *lv, const struct dm_config_node *sn,
+static int _read_segment(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
+ struct logical_volume *lv, const struct dm_config_node *sn,
struct dm_hash_table *pv_hash)
{
- struct dm_pool *mem = lv->vg->vgmem;
uint32_t area_count = 0u;
struct lv_segment *seg;
const struct dm_config_node *sn_child = sn->child;
@@ -348,7 +356,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return 0;
}
- if (!(segtype = get_segtype_from_string(lv->vg->cmd, segtype_with_flags)))
+ if (!(segtype = get_segtype_from_string(cmd, segtype_with_flags)))
return_0;
/* Can drop temporary string here as nothing has allocated from VGMEM meanwhile */
@@ -465,7 +473,11 @@ int text_import_areas(struct lv_segment *seg, const struct dm_config_node *sn,
return 1;
}
-static int _read_segments(struct logical_volume *lv, const struct dm_config_node *lvn,
+static int _read_segments(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
+ struct logical_volume *lv, const struct dm_config_node *lvn,
struct dm_hash_table *pv_hash)
{
const struct dm_config_node *sn;
@@ -477,7 +489,7 @@ static int _read_segments(struct logical_volume *lv, const struct dm_config_node
* All sub-sections are assumed to be segments.
*/
if (!sn->v) {
- if (!_read_segment(lv, sn, pv_hash))
+ if (!_read_segment(cmd, fmt, fid, mem, lv, sn, pv_hash))
return_0;
count++;
@@ -516,13 +528,15 @@ static int _read_segments(struct logical_volume *lv, const struct dm_config_node
return 1;
}
-static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
+static int _read_lvnames(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid __attribute__((unused)),
+ struct dm_pool *mem,
struct volume_group *vg, const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash)
{
- struct dm_pool *mem = vg->vgmem;
struct logical_volume *lv;
const char *str;
const struct dm_config_value *cv;
@@ -612,7 +626,7 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
if (dm_config_get_str(lvn, "profile", &str)) {
log_debug_metadata("Adding profile configuration %s for LV %s.",
str, display_lvname(lv));
- if (!(lv->profile = add_profile(vg->cmd, str, CONFIG_PROFILE_METADATA))) {
+ if (!(lv->profile = add_profile(cmd, str, CONFIG_PROFILE_METADATA))) {
log_error("Failed to add configuration profile %s for LV %s.",
str, display_lvname(lv));
return 0;
@@ -621,7 +635,7 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
/* If not present, choice of auto or none is configurable */
- lv->read_ahead = vg->cmd->default_settings.read_ahead;
+ lv->read_ahead = cmd->default_settings.read_ahead;
else {
switch (lv->read_ahead) {
case 0:
@@ -671,13 +685,15 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
return 1;
}
-static int _read_historical_lvnames(struct format_instance *fid __attribute__((unused)),
+static int _read_historical_lvnames(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid __attribute__((unused)),
+ struct dm_pool *mem,
struct volume_group *vg, const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
{
- struct dm_pool *mem = vg->vgmem;
struct generic_logical_volume *glv;
struct glv_list *glvl;
const char *str;
@@ -740,13 +756,15 @@ bad:
return 0;
}
-static int _read_historical_lvnames_interconnections(struct format_instance *fid __attribute__((unused)),
+static int _read_historical_lvnames_interconnections(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid __attribute__((unused)),
+ struct dm_pool *mem,
struct volume_group *vg, const struct dm_config_node *hlvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash __attribute__((unused)),
struct dm_hash_table *lv_hash __attribute__((unused)))
{
- struct dm_pool *mem = vg->vgmem;
const char *historical_lv_name, *origin_name = NULL;
struct generic_logical_volume *glv, *origin_glv, *descendant_glv;
struct logical_volume *tmp_lv;
@@ -850,7 +868,10 @@ bad:
return 0;
}
-static int _read_lvsegs(struct format_instance *fid,
+static int _read_lvsegs(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
struct volume_group *vg, const struct dm_config_node *lvn,
const struct dm_config_node *vgn __attribute__((unused)),
struct dm_hash_table *pv_hash,
@@ -877,7 +898,7 @@ static int _read_lvsegs(struct format_instance *fid,
memcpy(&lv->lvid.id[0], &lv->vg->id, sizeof(lv->lvid.id[0]));
- if (!_read_segments(lv, lvn, pv_hash))
+ if (!_read_segments(cmd, fmt, fid, mem, lv, lvn, pv_hash))
return_0;
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
@@ -893,14 +914,14 @@ static int _read_lvsegs(struct format_instance *fid,
if (!dm_config_has_node(lvn, "major"))
/* If major is missing, pick default */
- lv->major = vg->cmd->dev_types->device_mapper_major;
+ lv->major = cmd->dev_types->device_mapper_major;
else if (!_read_int32(lvn, "major", &lv->major)) {
log_warn("WARNING: Couldn't read major number for logical "
"volume %s.", display_lvname(lv));
- lv->major = vg->cmd->dev_types->device_mapper_major;
+ lv->major = cmd->dev_types->device_mapper_major;
}
- if (!validate_major_minor(vg->cmd, fid->fmt, lv->major, lv->minor)) {
+ if (!validate_major_minor(cmd, fmt, lv->major, lv->minor)) {
log_warn("WARNING: Ignoring invalid major, minor number for "
"logical volume %s.", display_lvname(lv));
lv->major = lv->minor = -1;
@@ -910,7 +931,10 @@ static int _read_lvsegs(struct format_instance *fid,
return 1;
}
-static int _read_sections(struct format_instance *fid,
+static int _read_sections(struct cmd_context *cmd,
+ struct format_type *fmt,
+ struct format_instance *fid,
+ struct dm_pool *mem,
const char *section, section_fn fn,
struct volume_group *vg, const struct dm_config_node *vgn,
struct dm_hash_table *pv_hash,
@@ -929,7 +953,7 @@ static int _read_sections(struct format_instance *fid,
}
for (n = n->child; n; n = n->sib) {
- if (!fn(fid, vg, n, vgn, pv_hash, lv_hash))
+ if (!fn(cmd, fmt, fid, mem, vg, n, vgn, pv_hash, lv_hash))
return_0;
}
@@ -940,6 +964,9 @@ static struct volume_group *_read_vg(struct format_instance *fid,
const struct dm_config_tree *cft,
unsigned allow_lvmetad_extensions)
{
+ struct cmd_context *cmd = fid->fmt->cmd;
+ struct format_type *fmt = fid->fmt;
+ struct dm_pool *mem;
const struct dm_config_node *vgn;
const struct dm_config_value *cv;
const char *str, *format_str, *system_id;
@@ -956,9 +983,11 @@ static struct volume_group *_read_vg(struct format_instance *fid,
return NULL;
}
- if (!(vg = alloc_vg("read_vg", fid->fmt->cmd, vgn->key)))
+ if (!(vg = alloc_vg("read_vg", cmd, vgn->key)))
return_NULL;
+ mem = vg->vgmem;
+
/*
* The pv hash memorises the pv section names -> pv
* structures.
@@ -981,13 +1010,13 @@ static struct volume_group *_read_vg(struct format_instance *fid,
/* A backup file might be a backup of a different format */
if (dm_config_get_str(vgn, "format", &format_str) &&
- !(vg->original_fmt = get_format_by_name(fid->fmt->cmd, format_str))) {
+ !(vg->original_fmt = get_format_by_name(cmd, format_str))) {
log_error("Unrecognised format %s for volume group %s.", format_str, vg->name);
goto bad;
}
if (dm_config_get_str(vgn, "lock_type", &str)) {
- if (!(vg->lock_type = dm_pool_strdup(vg->vgmem, str)))
+ if (!(vg->lock_type = dm_pool_strdup(mem, str)))
goto bad;
}
@@ -1013,7 +1042,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
* the lock_args before using it to access the lock manager.
*/
if (dm_config_get_str(vgn, "lock_args", &str)) {
- if (!(vg->lock_args = dm_pool_strdup(vg->vgmem, str)))
+ if (!(vg->lock_args = dm_pool_strdup(mem, str)))
goto bad;
}
@@ -1035,7 +1064,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
}
if (dm_config_get_str(vgn, "system_id", &system_id)) {
- if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) {
+ if (!(vg->system_id = dm_pool_strdup(mem, system_id))) {
log_error("Failed to allocate memory for system_id in _read_vg.");
goto bad;
}
@@ -1080,7 +1109,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
if (dm_config_get_str(vgn, "profile", &str)) {
log_debug_metadata("Adding profile configuration %s for VG %s.", str, vg->name);
- vg->profile = add_profile(vg->cmd, str, CONFIG_PROFILE_METADATA);
+ vg->profile = add_profile(cmd, str, CONFIG_PROFILE_METADATA);
if (!vg->profile) {
log_error("Failed to add configuration profile %s for VG %s", str, vg->name);
goto bad;
@@ -1091,7 +1120,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
vg->mda_copies = DEFAULT_VGMETADATACOPIES;
}
- if (!_read_sections(fid, "physical_volumes", _read_pv, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg,
vgn, pv_hash, lv_hash, 0)) {
log_error("Couldn't find all physical volumes for volume "
"group %s.", vg->name);
@@ -1100,33 +1129,33 @@ static struct volume_group *_read_vg(struct format_instance *fid,
/* Optional tags */
if (dm_config_get_list(vgn, "tags", &cv) &&
- !(_read_str_list(vg->vgmem, &vg->tags, cv))) {
+ !(_read_str_list(mem, &vg->tags, cv))) {
log_error("Couldn't read tags for volume group %s.", vg->name);
goto bad;
}
- if (!_read_sections(fid, "logical_volumes", _read_lvnames, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all logical volume names for volume "
"group %s.", vg->name);
goto bad;
}
- if (!_read_sections(fid, "historical_logical_volumes", _read_historical_lvnames, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all historical logical volumes for volume "
"group %s.", vg->name);
goto bad;
}
- if (!_read_sections(fid, "logical_volumes", _read_lvsegs, vg,
+ if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg,
vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all logical volumes for "
"volume group %s.", vg->name);
goto bad;
}
- if (!_read_sections(fid, "historical_logical_volumes", _read_historical_lvnames_interconnections,
+ if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames_interconnections,
vg, vgn, pv_hash, lv_hash, 1)) {
log_error("Couldn't read all removed logical volume interconnections "
"for volume group %s.", vg->name);
4 years, 2 months
stable-2.02 - dmsetup: do not treat no groups as an error in dmstats list --group
by Bryn Reeves
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1f970f590f969d5a3d8...
Commit: 1f970f590f969d5a3d8b9d458ae257bf93c00432
Parent: 61358d92cbf202dbb483d63a63d5adf0463bb934
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Mon Sep 30 17:10:05 2019 +0100
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Mon Sep 30 17:12:21 2019 +0100
dmsetup: do not treat no groups as an error in dmstats list --group
Analogous to the case of a device with no regions, it is not an
error to attempt to list the stats groups on a device that has no
configured groups: just return success and continue.
---
tools/dmsetup.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 60e0638..15a09c6 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -941,10 +941,12 @@ static int _display_info_cols(struct dm_task *dmt, struct dm_info *info)
}
}
- /* group report with no groups? */
+ /* Group report with no groups is not an error */
if ((walk_flags == DM_STATS_WALK_GROUP)
- && !dm_stats_get_nr_groups(obj.stats))
+ && !dm_stats_get_nr_groups(obj.stats)) {
+ r = 1;
goto out;
+ }
dm_stats_walk_init(obj.stats, walk_flags);
dm_stats_walk_do(obj.stats) {
4 years, 2 months
master - dmsetup: do not treat no groups as an error in dmstats list --group
by Bryn Reeves
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8f02f8dcd72571ce3bc...
Commit: 8f02f8dcd72571ce3bc6538f1cd23807e2b6a64d
Parent: 5c0264d68954e5677f21459bb18d50704b2b9d77
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Mon Sep 30 17:10:05 2019 +0100
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Mon Sep 30 17:10:05 2019 +0100
dmsetup: do not treat no groups as an error in dmstats list --group
Analogous to the case of a device with no regions, it is not an
error to attempt to list the stats groups on a device that has no
configured groups: just return success and continue.
---
libdm/dm-tools/dmsetup.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/libdm/dm-tools/dmsetup.c b/libdm/dm-tools/dmsetup.c
index 2f8a1be..7267d0d 100644
--- a/libdm/dm-tools/dmsetup.c
+++ b/libdm/dm-tools/dmsetup.c
@@ -942,10 +942,12 @@ static int _display_info_cols(struct dm_task *dmt, struct dm_info *info)
}
}
- /* group report with no groups? */
+ /* Group report with no groups is not an error */
if ((walk_flags == DM_STATS_WALK_GROUP)
- && !dm_stats_get_nr_groups(obj.stats))
+ && !dm_stats_get_nr_groups(obj.stats)) {
+ r = 1;
goto out;
+ }
dm_stats_walk_init(obj.stats, walk_flags);
dm_stats_walk_do(obj.stats) {
4 years, 2 months