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