commit 03ed86585e1bfbaf5df1e3488b6268b8887ca427 Author: Peter Rajnoha 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) ||