Blob Blame History Raw
commit 811db05e50b042c7ce3dc3ca9cfd3eccac464caa
Author: Peter Rajnoha <prajnoha@redhat.com>
Date:   Tue May 14 11:22:58 2013 +0200

    lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch
---
 WHATS_NEW                  |  1 +
 lib/activate/dev_manager.c | 58 +++++++++++++++++++++++++++++++++++++++++++---
 lib/commands/toolcontext.c | 46 +++++++-----------------------------
 3 files changed, 64 insertions(+), 41 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index 8516f40..eb7897d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.99 - 
 ===================================
+  Fix premature DM version checking which caused useless mapper/control access.
   Recognize DM_DISABLE_UDEV environment variable for a complete fallback.
   Do not verify udev operations if --noudevsync command option is used.
   Fix blkdeactivate to handle nested mountpoints and mangled mount paths.
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 31c1c27..7abd43b 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1016,6 +1016,58 @@ int dev_manager_mknodes(const struct logical_volume *lv)
 	return r;
 }
 
+#ifdef UDEV_SYNC_SUPPORT
+/*
+ * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch
+ * 856a6f1dbd8940e72755af145ebcd806408ecedd
+ * some operations could not be performed by udev, requiring our fallback code.
+ */
+static int _dm_driver_has_stable_udev_support(void)
+{
+	char vsn[80];
+	unsigned maj, min, patchlevel;
+
+	return driver_version(vsn, sizeof(vsn)) &&
+	       (sscanf(vsn, "%u.%u.%u", &maj, &min, &patchlevel) == 3) &&
+	       (maj == 4 ? min >= 18 : maj > 4);
+}
+
+static int _check_udev_fallback(struct cmd_context *cmd)
+{
+	struct config_info *settings = &cmd->current_settings;
+
+	if (settings->udev_fallback != -1)
+		goto out;
+
+	/*
+	 * Use udev fallback automatically in case udev
+	 * is disabled via DM_DISABLE_UDEV environment
+	 * variable or udev rules are switched off.
+	 */
+	settings->udev_fallback = !settings->udev_rules ? 1 :
+		find_config_tree_bool(cmd, "activation/verify_udev_operations",
+				      DEFAULT_VERIFY_UDEV_OPERATIONS);
+
+	/* Do not rely fully on udev if the udev support is known to be incomplete. */
+	if (!settings->udev_fallback && !_dm_driver_has_stable_udev_support()) {
+		log_very_verbose("Kernel driver has incomplete udev support so "
+				 "LVM will check and perform some operations itself.");
+		settings->udev_fallback = 1;
+	}
+out:
+	return settings->udev_fallback;
+}
+
+#else /* UDEV_SYNC_SUPPORT */
+
+static int _check_udev_fallback(struct cmd_context *cmd)
+{
+	/* We must use old node/symlink creation code if not compiled with udev support at all! */
+	return cmd->current_settings.udev_fallback = 1;
+}
+
+#endif /* UDEV_SYNC_SUPPORT */
+
 static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *lv,
 				const char *layer)
 {
@@ -1025,7 +1077,7 @@ static uint16_t _get_udev_flags(struct dev_manager *dm, struct logical_volume *l
 	 * Instruct also libdevmapper to disable udev
 	 * fallback in accordance to LVM2 settings.
 	 */
-	if (!dm->cmd->current_settings.udev_fallback)
+	if (!_check_udev_fallback(dm->cmd))
 		udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
 
 	/*
@@ -2036,7 +2088,7 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
 	int r = 1;
 
 	/* Nothing to do if udev fallback is disabled. */
-	if (!dm->cmd->current_settings.udev_fallback) {
+	if (!_check_udev_fallback(dm->cmd)) {
 		fs_set_create();
 		return 1;
 	}
@@ -2084,7 +2136,7 @@ static int _remove_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
 	int r = 1;
 
 	/* Nothing to do if udev fallback is disabled. */
-	if (!dm->cmd->current_settings.udev_fallback)
+	if (!_check_udev_fallback(dm->cmd))
 		return 1;
 
 	while ((child = dm_tree_next_child(&handle, root, 0))) {
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 80d0f3e..61d5c26 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -226,23 +226,6 @@ static int _check_disable_udev(const char *msg) {
 	return 0;
 }
 
-#ifdef UDEV_SYNC_SUPPORT
-/*
- * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch 
- * 856a6f1dbd8940e72755af145ebcd806408ecedd
- * some operations could not be performed by udev, requiring our fallback code.
- */
-static int _dm_driver_has_stable_udev_support(void)
-{
-	char vsn[80];
-	unsigned maj, min, patchlevel;
-
-	return driver_version(vsn, sizeof(vsn)) &&
-	       (sscanf(vsn, "%u.%u.%u", &maj, &min, &patchlevel) == 3) &&
-	       (maj == 4 ? min >= 18 : maj > 4);
-}
-#endif
-
 static int _process_config(struct cmd_context *cmd)
 {
 	mode_t old_umask;
@@ -341,33 +324,20 @@ static int _process_config(struct cmd_context *cmd)
 	cmd->default_settings.udev_sync = udev_disabled ? 0 :
 		find_config_tree_int(cmd, "activation/udev_sync", DEFAULT_UDEV_SYNC);
 
+	/*
+	 * Set udev_fallback lazily on first use since it requires
+	 * checking DM driver version which is an extra ioctl!
+	 * This also prevents unnecessary use of mapper/control.
+	 * If udev is disabled globally, set fallback mode immediately.
+	*/
+        cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1;
+
 	init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation",
 							DEFAULT_RETRY_DEACTIVATION));
 
 	init_activation_checks(find_config_tree_int(cmd, "activation/checks",
 						      DEFAULT_ACTIVATION_CHECKS));
 
-#ifdef UDEV_SYNC_SUPPORT
-	/*
-	 * Use udev fallback automatically in case udev
-	 * is disabled via DM_DISABLE_UDEV environment
-	 * variable or udev rules are switched off.
-	 */
-	cmd->default_settings.udev_fallback = !cmd->default_settings.udev_rules || udev_disabled ? 1 :
-		find_config_tree_int(cmd, "activation/verify_udev_operations", DEFAULT_VERIFY_UDEV_OPERATIONS);
-
-	/* Do not rely fully on udev if the udev support is known to be incomplete. */
-	if (!cmd->default_settings.udev_fallback && !_dm_driver_has_stable_udev_support()) {
-		log_very_verbose("Kernel driver has incomplete udev support so "
-				 "LVM will check and perform some operations itself.");
-		cmd->default_settings.udev_fallback = 1;
-	}
-
-#else
-	/* We must use old node/symlink creation code if not compiled with udev support at all! */
-	cmd->default_settings.udev_fallback = 1;
-#endif
-
 	cmd->use_linear_target = find_config_tree_int(cmd,
 						      "activation/use_linear_target",
 						       DEFAULT_USE_LINEAR_TARGET);