diff --git a/WHATS_NEW b/WHATS_NEW index 4da72a841..93cd914c8 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.89 - ================================== + Add activation/retry_deactivation to lvm.conf to retry deactivation of an LV. Replace open_count check with holders/mounted_fs check on lvremove path. Disallow the creation of mirrors (mirror or raid1 segtype) with only one leg. Cleanup restart clvmd code (no memory allocation, debug print passed args). diff --git a/doc/example.conf.in b/doc/example.conf.in index 94c632f40..eaba6cdd4 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -465,6 +465,11 @@ activation { # Useful for diagnosing problems with LVM2/udev interactions. verify_udev_operations = 0 + # If set to 1 and if deactivation of an LV fails, perhaps because + # a process run from a quick udev rule temporarily opened the device, + # retry the operation for a few seconds before failing. + retry_deactivation = 1 + # How to fill in missing stripes if activating an incomplete volume. # Using "error" will make inaccessible parts of the device return # I/O errors on access. You can instead use a device path, in which diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index b5b4b9eda..0a3c29c14 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -1782,6 +1782,8 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, goto_out; break; case DEACTIVATE: + if (retry_deactivation()) + dm_tree_retry_remove(root); /* Deactivate LV and all devices it references that nothing else has open. */ r = dm_tree_deactivate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1); if (!r) diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index 336689604..6c554b20e 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -303,6 +303,9 @@ static int _process_config(struct cmd_context *cmd) "activation/udev_sync", DEFAULT_UDEV_SYNC); + 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)); diff --git a/lib/config/defaults.h b/lib/config/defaults.h index a5179432d..16b524db9 100644 --- a/lib/config/defaults.h +++ b/lib/config/defaults.h @@ -81,6 +81,7 @@ #define DEFAULT_UDEV_RULES 1 #define DEFAULT_UDEV_SYNC 1 #define DEFAULT_VERIFY_UDEV_OPERATIONS 0 +#define DEFAULT_RETRY_DEACTIVATION 1 #define DEFAULT_ACTIVATION_CHECKS 0 #define DEFAULT_EXTENT_SIZE 4096 /* In KB */ #define DEFAULT_MAX_PV 0 diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c index 7358a345d..69de6231d 100644 --- a/lib/misc/lvm-globals.c +++ b/lib/misc/lvm-globals.c @@ -42,6 +42,7 @@ static int _ignore_suspended_devices = 0; static int _error_message_produced = 0; static unsigned _is_static = 0; static int _udev_checking = 1; +static int _retry_deactivation = DEFAULT_RETRY_DEACTIVATION; static int _activation_checks = 0; static char _sysfs_dir_path[PATH_MAX] = ""; static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT; @@ -134,6 +135,11 @@ void init_udev_checking(int checking) log_debug("LVM udev checking disabled"); } +void init_retry_deactivation(int retry) +{ + _retry_deactivation = retry; +} + void init_activation_checks(int checks) { if ((_activation_checks = checks)) @@ -272,6 +278,11 @@ int udev_checking(void) return _udev_checking; } +int retry_deactivation(void) +{ + return _retry_deactivation; +} + int activation_checks(void) { return _activation_checks; diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h index fcba687ba..ba104177f 100644 --- a/lib/misc/lvm-globals.h +++ b/lib/misc/lvm-globals.h @@ -42,6 +42,7 @@ void init_dev_disable_after_error_count(int value); void init_pv_min_size(uint64_t sectors); void init_activation_checks(int checks); void init_detect_internal_vg_cache_corruption(int detect); +void init_retry_deactivation(int retry); void set_cmd_name(const char *cmd_name); void set_sysfs_dir_path(const char *path); @@ -67,6 +68,7 @@ const char *sysfs_dir_path(void); uint64_t pv_min_size(void); int activation_checks(void); int detect_internal_vg_cache_corruption(void); +int retry_deactivation(void); #define DMEVENTD_MONITOR_IGNORE -1 int dmeventd_monitor_mode(void);