master - scanning: optimize by checking text offset and checksum
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0c1316cda876849d5d1...
Commit: 0c1316cda876849d5d1375d40e8cdc08db37c2b5
Parent: 56a295f78c4638e201ad78a8b25fd7874f2d905d
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Nov 26 11:56:51 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Nov 26 16:52:28 2019 -0600
scanning: optimize by checking text offset and checksum
After the VG lock is taken for vg_read, reread the mda_header
and compare the metadata text offset and checksum to what was
seen during label scan. If it is unchanged, then the metadata
has not changed since the label scan, and the metadata does not
need to be reread under the lock for command processing.
For commands that do not make changes (e.g. reporting), the
mda_header is reread and checked on one mda to decide if the
full metadata rereading can be skipped. For other commands
(e.g. modifying the vg) the mda_header is reread and checked
from all PVs. (These could probably just check one mda also.)
---
lib/cache/lvmcache.c | 24 ++++++++
lib/cache/lvmcache.h | 4 +
lib/format_text/format-text.c | 12 ++++
lib/format_text/layout.h | 3 +-
lib/format_text/text_label.c | 2 +-
lib/metadata/metadata.c | 130 ++++++++++++++++++++++++++++++++++++++--
lib/metadata/metadata.h | 2 +
7 files changed, 168 insertions(+), 9 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 6224fe0..2c8c614 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -238,6 +238,30 @@ void lvmcache_get_bad_mdas(struct cmd_context *cmd,
}
}
+void lvmcache_get_mdas(struct cmd_context *cmd,
+ const char *vgname, const char *vgid,
+ struct dm_list *mda_list)
+{
+ struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
+ struct mda_list *mdal;
+ struct metadata_area *mda, *mda2;
+
+ if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) {
+ log_error(INTERNAL_ERROR "lvmcache_get_mdas no vginfo %s", vgname);
+ return;
+ }
+
+ dm_list_iterate_items(info, &vginfo->infos) {
+ dm_list_iterate_items_safe(mda, mda2, &info->mdas) {
+ if (!(mdal = zalloc(sizeof(*mdal))))
+ continue;
+ mdal->mda = mda;
+ dm_list_add(mda_list, &mdal->list);
+ }
+ }
+}
+
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info)
{
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index d614e54..0c8c789 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -216,4 +216,8 @@ void lvmcache_get_bad_mdas(struct cmd_context *cmd,
const char *vgname, const char *vgid,
struct dm_list *bad_mda_list);
+void lvmcache_get_mdas(struct cmd_context *cmd,
+ const char *vgname, const char *vgid,
+ struct dm_list *mda_list);
+
#endif
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 2c2b7fa..268bd64 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1507,6 +1507,7 @@ static int _vg_remove_file(struct format_instance *fid __attribute__((unused)),
}
int read_metadata_location_summary(const struct format_type *fmt,
+ struct metadata_area *mda,
struct mda_header *mdah, int primary_mda, struct device_area *dev_area,
struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors)
{
@@ -1565,6 +1566,17 @@ int read_metadata_location_summary(const struct format_type *fmt,
}
/*
+ * This function is used to read the vg summary during label scan.
+ * Save the text start location and checksum during scan. After the VG
+ * lock is acquired in vg_read, we can reread the mda_header, and
+ * compare rlocn->offset,checksum to what was saved during scan. If
+ * unchanged, it means that the metadata was not changed between scan
+ * and the read.
+ */
+ mda->scan_text_offset = rlocn->offset;
+ mda->scan_text_checksum = rlocn->checksum;
+
+ /*
* When the current metadata wraps around the end of the metadata area
* (so some is located at the end and some is located at the
* beginning), then "wrap" is the number of bytes that was written back
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index 7320d9c..7ec699e 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -104,7 +104,8 @@ struct mda_context {
#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
#define MDA_ORIGINAL_ALIGNMENT 512 /* Original alignment used for start of VG metadata content */
-int read_metadata_location_summary(const struct format_type *fmt, struct mda_header *mdah, int primary_mda,
+int read_metadata_location_summary(const struct format_type *fmt,
+ struct metadata_area *mda, struct mda_header *mdah, int primary_mda,
struct device_area *dev_area, struct lvmcache_vgsummary *vgsummary,
uint64_t *mda_free_sectors);
diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c
index cb60c15..9241eca 100644
--- a/lib/format_text/text_label.c
+++ b/lib/format_text/text_label.c
@@ -349,7 +349,7 @@ static int _read_mda_header_and_metadata(const struct format_type *fmt,
return 1;
}
- if (!read_metadata_location_summary(fmt, mdah, mda_is_primary(mda), &mdac->area,
+ if (!read_metadata_location_summary(fmt, mda, mdah, mda_is_primary(mda), &mdac->area,
vgsummary, &mdac->free_sectors)) {
if (vgsummary->zero_offset)
return 1;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index c4f7247..1ac5445 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4571,6 +4571,118 @@ void vg_write_commit_bad_mdas(struct cmd_context *cmd, struct volume_group *vg)
}
}
+/*
+ * Reread an mda_header. If the text offset is the same as was seen and saved
+ * by label scan, it means the metadata is unchanged and we do not need to
+ * reread metadata.
+ */
+
+static int _scan_text_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid)
+{
+ struct dm_list mda_list;
+ struct mda_list *mdal, *safe;
+ struct metadata_area *mda;
+ struct mda_context *mdac;
+ struct device_area *area;
+ struct mda_header *mdah;
+ struct raw_locn *rlocn;
+ struct device *dev;
+ uint32_t bad_fields;
+ int ret = 1;
+
+ /*
+ * if cmd->can_use_one_scan, check one mda_header is unchanged,
+ * else check that all mda_headers are unchanged.
+ */
+
+ dm_list_init(&mda_list);
+
+ lvmcache_get_mdas(cmd, vgname, vgid, &mda_list);
+
+ dm_list_iterate_items(mdal, &mda_list) {
+ mda = mdal->mda;
+
+ if (!mda->scan_text_offset)
+ continue;
+
+ if (mda->mda_num != 1)
+ continue;
+
+ if (!(dev = mda_get_device(mda))) {
+ log_debug("rescan for text mismatch - no mda dev");
+ ret = 1;
+ goto out;
+ }
+
+ bad_fields = 0;
+
+ mdac = mda->metadata_locn;
+ area = &mdac->area;
+
+ /*
+ * Invalidate mda_header in bcache so it will be reread from disk.
+ */
+ if (!dev_invalidate_bytes(dev, 4096, 512)) {
+ log_debug("rescan for text mismatch - cannot invalidate");
+ ret = 1;
+ goto out;
+ }
+
+ if (!(mdah = raw_read_mda_header(cmd->fmt, area, 1, 0, &bad_fields))) {
+ log_debug("rescan for text mismatch - no mda header");
+ ret = 1;
+ goto out;
+ }
+
+ rlocn = mdah->raw_locns;
+
+ if (bad_fields) {
+ log_debug("rescan for text mismatch - bad_fields");
+ ret = 1;
+ } else if (rlocn->checksum != mda->scan_text_checksum) {
+ log_debug("rescan for text checksum mismatch - now %x prev %x",
+ rlocn->checksum, mda->scan_text_checksum);
+ ret = 1;
+ } else if (rlocn->offset != mda->scan_text_offset) {
+ log_debug("rescan for text offset mismatch - now %llu prev %llu",
+ (unsigned long long)rlocn->offset,
+ (unsigned long long)mda->scan_text_offset);
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+
+ dm_pool_free(cmd->mem, mdah);
+
+ /* For can_use_one_scan commands, return result from checking one mda. */
+ if (cmd->can_use_one_scan)
+ goto out;
+
+ /* For other commands, return mismatch immediately. */
+ if (ret)
+ goto_out;
+ }
+
+ if (ret) {
+ /* shouldn't happen */
+ log_debug("rescan for text mismatch - no mdas");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ if (!ret)
+ log_debug("rescan skipped - text offset and checksum unchanged");
+
+ dm_list_iterate_items_safe(mdal, safe, &mda_list) {
+ dm_list_del(&mdal->list);
+ free(mdal);
+ }
+
+ return ret;
+}
+
static struct volume_group *_vg_read(struct cmd_context *cmd,
const char *vgname,
const char *vgid,
@@ -4625,19 +4737,23 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
* find the same inconsistency. The VG repair (mistakenly done by
* vg_read below) is supposed to fix that.
*
- * FIXME: sort out the usage of the global lock (which is mixed up
- * with the orphan lock), and when we can tell that the global
- * lock is taken prior to the label scan, and still held here,
- * we can also skip the rescan in that case.
+ * If the VG was not modified between the time we scanned the PVs
+ * and now, when we hold the lock, then we don't need to rescan.
+ * We can read the mda_header, and look at the text offset/checksum,
+ * and if the current text offset/checksum matches what was seen during
+ * label scan, we know that metadata is unchanged and doesn't need
+ * to be rescanned. For reporting/display commands (CAN_USE_ONE_SCAN/
+ * can_use_one_scan), we check that the text offset/checksum are unchanged
+ * in just one mda before deciding to skip rescanning. For other commands,
+ * we check that they are unchanged in all mdas. This added checking is
+ * probably unnecessary; all commands could likely just check a single mda.
*/
- if (!cmd->can_use_one_scan || lvmcache_scan_mismatch(cmd, vgname, vgid)) {
+ if (lvmcache_scan_mismatch(cmd, vgname, vgid) || _scan_text_mismatch(cmd, vgname, vgid)) {
log_debug_metadata("Rescanning devices for %s %s", vgname, writing ? "rw" : "");
if (writing)
lvmcache_label_rescan_vg_rw(cmd, vgname, vgid);
else
lvmcache_label_rescan_vg(cmd, vgname, vgid);
- } else {
- log_debug_metadata("Skipped rescanning devices for %s", vgname);
}
/* Now determine the correct vgname if none was supplied */
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index ac18879..377a063 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -187,6 +187,8 @@ struct metadata_area {
void *metadata_locn;
uint32_t status;
uint64_t header_start; /* mda_header.start */
+ uint64_t scan_text_offset; /* rlocn->offset seen during scan */
+ uint32_t scan_text_checksum; /* rlocn->checksum seen during scan */
int mda_num;
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 */
4 years, 5 months
master - bcache: add invalidate_bytes function
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=56a295f78c4638e201a...
Commit: 56a295f78c4638e201ad78a8b25fd7874f2d905d
Parent: 29db9c6325ac3552b0ba3a0f49682e8e8112cca2
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Nov 26 15:46:49 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Nov 26 16:52:28 2019 -0600
bcache: add invalidate_bytes function
---
lib/device/bcache-utils.c | 15 +++++++++++++++
lib/device/bcache.h | 1 +
lib/label/label.c | 5 +++++
lib/label/label.h | 1 +
4 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/lib/device/bcache-utils.c b/lib/device/bcache-utils.c
index 2553554..cf74144 100644
--- a/lib/device/bcache-utils.c
+++ b/lib/device/bcache-utils.c
@@ -79,6 +79,21 @@ bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len,
return true;
}
+bool bcache_invalidate_bytes(struct bcache *cache, int fd, uint64_t start, size_t len)
+{
+ block_address bb, be;
+ bool result = true;
+
+ byte_range_to_block_range(cache, start, len, &bb, &be);
+
+ for (; bb != be; bb++) {
+ if (!bcache_invalidate(cache, fd, bb))
+ result = false;
+ }
+
+ return result;
+}
+
//----------------------------------------------------------------
// Writing bytes and zeroing bytes are very similar, so we factor out
diff --git a/lib/device/bcache.h b/lib/device/bcache.h
index 7622fd3..4ef044c 100644
--- a/lib/device/bcache.h
+++ b/lib/device/bcache.h
@@ -163,6 +163,7 @@ bool bcache_read_bytes(struct bcache *cache, int fd, uint64_t start, size_t len,
bool bcache_write_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, void *data);
bool bcache_zero_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
bool bcache_set_bytes(struct bcache *cache, int fd, uint64_t start, size_t len, uint8_t val);
+bool bcache_invalidate_bytes(struct bcache *cache, int fd, uint64_t start, size_t len);
void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size);
void bcache_unset_last_byte(struct bcache *cache, int fd);
diff --git a/lib/label/label.c b/lib/label/label.c
index 05986cb..64b7ca0 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1464,6 +1464,11 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
return true;
}
+bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len)
+{
+ return bcache_invalidate_bytes(scan_bcache, dev->bcache_fd, start, len);
+}
+
bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
{
if (test_mode())
diff --git a/lib/label/label.h b/lib/label/label.h
index f06b7df..33a91fa 100644
--- a/lib/label/label.h
+++ b/lib/label/label.h
@@ -126,6 +126,7 @@ bool dev_read_bytes(struct device *dev, uint64_t start, size_t len, void *data);
bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data);
bool dev_write_zeros(struct device *dev, uint64_t start, size_t len);
bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val);
+bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len);
void dev_set_last_byte(struct device *dev, uint64_t offset);
void dev_unset_last_byte(struct device *dev);
4 years, 5 months
master - lvcreate: ensure striped raid region size is at least stripe size
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=29db9c6325ac3552b0b...
Commit: 29db9c6325ac3552b0ba3a0f49682e8e8112cca2
Parent: 2037476008ea42e79388a407355c7f285656a5d9
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Nov 26 22:17:34 2019 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Nov 26 22:31:58 2019 +0100
lvcreate: ensure striped raid region size is at least stripe size
The kernel MD runtime requires region size to be larger than stripe size
on striped raid layouts, thus the dm-raid target's constructor rejects
such request.
This causes e.g. an 'lvcreate --type raid10 -i3 -I4096 -R2048 -n lv vg' to fail.
Avoid failing late in the kernel by enforcing region size to be
larger or equal to stripe size.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1698225
---
WHATS_NEW | 1 +
tools/lvcreate.c | 7 +++++++
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index e5af036..41d0e56 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.03.07 -
===================================
+ Ensure minimum required region size on striped RaidLV creation.
Fix resize of thin-pool with data and metadata of different segtype.
Improve mirror type leg splitting.
Fix activation order when removing merged snapshot.
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index ebe6c9f..4a1534c 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -575,6 +575,13 @@ static int _read_raid_params(struct cmd_context *cmd,
log_error("Minimum recovery rate cannot be higher than maximum.");
return 0;
}
+
+ if (lp->region_size < lp->stripe_size) {
+ log_print_unless_silent("Adjusting %s %s region size to required minimum of stripe size %s.",
+ lp->segtype->name, display_size(cmd, (uint64_t)lp->region_size),
+ display_size(cmd, (uint64_t)lp->stripe_size));
+ lp->region_size = lp->stripe_size;
+ }
}
return 1;
4 years, 5 months
stable-2.02 - lvcreate: ensure striped raid region size is at least stripe size
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=50c56ade2a7a89f7510...
Commit: 50c56ade2a7a89f751091669fb8b31854f93eff1
Parent: 61c321d110630d4fc2ed8f75cb3a9ba78e29599b
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Nov 26 22:17:34 2019 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Nov 26 22:30:54 2019 +0100
lvcreate: ensure striped raid region size is at least stripe size
The kernel MD runtime requires region size to be larger than stripe size
on striped raid layouts, thus the dm-raid target's constructor rejects
such request.
This causes e.g. an 'lvcreate --type raid10 -i3 -I4096 -R2048 -n lv vg' to fail.
Avoid failing late in the kernel by enforcing region size to be
larger or equal to stripe size.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1698225
---
WHATS_NEW | 1 +
tools/lvcreate.c | 7 +++++++
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 50fd519..047479b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.187 -
===================================
+ Ensure minimum required region size on striped RaidLV creation.
Fix resize of thin-pool with data and metadata of different segtype.
Fix splitting mirror leg in cluster.
Fix activation order when removing merged snapshot.
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 6e8cc90..c27b798 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -574,6 +574,13 @@ static int _read_raid_params(struct cmd_context *cmd,
log_error("Minimum recovery rate cannot be higher than maximum.");
return 0;
}
+
+ if (lp->region_size < lp->stripe_size) {
+ log_print_unless_silent("Adjusting %s %s region size to required minimum of stripe size %s.",
+ lp->segtype->name, display_size(cmd, (uint64_t)lp->region_size),
+ display_size(cmd, (uint64_t)lp->stripe_size));
+ lp->region_size = lp->stripe_size;
+ }
}
return 1;
4 years, 5 months
master - lvcreate: ensure striped raid region size is at least stripe size
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=54a9d086db46a4e61e2...
Commit: 54a9d086db46a4e61e2edbcd6c35ed2d913f6a46
Parent: 2037476008ea42e79388a407355c7f285656a5d9
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Tue Nov 26 22:17:34 2019 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Tue Nov 26 22:27:06 2019 +0100
lvcreate: ensure striped raid region size is at least stripe size
The kernel MD runtime requires region size to be larger than stripe size
on striped raid layouts, thus the dm-raid target's constructor rejects
such request.
This causes e.g. an 'lvcreate --type raid10 -i3 -I4096 -R2048 -n lv vg' to fail.
Avoid failing late in the kernel by enforcing region size to be
larger or equal to stripe size.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1698225
---
tools/lvcreate.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index ebe6c9f..4a1534c 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -575,6 +575,13 @@ static int _read_raid_params(struct cmd_context *cmd,
log_error("Minimum recovery rate cannot be higher than maximum.");
return 0;
}
+
+ if (lp->region_size < lp->stripe_size) {
+ log_print_unless_silent("Adjusting %s %s region size to required minimum of stripe size %s.",
+ lp->segtype->name, display_size(cmd, (uint64_t)lp->region_size),
+ display_size(cmd, (uint64_t)lp->stripe_size));
+ lp->region_size = lp->stripe_size;
+ }
}
return 1;
4 years, 5 months
master - pvcreate,pvremove: fix reacquiring global lock after prompt
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2037476008ea42e7938...
Commit: 2037476008ea42e79388a407355c7f285656a5d9
Parent: 1c9b36618ec8357350ed4d83c807ae0bf27a12be
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Nov 26 14:34:43 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Nov 26 14:34:43 2019 -0600
pvcreate,pvremove: fix reacquiring global lock after prompt
When pvcreate/pvremove prompt the user, they first release
the global lock, then acquire it again after the prompt,
to avoid blocking other commands while waiting for a user
response. This release/reacquire changes the locking
order with respect to the hints flock (and potentially other
locks). So, to avoid deadlock, use a nonblocking request
when reacquiring the global lock.
---
lib/locking/locking.c | 14 +++++++++++---
lib/locking/locking.h | 1 +
lib/misc/lvm-flock.c | 2 +-
tools/toollib.c | 5 +++--
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 3058a8b..65ff8c2 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -338,7 +338,7 @@ int sync_local_dev_names(struct cmd_context* cmd)
* an explicitly acquired ex global lock to sh in process_each.
*/
-static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert)
+static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert, int nonblock)
{
uint32_t flags = 0;
int ret;
@@ -346,6 +346,9 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert)
if (convert)
flags |= LCK_CONVERT;
+ if (nonblock)
+ flags |= LCK_NONBLOCK;
+
if (!strcmp(mode, "ex")) {
flags |= LCK_WRITE;
@@ -379,7 +382,7 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert)
int lockf_global(struct cmd_context *cmd, const char *mode)
{
- return _lockf_global(cmd, mode, 0);
+ return _lockf_global(cmd, mode, 0, 0);
}
int lockf_global_convert(struct cmd_context *cmd, const char *mode)
@@ -388,7 +391,12 @@ int lockf_global_convert(struct cmd_context *cmd, const char *mode)
if (cmd->lockf_global_ex && !strcmp(mode, "ex"))
return 1;
- return _lockf_global(cmd, mode, 1);
+ return _lockf_global(cmd, mode, 1, 0);
+}
+
+int lockf_global_nonblock(struct cmd_context *cmd, const char *mode)
+{
+ return _lockf_global(cmd, mode, 0, 1);
}
int lock_global(struct cmd_context *cmd, const char *mode)
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 746667a..3e8ae6f 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -75,6 +75,7 @@ int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusiv
int lockf_global(struct cmd_context *cmd, const char *mode);
int lockf_global_convert(struct cmd_context *cmd, const char *mode);
+int lockf_global_nonblock(struct cmd_context *cmd, const char *mode);
int lock_global(struct cmd_context *cmd, const char *mode);
int lock_global_convert(struct cmd_context *cmd, const char *mode);
diff --git a/lib/misc/lvm-flock.c b/lib/misc/lvm-flock.c
index d65601d..d48ff22 100644
--- a/lib/misc/lvm-flock.c
+++ b/lib/misc/lvm-flock.c
@@ -164,7 +164,7 @@ static int _do_write_priority_flock(const char *file, int *fd, int operation, ui
strcpy(file_aux, file);
strcat(file_aux, AUX_LOCK_SUFFIX);
- if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, 0))) {
+ if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, nonblock))) {
if (operation == LOCK_EX) {
r = _do_flock(file, fd, operation, nonblock);
_undo_flock(file_aux, fd_aux);
diff --git a/tools/toollib.c b/tools/toollib.c
index ee2419b..a5304bf 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -5577,10 +5577,11 @@ int pvcreate_each_device(struct cmd_context *cmd,
* Reacquire the lock that was released above before waiting, then
* check again that the devices can still be used. If the second loop
* finds them changed, or can't find them any more, then they aren't
- * used.
+ * used. Use a non-blocking request when reacquiring to avoid
+ * potential deadlock since this is not the normal locking sequence.
*/
- if (!lockf_global(cmd, "ex")) {
+ if (!lockf_global_nonblock(cmd, "ex")) {
log_error("Failed to reacquire global lock after prompt.");
goto_out;
}
4 years, 5 months
master - writecache: modprobe dm-writecache
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1c9b36618ec8357350e...
Commit: 1c9b36618ec8357350ed4d83c807ae0bf27a12be
Parent: bbd8badaef630c3534ccd1ae27602b66c37d5c6e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Nov 26 11:21:09 2019 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Nov 26 11:21:09 2019 -0600
writecache: modprobe dm-writecache
---
lib/writecache/writecache.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/writecache/writecache.c b/lib/writecache/writecache.c
index 0a5b485..130922a 100644
--- a/lib/writecache/writecache.c
+++ b/lib/writecache/writecache.c
@@ -214,7 +214,7 @@ static int _target_present(struct cmd_context *cmd,
if (!_writecache_checked) {
_writecache_checked = 1;
- _writecache_present = target_present(cmd, TARGET_NAME_WRITECACHE, 0);
+ _writecache_present = target_present(cmd, TARGET_NAME_WRITECACHE, 1);
}
return _writecache_present;
4 years, 5 months
master - tests: update to md dev name
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=bbd8badaef630c3534c...
Commit: bbd8badaef630c3534ccd1ae27602b66c37d5c6e
Parent: b6902585187e9a7e29fb57d8415743db1bf80dab
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Oct 2 12:51:17 2019 -0500
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Tue Nov 26 10:34:51 2019 +0100
tests: update to md dev name
Restore WAIT_MD_DEV in teardown.
NOTE: The name of MD device may have changed.
(cherry picked from commit c2ff8876f97a5840cd9d6fcda1bec55ef6220dc3)
---
test/lib/aux.sh | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 19365cd..566e9b5 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -421,13 +421,15 @@ teardown_devs() {
teardown_udev_cookies
test ! -f MD_DEV || cleanup_md_dev
+
+ test ! -f WAIT_MD_DEV || mddev=$(< WAIT_MD_DEV)
udev_wait
- mdadm --stop --scan || true
+ test ! -f WAIT_MD_DEV || mdadm --stop $mddev || true
udev_wait
test ! -f DEVICES || teardown_devs_prefixed "$PREFIX"
test ! -f RAMDISK || { modprobe -r brd || true ; }
- mdadm --stop --scan || true
+ test ! -f WAIT_MD_DEV || mdadm --stop $mddev || true
# NOTE: SCSI_DEBUG_DEV test must come before the LOOP test because
# prepare_scsi_debug_dev() also sets LOOP to short-circuit prepare_loop()
@@ -792,6 +794,7 @@ wait_md_create() {
break
fi
done
+ echo "$md" > WAIT_MD_DEV
}
wipefs_a() {
4 years, 5 months
master - tests: Find md name using lsblk
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b6902585187e9a7e29f...
Commit: b6902585187e9a7e29fb57d8415743db1bf80dab
Parent: 4757ce4c2a4d67ca7170fd25a5dc6e160fb7a788
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Tue Nov 26 09:11:05 2019 +0100
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Tue Nov 26 09:13:17 2019 +0100
tests: Find md name using lsblk
After stopping MD device and rescanning the leg, it is created with
different name.
---
test/shell/duplicate-pvs-md0.sh | 6 ++----
test/shell/duplicate-pvs-md1.sh | 9 +++------
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/test/shell/duplicate-pvs-md0.sh b/test/shell/duplicate-pvs-md0.sh
index 036f570..6ff9ba2 100644
--- a/test/shell/duplicate-pvs-md0.sh
+++ b/test/shell/duplicate-pvs-md0.sh
@@ -368,8 +368,7 @@ aux enable_dev "$dev2"
aux aux udev_wait
cat /proc/mdstat
# for some reason enabling dev2 starts an odd md dev
-mdadm --stop "$mddev" || true
-mdadm --stop --scan
+mdadm --stop $(lsblk -al -o NAME --noheadings "$dev2" | grep '^md') || true
cat /proc/mdstat
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -434,8 +433,7 @@ aux enable_dev "$dev2"
aux aux udev_wait
cat /proc/mdstat
# for some reason enabling dev2 starts an odd md dev
-mdadm --stop "$mddev" || true
-mdadm --stop --scan
+mdadm --stop $(lsblk -al -o NAME --noheadings "$dev2" | grep '^md') || true
cat /proc/mdstat
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
diff --git a/test/shell/duplicate-pvs-md1.sh b/test/shell/duplicate-pvs-md1.sh
index 64d9b98..0e1b83c 100644
--- a/test/shell/duplicate-pvs-md1.sh
+++ b/test/shell/duplicate-pvs-md1.sh
@@ -415,8 +415,7 @@ 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
+mdadm --stop $(lsblk -al -o NAME --noheadings "$dev2" | grep '^md') || true
cat /proc/mdstat
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -480,8 +479,7 @@ 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
+mdadm --stop $(lsblk -al -o NAME --noheadings "$dev2" | grep '^md') || true
cat /proc/mdstat
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -619,8 +617,7 @@ aux enable_dev "$dev4"
aux udev_wait
cat /proc/mdstat
# for some reason enabling dev2 starts an odd md dev
-mdadm --stop "$mddev" || true
-mdadm --stop --scan
+mdadm --stop $(lsblk -al -o NAME --noheadings "$dev2" | grep '^md') || true
cat /proc/mdstat
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
4 years, 5 months
master - Partial revert "tests: update to md dev name"
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4757ce4c2a4d67ca717...
Commit: 4757ce4c2a4d67ca7170fd25a5dc6e160fb7a788
Parent: 1e669ab315c32aba3f47c37771f26ab7c8e151dd
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Mon Nov 25 09:23:02 2019 +0100
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Mon Nov 25 09:23:02 2019 +0100
Partial revert "tests: update to md dev name"
This partially reverts commit c2ff8876f97a5840cd9d6fcda1bec55ef6220dc3.
Not all MD devices are stopped. Something is missing there...
---
test/lib/aux.sh | 7 ++-----
test/shell/duplicate-pvs-md0.sh | 2 ++
test/shell/duplicate-pvs-md1.sh | 3 +++
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 566e9b5..19365cd 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -421,15 +421,13 @@ teardown_devs() {
teardown_udev_cookies
test ! -f MD_DEV || cleanup_md_dev
-
- test ! -f WAIT_MD_DEV || mddev=$(< WAIT_MD_DEV)
udev_wait
- test ! -f WAIT_MD_DEV || mdadm --stop $mddev || true
+ mdadm --stop --scan || true
udev_wait
test ! -f DEVICES || teardown_devs_prefixed "$PREFIX"
test ! -f RAMDISK || { modprobe -r brd || true ; }
- test ! -f WAIT_MD_DEV || mdadm --stop $mddev || true
+ mdadm --stop --scan || true
# NOTE: SCSI_DEBUG_DEV test must come before the LOOP test because
# prepare_scsi_debug_dev() also sets LOOP to short-circuit prepare_loop()
@@ -794,7 +792,6 @@ wait_md_create() {
break
fi
done
- echo "$md" > WAIT_MD_DEV
}
wipefs_a() {
diff --git a/test/shell/duplicate-pvs-md0.sh b/test/shell/duplicate-pvs-md0.sh
index 21f1442..036f570 100644
--- a/test/shell/duplicate-pvs-md0.sh
+++ b/test/shell/duplicate-pvs-md0.sh
@@ -369,6 +369,7 @@ aux 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
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -434,6 +435,7 @@ aux 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
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
diff --git a/test/shell/duplicate-pvs-md1.sh b/test/shell/duplicate-pvs-md1.sh
index be223df..64d9b98 100644
--- a/test/shell/duplicate-pvs-md1.sh
+++ b/test/shell/duplicate-pvs-md1.sh
@@ -416,6 +416,7 @@ 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
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -480,6 +481,7 @@ 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
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
@@ -618,6 +620,7 @@ 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
aux wipefs_a "$dev1" || true
aux wipefs_a "$dev2" || true
4 years, 5 months