[lvm-devel] main - vgchange autoactivation: lock vg early to avoid second label scan

David Teigland teigland at sourceware.org
Thu Nov 11 22:59:19 UTC 2021


Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=0e0faf30e01f78828b7e240f57217755b62650bb
Commit:        0e0faf30e01f78828b7e240f57217755b62650bb
Parent:        92e741eda060b4712fab5b37e0bee2cc5e155a57
Author:        David Teigland <teigland at redhat.com>
AuthorDate:    Wed Nov 10 16:43:21 2021 -0600
Committer:     David Teigland <teigland at redhat.com>
CommitterDate: Wed Nov 10 16:50:50 2021 -0600

vgchange autoactivation: lock vg early to avoid second label scan

Copy another optimization from pvscan -aay to vgchange -aay.
When using the optimized label scan for only one VG, acquire the
VG lock prior to the scan.  This allows vg_read to then skip the
repeated label scan that normally happens after locking the vg.
---
 lib/label/label.c                 |  4 ---
 test/shell/vgchange-pvs-online.sh |  4 ++-
 tools/vgchange.c                  | 58 +++++++++++++++++++++------------------
 3 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/lib/label/label.c b/lib/label/label.c
index 324cfd034..d506b81e3 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -1044,10 +1044,6 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
 
 	log_debug_devs("Finding online devices to scan");
 
-	/* reads devices file, does not populate dev-cache */
-	if (!setup_devices_for_online_autoactivation(cmd))
-		return 0;
-
 	/*
 	 * First attempt to use /run/lvm/pvs_lookup/vgname which should be
 	 * used in cases where all PVs in a VG do not contain metadata.
diff --git a/test/shell/vgchange-pvs-online.sh b/test/shell/vgchange-pvs-online.sh
index c2ebe7327..1e9c37db8 100644
--- a/test/shell/vgchange-pvs-online.sh
+++ b/test/shell/vgchange-pvs-online.sh
@@ -56,13 +56,14 @@ check lv_field $vg2/$lv1 lv_active "active"
 # Count io to check the pvs_online optimization 
 # is working to limit scanning.
 
+if which strace; then
 vgchange -an
 _clear_online_files
 
 pvscan --cache "$dev1"
 pvscan --cache "$dev2"
 strace -e io_submit vgchange -aay --autoactivation event $vg1 2>&1|tee trace.out
-test "$(grep io_submit trace.out | wc -l)" -eq 4
+test "$(grep io_submit trace.out | wc -l)" -eq 3
 rm trace.out
 
 strace -e io_submit pvscan --cache "$dev3" 2>&1|tee trace.out
@@ -72,6 +73,7 @@ rm trace.out
 strace -e io_submit vgchange -aay --autoactivation event $vg2 2>&1|tee trace.out
 test "$(grep io_submit trace.out | wc -l)" -eq 2
 rm trace.out
+fi
 
 # non-standard usage: no VG name arg, vgchange will only used pvs_online files
 
diff --git a/tools/vgchange.c b/tools/vgchange.c
index bbb565643..5eebc9ae9 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -743,6 +743,7 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
 {
 	const char *aa;
 	char *vgname = NULL;
+	int vg_locked = 0;
 	int found_none = 0, found_all = 0, found_incomplete = 0;
 
 	if (!(aa = arg_str_value(cmd, autoactivation_ARG, NULL)))
@@ -763,29 +764,35 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
 	vp->vg_complete_to_activate = 1;
 	cmd->use_hints = 0;
 
-	get_single_vgname_cmd_arg(cmd, NULL, &vgname);
-
 	/*
-	 * Special label scan optimized for autoactivation that is based on
-	 * info read from /run/lvm/ files created by pvscan --cache during
-	 * autoactivation.  Add an option to disable this optimization?  e.g.
+	 * Add an option to skip the pvs_online optimization? e.g.
 	 * "online_skip" in --autoactivation / auto_activation_settings
 	 *
-	 * In some cases it might be useful to strictly follow the online
-	 * files, and not fall back to a standard label scan when no pvs or
-	 * incomplete pvs are found from the online files.  Add option for
-	 * that?  e.g.
-	 * "online_only" in --autoactivation / auto_activation_settings
-	 *
-	 * Generally the way that vgchange -aay --autoactivation event is
-	 * currently used, it will not be called until pvscan --cache has found
-	 * the VG is complete, so it will not generally be following the paths
-	 * that fall back to standard label_scan.
-	 *
-	 * TODO: Like pvscan_aa_quick, this could do lock_vol(vgname) before
-	 * label_scan_vg_online, then set cmd->can_use_one_scan=1 to avoid
-	 * rescanning in _vg_read called by process_each_vg.
+	 * if (online_skip)
+	 *	return 1;
+	 */
+
+	/* reads devices file, does not populate dev-cache */
+	if (!setup_devices_for_online_autoactivation(cmd))
+		return_0;
+
+	get_single_vgname_cmd_arg(cmd, NULL, &vgname);
+
+	/*
+	 * Lock the VG before scanning the PVs so _vg_read can avoid the normal
+	 * lock_vol+rescan (READ_WITHOUT_LOCK avoids the normal lock_vol and
+	 * can_use_one_scan avoids the normal rescan.)  If this early lock_vol
+	 * fails, continue and use the normal lock_vol in _vg_read.
 	 */
+	if (vgname) {
+		if (!lock_vol(cmd, vgname, LCK_VG_WRITE, NULL)) {
+			log_debug("Failed early VG locking for autoactivation.");
+		} else {
+			*flags |= READ_WITHOUT_LOCK;
+			cmd->can_use_one_scan = 1;
+			vg_locked = 1;
+		}
+	}
 
 	/*
 	 * Perform label_scan on PVs that are online (per /run/lvm files)
@@ -819,15 +826,14 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
 	}
 
 	/*
-	 * Possible option to only activate from only online pvs even if they
-	 * are not all found, and not fall back to a full label_scan.
+	 * The online scanning optimiziation didn't work, so undo the vg
+	 * locking optimization before falling back to normal processing.
 	 */
-	/*
-	if (online_only) {
-		log_print("PVs online %s.", found_none ? "not found" : "incomplete");
-		return vgname ? 0 : 1;
+	if (vg_locked) {
+		unlock_vg(cmd, NULL, vgname);
+		*flags &= ~READ_WITHOUT_LOCK;
+		cmd->can_use_one_scan = 0;
 	}
-	*/
 
 	/*
 	 * Not expected usage, no online pvs for the vgname were found.  The




More information about the lvm-devel mailing list