summaryrefslogtreecommitdiff
path: root/lib/locking/locking.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2021-06-14 15:31:34 -0500
committerDavid Teigland <teigland@redhat.com>2021-06-14 16:18:33 -0500
commit31e2c4c1a6e0ddb7ee8a34fe96505b3135d51aa6 (patch)
tree593c54fd04131229ed6feeb1ced1fd36f0731a19 /lib/locking/locking.c
parent09b0eea6a010ba37dfd793caecc79876017679de (diff)
downloadlvm2-dev-dct-scan-errors-1.tar.gz
locking: allow using global lock for scanningdev-dct-scan-errors-1
When vg metadata consumes a major percentage of the metadata area, acquire the global lock prior to label_scan. Many commands already acquire the global lock prior to label_scan, but VG-specific commands may not otherwise use the global lock. This attempts to avoid the rare situation in which the metadata is large enough to wrap around the metadata area and invalidate the metadata location information that a single command gathered from label_scan. If this wrapping with large sizes occurs, the metadata locations seen during label scan may be overwritten before the same command is able to use them for vg_read(), causing vg_read to see invalid metadata and the command to fail. A large number of concurrent lvm commands is also a factor that can lead to this problem due to longer delays between label_scan and vg_read. This problem can be avoided if all commands acquire the global lock prior to label scan, and hold it across all the vg_read() calls. This ensures that the results from label scan are unchanging during label scan and remain valid for use in vg_read. Commands modifying vg metadata take the global lock ex, and those only reading vg metadata use sh. This extra use of the global lock is usually unnecessary, so lvm automatically detects when the extra locking may be needed before starting to use it. When vg metadata is a large enough percentage of the total metadata area, lvm begins doing extra locking. Currently this is 25% (could be configurable.) When one command sees this threshold has been reached, it creates the file /run/lvm/scan_lock_global. When subsequent commands see this file exists, then will acquire the global lock prior to their label_scan. When metadata goes below the threshold, the temp file is removed, and commands no longer do the extra locking.
Diffstat (limited to 'lib/locking/locking.c')
-rw-r--r--lib/locking/locking.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 0aceb194a..3236b523a 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -359,10 +359,8 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert,
if (!strcmp(mode, "ex")) {
flags |= LCK_WRITE;
- if (cmd->lockf_global_ex) {
- log_warn("global flock already held ex");
+ if (cmd->lockf_global_ex)
return 1;
- }
ret = lock_vol(cmd, VG_GLOBAL, flags, NULL);
if (ret)