Blob Blame History Raw
commit 03ed86585e1bfbaf5df1e3488b6268b8887ca427
Author: Peter Rajnoha <prajnoha@redhat.com>
Date:   Tue May 14 11:17:52 2013 +0200

    lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch
---
 WHATS_NEW                  |  2 ++
 WHATS_NEW_DM               |  1 +
 lib/commands/toolcontext.c | 62 ++++++++++++++++++++++++++++++++++------------
 libdm/libdm-common.c       | 43 ++++++++++++++++++++++++++------
 tools/lvmcmdline.c         |  4 +--
 5 files changed, 86 insertions(+), 26 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index 1bdfeb0..8516f40 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
 Version 2.02.99 - 
 ===================================
+  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.
   Fix a crash-inducing race condition in lvmetad while updating metadata.
   Fix possible race while removing metadata from lvmetad.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index e0b8d51..9574fdf 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
 Version 1.02.78 - 
 ===================================
+  Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only.
   Automatically deactivate failed preloaded dm tree node.
   Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled.
 
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index eb1a90b..80d0f3e 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -211,6 +211,21 @@ static void _init_logging(struct cmd_context *cmd)
 	reset_lvm_errno(1);
 }
 
+static int _check_disable_udev(const char *msg) {
+	if (getenv("DM_DISABLE_UDEV")) {
+		log_very_verbose("DM_DISABLE_UDEV environment variable set. "
+				 "Overriding configuration to use "
+				 "udev_rules=0, udev_sync=0, verify_udev_operations=1.");
+		if (udev_is_running())
+			log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
+				 "Bypassing udev, LVM will %s.", msg);
+
+		return 1;
+	}
+
+	return 0;
+}
+
 #ifdef UDEV_SYNC_SUPPORT
 /*
  * Until the DM_UEVENT_GENERATED_FLAG was introduced in kernel patch 
@@ -237,6 +252,7 @@ static int _process_config(struct cmd_context *cmd)
 	const struct dm_config_value *cv;
 	int64_t pv_min_kb;
 	const char *lvmetad_socket;
+	int udev_disabled = 0;
 
 	/* umask */
 	cmd->default_settings.umask = find_config_tree_int(cmd,
@@ -310,13 +326,20 @@ static int _process_config(struct cmd_context *cmd)
 		return 0;
 	}
 
-	cmd->default_settings.udev_rules = find_config_tree_int(cmd,
-								"activation/udev_rules",
-								DEFAULT_UDEV_RULES);
+	/*
+	 * If udev is disabled using DM_DISABLE_UDEV environment
+	 * variable, override existing config and hardcode these:
+	 *   - udev_rules = 0
+	 *   - udev_sync = 0
+	 *   - udev_fallback = 1
+	 */
+	udev_disabled = _check_disable_udev("manage logical volume symlinks in device directory");
 
-	cmd->default_settings.udev_sync = find_config_tree_int(cmd,
-								"activation/udev_sync",
-								DEFAULT_UDEV_SYNC);
+	cmd->default_settings.udev_rules = udev_disabled ? 0 :
+		find_config_tree_int(cmd, "activation/udev_rules", DEFAULT_UDEV_RULES);
+
+	cmd->default_settings.udev_sync = udev_disabled ? 0 :
+		find_config_tree_int(cmd, "activation/udev_sync", DEFAULT_UDEV_SYNC);
 
 	init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation",
 							DEFAULT_RETRY_DEACTIVATION));
@@ -326,14 +349,12 @@ static int _process_config(struct cmd_context *cmd)
 
 #ifdef UDEV_SYNC_SUPPORT
 	/*
-	 * We need udev rules to be applied, otherwise we would end up with no
-	 * nodes and symlinks! However, we can disable the synchronization itself
-	 * in runtime and still have only udev to create the nodes and symlinks
-	 * without any fallback.
+	 * 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 ?
-		find_config_tree_int(cmd, "activation/verify_udev_operations",
-				     DEFAULT_VERIFY_UDEV_OPERATIONS) : 1;
+	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()) {
@@ -693,9 +714,18 @@ static int _init_dev_cache(struct cmd_context *cmd)
 	if (!dev_cache_init(cmd))
 		return_0;
 
-	device_list_from_udev = udev_is_running() ?
-		find_config_tree_bool(cmd, "devices/obtain_device_list_from_udev",
-				      DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV) : 0;
+	/*
+	 * Override existing config and hardcode device_list_from_udev = 0 if:
+	 *   - udev is not running
+	 *   - udev is disabled using DM_DISABLE_UDEV environment variable
+	 */
+	if (_check_disable_udev("obtain device list by scanning device directory"))
+		device_list_from_udev = 0;
+	else
+		device_list_from_udev = udev_is_running() ?
+			find_config_tree_bool(cmd, "devices/obtain_device_list_from_udev",
+					      DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV) : 0;
+
 	init_obtain_device_list_from_udev(device_list_from_udev);
 
 	if (!(cn = find_config_tree_node(cmd, "devices/scan"))) {
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index afdac89..075fba8 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -74,6 +74,8 @@ static dm_string_mangling_t _name_mangling_mode = DEFAULT_DM_NAME_MANGLING;
 static struct selabel_handle *_selabel_handle = NULL;
 #endif
 
+static int _udev_disabled = 0;
+
 #ifdef UDEV_SYNC_SUPPORT
 static int _semaphore_supported = -1;
 static int _udev_running = -1;
@@ -85,6 +87,9 @@ void dm_lib_init(void)
 {
 	const char *env;
 
+	if ((env = getenv("DM_DISABLE_UDEV")))
+		_udev_disabled = 1;
+
 	env = getenv(DM_DEFAULT_NAME_MANGLING_MODE_ENV_VAR_NAME);
 	if (env && *env) {
 		if (!strcasecmp(env, "none"))
@@ -1814,6 +1819,26 @@ out:
 	return r;
 }
 
+static void _set_cookie_flags(struct dm_task *dmt, uint16_t flags)
+{
+	if (!dm_cookie_supported())
+		return;
+
+	if (_udev_disabled) {
+		/*
+		 * If udev is disabled, hardcode this functionality:
+		 *   - we want libdm to create the nodes
+		 *   - we don't want the /dev/mapper and any subsystem
+		 *     related content to be created by udev if udev
+		 *     rules are installed
+		 */
+		flags &= ~DM_UDEV_DISABLE_LIBRARY_FALLBACK;
+		flags |= DM_UDEV_DISABLE_DM_RULES_FLAG | DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG;
+	}
+
+	dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT;
+}
+
 #ifndef UDEV_SYNC_SUPPORT
 void dm_udev_set_sync_support(int sync_with_udev)
 {
@@ -1835,8 +1860,8 @@ int dm_udev_get_checking(void)
 
 int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
 {
-	if (dm_cookie_supported())
-		dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT;
+	_set_cookie_flags(dmt, flags);
+
 	*cookie = 0;
 	dmt->cookie_set = 1;
 
@@ -1908,8 +1933,13 @@ static void _check_udev_sync_requirements_once(void)
 	if (_semaphore_supported < 0)
 		_semaphore_supported = _check_semaphore_is_supported();
 
-	if (_udev_running < 0)
+	if (_udev_running < 0) {
 		_udev_running = _check_udev_is_running();
+		if (_udev_disabled && _udev_running)
+			log_warn("Udev is running and DM_DISABLE_UDEV environment variable is set. "
+				 "Bypassing udev, device-mapper library will manage device "
+				 "nodes in device directory.");
+	}
 }
 
 void dm_udev_set_sync_support(int sync_with_udev)
@@ -1922,8 +1952,8 @@ int dm_udev_get_sync_support(void)
 {
 	_check_udev_sync_requirements_once();
 
-	return _semaphore_supported && dm_cookie_supported() &&
-		_udev_running && _sync_with_udev;
+	return !_udev_disabled && _semaphore_supported &&
+		dm_cookie_supported() &&_udev_running && _sync_with_udev;
 }
 
 void dm_udev_set_checking(int checking)
@@ -2203,8 +2233,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags)
 {
 	int semid;
 
-	if (dm_cookie_supported())
-		dmt->event_nr = flags << DM_UDEV_FLAGS_SHIFT;
+	_set_cookie_flags(dmt, flags);
 
 	if (!dm_udev_get_sync_support()) {
 		*cookie = 0;
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 39a8c58..652d57e 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -901,10 +901,8 @@ static int _get_settings(struct cmd_context *cmd)
 	} else
 		init_trust_cache(0);
 
-	if (arg_count(cmd, noudevsync_ARG)) {
+	if (arg_count(cmd, noudevsync_ARG))
 		cmd->current_settings.udev_sync = 0;
-		cmd->current_settings.udev_fallback = 1;
-	}
 
 	/* Handle synonyms */
 	if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||