diff --git a/.gitignore b/.gitignore index 510e3f5..6af6a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /LVM2.2.02.96.tgz /LVM2.2.02.97.tgz /LVM2.2.02.98.tgz +/LVM2.2.02.99.tgz diff --git a/LVM2.2.02.98.tgz.asc b/LVM2.2.02.98.tgz.asc deleted file mode 100644 index b9da58e..0000000 --- a/LVM2.2.02.98.tgz.asc +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.11 (GNU/Linux) - -iEYEABECAAYFAlB8HicACgkQIoGRwVZ+LBd+mwCg2X9MFz3iFlnARwxVgNBCWgYY -KHYAn1fgrjMIeoQaKUEDjMrhvapj9wOK -=/QEd ------END PGP SIGNATURE----- diff --git a/LVM2.2.02.99.tgz.asc b/LVM2.2.02.99.tgz.asc new file mode 100644 index 0000000..3b0e079 --- /dev/null +++ b/LVM2.2.02.99.tgz.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.11 (GNU/Linux) + +iEYEABECAAYFAlHwX8oACgkQIoGRwVZ+LBezWwCfb+zArz0U8G3FOgN76MTWjc5A +zsMAoJiKRG9xfU8iK0cK3vtJUfJPLe5A +=27LF +-----END PGP SIGNATURE----- diff --git a/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch b/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch deleted file mode 100644 index d2f1570..0000000 --- a/lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch +++ /dev/null @@ -1,252 +0,0 @@ -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) || diff --git a/lvm2-2_02_99-also-autoactivate-on-coldplug.patch b/lvm2-2_02_99-also-autoactivate-on-coldplug.patch deleted file mode 100644 index c1ceda9..0000000 --- a/lvm2-2_02_99-also-autoactivate-on-coldplug.patch +++ /dev/null @@ -1,73 +0,0 @@ -commit 764195207d4773cf6f1674a2fb16e9a0acda304a -Author: Peter Rajnoha -Date: Fri Apr 19 12:17:53 2013 +0200 - - udev: also autoactivate on coldplug - - Commit 756bcabbfe297688ba240a880bc2b55265ad33f0 fixed autoactivation - to not trigger on each uevent for a PV that appeared in the system - most notably the events that are triggered artificially (udevadm - trigger or as the result of the WATCH udev rule being applied that - consequently generates CHANGE uevents). This fixed a situation in - which VGs/LVs were activated when they should not. - - BUT we still need to care about the coldplug used at boot to - retrigger the ADD events - the "udevadm trigger --action=add"! - - For non-DM-based PVs, this is already covered as for these we - run the autoactivation on ADD event only. - - However, for DM-based PVs, we still need to run the - autoactivation even for the artificial ADD event, reusing - the udev DB content from previous proper CHANGE event that - came with the DM device activation. - - Simply, this patch fixes a situation in which we run extra - "udevadm trigger --action=add" (or echo add > /sys/block//uevent) - for DM-based PVs (cryptsetup devices, multipath devices, any - other DM devices...). - - Without this patch, while using lvmetad + autoactivation, - any VG/LV that has a DM-based PV and for which we do not - call the activation directly, the VG/LV is not activated. - - For example a VG with an LV with root FS on it which is directly - activated in initrd and then missing activation of the rest - of the LVs in the VG because of unhandled uevent retrigger on - boot after switching to root FS (the "coldplug"). - - (No WHATS_NEW here as this fixes the commit mentioned - above and which was not released yet.) ---- - udev/10-dm.rules.in | 5 ++++- - udev/69-dm-lvm-metad.rules.in | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in -index cfee145..512d156 100644 ---- a/udev/10-dm.rules.in -+++ b/udev/10-dm.rules.in -@@ -77,7 +77,10 @@ LABEL="dm_flags_done" - # before (e.g. in initrd). If udev is used in initrd, we require the udev init - # script to not remove the existing udev database so we can reuse the information - # stored at the time of device activation in the initrd. --ACTION=="add", ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" -+ACTION!="add", GOTO="dm_no_coldplug" -+ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" -+ENV{DM_ACTIVATION}="1" -+LABEL="dm_no_coldplug" - - # "dm" sysfs subdirectory is available in newer versions of DM - # only (kernels >= 2.6.29). We have to check for its existence -diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in -index b16a27a..66c58b3 100644 ---- a/udev/69-dm-lvm-metad.rules.in -+++ b/udev/69-dm-lvm-metad.rules.in -@@ -26,6 +26,7 @@ ACTION=="remove", GOTO="lvm_scan" - KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" - - # If the PV is a dm device, scan only after proper mapping activation (CHANGE event + DM_ACTIVATION=1) -+# or after a coldplug (event retrigger) with "add" event (ADD event + DM_ACTIVATION=1) - KERNEL=="dm-[0-9]*", ENV{DM_ACTIVATION}!="1", GOTO="lvm_end" - - LABEL="lvm_scan" diff --git a/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch b/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch deleted file mode 100644 index e1ecef0..0000000 --- a/lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch +++ /dev/null @@ -1,34 +0,0 @@ -commit 9cff3357bd69f15497af8c03774df07081d361dd -Author: Peter Rajnoha -Date: Tue May 14 11:04:08 2013 +0200 - - lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch ---- - WHATS_NEW | 1 + - tools/toollib.c | 2 +- - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 62efb53..25e07ee 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Avoid a global lock in pvs when lvmetad is in use. - Fix crash in pvscan --cache -aay triggered by non-mda PV. - Fix lvm2app to return all property sizes in bytes. - Add lvm.conf option global/thin_disabled_features. -diff --git a/tools/toollib.c b/tools/toollib.c -index 5fe94e0..dce42f4 100644 ---- a/tools/toollib.c -+++ b/tools/toollib.c -@@ -701,7 +701,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, - int opt = 0; - int ret_max = ECMD_PROCESSED; - int ret = 0; -- int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE); -+ int lock_global = !(flags & READ_WITHOUT_LOCK) && !(flags & READ_FOR_UPDATE) && !lvmetad_active(); - - struct pv_list *pvl; - struct physical_volume *pv; diff --git a/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch b/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch deleted file mode 100644 index 5fa9f6f..0000000 --- a/lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch +++ /dev/null @@ -1,109 +0,0 @@ -commit b7e453f3821c4a896e00a29800351687d3365f64 -Author: Peter Rajnoha -Date: Tue May 14 11:26:40 2013 +0200 - - lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch ---- - WHATS_NEW_DM | 1 + - daemons/dmeventd/dmeventd.c | 37 ++++++++++++++++++++++++++++--------- - 2 files changed, 29 insertions(+), 9 deletions(-) - -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index 9574fdf..30d01f9 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,5 +1,6 @@ - Version 1.02.78 - - =================================== -+ Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). - 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/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c -index 13148c3..5f2339f 100644 ---- a/daemons/dmeventd/dmeventd.c -+++ b/daemons/dmeventd/dmeventd.c -@@ -1237,7 +1237,8 @@ static int _get_timeout(struct message_data *message_data) - /* Initialize a fifos structure with path names. */ - static void _init_fifos(struct dm_event_fifos *fifos) - { -- memset(fifos, 0, sizeof(*fifos)); -+ fifos->client = -1; -+ fifos->server = -1; - - fifos->client_path = DM_EVENT_FIFO_CLIENT; - fifos->server_path = DM_EVENT_FIFO_SERVER; -@@ -1254,7 +1255,7 @@ static int _open_fifos(struct dm_event_fifos *fifos) - syslog(LOG_ERR, "%s: Failed to create client fifo %s: %m.\n", - __func__, fifos->client_path); - (void) dm_prepare_selinux_context(NULL, 0); -- return 0; -+ goto fail; - } - - /* Create server fifo. */ -@@ -1263,7 +1264,7 @@ static int _open_fifos(struct dm_event_fifos *fifos) - syslog(LOG_ERR, "%s: Failed to create server fifo %s: %m.\n", - __func__, fifos->server_path); - (void) dm_prepare_selinux_context(NULL, 0); -- return 0; -+ goto fail; - } - - (void) dm_prepare_selinux_context(NULL, 0); -@@ -1281,31 +1282,49 @@ static int _open_fifos(struct dm_event_fifos *fifos) - if (chmod(fifos->client_path, 0600)) { - syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n", - fifos->client_path); -- return 0; -+ goto fail; - } - - if (chmod(fifos->server_path, 0600)) { - syslog(LOG_ERR, "Unable to set correct file permissions on %s: %m.\n", - fifos->server_path); -- return 0; -+ goto fail; - } - - /* Need to open read+write or we will block or fail */ - if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) { - syslog(LOG_ERR, "Failed to open fifo server %s: %m.\n", - fifos->server_path); -- return 0; -+ goto fail; -+ } -+ -+ if (fcntl(fifos->server, F_SETFD, FD_CLOEXEC) < 0) { -+ syslog(LOG_ERR, "Failed to set FD_CLOEXEC for fifo server %s: %m.\n", -+ fifos->server_path); -+ goto fail; - } - - /* Need to open read+write for select() to work. */ - if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) { - syslog(LOG_ERR, "Failed to open fifo client %s: %m", fifos->client_path); -- if (close(fifos->server)) -- syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path); -- return 0; -+ goto fail; -+ } -+ -+ if (fcntl(fifos->client, F_SETFD, FD_CLOEXEC) < 0) { -+ syslog(LOG_ERR, "Failed to set FD_CLOEXEC for fifo client %s: %m.\n", -+ fifos->client_path); -+ goto fail; - } - - return 1; -+fail: -+ if (fifos->server >= 0 && close(fifos->server)) -+ syslog(LOG_ERR, "Failed to close fifo server %s: %m", fifos->server_path); -+ -+ if (fifos->client >= 0 && close(fifos->client)) -+ syslog(LOG_ERR, "Failed to close fifo client %s: %m", fifos->client_path); -+ -+ return 0; - } - - /* diff --git a/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch b/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch deleted file mode 100644 index 8883b37..0000000 --- a/lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch +++ /dev/null @@ -1,41 +0,0 @@ - WHATS_NEW | 1 + - tools/pvscan.c | 15 +++++++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 12307ed..e247391 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Exit pvscan --cache immediately if cluster locking used or lvmetad not used. - Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. - Remove dependency on fedora-storage-init.service in lvm2 systemd units. - Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. -diff --git a/tools/pvscan.c b/tools/pvscan.c -index 3d5ddef..34ab792 100644 ---- a/tools/pvscan.c -+++ b/tools/pvscan.c -@@ -119,6 +119,21 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) - char *buf; - activation_handler handler = NULL; - -+ /* -+ * Return here immediately if lvmetad is not used. -+ * Also return if locking_type=3 (clustered) as we -+ * dont't support cluster + lvmetad yet. -+ * -+ * This is to avoid taking the global lock uselessly -+ * and to prevent hangs in clustered environment. -+ */ -+ /* TODO: Remove this once lvmetad + cluster supported! */ -+ if (find_config_tree_int(cmd, "global/locking_type", 1) == 3 || -+ !find_config_tree_int(cmd, "global/use_lvmetad", 0)) { -+ log_debug("_pvscan_lvmetad: immediate return"); -+ return ret; -+ } -+ - if (arg_count(cmd, activate_ARG)) { - if (arg_uint_value(cmd, activate_ARG, CHANGE_AAY) != CHANGE_AAY) { - log_error("Only --activate ay allowed with pvscan."); diff --git a/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch b/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch deleted file mode 100644 index bb1e09e..0000000 --- a/lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch +++ /dev/null @@ -1,50 +0,0 @@ -commit 2ac217d408470dcecb69b83d9cbf7a254747fa5b -Author: Peter Rajnoha -Date: Fri May 3 13:20:07 2013 +0200 - - udev: fire pvscan --cache properly on CHANGE event for MD devices - - Commit 756bcabbfe297688ba240a880bc2b55265ad33f0 restricted the - situations at which the LVM autoactivation fires - only on ADD - event for devices other than DM. However, this caused a problem - for MD devices... - - MD devices are activated in a very similar way as DM devices: - the MD dev is created on first appeareance of MD array member - (ADD event) and stays *inactive* until the array is complete. - Just then the MD dev turns to active state and this is reported - to userspace by CHANGE event. - - Unfortunately, we can't differentiate between the CHANGE event - coming from udev trigger/WATCH rule and CHANGE event coming from - the transition to active state - MD would need to add similar logic - we already use to detect this in DM world. For now, we just have - to enable pvscan --cache on *all* CHANGE events for MD so the - autoactivation of the LVM volumes on top of MD works. - - A downside of this is that a spurious CHANGE event for MD dev - can cause the LVM volumes on top of it to be automatically activated. - However, one should not open/change the device underneath until - the device above in the stack is removed! So this situation should - only happen if one opens the MD dev for read-write by mistake - (and hence firing the CHANGE event because of the WATCH udev rule), - or if calling udev trigger manually for the MD dev. - - (No WHATS_NEW here as this fixes the commit mentioned - above and which has not been released yet.) ---- - udev/69-dm-lvm-metad.rules.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in -index 66c58b3..a0e48a1 100644 ---- a/udev/69-dm-lvm-metad.rules.in -+++ b/udev/69-dm-lvm-metad.rules.in -@@ -21,6 +21,7 @@ SUBSYSTEM!="block", GOTO="lvm_end" - ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end" - - ACTION=="remove", GOTO="lvm_scan" -+ACTION=="change", KERNEL=="md[0-9]*", GOTO="lvm_scan" - - # If the PV is not a dm device, scan only after device addition (ADD event) - KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" diff --git a/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch b/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch deleted file mode 100644 index ddcf3d7..0000000 --- a/lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch +++ /dev/null @@ -1,62 +0,0 @@ -commit 0bf7bdf5216eae93cff7abb47a76b39270d71413 -Author: Peter Rajnoha -Date: Tue Apr 9 10:07:15 2013 +0200 - - 0 ---- - WHATS_NEW | 1 + - udev/10-dm.rules.in | 2 +- - udev/69-dm-lvm-metad.rules.in | 16 ++++++++++++---- - 3 files changed, 14 insertions(+), 5 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 67a24c7..c481e68 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. - Skip mlocking [vectors] on arm architecture. - Exit pvscan --cache immediately if cluster locking used or lvmetad not used. - Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. -diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in -index 29af467..cfee145 100644 ---- a/udev/10-dm.rules.in -+++ b/udev/10-dm.rules.in -@@ -45,7 +45,7 @@ ENV{DISK_RO}=="1", GOTO="dm_disable" - # in libdevmapper so we need to detect this and try to behave correctly. - # For such spurious events, regenerate all flags from current udev database content - # (this information would normally be inaccessible for spurious ADD and CHANGE events). --ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="dm_flags_done" -+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done" - IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG" - IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG" - IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG" -diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in -index 706c03b..b16a27a 100644 ---- a/udev/69-dm-lvm-metad.rules.in -+++ b/udev/69-dm-lvm-metad.rules.in -@@ -17,10 +17,18 @@ - SUBSYSTEM!="block", GOTO="lvm_end" - (LVM_EXEC_RULE) - --# Device-mapper devices are processed only on change event or on supported synthesized event. --KERNEL=="dm-[0-9]*", ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="lvm_end" -- - # Only process devices already marked as a PV - this requires blkid to be called before. --ENV{ID_FS_TYPE}=="LVM2_member|LVM1_member", RUN+="(LVM_EXEC)/lvm pvscan --cache --activate ay --major $major --minor $minor" -+ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end" -+ -+ACTION=="remove", GOTO="lvm_scan" -+ -+# If the PV is not a dm device, scan only after device addition (ADD event) -+KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end" -+ -+# If the PV is a dm device, scan only after proper mapping activation (CHANGE event + DM_ACTIVATION=1) -+KERNEL=="dm-[0-9]*", ENV{DM_ACTIVATION}!="1", GOTO="lvm_end" -+ -+LABEL="lvm_scan" -+RUN+="(LVM_EXEC)/lvm pvscan --cache --activate ay --major $major --minor $minor" - - LABEL="lvm_end" diff --git a/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch b/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch deleted file mode 100644 index a9dab21..0000000 --- a/lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch +++ /dev/null @@ -1,93 +0,0 @@ -commit 5025178f95b122c6862dc7d925a7c089f5fb61a8 -Author: Peter Rajnoha -Date: Tue May 14 11:05:50 2013 +0200 - - lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch ---- - WHATS_NEW | 1 + - scripts/blkdeactivate.sh.in | 30 ++++++++++++++++++++++++------ - 2 files changed, 25 insertions(+), 6 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 35c5e43..1bdfeb0 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ 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. - Fix possible deadlock when querying and updating lvmetad at the same time. -diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in -index 740bac5..be00c24 100644 ---- a/scripts/blkdeactivate.sh.in -+++ b/scripts/blkdeactivate.sh.in -@@ -39,6 +39,7 @@ LVM="@sbindir@/lvm" - LSBLK="/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT" - LSBLK_VARS="local devtype local kname local name local mnt" - LSBLK_READ="read -r devtype kname name mnt" -+SORT_MNT="/bin/sort -r -u -k 4" - - # Do not unmount mounted devices by default. - DO_UMOUNT=0 -@@ -122,9 +123,11 @@ is_top_level_device() { - device_umount () { - test -z "$mnt" && return 0; - -+ test "$devtype" != "lvm" && test "${kname:0:3}" != "dm-" && return 0 -+ - if test -z "${SKIP_UMOUNT_LIST["$mnt"]}" -a "$DO_UMOUNT" -eq "1"; then - echo " UMOUNT: unmounting $name ($kname) mounted on $mnt" -- $UMOUNT "$mnt" || add_device_to_skip_list -+ $UMOUNT "$(printf $mnt)" || add_device_to_skip_list - else - echo " [SKIP]: unmount of $name ($kname) mounted on $mnt" - add_device_to_skip_list -@@ -142,9 +145,6 @@ deactivate_holders () { - # check if the device not on the skip list already - test -z ${SKIP_DEVICE_LIST["$kname"]} || return 1 - -- # try to unmount it if mounted -- device_umount || return 1 -- - # try to deactivate the holder - test $skip -eq 1 && skip=0 && continue - deactivate || return 1 -@@ -226,7 +226,16 @@ deactivate_all() { - echo "Deactivating block devices:" - - if test $# -eq 0; then -- # Deactivate all devices -+ ####################### -+ # Process all devices # -+ ####################### -+ -+ # Unmount all relevant mountpoints first -+ while $LSBLK_READ; do -+ device_umount -+ done <<< "`$LSBLK | $SORT_MNT`" -+ -+ # Do deactivate - while $LSBLK_READ; do - # 'disk' is at the bottom already and it's a real device - test "$devtype" = "disk" && continue -@@ -249,8 +258,17 @@ deactivate_all() { - deactivate || skip=1 - done <<< "`$LSBLK -s`" - else -- # Deactivate only specified devices -+ ################################## -+ # Process only specified devices # -+ ################################## -+ - while test $# -ne 0; do -+ # Unmount all relevant mountpoints first -+ while $LSBLK_READ; do -+ device_umount -+ done <<< "`$LSBLK $1 | $SORT_MNT`" -+ -+ # Do deactivate - # Single dm device tree deactivation. - if test -b "$1"; then - $LSBLK_READ <<< "`$LSBLK --nodeps $1`" diff --git a/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch b/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch deleted file mode 100644 index 491a1e5..0000000 --- a/lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch +++ /dev/null @@ -1,175 +0,0 @@ -commit 5e247adf415942fcc0a5b888567f51a148619b65 -Author: Peter Rajnoha -Date: Tue May 14 11:03:46 2013 +0200 - - lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch ---- - WHATS_NEW | 1 + - lib/cache/lvmetad.c | 12 ++++------ - lib/cache/lvmetad.h | 3 ++- - test/shell/lvmetad-pvscan-nomda.sh | 49 ++++++++++++++++++++++++++++++++++++++ - tools/pvscan.c | 22 +++++++++++++++-- - 5 files changed, 76 insertions(+), 11 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 5231745..62efb53 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Fix crash in pvscan --cache -aay triggered by non-mda PV. - Fix lvm2app to return all property sizes in bytes. - Add lvm.conf option global/thin_disabled_features. - Add lvconvert support to swap thin pool metadata volume. -diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c -index 72e07fd..a636f43 100644 ---- a/lib/cache/lvmetad.c -+++ b/lib/cache/lvmetad.c -@@ -675,7 +675,7 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct - daemon_reply reply; - struct lvmcache_info *info; - struct dm_config_tree *pvmeta, *vgmeta; -- const char *status; -+ const char *status, *vgid; - int result; - - if (!lvmetad_active() || test_mode()) -@@ -724,11 +724,6 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct - NULL); - dm_config_destroy(vgmeta); - } else { -- if (handler) { -- log_error(INTERNAL_ERROR "Handler needs existing VG."); -- dm_free(pvmeta); -- return 0; -- } - /* There are no MDAs on this PV. */ - reply = _lvmetad_send("pv_found", "pvmeta = %t", pvmeta, NULL); - } -@@ -744,10 +739,11 @@ int lvmetad_pv_found(const struct id *pvid, struct device *device, const struct - - if (result && handler) { - status = daemon_reply_str(reply, "status", ""); -+ vgid = daemon_reply_str(reply, "vgid", ""); - if (!strcmp(status, "partial")) -- handler(vg, 1, CHANGE_AAY); -+ handler(_lvmetad_cmd, vgid, 1, CHANGE_AAY); - else if (!strcmp(status, "complete")) -- handler(vg, 0, CHANGE_AAY); -+ handler(_lvmetad_cmd, vgid, 0, CHANGE_AAY); - else if (!strcmp(status, "orphan")) - ; - else -diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h -index 5f0f552..c644069 100644 ---- a/lib/cache/lvmetad.h -+++ b/lib/cache/lvmetad.h -@@ -22,7 +22,8 @@ struct cmd_context; - struct dm_config_tree; - enum activation_change; - --typedef int (*activation_handler) (struct volume_group *vg, int partial, -+typedef int (*activation_handler) (struct cmd_context *cmd, -+ const char *vgid, int partial, - enum activation_change activate); - - #ifdef LVMETAD_SUPPORT -diff --git a/test/shell/lvmetad-pvscan-nomda.sh b/test/shell/lvmetad-pvscan-nomda.sh -new file mode 100644 -index 0000000..c04a275 ---- /dev/null -+++ b/test/shell/lvmetad-pvscan-nomda.sh -@@ -0,0 +1,49 @@ -+#!/bin/sh -+# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -+# -+# This copyrighted material is made available to anyone wishing to use, -+# modify, copy, or redistribute it subject to the terms and conditions -+# of the GNU General Public License v.2. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software Foundation, -+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+. lib/test -+ -+test -e LOCAL_LVMETAD || skip -+kill $(cat LOCAL_LVMETAD) -+rm LOCAL_LVMETAD -+ -+aux prepare_devs 2 -+ -+pvcreate --metadatacopies 0 $dev1 -+pvcreate --metadatacopies 1 $dev2 -+vgcreate $vg1 $dev1 $dev2 -+lvcreate -n foo -l 1 -an --zero n $vg1 -+ -+# start lvmetad but make sure it doesn't know about $dev1 or $dev2 -+aux disable_dev $dev1 -+aux disable_dev $dev2 -+aux prepare_lvmetad -+lvs -+mv LOCAL_LVMETAD XXX -+aux enable_dev $dev2 -+aux enable_dev $dev1 -+mv XXX LOCAL_LVMETAD -+ -+aux lvmconf 'global/use_lvmetad = 0' -+check inactive $vg1 foo -+aux lvmconf 'global/use_lvmetad = 1' -+ -+pvscan --cache $dev2 -aay -+ -+aux lvmconf 'global/use_lvmetad = 0' -+check inactive $vg1 foo -+aux lvmconf 'global/use_lvmetad = 1' -+ -+pvscan --cache $dev1 -aay -+ -+aux lvmconf 'global/use_lvmetad = 0' -+check active $vg1 foo -+aux lvmconf 'global/use_lvmetad = 1' -diff --git a/tools/pvscan.c b/tools/pvscan.c -index fbd524b..1e844c5 100644 ---- a/tools/pvscan.c -+++ b/tools/pvscan.c -@@ -91,18 +91,36 @@ static void _pvscan_display_single(struct cmd_context *cmd, - display_size(cmd, (uint64_t) (pv_pe_count(pv) - pv_pe_alloc_count(pv)) * pv_pe_size(pv))); - } - --static int _auto_activation_handler(struct volume_group *vg, int partial, -+static int _auto_activation_handler(struct cmd_context *cmd, -+ const char *vgid, int partial, - activation_change_t activate) - { -+ struct volume_group *vg; -+ int consistent = 0; -+ struct id vgid_raw; -+ - /* TODO: add support for partial and clustered VGs */ -- if (partial || vg_is_clustered(vg)) -+ if (partial) - return 1; - -+ id_read_format(&vgid_raw, vgid); -+ /* NB. This is safe because we know lvmetad is running and we won't hit -+ * disk. */ -+ if (!(vg = vg_read_internal(cmd, NULL, (const char *) &vgid_raw, 0, &consistent))) -+ return 1; -+ -+ if (vg_is_clustered(vg)) { -+ release_vg(vg); -+ return 1; -+ } -+ - if (!vgchange_activate(vg->cmd, vg, activate)) { - log_error("%s: autoactivation failed.", vg->name); -+ release_vg(vg); - return 0; - } - -+ release_vg(vg); - return 1; - } - diff --git a/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch b/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch deleted file mode 100644 index 2ad182b..0000000 --- a/lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit f03877ecb56f32d91dd98e8e3331164f472f8b77 -Author: Peter Rajnoha -Date: Tue May 14 11:48:51 2013 +0200 - - lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch ---- - WHATS_NEW_DM | 1 + - tools/dmsetup.c | 8 +++++--- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index 30d01f9..34a0f70 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,5 +1,6 @@ - Version 1.02.78 - - =================================== -+ Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68). - Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). - Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. - Automatically deactivate failed preloaded dm tree node. -diff --git a/tools/dmsetup.c b/tools/dmsetup.c -index 196c170..2dc3abd 100644 ---- a/tools/dmsetup.c -+++ b/tools/dmsetup.c -@@ -3749,9 +3749,6 @@ static int _process_switches(int *argc, char ***argv, const char *dev_dir) - return 0; - } - -- if (!_process_options(_string_args[OPTIONS_ARG])) -- return 0; -- - if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) { - fprintf(stderr, "--table and --notable are incompatible.\n"); - return 0; -@@ -3824,6 +3821,11 @@ int main(int argc, char **argv) - if (!strcmp(cmd->name, "mangle")) - dm_set_name_mangling_mode(DM_STRING_MANGLING_NONE); - -+ if (!_process_options(_string_args[OPTIONS_ARG])) { -+ fprintf(stderr, "Couldn't process command line.\n"); -+ goto out; -+ } -+ - if (_switches[COLS_ARG]) { - if (!_report_init(cmd)) - goto out; diff --git a/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch b/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch deleted file mode 100644 index 446e50a..0000000 --- a/lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit 5bad6200b66259dde0c1cf3bd6295e65a5ade3c9 -Author: Peter Rajnoha -Date: Tue May 14 12:57:54 2013 +0200 - - lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch ---- - lib/cache/lvmetad.c | 8 +++++++- - lib/metadata/metadata.c | 4 ++-- - lib/metadata/metadata.h | 3 +++ - 3 files changed, 12 insertions(+), 3 deletions(-) - -diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c -index a636f43..d8ad4dd 100644 ---- a/lib/cache/lvmetad.c -+++ b/lib/cache/lvmetad.c -@@ -354,14 +354,20 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna - if ((info = lvmcache_info_from_pvid((const char *)&pvl->pv->id, 0))) { - pvl->pv->label_sector = lvmcache_get_label(info)->sector; - pvl->pv->dev = lvmcache_device(info); -+ if (!pvl->pv->dev) -+ pvl->pv->status |= MISSING_PV; -+ else -+ check_reappeared_pv(vg, pvl->pv); - if (!lvmcache_fid_add_mdas_pv(info, fid)) { - vg = NULL; - goto_out; /* FIXME error path */ - } -- } /* else probably missing */ -+ } else -+ pvl->pv->status |= MISSING_PV; /* probably missing */ - } - - lvmcache_update_vg(vg, 0); -+ vg_mark_partial_lvs(vg, 1); - } - - out: -diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c -index c210a63..2cca93c 100644 ---- a/lib/metadata/metadata.c -+++ b/lib/metadata/metadata.c -@@ -2870,8 +2870,8 @@ int vg_missing_pv_count(const struct volume_group *vg) - return ret; - } - --static void check_reappeared_pv(struct volume_group *correct_vg, -- struct physical_volume *pv) -+void check_reappeared_pv(struct volume_group *correct_vg, -+ struct physical_volume *pv) - { - struct pv_list *pvl; - -diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h -index 19bf742..630c4ca 100644 ---- a/lib/metadata/metadata.h -+++ b/lib/metadata/metadata.h -@@ -492,4 +492,7 @@ int is_mirror_image_removable(struct logical_volume *mimage_lv, void *baton); - uint64_t find_min_mda_size(struct dm_list *mdas); - char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags); - -+void check_reappeared_pv(struct volume_group *correct_vg, -+ struct physical_volume *pv); -+ - #endif diff --git a/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch b/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch deleted file mode 100644 index 3b2281b..0000000 --- a/lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch +++ /dev/null @@ -1,44 +0,0 @@ -commit 191de7c40463b04ef80b424982221784df0a99ed -Author: Peter Rajnoha -Date: Tue May 14 11:02:39 2013 +0200 - - lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch ---- - lib/metadata/lv_manip.c | 10 ++-------- - test/shell/lvcreate-usage.sh | 2 ++ - 2 files changed, 4 insertions(+), 8 deletions(-) - -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index a59e03f..557df58 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -4348,14 +4348,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l - log_warn("WARNING: See global/mirror_segtype_default in lvm.conf."); - } - -- if (!lv_is_active(org)) { -- log_error("Check for existence of active snapshot " -- "origin '%s' failed.", org->name); -- return NULL; -- } -- origin_active = 1; -- -- if (vg_is_clustered(vg) && -+ if ((origin_active = lv_is_active(org)) && -+ vg_is_clustered(vg) && - !lv_is_active_exclusive_locally(org)) { - log_error("%s must be active exclusively to" - " create snapshot", org->name); -diff --git a/test/shell/lvcreate-usage.sh b/test/shell/lvcreate-usage.sh -index ddde401..c9c906a 100644 ---- a/test/shell/lvcreate-usage.sh -+++ b/test/shell/lvcreate-usage.sh -@@ -64,6 +64,8 @@ lvcreate -l1 -n $lv3 $vg - not lvcreate -l1 -n $lv4 $vg - - lvremove -ff $vg/$lv3 -+# check snapshot of inactive origin -+lvchange -an $vg/$lv1 - lvcreate -l1 -s -n $lv3 $vg/$lv1 - not lvcreate -l1 -n $lv4 $vg - not lvcreate -l1 -m1 -n $lv4 $vg diff --git a/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch b/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch deleted file mode 100644 index 62f4307..0000000 --- a/lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch +++ /dev/null @@ -1,35 +0,0 @@ -commit 509ba58eaa537a8db2e0bd41d8c56c52a68e8512 -Author: Peter Rajnoha -Date: Tue May 14 11:04:30 2013 +0200 - - lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch ---- - WHATS_NEW | 1 + - daemons/lvmetad/lvmetad-core.c | 2 +- - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 25e07ee..4728466 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Fix possible deadlock when querying and updating lvmetad at the same time. - Avoid a global lock in pvs when lvmetad is in use. - Fix crash in pvscan --cache -aay triggered by non-mda PV. - Fix lvm2app to return all property sizes in bytes. -diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c -index 0a1c884..3f417da 100644 ---- a/daemons/lvmetad/lvmetad-core.c -+++ b/daemons/lvmetad/lvmetad-core.c -@@ -675,8 +675,8 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid - - lock_vgid_to_metadata(s); - old = dm_hash_lookup(s->vgid_to_metadata, _vgid); -- lock_vg(s, _vgid); - unlock_vgid_to_metadata(s); -+ lock_vg(s, _vgid); - - seq = dm_config_find_int(metadata, "metadata/seqno", -1); - diff --git a/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch b/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch deleted file mode 100644 index 5ca87f5..0000000 --- a/lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch +++ /dev/null @@ -1,54 +0,0 @@ -commit 8f17dc8027f1d9fd188468c26eb8c0a9957cc9cb -Author: Peter Rajnoha -Date: Tue May 14 11:04:52 2013 +0200 - - lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch ---- - WHATS_NEW | 1 + - daemons/lvmetad/lvmetad-core.c | 14 +++++++++----- - 2 files changed, 10 insertions(+), 5 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 4728466..20a8125 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Fix possible race while removing metadata from lvmetad. - Fix possible deadlock when querying and updating lvmetad at the same time. - Avoid a global lock in pvs when lvmetad is in use. - Fix crash in pvscan --cache -aay triggered by non-mda PV. -diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c -index 3f417da..fed9296 100644 ---- a/daemons/lvmetad/lvmetad-core.c -+++ b/daemons/lvmetad/lvmetad-core.c -@@ -605,19 +605,23 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids) - lock_vgid_to_metadata(s); - old = dm_hash_lookup(s->vgid_to_metadata, vgid); - oldname = dm_hash_lookup(s->vgid_to_vgname, vgid); -- unlock_vgid_to_metadata(s); - -- if (!old) -+ if (!old) { -+ unlock_vgid_to_metadata(s); - return 0; -+ } -+ - assert(oldname); - -- if (update_pvids) -- /* FIXME: What should happen when update fails */ -- update_pvid_to_vgid(s, old, "#orphan", 0); - /* need to update what we have since we found a newer version */ - dm_hash_remove(s->vgid_to_metadata, vgid); - dm_hash_remove(s->vgid_to_vgname, vgid); - dm_hash_remove(s->vgname_to_vgid, oldname); -+ unlock_vgid_to_metadata(s); -+ -+ if (update_pvids) -+ /* FIXME: What should happen when update fails */ -+ update_pvid_to_vgid(s, old, "#orphan", 0); - dm_config_destroy(old); - return 1; - } diff --git a/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch b/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch deleted file mode 100644 index f565786..0000000 --- a/lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch +++ /dev/null @@ -1,182 +0,0 @@ -commit 811db05e50b042c7ce3dc3ca9cfd3eccac464caa -Author: Peter Rajnoha -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); diff --git a/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch b/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch deleted file mode 100644 index 450196e..0000000 --- a/lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git a/WHATS_NEW b/WHATS_NEW -index c0ae3df..5887ec7 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,7 @@ -+Version 2.02.99 - -+=================================== -+ Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. -+ - Version 2.02.98 - 15th October 2012 - =================================== - Switch from DEBUG() to DEBUGLOG() in lvmetad as -DDEBUG is already used. -diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c -index d7f8ece..eb1a90b 100644 ---- a/lib/commands/toolcontext.c -+++ b/lib/commands/toolcontext.c -@@ -413,7 +413,15 @@ static int _process_config(struct cmd_context *cmd) - lvmetad_set_socket(lvmetad_socket); - cn = find_config_tree_node(cmd, "devices/global_filter"); - lvmetad_set_token(cn ? cn->v : NULL); -- lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); -+ -+ if (find_config_tree_int(cmd, "global/locking_type", 1) == 3 && -+ find_config_tree_int(cmd, "global/use_lvmetad", 1)) { -+ log_warn("WARNING: configuration setting use_lvmetad overriden to 0 due to locking_type 3. " -+ "Clustered environment not supported by lvmetad yet."); -+ lvmetad_set_active(0); -+ } else -+ lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); -+ - lvmetad_init(cmd); - - return 1; -diff --git a/test/shell/lvmetad-no-cluster.sh b/test/shell/lvmetad-no-cluster.sh -new file mode 100644 -index 0000000..db68e77 ---- /dev/null -+++ b/test/shell/lvmetad-no-cluster.sh -@@ -0,0 +1,19 @@ -+#!/bin/sh -+# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -+# -+# This copyrighted material is made available to anyone wishing to use, -+# modify, copy, or redistribute it subject to the terms and conditions -+# of the GNU General Public License v.2. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software Foundation, -+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+. lib/test -+ -+test -e LOCAL_CLVMD || skip -+aux prepare_vg 2 -+aux prepare_lvmetad -+vgs -vv 2> errs -+cat errs -+grep 'use_lvmetad' errs diff --git a/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch b/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch deleted file mode 100644 index 9709d34..0000000 --- a/lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch +++ /dev/null @@ -1,111 +0,0 @@ -diff --git a/WHATS_NEW b/WHATS_NEW -index 5887ec7..d0e0cd4 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Initialize lvmetad lazily to avoid early socket access on config overrides. - Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. - - Version 2.02.98 - 15th October 2012 -diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c -index 6a374ac..72e07fd 100644 ---- a/lib/cache/lvmetad.c -+++ b/lib/cache/lvmetad.c -@@ -33,7 +33,8 @@ static struct cmd_context *_lvmetad_cmd = NULL; - - void lvmetad_disconnect(void) - { -- daemon_close(_lvmetad); -+ if (_lvmetad_connected) -+ daemon_close(_lvmetad); - _lvmetad_connected = 0; - _lvmetad_cmd = NULL; - } -@@ -41,19 +42,25 @@ void lvmetad_disconnect(void) - void lvmetad_init(struct cmd_context *cmd) - { - if (!_lvmetad_use && !access(LVMETAD_PIDFILE, F_OK)) -- log_warn("WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!"); -+ log_warn("WARNING: lvmetad is running but disabled." -+ " Restart lvmetad before enabling it!"); -+ _lvmetad_cmd = cmd; -+} -+ -+static void _lvmetad_connect() -+{ - if (_lvmetad_use && _lvmetad_socket && !_lvmetad_connected) { - assert(_lvmetad_socket); - _lvmetad = lvmetad_open(_lvmetad_socket); -- if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) { -+ if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) - _lvmetad_connected = 1; -- _lvmetad_cmd = cmd; -- } - } - } - - void lvmetad_warning(void) - { -+ if (!_lvmetad_connected) -+ _lvmetad_connect(); - if (_lvmetad_use && (_lvmetad.socket_fd < 0 || _lvmetad.error)) - log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.", - strerror(_lvmetad.error)); -@@ -61,7 +68,11 @@ void lvmetad_warning(void) - - int lvmetad_active(void) - { -- return _lvmetad_use && _lvmetad_connected; -+ if (!_lvmetad_use) -+ return 0; -+ if (!_lvmetad_connected) -+ _lvmetad_connect(); -+ return _lvmetad_connected; - } - - void lvmetad_set_active(int active) -@@ -873,6 +884,11 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler) - char *future_token; - int was_silent; - -+ if (!lvmetad_active()) { -+ log_error("Cannot proceed since lvmetad is not active."); -+ return 0; -+ } -+ - if (!(iter = dev_iter_create(cmd->lvmetad_filter, 1))) { - log_error("dev_iter creation failed"); - return 0; -diff --git a/test/shell/lvmetad-override.sh b/test/shell/lvmetad-override.sh -new file mode 100644 -index 0000000..3fb281a ---- /dev/null -+++ b/test/shell/lvmetad-override.sh -@@ -0,0 +1,25 @@ -+#!/bin/sh -+# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -+# -+# This copyrighted material is made available to anyone wishing to use, -+# modify, copy, or redistribute it subject to the terms and conditions -+# of the GNU General Public License v.2. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software Foundation, -+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+. lib/test -+ -+test -e LOCAL_LVMETAD || skip -+aux prepare_pvs 2 -+ -+vgcreate $vg1 $dev1 $dev2 -+lvchange -ay $vg1 2>&1 | not grep "Failed to connect" -+kill $(cat LOCAL_LVMETAD) -+lvchange -ay $vg1 2>&1 | grep "Failed to connect" -+lvchange -ay $vg1 --sysinit 2>&1 | not grep "Failed to connect" -+lvchange -ay $vg1 --config 'global { use_lvmetad = 0 }' 2>&1 | not grep "Failed to connect" -+aux lvmconf "global/use_lvmetad = 0" -+lvchange -ay $vg1 --config 'global { use_lvmetad = 1 }' 2>&1 | grep "Failed to connect" -+ diff --git a/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch b/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch deleted file mode 100644 index 9e5a178..0000000 --- a/lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch +++ /dev/null @@ -1,86 +0,0 @@ -commit 98c5eb308690d990b957012db9d48b6722ea93cb -Author: Peter Rajnoha -Date: Tue May 14 12:47:24 2013 +0200 - - lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch ---- - WHATS_NEW | 1 + - daemons/lvmetad/lvmetad-core.c | 21 +++++++++++++-------- - 2 files changed, 14 insertions(+), 8 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 20a8125..35c5e43 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Fix a crash-inducing race condition in lvmetad while updating metadata. - Fix possible race while removing metadata from lvmetad. - Fix possible deadlock when querying and updating lvmetad at the same time. - Avoid a global lock in pvs when lvmetad is in use. -diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c -index fed9296..1f855a7 100644 ---- a/daemons/lvmetad/lvmetad-core.c -+++ b/daemons/lvmetad/lvmetad-core.c -@@ -450,7 +450,8 @@ static response vg_lookup(lvmetad_state *s, request r) - - DEBUGLOG(s, "vg_lookup: updated uuid = %s, name = %s", uuid, name); - -- if (!uuid) -+ /* Check the name here. */ -+ if (!uuid || !name) - return reply_unknown("VG not found"); - - cft = lock_vg(s, uuid); -@@ -679,16 +680,14 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid - - lock_vgid_to_metadata(s); - old = dm_hash_lookup(s->vgid_to_metadata, _vgid); -+ oldname = dm_hash_lookup(s->vgid_to_vgname, _vgid); - unlock_vgid_to_metadata(s); - lock_vg(s, _vgid); - - seq = dm_config_find_int(metadata, "metadata/seqno", -1); - -- if (old) { -+ if (old) - haveseq = dm_config_find_int(old->root, "metadata/seqno", -1); -- oldname = dm_hash_lookup(s->vgid_to_vgname, _vgid); -- assert(oldname); -- } - - if (seq < 0) - goto out; -@@ -740,7 +739,7 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid - if (haveseq >= 0 && haveseq < seq) { - INFO(s, "Updating metadata for %s at %d to %d", _vgid, haveseq, seq); - /* temporarily orphan all of our PVs */ -- remove_metadata(s, vgid, 1); -+ update_pvid_to_vgid(s, old, "#orphan", 0); - } - - lock_vgid_to_metadata(s); -@@ -750,14 +749,20 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid - dm_hash_insert(s->vgid_to_metadata, vgid, cft) && - dm_hash_insert(s->vgid_to_vgname, vgid, cfgname) && - dm_hash_insert(s->vgname_to_vgid, name, (void*) vgid)) ? 1 : 0; -+ -+ if (retval && oldname && strcmp(name, oldname)) -+ dm_hash_remove(s->vgname_to_vgid, oldname); -+ -+ if (haveseq >= 0 && haveseq < seq) -+ dm_config_destroy(old); -+ - unlock_vgid_to_metadata(s); - - if (retval) -- /* FIXME: What should happen when update fails */ - retval = update_pvid_to_vgid(s, cft, vgid, 1); - - unlock_pvid_to_vgid(s); --out: -+out: /* FIXME: We should probably abort() on partial failures. */ - if (!retval && cft) - dm_config_destroy(cft); - unlock_vg(s, _vgid); diff --git a/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch b/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch deleted file mode 100644 index 1608ed9..0000000 --- a/lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index 2d0b05c..3f8d9c9 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,3 +1,7 @@ -+Version 1.02.78 - -+=================================== -+ Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. -+ - Version 1.02.77 - 15th October 2012 - =================================== - Support unmount of thin volumes from pool above thin pool threshold. -diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c -index b8533ed..afdac89 100644 ---- a/libdm/libdm-common.c -+++ b/libdm/libdm-common.c -@@ -1838,6 +1838,7 @@ 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; - *cookie = 0; -+ dmt->cookie_set = 1; - - return 1; - } -@@ -2207,6 +2208,7 @@ int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) - - if (!dm_udev_get_sync_support()) { - *cookie = 0; -+ dmt->cookie_set = 1; - return 1; - } - diff --git a/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch b/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch deleted file mode 100644 index c498492..0000000 --- a/lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch +++ /dev/null @@ -1,470 +0,0 @@ -commit 0e47639a44e1630250ea10643f5a440281edfdce -Author: Andy Grover -Date: Wed Oct 17 12:55:25 2012 -0700 - - python-lvm: Implement proper refcounting for parent objects - - Our object nesting: - - lib -> VG -> LV -> lvseg - -> PV -> pvseg - - Implement refcounting and checks to ensure parent objects are not - dealloced before their children. Also ensure calls to self or child's - methods are handled cleanly for objects that have been closed or removed. - - Ensure all functions that are object methods have a first parameter named - 'self', for consistency - - Rename local vars that reference a Python object to '*obj', in order to - differentiate from liblvm handles - - Fix a misspelled pv method name - - Signed-off-by: Andy Grover ---- - python/liblvm.c | 152 +++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 106 insertions(+), 46 deletions(-) - -diff --git a/python/liblvm.c b/python/liblvm.c -index 8a73ced..024d769 100644 ---- a/python/liblvm.c -+++ b/python/liblvm.c -@@ -35,21 +35,25 @@ typedef struct { - typedef struct { - PyObject_HEAD - lv_t lv; /* lv handle */ -+ vgobject *parent_vgobj; - } lvobject; - - typedef struct { - PyObject_HEAD - pv_t pv; /* pv handle */ -+ vgobject *parent_vgobj; - } pvobject; - - typedef struct { - PyObject_HEAD - lvseg_t lv_seg; /* lv segment handle */ -+ lvobject *parent_lvobj; - } lvsegobject; - - typedef struct { - PyObject_HEAD - pvseg_t pv_seg; /* pv segment handle */ -+ pvobject *parent_pvobj; - } pvsegobject; - - static PyTypeObject LibLVMvgType; -@@ -347,6 +351,7 @@ liblvm_vg_dealloc(vgobject *self) - - #define VG_VALID(vgobject) \ - do { \ -+ LVM_VALID(); \ - if (!vgobject->vg) { \ - PyErr_SetString(PyExc_UnboundLocalError, "VG object invalid"); \ - return NULL; \ -@@ -785,18 +790,18 @@ liblvm_lvm_vg_set_extent_size(vgobject *self, PyObject *args) - } - - static PyObject * --liblvm_lvm_vg_list_lvs(vgobject *vg) -+liblvm_lvm_vg_list_lvs(vgobject *self) - { - struct dm_list *lvs; - struct lvm_lv_list *lvl; - PyObject * pytuple; -- lvobject * self; -+ lvobject * lvobj; - int i = 0; - -- VG_VALID(vg); -+ VG_VALID(self); - - /* unlike other LVM api calls, if there are no results, we get NULL */ -- lvs = lvm_vg_list_lvs(vg->vg); -+ lvs = lvm_vg_list_lvs(self->vg); - if (!lvs) - return Py_BuildValue("()"); - -@@ -806,14 +811,17 @@ liblvm_lvm_vg_list_lvs(vgobject *vg) - - dm_list_iterate_items(lvl, lvs) { - /* Create and initialize the object */ -- self = PyObject_New(lvobject, &LibLVMlvType); -- if (!self) { -+ lvobj = PyObject_New(lvobject, &LibLVMlvType); -+ if (!lvobj) { - Py_DECREF(pytuple); - return NULL; - } - -- self->lv = lvl->lv; -- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); -+ lvobj->parent_vgobj = self; -+ Py_INCREF(lvobj->parent_vgobj); -+ -+ lvobj->lv = lvl->lv; -+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvobj); - i++; - } - -@@ -849,49 +857,53 @@ liblvm_lvm_vg_get_tags(vgobject *self) - } - - static PyObject * --liblvm_lvm_vg_create_lv_linear(vgobject *vg, PyObject *args) -+liblvm_lvm_vg_create_lv_linear(vgobject *self, PyObject *args) - { - const char *vgname; - uint64_t size; -- lvobject *self; -+ lvobject *lvobj; - -- VG_VALID(vg); -+ VG_VALID(self); - - if (!PyArg_ParseTuple(args, "sl", &vgname, &size)) { - return NULL; - } - -- if ((self = PyObject_New(lvobject, &LibLVMlvType)) == NULL) -+ if ((lvobj = PyObject_New(lvobject, &LibLVMlvType)) == NULL) - return NULL; - -- if ((self->lv = lvm_vg_create_lv_linear(vg->vg, vgname, size))== NULL) { -+ if ((lvobj->lv = lvm_vg_create_lv_linear(self->vg, vgname, size)) == NULL) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); -- Py_DECREF(self); -+ Py_DECREF(lvobj); - return NULL; - } - -- return (PyObject *)self; -+ lvobj->parent_vgobj = self; -+ Py_INCREF(lvobj->parent_vgobj); -+ -+ return (PyObject *)lvobj; - } - - static void - liblvm_lv_dealloc(lvobject *self) - { -+ Py_DECREF(self->parent_vgobj); - PyObject_Del(self); - } - - static PyObject * --liblvm_lvm_vg_list_pvs(vgobject *vg) -+liblvm_lvm_vg_list_pvs(vgobject *self) - { - struct dm_list *pvs; - struct lvm_pv_list *pvl; - PyObject * pytuple; -- pvobject * self; -+ pvobject * pvobj; - int i = 0; - -- VG_VALID(vg); -+ VG_VALID(self); - - /* unlike other LVM api calls, if there are no results, we get NULL */ -- pvs = lvm_vg_list_pvs(vg->vg); -+ pvs = lvm_vg_list_pvs(self->vg); - if (!pvs) - return Py_BuildValue("()"); - -@@ -901,14 +913,17 @@ liblvm_lvm_vg_list_pvs(vgobject *vg) - - dm_list_iterate_items(pvl, pvs) { - /* Create and initialize the object */ -- self = PyObject_New(pvobject, &LibLVMpvType); -- if (!self) { -+ pvobj = PyObject_New(pvobject, &LibLVMpvType); -+ if (!pvobj) { - Py_DECREF(pytuple); - return NULL; - } - -- self->pv = pvl->pv; -- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); -+ pvobj->parent_vgobj = self; -+ Py_INCREF(pvobj->parent_vgobj); -+ -+ pvobj->pv = pvl->pv; -+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) pvobj); - i++; - } - -@@ -922,7 +937,7 @@ static PyObject * - liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) - { - const char *id; -- lvobject *rc; -+ lvobject *lvobj; - lv_t lv = NULL; - - VG_VALID(self); -@@ -936,13 +951,16 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) - return NULL; - } - -- rc = PyObject_New(lvobject, &LibLVMlvType); -- if (!rc) { -+ lvobj = PyObject_New(lvobject, &LibLVMlvType); -+ if (!lvobj) { - return NULL; - } - -- rc->lv = lv; -- return (PyObject *)rc; -+ lvobj->parent_vgobj = self; -+ Py_INCREF(lvobj->parent_vgobj); -+ -+ lvobj->lv = lv; -+ return (PyObject *)lvobj; - } - - static PyObject * -@@ -980,6 +998,7 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) - return NULL; - } - -+ Py_INCREF(self); - rc->pv = pv; - return (PyObject *)rc; - } -@@ -999,6 +1018,7 @@ liblvm_lvm_pv_from_uuid(vgobject *self, PyObject *arg) - static void - liblvm_pv_dealloc(pvobject *self) - { -+ Py_DECREF(self->parent_vgobj); - PyObject_Del(self); - } - -@@ -1006,6 +1026,7 @@ liblvm_pv_dealloc(pvobject *self) - - #define LV_VALID(lvobject) \ - do { \ -+ VG_VALID(lvobject->parent_vgobj); \ - if (!lvobject->lv) { \ - PyErr_SetString(PyExc_UnboundLocalError, "LV object invalid"); \ - return NULL; \ -@@ -1242,17 +1263,17 @@ liblvm_lvm_lv_resize(lvobject *self, PyObject *args) - } - - static PyObject * --liblvm_lvm_lv_list_lvsegs(lvobject *lv) -+liblvm_lvm_lv_list_lvsegs(lvobject *self) - { - struct dm_list *lvsegs; - lvseg_list_t *lvsegl; - PyObject * pytuple; -- lvsegobject *self; -+ lvsegobject *lvsegobj; - int i = 0; - -- LV_VALID(lv); -+ LV_VALID(self); - -- lvsegs = lvm_lv_list_lvsegs(lv->lv); -+ lvsegs = lvm_lv_list_lvsegs(self->lv); - if (!lvsegs) { - return Py_BuildValue("()"); - } -@@ -1263,14 +1284,17 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - - dm_list_iterate_items(lvsegl, lvsegs) { - /* Create and initialize the object */ -- self = PyObject_New(lvsegobject, &LibLVMlvsegType); -- if (!self) { -+ lvsegobj = PyObject_New(lvsegobject, &LibLVMlvsegType); -+ if (!lvsegobj) { - Py_DECREF(pytuple); - return NULL; - } - -- self->lv_seg = lvsegl->lvseg; -- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); -+ lvsegobj->parent_lvobj = self; -+ Py_INCREF(lvsegobj->parent_lvobj); -+ -+ lvsegobj->lv_seg = lvsegl->lvseg; -+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) lvsegobj); - i++; - } - -@@ -1281,7 +1305,8 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - - #define PV_VALID(pvobject) \ - do { \ -- if (!pvobject->pv || !libh) { \ -+ VG_VALID(pvobject->parent_vgobj); \ -+ if (!pvobject->pv) { \ - PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \ - return NULL; \ - } \ -@@ -1290,18 +1315,24 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - static PyObject * - liblvm_lvm_pv_get_name(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("s", lvm_pv_get_name(self->pv)); - } - - static PyObject * - liblvm_lvm_pv_get_uuid(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("s", lvm_pv_get_uuid(self->pv)); - } - - static PyObject * - liblvm_lvm_pv_get_mda_count(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("l", lvm_pv_get_mda_count(self->pv)); - } - -@@ -1323,18 +1354,24 @@ liblvm_lvm_pv_get_property(pvobject *self, PyObject *args) - static PyObject * - liblvm_lvm_pv_get_dev_size(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("l", lvm_pv_get_dev_size(self->pv)); - } - - static PyObject * - liblvm_lvm_pv_get_size(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("l", lvm_pv_get_size(self->pv)); - } - - static PyObject * - liblvm_lvm_pv_get_free(pvobject *self) - { -+ PV_VALID(self); -+ - return Py_BuildValue("l", lvm_pv_get_free(self->pv)); - } - -@@ -1344,6 +1381,8 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) - uint64_t new_size; - int rval; - -+ PV_VALID(self); -+ - if (!PyArg_ParseTuple(args, "l", &new_size)) { - return NULL; - } -@@ -1358,17 +1397,17 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) - } - - static PyObject * --liblvm_lvm_lv_list_pvsegs(pvobject *pv) -+liblvm_lvm_pv_list_pvsegs(pvobject *self) - { - struct dm_list *pvsegs; - pvseg_list_t *pvsegl; - PyObject *pytuple; -- pvsegobject *self; -+ pvsegobject *pvsegobj; - int i = 0; - -- PV_VALID(pv); -+ PV_VALID(self); - -- pvsegs = lvm_pv_list_pvsegs(pv->pv); -+ pvsegs = lvm_pv_list_pvsegs(self->pv); - if (!pvsegs) { - return Py_BuildValue("()"); - } -@@ -1379,14 +1418,17 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) - - dm_list_iterate_items(pvsegl, pvsegs) { - /* Create and initialize the object */ -- self = PyObject_New(pvsegobject, &LibLVMpvsegType); -- if (!self) { -+ pvsegobj = PyObject_New(pvsegobject, &LibLVMpvsegType); -+ if (!pvsegobj) { - Py_DECREF(pytuple); - return NULL; - } - -- self->pv_seg = pvsegl->pvseg; -- PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); -+ pvsegobj->parent_pvobj = self; -+ Py_INCREF(pvsegobj->parent_pvobj); -+ -+ pvsegobj->pv_seg = pvsegl->pvseg; -+ PyTuple_SET_ITEM(pytuple, i, (PyObject *) pvsegobj); - i++; - } - -@@ -1395,9 +1437,16 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) - - /* LV seg methods */ - -+/* -+ * No way to close/destroy an lvseg, just need to make sure parents are -+ * still good -+ */ -+#define LVSEG_VALID(lvsegobject) LV_VALID(lvsegobject->parent_lvobj) -+ - static void - liblvm_lvseg_dealloc(lvsegobject *self) - { -+ Py_DECREF(self->parent_lvobj); - PyObject_Del(self); - } - -@@ -1407,6 +1456,8 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) - const char *name; - struct lvm_property_value prop_value; - -+ LVSEG_VALID(self); -+ - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - -@@ -1416,9 +1467,16 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) - - /* PV seg methods */ - -+/* -+ * No way to close/destroy a pvseg, just need to make sure parents are -+ * still good -+ */ -+#define PVSEG_VALID(pvsegobject) PV_VALID(pvsegobject->parent_pvobj) -+ - static void - liblvm_pvseg_dealloc(pvsegobject *self) - { -+ Py_DECREF(self->parent_pvobj); - PyObject_Del(self); - } - -@@ -1428,6 +1486,8 @@ liblvm_lvm_pvseg_get_property(pvsegobject *self, PyObject *args) - const char *name; - struct lvm_property_value prop_value; - -+ PVSEG_VALID(self); -+ - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - -@@ -1522,7 +1582,7 @@ static PyMethodDef liblvm_pv_methods[] = { - { "getDevSize", (PyCFunction)liblvm_lvm_pv_get_dev_size, METH_NOARGS }, - { "getFree", (PyCFunction)liblvm_lvm_pv_get_free, METH_NOARGS }, - { "resize", (PyCFunction)liblvm_lvm_pv_resize, METH_VARARGS }, -- { "listPVsegs", (PyCFunction)liblvm_lvm_lv_list_pvsegs, METH_NOARGS }, -+ { "listPVsegs", (PyCFunction)liblvm_lvm_pv_list_pvsegs, METH_NOARGS }, - { NULL, NULL} /* sentinel */ - }; - diff --git a/lvm2-2_02_99-python-remove-liblvm-object.patch b/lvm2-2_02_99-python-remove-liblvm-object.patch deleted file mode 100644 index aef2284..0000000 --- a/lvm2-2_02_99-python-remove-liblvm-object.patch +++ /dev/null @@ -1,793 +0,0 @@ -commit 84a4d4b970bb9aaf540ad5fa82276b1caf5aa9bd -Author: Andy Grover -Date: Mon Oct 15 13:26:01 2012 -0700 - - python-lvm: Remove liblvm object - - Instead of requiring users to create a liblvm object, and then calling - methods on it, the module acquires a liblvm handle as part of - initialization. This makes it impossible to instantiate a liblvm object - with a different systemdir, but there is an alternate envvar method for - that obscure use case. - - Signed-off-by: Andy Grover ---- - python/liblvm.c | 269 ++++++++++++++++++++------------------------------------ - 1 file changed, 97 insertions(+), 172 deletions(-) - -diff --git a/python/liblvm.c b/python/liblvm.c -index cbfa170..4518cf4 100644 ---- a/python/liblvm.c -+++ b/python/liblvm.c -@@ -24,39 +24,32 @@ - #include - #include "lvm2app.h" - --typedef struct { -- PyObject_HEAD -- lvm_t libh; /* lvm lib handle */ --} lvmobject; -+static lvm_t libh; -+ - - typedef struct { - PyObject_HEAD - vg_t vg; /* vg handle */ -- lvmobject *lvm_obj; - } vgobject; - - typedef struct { - PyObject_HEAD - lv_t lv; /* lv handle */ -- lvmobject *lvm_obj; - } lvobject; - - typedef struct { - PyObject_HEAD - pv_t pv; /* pv handle */ -- lvmobject *lvm_obj; - } pvobject; - - typedef struct { - PyObject_HEAD - lvseg_t lv_seg; /* lv segment handle */ -- lvmobject *lvm_obj; - } lvsegobject; - - typedef struct { - PyObject_HEAD - pvseg_t pv_seg; /* pv segment handle */ -- lvmobject *lvm_obj; - } pvsegobject; - - static PyTypeObject LibLVMvgType; -@@ -67,100 +60,51 @@ static PyTypeObject LibLVMpvsegType; - - static PyObject *LibLVMError; - -- --/* ---------------------------------------------------------------------- -- * LVM object initialization/deallocation -- */ -- --static int --liblvm_init(lvmobject *self, PyObject *arg) --{ -- char *systemdir = NULL; -- -- if (!PyArg_ParseTuple(arg, "|s", &systemdir)) -- return -1; -- -- self->libh = lvm_init(systemdir); -- if (lvm_errno(self->libh)) { -- PyErr_SetFromErrno(PyExc_OSError); -- return -1; -- } -- -- return 0; --} -- --static void --liblvm_dealloc(lvmobject *self) --{ -- /* if already closed, don't reclose it */ -- if (self->libh != NULL){ -- lvm_quit(self->libh); -- } -- -- PyObject_Del(self); --} -- --#define LVM_VALID(lvmobject) \ -+#define LVM_VALID() \ - do { \ -- if (!lvmobject->libh) { \ -- PyErr_SetString(PyExc_UnboundLocalError, "LVM object invalid"); \ -+ if (!libh) { \ -+ PyErr_SetString(PyExc_UnboundLocalError, "LVM handle invalid"); \ - return NULL; \ - } \ - } while (0) - - static PyObject * --liblvm_get_last_error(lvmobject *self) -+liblvm_get_last_error(void) - { - PyObject *info; - -- LVM_VALID(self); -+ LVM_VALID(); - - if((info = PyTuple_New(2)) == NULL) - return NULL; - -- PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(self->libh))); -- PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(self->libh))); -+ PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(libh))); -+ PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(libh))); - - return info; - } - - static PyObject * --liblvm_library_get_version(lvmobject *self) -+liblvm_library_get_version(void) - { -- LVM_VALID(self); -+ LVM_VALID(); - - return Py_BuildValue("s", lvm_library_get_version()); - } - -- --static PyObject * --liblvm_close(lvmobject *self) --{ -- LVM_VALID(self); -- -- /* if already closed, don't reclose it */ -- if (self->libh != NULL) -- lvm_quit(self->libh); -- -- self->libh = NULL; -- -- Py_INCREF(Py_None); -- return Py_None; --} -- - static PyObject * --liblvm_lvm_list_vg_names(lvmobject *self) -+liblvm_lvm_list_vg_names(void) - { - struct dm_list *vgnames; - struct lvm_str_list *strl; - PyObject * pytuple; - int i = 0; - -- LVM_VALID(self); -+ LVM_VALID(); - -- vgnames = lvm_list_vg_names(self->libh); -+ vgnames = lvm_list_vg_names(libh); - if (!vgnames) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -177,18 +121,18 @@ liblvm_lvm_list_vg_names(lvmobject *self) - } - - static PyObject * --liblvm_lvm_list_vg_uuids(lvmobject *self) -+liblvm_lvm_list_vg_uuids(void) - { - struct dm_list *uuids; - struct lvm_str_list *strl; - PyObject * pytuple; - int i = 0; - -- LVM_VALID(self); -+ LVM_VALID(); - -- uuids = lvm_list_vg_uuids(self->libh); -+ uuids = lvm_list_vg_uuids(libh); - if (!uuids) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -205,12 +149,12 @@ liblvm_lvm_list_vg_uuids(lvmobject *self) - } - - static PyObject * --liblvm_lvm_percent_to_float(lvmobject *self, PyObject *arg) -+liblvm_lvm_percent_to_float(PyObject *arg) - { - double converted; - int percent; - -- LVM_VALID(self); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(arg, "i", &percent)) - return NULL; -@@ -220,18 +164,18 @@ liblvm_lvm_percent_to_float(lvmobject *self, PyObject *arg) - } - - static PyObject * --liblvm_lvm_vgname_from_pvid(lvmobject *self, PyObject *arg) -+liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg) - { - const char *pvid; - const char *vgname; - -- LVM_VALID(self); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(arg, "s", &pvid)) - return NULL; - -- if((vgname = lvm_vgname_from_pvid(self->libh, pvid)) == NULL) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ if((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -239,18 +183,18 @@ liblvm_lvm_vgname_from_pvid(lvmobject *self, PyObject *arg) - } - - static PyObject * --liblvm_lvm_vgname_from_device(lvmobject *self, PyObject *arg) -+liblvm_lvm_vgname_from_device(PyObject *self, PyObject *arg) - { - const char *device; - const char *vgname; - -- LVM_VALID(self); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(arg, "s", &device)) - return NULL; - -- if((vgname = lvm_vgname_from_device(self->libh, device)) == NULL) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ if((vgname = lvm_vgname_from_device(libh, device)) == NULL) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -259,18 +203,18 @@ liblvm_lvm_vgname_from_device(lvmobject *self, PyObject *arg) - - - static PyObject * --liblvm_lvm_config_find_bool(lvmobject *self, PyObject *arg) -+liblvm_lvm_config_find_bool(PyObject *self, PyObject *arg) - { - const char *config; - int rval; - PyObject *rc; - -- LVM_VALID(self); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(arg, "s", &config)) - return NULL; - -- if ((rval = lvm_config_find_bool(self->libh, config, -10)) == -10) { -+ if ((rval = lvm_config_find_bool(libh, config, -10)) == -10) { - /* Retrieving error information yields no error in this case */ - PyErr_Format(PyExc_ValueError, "config path not found"); - return NULL; -@@ -283,14 +227,14 @@ liblvm_lvm_config_find_bool(lvmobject *self, PyObject *arg) - } - - static PyObject * --liblvm_lvm_config_reload(lvmobject *self) -+liblvm_lvm_config_reload(void) - { - int rval; - -- LVM_VALID(self); -+ LVM_VALID(); - -- if((rval = lvm_config_reload(self->libh)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ if((rval = lvm_config_reload(libh)) == -1) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -300,14 +244,14 @@ liblvm_lvm_config_reload(lvmobject *self) - - - static PyObject * --liblvm_lvm_scan(lvmobject *self) -+liblvm_lvm_scan(void) - { - int rval; - -- LVM_VALID(self); -+ LVM_VALID(); - -- if((rval = lvm_scan(self->libh)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ if((rval = lvm_scan(libh)) == -1) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -316,18 +260,18 @@ liblvm_lvm_scan(lvmobject *self) - } - - static PyObject * --liblvm_lvm_config_override(lvmobject *self, PyObject *arg) -+liblvm_lvm_config_override(PyObject *self, PyObject *arg) - { - const char *config; - int rval; - -- LVM_VALID(self); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(arg, "s", &config)) - return NULL; - -- if ((rval = lvm_config_override(self->libh, config)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self)); -+ if ((rval = lvm_config_override(libh, config)) == -1) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -340,14 +284,14 @@ liblvm_lvm_config_override(lvmobject *self, PyObject *arg) - - - static PyObject * --liblvm_lvm_vg_open(lvmobject *lvm, PyObject *args) -+liblvm_lvm_vg_open(PyObject *self, PyObject *args) - { - const char *vgname; - const char *mode = NULL; - -- vgobject *self; -+ vgobject *vgobj; - -- LVM_VALID(lvm); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(args, "s|s", &vgname, &mode)) { - return NULL; -@@ -356,42 +300,38 @@ liblvm_lvm_vg_open(lvmobject *lvm, PyObject *args) - if (mode == NULL) - mode = "r"; - -- if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL) -+ if ((vgobj = PyObject_New(vgobject, &LibLVMvgType)) == NULL) - return NULL; - -- if ((self->vg = lvm_vg_open(lvm->libh, vgname, mode, 0))== NULL) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm)); -- Py_DECREF(self); -+ if ((vgobj->vg = lvm_vg_open(libh, vgname, mode, 0))== NULL) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -- self->lvm_obj = lvm; - -- return (PyObject *)self; -+ return (PyObject *)vgobj; - } - - static PyObject * --liblvm_lvm_vg_create(lvmobject *lvm, PyObject *args) -+liblvm_lvm_vg_create(PyObject *self, PyObject *args) - { - const char *vgname; -- vgobject *self; -+ vgobject *vgobj; - -- LVM_VALID(lvm); -+ LVM_VALID(); - - if (!PyArg_ParseTuple(args, "s", &vgname)) { - return NULL; - } - -- if ((self = PyObject_New(vgobject, &LibLVMvgType)) == NULL) -+ if ((vgobj = PyObject_New(vgobject, &LibLVMvgType)) == NULL) - return NULL; - -- if ((self->vg = lvm_vg_create(lvm->libh, vgname))== NULL) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(lvm)); -- Py_DECREF(self); -+ if ((vgobj->vg = lvm_vg_create(libh, vgname))== NULL) { -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -- self->lvm_obj = lvm; - -- return (PyObject *)self; -+ return (PyObject *)vgobj; - } - - static void -@@ -462,7 +402,7 @@ liblvm_lvm_vg_remove(vgobject *self) - return Py_None; - - error: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -488,7 +428,7 @@ liblvm_lvm_vg_extend(vgobject *self, PyObject *args) - return Py_None; - - error: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -514,7 +454,7 @@ liblvm_lvm_vg_reduce(vgobject *self, PyObject *args) - return Py_None; - - error: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -538,7 +478,7 @@ liblvm_lvm_vg_add_tag(vgobject *self, PyObject *args) - return Py_BuildValue("i", rval); - - error: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -564,7 +504,7 @@ liblvm_lvm_vg_remove_tag(vgobject *self, PyObject *args) - return Py_None; - - error: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - - } -@@ -658,13 +598,13 @@ liblvm_lvm_vg_get_free_extent_count(vgobject *self) - - /* Builds a python tuple ([string|number], bool) from a struct lvm_property_value */ - static PyObject * --get_property(lvmobject *h, struct lvm_property_value *prop) -+get_property(struct lvm_property_value *prop) - { - PyObject *pytuple; - PyObject *setable; - - if( !prop->is_valid ) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(h)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -703,7 +643,7 @@ liblvm_lvm_vg_get_property(vgobject *self, PyObject *args) - return NULL; - - prop_value = lvm_vg_get_property(self->vg, name); -- return get_property(self->lvm_obj, &prop_value); -+ return get_property(&prop_value); - } - - static PyObject * -@@ -791,7 +731,7 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - return Py_None; - - lvmerror: -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - bail: - free(string_value); - if( variant_type_arg ) { -@@ -838,7 +778,7 @@ liblvm_lvm_vg_set_extent_size(vgobject *self, PyObject *args) - } - - if ((rval = lvm_vg_set_extent_size(self->vg, new_size)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -875,7 +815,6 @@ liblvm_lvm_vg_list_lvs(vgobject *vg) - } - - self->lv = lvl->lv; -- self->lvm_obj = vg->lvm_obj; - PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); - i++; - } -@@ -895,7 +834,7 @@ liblvm_lvm_vg_get_tags(vgobject *self) - - tags = lvm_vg_get_tags(self->vg); - if (!tags) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -928,11 +867,10 @@ liblvm_lvm_vg_create_lv_linear(vgobject *vg, PyObject *args) - return NULL; - - if ((self->lv = lvm_vg_create_lv_linear(vg->vg, vgname, size))== NULL) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(vg->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - Py_DECREF(self); - return NULL; - } -- self->lvm_obj = vg->lvm_obj; - - return (PyObject *)self; - } -@@ -972,7 +910,6 @@ liblvm_lvm_vg_list_pvs(vgobject *vg) - } - - self->pv = pvl->pv; -- self->lvm_obj = vg->lvm_obj; - PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); - i++; - } -@@ -997,7 +934,7 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) - - lv = method(self->vg, id); - if( !lv ) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1007,7 +944,6 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) - } - - rc->lv = lv; -- rc->lvm_obj = self->lvm_obj; - return (PyObject *)rc; - } - -@@ -1037,7 +973,7 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) - - pv = method(self->vg, id); - if( !pv ) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1047,7 +983,6 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) - } - - rc->pv = pv; -- rc->lvm_obj = self->lvm_obj; - return (PyObject *)rc; - } - -@@ -1104,7 +1039,7 @@ liblvm_lvm_lv_activate(lvobject *self) - LV_VALID(self); - - if ((rval = lvm_lv_activate(self->lv)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1120,7 +1055,7 @@ liblvm_lvm_lv_deactivate(lvobject *self) - LV_VALID(self); - - if ((rval = lvm_lv_deactivate(self->lv)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1136,7 +1071,7 @@ liblvm_lvm_vg_remove_lv(lvobject *self) - LV_VALID(self); - - if ((rval = lvm_vg_remove_lv(self->lv)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1149,7 +1084,7 @@ liblvm_lvm_vg_remove_lv(lvobject *self) - /* This will return a tuple of (value, bool) with the value being a string or - integer and bool indicating if property is settable */ - static PyObject * --liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) -+liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) - { - const char *name; - struct lvm_property_value prop_value; -@@ -1160,7 +1095,7 @@ liblvm_lvm_lv_get_property(lvobject *self, PyObject *args) - return NULL; - - prop_value = lvm_lv_get_property(self->lv, name); -- return get_property(self->lvm_obj, &prop_value); -+ return get_property(&prop_value); - } - - static PyObject * -@@ -1210,7 +1145,7 @@ liblvm_lvm_lv_add_tag(lvobject *self, PyObject *args) - } - - if ((rval = lvm_lv_add_tag(self->lv, tag)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1231,7 +1166,7 @@ liblvm_lvm_lv_remove_tag(lvobject *self, PyObject *args) - } - - if ((rval = lvm_lv_remove_tag(self->lv, tag)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1251,7 +1186,7 @@ liblvm_lvm_lv_get_tags(lvobject *self) - - tags = lvm_lv_get_tags(self->lv); - if (!tags) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1279,7 +1214,7 @@ liblvm_lvm_lv_rename(lvobject *self, PyObject *args) - return NULL; - - if ((rval = lvm_lv_rename(self->lv, new_name)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1300,7 +1235,7 @@ liblvm_lvm_lv_resize(lvobject *self, PyObject *args) - } - - if ((rval = lvm_lv_resize(self->lv, new_size)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1337,7 +1272,6 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - } - - self->lv_seg = lvsegl->lvseg; -- self->lvm_obj = lv->lvm_obj; - PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); - i++; - } -@@ -1349,7 +1283,7 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - - #define PV_VALID(pvobject) \ - do { \ -- if (!pvobject->pv || !pvobject->lvm_obj) { \ -+ if (!pvobject->pv || !libh) { \ - PyErr_SetString(PyExc_UnboundLocalError, "PV object invalid"); \ - return NULL; \ - } \ -@@ -1385,7 +1319,7 @@ liblvm_lvm_pv_get_property(pvobject *self, PyObject *args) - return NULL; - - prop_value = lvm_pv_get_property(self->pv, name); -- return get_property(self->lvm_obj, &prop_value); -+ return get_property(&prop_value); - } - - static PyObject * -@@ -1417,7 +1351,7 @@ liblvm_lvm_pv_resize(pvobject *self, PyObject *args) - } - - if ((rval = lvm_pv_resize(self->pv, new_size)) == -1) { -- PyErr_SetObject(LibLVMError, liblvm_get_last_error(self->lvm_obj)); -+ PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - -@@ -1454,7 +1388,6 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) - } - - self->pv_seg = pvsegl->pvseg; -- self->lvm_obj = pv->lvm_obj; - PyTuple_SET_ITEM(pytuple, i, (PyObject *) self); - i++; - } -@@ -1480,7 +1413,7 @@ liblvm_lvm_lvseg_get_property(lvsegobject *self, PyObject *args) - return NULL; - - prop_value = lvm_lvseg_get_property(self->lv_seg, name); -- return get_property(self->lvm_obj, &prop_value); -+ return get_property(&prop_value); - } - - /* PV seg methods */ -@@ -1501,7 +1434,7 @@ liblvm_lvm_pvseg_get_property(pvsegobject *self, PyObject *args) - return NULL; - - prop_value = lvm_pvseg_get_property(self->pv_seg, name); -- return get_property(self->lvm_obj, &prop_value); -+ return get_property(&prop_value); - } - - /* ---------------------------------------------------------------------- -@@ -1513,7 +1446,6 @@ static PyMethodDef Liblvm_methods[] = { - { "getVersion", (PyCFunction)liblvm_library_get_version, METH_NOARGS }, - { "vgOpen", (PyCFunction)liblvm_lvm_vg_open, METH_VARARGS }, - { "vgCreate", (PyCFunction)liblvm_lvm_vg_create, METH_VARARGS }, -- { "close", (PyCFunction)liblvm_close, METH_NOARGS }, - { "configFindBool", (PyCFunction)liblvm_lvm_config_find_bool, METH_VARARGS }, - { "configReload", (PyCFunction)liblvm_lvm_config_reload, METH_NOARGS }, - { "configOverride", (PyCFunction)liblvm_lvm_config_override, METH_VARARGS }, -@@ -1606,18 +1538,6 @@ static PyMethodDef liblvm_pvseg_methods[] = { - { NULL, NULL} /* sentinel */ - }; - --static PyTypeObject LiblvmType = { -- PyObject_HEAD_INIT(&PyType_Type) -- .tp_name = "liblvm.Liblvm", -- .tp_basicsize = sizeof(lvmobject), -- .tp_new = PyType_GenericNew, -- .tp_dealloc = (destructor)liblvm_dealloc, -- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -- .tp_doc = "Liblvm objects", -- .tp_methods = Liblvm_methods, -- .tp_init = (initproc)liblvm_init, --}; -- - static PyTypeObject LibLVMvgType = { - PyObject_HEAD_INIT(&PyType_Type) - .tp_name = "liblvm.Liblvm_vg", -@@ -1673,13 +1593,20 @@ static PyTypeObject LibLVMpvsegType = { - .tp_methods = liblvm_pvseg_methods, - }; - -+static void -+liblvm_cleanup(void) -+{ -+ lvm_quit(libh); -+ libh = NULL; -+} -+ - PyMODINIT_FUNC - initlvm(void) - { - PyObject *m; - -- if (PyType_Ready(&LiblvmType) < 0) -- return; -+ libh = lvm_init(NULL); -+ - if (PyType_Ready(&LibLVMvgType) < 0) - return; - if (PyType_Ready(&LibLVMlvType) < 0) -@@ -1695,9 +1622,6 @@ initlvm(void) - if (m == NULL) - return; - -- Py_INCREF(&LiblvmType); -- PyModule_AddObject(m, "Liblvm", (PyObject *)&LiblvmType); -- - LibLVMError = PyErr_NewException("Liblvm.LibLVMError", - NULL, NULL); - if (LibLVMError) { -@@ -1708,4 +1632,5 @@ initlvm(void) - PyModule_AddObject(m, "LibLVMError", LibLVMError); - } - -+ Py_AtExit(liblvm_cleanup); - } diff --git a/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch b/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch deleted file mode 100644 index 621d1df..0000000 --- a/lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch +++ /dev/null @@ -1,103 +0,0 @@ -commit 10ba799ab08001d5435425e65f039f20cadd306e -Author: Tony Asleson -Date: Mon Oct 15 13:54:19 2012 -0700 - - python-lvm: Update example to work with lvm object removal. - - Signed-off-by: Tony Asleson - Signed-off-by: Andy Grover ---- - python/example.py | 35 +++++++++++++++-------------------- - 1 file changed, 15 insertions(+), 20 deletions(-) - -diff --git a/python/example.py b/python/example.py -index 67bb7e4..5c14ee1 100644 ---- a/python/example.py -+++ b/python/example.py -@@ -31,9 +31,9 @@ def print_pv(pv): - - - #Dump some information about a specific volume group --def print_vg(h, vg_name): -+def print_vg(vg_name): - #Open read only -- vg = h.vgOpen(vg_name, 'r') -+ vg = lvm.vgOpen(vg_name, 'r') - - print 'Volume group:', vg_name, 'Size: ', vg.getSize() - -@@ -55,13 +55,13 @@ def print_vg(h, vg_name): - vg.close() - - #Returns the name of a vg with space available --def find_vg_with_free_space(h): -+def find_vg_with_free_space(): - free_space = 0 - rc = None - -- vg_names = l.listVgNames() -+ vg_names = lvm.listVgNames() - for v in vg_names: -- vg = h.vgOpen(v, 'r') -+ vg = lvm.vgOpen(v, 'r') - c_free = vg.getFreeSize() - if c_free > free_space: - free_space = c_free -@@ -72,13 +72,13 @@ def find_vg_with_free_space(h): - - #Walk through the volume groups and fine one with space in which we can - #create a new logical volume --def create_delete_logical_volume(h): -- vg_name = find_vg_with_free_space(h) -+def create_delete_logical_volume(): -+ vg_name = find_vg_with_free_space() - - print 'Using volume group ', vg_name, ' for example' - - if vg_name: -- vg = h.vgOpen(vg_name, 'w') -+ vg = lvm.vgOpen(vg_name, 'w') - lv = vg.createLvLinear('python_lvm_ok_to_delete', vg.getFreeSize()) - - if lv: -@@ -93,11 +93,11 @@ def create_delete_logical_volume(h): - #Remove tag - lv.removeTag(t) - -+ lv.deactivate() -+ - #Try to rename -- lv.rename("python_lvm_ok_to_be_removed_shortly") -+ lv.rename("python_lvm_renamed") - print 'LV name= ', lv.getName() -- -- lv.deactivate() - lv.remove() - - vg.close() -@@ -105,21 +105,16 @@ def create_delete_logical_volume(h): - print 'No free space available to create demo lv!' - - if __name__ == '__main__': -- #Create a new LVM instance -- l = lvm.Liblvm() -- - #What version -- print 'lvm version=', l.getVersion() -+ print 'lvm version=', lvm.getVersion() - - #Get a list of volume group names -- vg_names = l.listVgNames() -+ vg_names = lvm.listVgNames() - - #For each volume group display some information about each of them - for vg_i in vg_names: -- print_vg(l, vg_i) -+ print_vg(vg_i) - - #Demo creating a logical volume -- create_delete_logical_volume(l) -+ create_delete_logical_volume() - -- #Close -- l.close() diff --git a/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch b/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch deleted file mode 100644 index 454e7b7..0000000 --- a/lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch +++ /dev/null @@ -1,205 +0,0 @@ -commit 12b631a6768e6f2a2005ef8ea91c0afbc2455c54 -Author: Andy Grover -Date: Mon Oct 15 13:34:43 2012 -0700 - - python-lvm: whitespace and Yoda conditionals - - Signed-off-by: Andy Grover ---- - python/liblvm.c | 50 ++++++++++++++++++++++++-------------------------- - 1 file changed, 24 insertions(+), 26 deletions(-) - -diff --git a/python/liblvm.c b/python/liblvm.c -index 4518cf4..8a73ced 100644 ---- a/python/liblvm.c -+++ b/python/liblvm.c -@@ -75,7 +75,7 @@ liblvm_get_last_error(void) - - LVM_VALID(); - -- if((info = PyTuple_New(2)) == NULL) -+ if ((info = PyTuple_New(2)) == NULL) - return NULL; - - PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(libh))); -@@ -174,7 +174,7 @@ liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg) - if (!PyArg_ParseTuple(arg, "s", &pvid)) - return NULL; - -- if((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { -+ if ((vgname = lvm_vgname_from_pvid(libh, pvid)) == NULL) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -@@ -193,7 +193,7 @@ liblvm_lvm_vgname_from_device(PyObject *self, PyObject *arg) - if (!PyArg_ParseTuple(arg, "s", &device)) - return NULL; - -- if((vgname = lvm_vgname_from_device(libh, device)) == NULL) { -+ if ((vgname = lvm_vgname_from_device(libh, device)) == NULL) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -@@ -233,7 +233,7 @@ liblvm_lvm_config_reload(void) - - LVM_VALID(); - -- if((rval = lvm_config_reload(libh)) == -1) { -+ if ((rval = lvm_config_reload(libh)) == -1) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -@@ -250,7 +250,7 @@ liblvm_lvm_scan(void) - - LVM_VALID(); - -- if((rval = lvm_scan(libh)) == -1) { -+ if ((rval = lvm_scan(libh)) == -1) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -@@ -603,7 +603,7 @@ get_property(struct lvm_property_value *prop) - PyObject *pytuple; - PyObject *setable; - -- if( !prop->is_valid ) { -+ if (!prop->is_valid) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } -@@ -612,7 +612,7 @@ get_property(struct lvm_property_value *prop) - if (!pytuple) - return NULL; - -- if( prop->is_integer ) { -+ if (prop->is_integer) { - PyTuple_SET_ITEM(pytuple, 0, Py_BuildValue("K", prop->value.integer)); - } else { - PyTuple_SET_ITEM(pytuple, 0, PyString_FromString(prop->value.string)); -@@ -661,11 +661,11 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - - lvm_property = lvm_vg_get_property(self->vg, property_name); - -- if( !lvm_property.is_valid ) { -+ if (!lvm_property.is_valid ) { - goto lvmerror; - } - -- if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyString_Type)) { -+ if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyString_Type)) { - - if (!lvm_property.is_string) { - PyErr_Format(PyExc_ValueError, "Property requires string value"); -@@ -676,7 +676,7 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - leak when calling into set_property, need to verify*/ - string_value = strdup(PyString_AsString(variant_type_arg)); - lvm_property.value.string = string_value; -- if(!lvm_property.value.string) { -+ if (!lvm_property.value.string) { - PyErr_NoMemory(); - goto bail; - } -@@ -688,14 +688,12 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - goto bail; - } - -- if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyInt_Type)) { -+ if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyInt_Type)) { - int temp_py_int = PyInt_AsLong(variant_type_arg); - - /* -1 could be valid, need to see if an exception was gen. */ -- if( -1 == temp_py_int ) { -- if( PyErr_Occurred() ) { -- goto bail; -- } -+ if (temp_py_int == -1 && PyErr_Occurred()) { -+ goto bail; - } - - if (temp_py_int < 0) { -@@ -704,10 +702,10 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - } - - lvm_property.value.integer = temp_py_int; -- } else if(PyObject_IsInstance(variant_type_arg, (PyObject*)&PyLong_Type)){ -+ } else if (PyObject_IsInstance(variant_type_arg, (PyObject*)&PyLong_Type)){ - /* This will fail on negative numbers */ - unsigned long long temp_py_long = PyLong_AsUnsignedLongLong(variant_type_arg); -- if( (unsigned long long)-1 == temp_py_long ) { -+ if (temp_py_long == (unsigned long long)-1) { - goto bail; - } - -@@ -718,11 +716,11 @@ liblvm_lvm_vg_set_property(vgobject *self, PyObject *args) - } - } - -- if( -1 == lvm_vg_set_property(self->vg, property_name, &lvm_property) ) { -+ if (lvm_vg_set_property(self->vg, property_name, &lvm_property) == -1) { - goto lvmerror; - } - -- if( -1 == lvm_vg_write(self->vg)) { -+ if (lvm_vg_write(self->vg) == -1) { - goto lvmerror; - } - -@@ -734,7 +732,7 @@ lvmerror: - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - bail: - free(string_value); -- if( variant_type_arg ) { -+ if (variant_type_arg) { - Py_DECREF(variant_type_arg); - variant_type_arg = NULL; - } -@@ -933,13 +931,13 @@ liblvm_lvm_lv_from_N(vgobject *self, PyObject *arg, lv_fetch_by_N method) - return NULL; - - lv = method(self->vg, id); -- if( !lv ) { -+ if (!lv) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - - rc = PyObject_New(lvobject, &LibLVMlvType); -- if( !rc ) { -+ if (!rc) { - return NULL; - } - -@@ -972,13 +970,13 @@ liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method) - return NULL; - - pv = method(self->vg, id); -- if( !pv ) { -+ if (!pv) { - PyErr_SetObject(LibLVMError, liblvm_get_last_error()); - return NULL; - } - - rc = PyObject_New(pvobject, &LibLVMpvType); -- if( !rc ) { -+ if (!rc) { - return NULL; - } - -@@ -1255,7 +1253,7 @@ liblvm_lvm_lv_list_lvsegs(lvobject *lv) - LV_VALID(lv); - - lvsegs = lvm_lv_list_lvsegs(lv->lv); -- if(!lvsegs) { -+ if (!lvsegs) { - return Py_BuildValue("()"); - } - -@@ -1371,7 +1369,7 @@ liblvm_lvm_lv_list_pvsegs(pvobject *pv) - PV_VALID(pv); - - pvsegs = lvm_pv_list_pvsegs(pv->pv); -- if(!pvsegs) { -+ if (!pvsegs) { - return Py_BuildValue("()"); - } - diff --git a/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch b/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch deleted file mode 100644 index 3eeec36..0000000 --- a/lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch +++ /dev/null @@ -1,27 +0,0 @@ - WHATS_NEW | 1 + - lib/mm/memlock.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index e247391..67a24c7 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Skip mlocking [vectors] on arm architecture. - Exit pvscan --cache immediately if cluster locking used or lvmetad not used. - Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. - Remove dependency on fedora-storage-init.service in lvm2 systemd units. -diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c -index 2240a1d..6d0996a 100644 ---- a/lib/mm/memlock.c -+++ b/lib/mm/memlock.c -@@ -84,6 +84,7 @@ static int _default_priority; - static const char * const _ignore_maps[] = { - "[vdso]", - "[vsyscall]", -+ "[vectors]", - }; - - /* default blacklist for maps */ diff --git a/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch b/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch deleted file mode 100644 index bbdd76e..0000000 --- a/lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch +++ /dev/null @@ -1,33 +0,0 @@ -commit 0bcd33ecffb97f09e1ffb75868844cea40f3cd77 -Author: Peter Rajnoha -Date: Tue Apr 9 10:07:49 2013 +0200 - - 1 ---- - WHATS_NEW | 1 + - tools/pvscan.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index c481e68..03345d8 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,6 @@ - Version 2.02.99 - - =================================== -+ Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. - Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. - Skip mlocking [vectors] on arm architecture. - Exit pvscan --cache immediately if cluster locking used or lvmetad not used. -diff --git a/tools/pvscan.c b/tools/pvscan.c -index 34ab792..fbd524b 100644 ---- a/tools/pvscan.c -+++ b/tools/pvscan.c -@@ -223,6 +223,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) - } - - out: -+ sync_local_dev_names(cmd); - unlock_vg(cmd, VG_GLOBAL); - - return ret; diff --git a/lvm2-2_02_99-various-thin-support-related-fixes.patch b/lvm2-2_02_99-various-thin-support-related-fixes.patch deleted file mode 100644 index ff76e34..0000000 --- a/lvm2-2_02_99-various-thin-support-related-fixes.patch +++ /dev/null @@ -1,2066 +0,0 @@ -commit 426de775ff89de7fd9a01f3168e18a711615d23a -Author: Peter Rajnoha -Date: Tue May 14 11:02:19 2013 +0200 - - lvm2-2_02_99-various-thin-support-related-fixes.patch ---- - WHATS_NEW | 11 ++ - WHATS_NEW_DM | 1 + - doc/example.conf.in | 27 +++++ - lib/activate/activate.h | 1 + - lib/config/defaults.h | 3 + - lib/format_text/archiver.c | 24 ++-- - lib/format_text/archiver.h | 4 +- - lib/metadata/lv.c | 5 + - lib/metadata/lv.h | 1 + - lib/metadata/lv_manip.c | 11 +- - lib/metadata/metadata-exported.h | 5 +- - lib/metadata/metadata.h | 2 + - lib/metadata/mirror.c | 9 +- - lib/metadata/thin_manip.c | 18 +++ - lib/report/columns.h | 2 +- - lib/report/properties.c | 22 ++-- - lib/report/report.c | 3 +- - lib/thin/thin.c | 93 +++++++++++---- - libdm/libdm-deptree.c | 5 + - liblvm/lvm_lv.c | 8 +- - man/lvconvert.8.in | 114 +++++++++++++++--- - man/lvcreate.8.in | 18 +-- - man/vgcfgrestore.8.in | 9 ++ - test/api/thin_percent.c | 10 ++ - test/api/thin_percent.sh | 2 +- - test/shell/lvconvert-thin.sh | 81 ++++++++++--- - test/shell/thin-defaults.sh | 35 ++++++ - test/shell/thin-restore.sh | 34 ++++++ - tools/args.h | 1 + - tools/commands.h | 10 +- - tools/lvchange.c | 8 +- - tools/lvconvert.c | 245 +++++++++++++++++++++++++-------------- - tools/lvcreate.c | 117 +++++-------------- - tools/toollib.c | 195 +++++++++++++++++++++++++++++++ - tools/toollib.h | 14 +++ - tools/vgcfgrestore.c | 5 +- - 36 files changed, 860 insertions(+), 293 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 03345d8..5231745 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,16 @@ - Version 2.02.99 - - =================================== -+ Fix lvm2app to return all property sizes in bytes. -+ Add lvm.conf option global/thin_disabled_features. -+ Add lvconvert support to swap thin pool metadata volume. -+ Implement internal function detach_pool_metadata_lv(). -+ Fix lvm2app and return lvseg discards property as string. -+ Allow forced vgcfgrestore of lvm2 metadata with thin volumes. -+ Add lvm.conf thin pool defs thin_pool_{chunk_size|discards|zero}. -+ Support discards for non-power-of-2 thin pool chunks. -+ Support allocation of pool metadata with lvconvert command. -+ Move common functionality for thin lvcreate and lvconvert to toollib. -+ Use lv_is_active() instead of lv_info() call. - Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. - Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. - Skip mlocking [vectors] on arm architecture. -diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM -index 3f8d9c9..e0b8d51 100644 ---- a/WHATS_NEW_DM -+++ b/WHATS_NEW_DM -@@ -1,5 +1,6 @@ - Version 1.02.78 - - =================================== -+ Automatically deactivate failed preloaded dm tree node. - Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. - - Version 1.02.77 - 15th October 2012 -diff --git a/doc/example.conf.in b/doc/example.conf.in -index 442ad64..1bf89d3 100644 ---- a/doc/example.conf.in -+++ b/doc/example.conf.in -@@ -232,6 +232,23 @@ allocation { - # Set to 1 to guarantee that thin pool metadata will always - # be placed on different PVs from the pool data. - thin_pool_metadata_require_separate_pvs = 0 -+ -+ # Specify the minimal chunk size (in KB) for thin pool volumes. -+ # Use of the larger chunk size may improve perfomance for plain -+ # thin volumes, however using them for snapshot volumes is less efficient, -+ # as it consumes more space and takes extra time for copying. -+ # When unset, lvm tries to estimate chunk size starting from 64KB -+ # Supported values are in range from 64 to 1048576. -+ # thin_pool_chunk_size = 64 -+ -+ # Specify discards behavior of the thin pool volume. -+ # Select one of "ignore", "nopassdown", "passdown" -+ # thin_pool_discards = "passdown" -+ -+ # Set to 0, to disable zeroing of thin pool data chunks before their -+ # first use. -+ # N.B. zeroing larger thin pool chunk size degrades performance. -+ # thin_pool_zero = 1 - } - - # This section that allows you to configure the nature of the -@@ -507,6 +524,16 @@ global { - # String with options passed with thin_check command. By default, - # option '-q' is for quiet output. - thin_check_options = [ "-q" ] -+ -+ # If set, given features are not used by thin driver. -+ # This can be helpful not just for testing, but i.e. allows to avoid -+ # using problematic implementation of some thin feature. -+ # Features: -+ # block_size -+ # discards -+ # discards_non_power_2 -+ # -+ # thin_disabled_features = [ "discards", "block_size" ] - } - - activation { -diff --git a/lib/activate/activate.h b/lib/activate/activate.h -index ba24d2a..0a0c97e 100644 ---- a/lib/activate/activate.h -+++ b/lib/activate/activate.h -@@ -51,6 +51,7 @@ enum { - THIN_FEATURE_EXTERNAL_ORIGIN = (1 << 1), - THIN_FEATURE_HELD_ROOT = (1 << 2), - THIN_FEATURE_BLOCK_SIZE = (1 << 3), -+ THIN_FEATURE_DISCARDS_NON_POWER_2 = (1 << 4), - }; - - void set_activation(int activation); -diff --git a/lib/config/defaults.h b/lib/config/defaults.h -index 9730a2d..348fa75 100644 ---- a/lib/config/defaults.h -+++ b/lib/config/defaults.h -@@ -69,6 +69,9 @@ - #define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */ - #define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */ - #define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */ -+#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */ -+#define DEFAULT_THIN_POOL_DISCARDS "passdown" -+#define DEFAULT_THIN_POOL_ZERO 1 - - #define DEFAULT_UMASK 0077 - -diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c -index ccefb4c..8599e3b 100644 ---- a/lib/format_text/archiver.c -+++ b/lib/format_text/archiver.c -@@ -347,7 +347,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg) - - /* ORPHAN and VG locks held before calling this */ - int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, -- const char *file) -+ const char *file, int force) - { - struct volume_group *vg; - int missing_pvs, r = 0; -@@ -360,14 +360,20 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, - return_0; - - /* FIXME: Restore support is missing for now */ -- dm_list_iterate_items(lvl, &vg->lvs) -+ dm_list_iterate_items(lvl, &vg->lvs) { - if (lv_is_thin_type(lvl->lv)) { -- log_error("Cannot restore Volume Group %s with " -- "thin logical volumes. " -- "(not yet supported).", vg->name); -- r = 0; -- goto out; -+ if (!force) { -+ log_error("Consider using option --force to restore " -+ "Volume Group %s with thin volumes.", -+ vg->name); -+ goto out; -+ } else { -+ log_warn("WARNING: Forced restore of Volume Group " -+ "%s with thin volumes.", vg->name); -+ break; -+ } - } -+ } - - missing_pvs = vg_missing_pv_count(vg); - if (missing_pvs == 0) -@@ -381,7 +387,7 @@ out: - return r; - } - --int backup_restore(struct cmd_context *cmd, const char *vg_name) -+int backup_restore(struct cmd_context *cmd, const char *vg_name, int force) - { - char path[PATH_MAX]; - -@@ -391,7 +397,7 @@ int backup_restore(struct cmd_context *cmd, const char *vg_name) - return 0; - } - -- return backup_restore_from_file(cmd, vg_name, path); -+ return backup_restore_from_file(cmd, vg_name, path, force); - } - - int backup_to_file(const char *file, const char *desc, struct volume_group *vg) -diff --git a/lib/format_text/archiver.h b/lib/format_text/archiver.h -index 7346f93..ddff687 100644 ---- a/lib/format_text/archiver.h -+++ b/lib/format_text/archiver.h -@@ -53,8 +53,8 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd, - const char *vg_name, const char *file); - int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg); - int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name, -- const char *file); --int backup_restore(struct cmd_context *cmd, const char *vg_name); -+ const char *file, int force); -+int backup_restore(struct cmd_context *cmd, const char *vg_name, int force); - - int backup_to_file(const char *file, const char *desc, struct volume_group *vg); - -diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c -index 4032f34..34b428a 100644 ---- a/lib/metadata/lv.c -+++ b/lib/metadata/lv.c -@@ -123,6 +123,11 @@ char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg) - return dm_pool_strdup(mem, seg->segtype->ops->name(seg)); - } - -+char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg) -+{ -+ return dm_pool_strdup(mem, get_pool_discards_name(seg->discards)); -+} -+ - uint64_t lvseg_chunksize(const struct lv_segment *seg) - { - uint64_t size; -diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h -index 0daab62..838b002 100644 ---- a/lib/metadata/lv.h -+++ b/lib/metadata/lv.h -@@ -74,6 +74,7 @@ uint64_t lvseg_start(const struct lv_segment *seg); - uint64_t lvseg_size(const struct lv_segment *seg); - uint64_t lvseg_chunksize(const struct lv_segment *seg); - char *lvseg_segtype_dup(struct dm_pool *mem, const struct lv_segment *seg); -+char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg); - char *lvseg_tags_dup(const struct lv_segment *seg); - char *lvseg_devices(struct dm_pool *mem, const struct lv_segment *seg); - char *lvseg_seg_pe_ranges(struct dm_pool *mem, const struct lv_segment *seg); -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index d469fe8..a59e03f 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -4217,7 +4217,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l - struct logical_volume *pool_lv; - struct lv_list *lvl; - int origin_active = 0; -- struct lvinfo info; - - if (new_lv_name && find_lv_in_vg(vg, new_lv_name)) { - log_error("Logical volume \"%s\" already exists in " -@@ -4349,12 +4348,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l - log_warn("WARNING: See global/mirror_segtype_default in lvm.conf."); - } - -- if (!lv_info(cmd, org, 0, &info, 0, 0)) { -+ if (!lv_is_active(org)) { - log_error("Check for existence of active snapshot " - "origin '%s' failed.", org->name); - return NULL; - } -- origin_active = info.exists; -+ origin_active = 1; - - if (vg_is_clustered(vg) && - !lv_is_active_exclusive_locally(org)) { -@@ -4696,8 +4695,8 @@ revert_new_lv: - return NULL; - } - --int lv_create_single(struct volume_group *vg, -- struct lvcreate_params *lp) -+struct logical_volume *lv_create_single(struct volume_group *vg, -+ struct lvcreate_params *lp) - { - struct logical_volume *lv; - -@@ -4725,5 +4724,5 @@ int lv_create_single(struct volume_group *vg, - out: - log_print_unless_silent("Logical volume \"%s\" created", lv->name); - -- return 1; -+ return lv; - } -diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h -index d149f95..11ca5be 100644 ---- a/lib/metadata/metadata-exported.h -+++ b/lib/metadata/metadata-exported.h -@@ -609,6 +609,7 @@ struct lvcreate_params { - uint32_t mirrors; /* mirror */ - - const struct segment_type *segtype; /* all */ -+ unsigned target_attr; /* all */ - - /* size */ - uint32_t extents; /* all */ -@@ -625,8 +626,8 @@ struct lvcreate_params { - struct dm_list tags; /* all */ - }; - --int lv_create_single(struct volume_group *vg, -- struct lvcreate_params *lp); -+struct logical_volume *lv_create_single(struct volume_group *vg, -+ struct lvcreate_params *lp); - - /* - * Functions for layer manipulation -diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h -index 7bc7eaf..19bf742 100644 ---- a/lib/metadata/metadata.h -+++ b/lib/metadata/metadata.h -@@ -460,6 +460,8 @@ int fixup_imported_mirrors(struct volume_group *vg); - */ - int attach_pool_metadata_lv(struct lv_segment *pool_seg, - struct logical_volume *pool_metadata_lv); -+int detach_pool_metadata_lv(struct lv_segment *pool_seg, -+ struct logical_volume **pool_metadata_lv); - int attach_pool_data_lv(struct lv_segment *pool_seg, - struct logical_volume *pool_data_lv); - int attach_pool_lv(struct lv_segment *seg, struct logical_volume *pool_lv, -diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c -index c4683df..084c93a 100644 ---- a/lib/metadata/mirror.c -+++ b/lib/metadata/mirror.c -@@ -282,7 +282,6 @@ static int _init_mirror_log(struct cmd_context *cmd, - struct dm_list *tags, int remove_on_failure) - { - struct str_list *sl; -- struct lvinfo info; - uint64_t orig_status = log_lv->status; - int was_active = 0; - -@@ -298,14 +297,13 @@ static int _init_mirror_log(struct cmd_context *cmd, - } - - /* If the LV is active, deactivate it first. */ -- if (lv_info(cmd, log_lv, 0, &info, 0, 0) && info.exists) { -- (void)deactivate_lv(cmd, log_lv); -+ if (lv_is_active(log_lv)) { - /* - * FIXME: workaround to fail early - * Ensure that log is really deactivated because deactivate_lv - * on cluster do not fail if there is log_lv with different UUID. - */ -- if (lv_info(cmd, log_lv, 0, &info, 0, 0) && info.exists) { -+ if (!deactivate_lv(cmd, log_lv)) { - log_error("Aborting. Unable to deactivate mirror log."); - goto revert_new_lv; - } -@@ -1714,7 +1712,6 @@ int remove_mirror_log(struct cmd_context *cmd, - int force) - { - percent_t sync_percent; -- struct lvinfo info; - struct volume_group *vg = lv->vg; - - /* Unimplemented features */ -@@ -1724,7 +1721,7 @@ int remove_mirror_log(struct cmd_context *cmd, - } - - /* Had disk log, switch to core. */ -- if (lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) { -+ if (lv_is_active(lv)) { - if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, - NULL)) { - log_error("Unable to determine mirror sync status."); -diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c -index e7e96df..e2762a0 100644 ---- a/lib/metadata/thin_manip.c -+++ b/lib/metadata/thin_manip.c -@@ -30,6 +30,24 @@ int attach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume * - return add_seg_to_segs_using_this_lv(metadata_lv, pool_seg); - } - -+int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv) -+{ -+ struct logical_volume *lv = pool_seg->metadata_lv; -+ -+ if (!lv || !lv_is_thin_pool_metadata(lv) || -+ !remove_seg_from_segs_using_this_lv(lv, pool_seg)) { -+ log_error(INTERNAL_ERROR "LV %s is invalid thin pool.", pool_seg->lv->name); -+ return 0; -+ } -+ -+ lv_set_visible(lv); -+ lv->status &= ~THIN_POOL_METADATA; -+ *metadata_lv = lv; -+ pool_seg->metadata_lv = NULL; -+ -+ return 1; -+} -+ - int attach_pool_data_lv(struct lv_segment *pool_seg, struct logical_volume *pool_data_lv) - { - if (!set_lv_segment_area_lv(pool_seg, 0, pool_data_lv, 0, THIN_POOL_DATA)) -diff --git a/lib/report/columns.h b/lib/report/columns.h -index 6299a2b..11b3f3f 100644 ---- a/lib/report/columns.h -+++ b/lib/report/columns.h -@@ -140,7 +140,7 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, region_size, "For mirror - FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunksize, "For snapshots, the unit of data used when tracking changes.", 0) - FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunk_size, "For snapshots, the unit of data used when tracking changes.", 0) - FIELD(SEGS, seg, NUM, "#Thins", list, 4, thincount, thin_count, "For thin pools, the number of thin volumes in this pool.", 0) --FIELD(SEGS, seg, NUM, "Discards", list, 8, discards, discards, "For thin pools, how discards are handled.", 0) -+FIELD(SEGS, seg, STR, "Discards", list, 8, discards, discards, "For thin pools, how discards are handled.", 0) - FIELD(SEGS, seg, NUM, "Zero", list, 4, thinzero, zero, "For thin pools, if zeroing is enabled.", 0) - FIELD(SEGS, seg, NUM, "TransId", list, 4, transactionid, transaction_id, "For thin pools, the transaction id.", 0) - FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, seg_start, "Offset within the LV to the start of the segment in current units.", 0) -diff --git a/lib/report/properties.c b/lib/report/properties.c -index c4f6ab9..a871d66 100644 ---- a/lib/report/properties.c -+++ b/lib/report/properties.c -@@ -183,7 +183,7 @@ GET_LV_NUM_PROPERTY_FN(seg_count, dm_list_size(&lv->segments)) - #define _seg_count_set _not_implemented_set - GET_LV_STR_PROPERTY_FN(origin, lv_origin_dup(lv->vg->vgmem, lv)) - #define _origin_set _not_implemented_set --GET_LV_NUM_PROPERTY_FN(origin_size, lv_origin_size(lv)) -+GET_LV_NUM_PROPERTY_FN(origin_size, (SECTOR_SIZE * lv_origin_size(lv))) - #define _origin_size_set _not_implemented_set - GET_LV_NUM_PROPERTY_FN(snap_percent, _snap_percent(lv)) - #define _snap_percent_set _not_implemented_set -@@ -231,7 +231,7 @@ GET_VG_NUM_PROPERTY_FN(vg_free, (SECTOR_SIZE * vg_free(vg))) - #define _vg_free_set _not_implemented_set - GET_VG_STR_PROPERTY_FN(vg_sysid, vg_system_id_dup(vg)) - #define _vg_sysid_set _not_implemented_set --GET_VG_NUM_PROPERTY_FN(vg_extent_size, vg->extent_size) -+GET_VG_NUM_PROPERTY_FN(vg_extent_size, (SECTOR_SIZE * vg->extent_size)) - #define _vg_extent_size_set _not_implemented_set - GET_VG_NUM_PROPERTY_FN(vg_extent_count, vg->extent_count) - #define _vg_extent_count_set _not_implemented_set -@@ -267,17 +267,17 @@ GET_LVSEG_STR_PROPERTY_FN(segtype, lvseg_segtype_dup(lvseg->lv->vg->vgmem, lvseg - #define _segtype_set _not_implemented_set - GET_LVSEG_NUM_PROPERTY_FN(stripes, lvseg->area_count) - #define _stripes_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(stripesize, lvseg->stripe_size) -+GET_LVSEG_NUM_PROPERTY_FN(stripesize, (SECTOR_SIZE * lvseg->stripe_size)) - #define _stripesize_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(stripe_size, lvseg->stripe_size) -+GET_LVSEG_NUM_PROPERTY_FN(stripe_size, (SECTOR_SIZE * lvseg->stripe_size)) - #define _stripe_size_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(regionsize, lvseg->region_size) -+GET_LVSEG_NUM_PROPERTY_FN(regionsize, (SECTOR_SIZE * lvseg->region_size)) - #define _regionsize_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(region_size, lvseg->region_size) -+GET_LVSEG_NUM_PROPERTY_FN(region_size, (SECTOR_SIZE * lvseg->region_size)) - #define _region_size_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(chunksize, lvseg_chunksize(lvseg)) -+GET_LVSEG_NUM_PROPERTY_FN(chunksize, (SECTOR_SIZE * lvseg_chunksize(lvseg))) - #define _chunksize_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(chunk_size, lvseg_chunksize(lvseg)) -+GET_LVSEG_NUM_PROPERTY_FN(chunk_size, (SECTOR_SIZE * lvseg_chunksize(lvseg))) - #define _chunk_size_set _not_implemented_set - GET_LVSEG_NUM_PROPERTY_FN(thin_count, dm_list_size(&lvseg->lv->segs_using_this_lv)) - #define _thin_count_set _not_implemented_set -@@ -285,9 +285,9 @@ GET_LVSEG_NUM_PROPERTY_FN(zero, lvseg->zero_new_blocks) - #define _zero_set _not_implemented_set - GET_LVSEG_NUM_PROPERTY_FN(transaction_id, lvseg->transaction_id) - #define _transaction_id_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(discards, lvseg->discards) -+GET_LVSEG_STR_PROPERTY_FN(discards, lvseg_discards_dup(lvseg->lv->vg->vgmem, lvseg)) - #define _discards_set _not_implemented_set --GET_LVSEG_NUM_PROPERTY_FN(seg_start, lvseg_start(lvseg)) -+GET_LVSEG_NUM_PROPERTY_FN(seg_start, (SECTOR_SIZE * lvseg_start(lvseg))) - #define _seg_start_set _not_implemented_set - GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le) - #define _seg_start_pe_set _not_implemented_set -@@ -305,7 +305,7 @@ GET_LVSEG_STR_PROPERTY_FN(devices, lvseg_devices(lvseg->lv->vg->vgmem, lvseg)) - /* PVSEG */ - GET_PVSEG_NUM_PROPERTY_FN(pvseg_start, pvseg->pe) - #define _pvseg_start_set _not_implemented_set --GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, pvseg->len) -+GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, (SECTOR_SIZE * pvseg->len)) - #define _pvseg_size_set _not_implemented_set - - -diff --git a/lib/report/report.c b/lib/report/report.c -index eeca282..b1e2bc1 100644 ---- a/lib/report/report.c -+++ b/lib/report/report.c -@@ -830,7 +830,6 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct - const void *data, void *private __attribute__((unused))) - { - const struct logical_volume *lv = (const struct logical_volume *) data; -- struct lvinfo info; - percent_t snap_percent; - uint64_t *sortval; - char *repstr; -@@ -847,7 +846,7 @@ static int _snpercent_disp(struct dm_report *rh __attribute__((unused)), struct - } - - if ((!lv_is_cow(lv) && !lv_is_merging_origin(lv)) || -- !lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) || !info.exists) { -+ !lv_is_active(lv)) { - *sortval = UINT64_C(0); - dm_report_field_set_value(field, "", sortval); - return 1; -diff --git a/lib/thin/thin.c b/lib/thin/thin.c -index 2b6c71f..d7c45ca 100644 ---- a/lib/thin/thin.c -+++ b/lib/thin/thin.c -@@ -37,6 +37,9 @@ - log_error(t " segment %s of logical volume %s.", ## p, \ - dm_config_parent_name(sn), seg->lv->name), 0; - -+/* TODO: using static field here, maybe should be a part of segment_type */ -+static unsigned _feature_mask; -+ - static int _thin_target_present(struct cmd_context *cmd, - const struct lv_segment *seg, - unsigned *attributes); -@@ -282,10 +285,15 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, - return_0; - - if (attr & THIN_FEATURE_DISCARDS) { -+ /* Use ignore for discards ignore or non-power-of-2 chunk_size and <1.5 target */ - /* FIXME: Check whether underlying dev supports discards */ -- if (!dm_tree_node_set_thin_pool_discard(node, -- seg->discards == THIN_DISCARDS_IGNORE, -- seg->discards == THIN_DISCARDS_NO_PASSDOWN)) -+ if (((!(attr & THIN_FEATURE_DISCARDS_NON_POWER_2) && -+ (seg->chunk_size & (seg->chunk_size - 1))) || -+ (seg->discards == THIN_DISCARDS_IGNORE)) && -+ !dm_tree_node_set_thin_pool_discard(node, 1, 0)) -+ return_0; -+ else if (!dm_tree_node_set_thin_pool_discard(node, 0, -+ (seg->discards == THIN_DISCARDS_NO_PASSDOWN))) - return_0; - } else if (seg->discards != THIN_DISCARDS_IGNORE) - log_warn_suppress(_no_discards++, "WARNING: Thin pool target does " -@@ -534,10 +542,28 @@ static int _thin_target_present(struct cmd_context *cmd, - const struct lv_segment *seg, - unsigned *attributes) - { -+ /* List of features with their kernel target version */ -+ static const struct feature { -+ uint32_t maj; -+ uint32_t min; -+ unsigned thin_feature; -+ const char *feature; -+ } const _features[] = { -+ { 1, 1, THIN_FEATURE_DISCARDS, "discards" }, -+ { 1, 1, THIN_FEATURE_EXTERNAL_ORIGIN, "external_origin" }, -+ { 1, 4, THIN_FEATURE_BLOCK_SIZE, "block_size" }, -+ { 1, 5, THIN_FEATURE_DISCARDS_NON_POWER_2, "discards_non_power_2" }, -+ }; -+ -+ static const char _lvmconf[] = "global/thin_disabled_features"; - static int _checked = 0; - static int _present = 0; -- static int _attrs = 0; -+ static unsigned _attrs = 0; - uint32_t maj, min, patchlevel; -+ unsigned i; -+ const struct dm_config_node *cn; -+ const struct dm_config_value *cv; -+ const char *str; - - if (!_checked) { - _present = target_present(cmd, THIN_MODULE, 1); -@@ -547,29 +573,46 @@ static int _thin_target_present(struct cmd_context *cmd, - return 0; - } - -- if (maj >=1 && min >= 1) -- _attrs |= THIN_FEATURE_DISCARDS; -- else -- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ -- log_debug("Target " THIN_MODULE " does not support discards."); -- -- if (maj >=1 && min >= 1) -- _attrs |= THIN_FEATURE_EXTERNAL_ORIGIN; -- else -- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ -- log_debug("Target " THIN_MODULE " does not support external origins."); -- -- if (maj >=1 && min >= 4) -- _attrs |= THIN_FEATURE_BLOCK_SIZE; -- else -- /* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */ -- log_debug("Target " THIN_MODULE " does not support non power of 2 block sizes."); -+ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) -+ if (maj >= _features[i].maj && min >= _features[i].min) -+ _attrs |= _features[i].thin_feature; -+ else -+ log_very_verbose("Target " THIN_MODULE " does not support %s.", -+ _features[i].feature); - - _checked = 1; - } - -- if (attributes) -- *attributes = _attrs; -+ if (attributes) { -+ if (!_feature_mask) { -+ /* Support runtime lvm.conf changes, N.B. avoid 32 feature */ -+ if ((cn = find_config_tree_node(cmd, _lvmconf))) { -+ for (cv = cn->v; cv; cv = cv->next) { -+ if (cv->type != DM_CFG_STRING) { -+ log_error("Ignoring invalid string in config file %s.", -+ _lvmconf); -+ continue; -+ } -+ str = cv->v.str; -+ if (!*str) { -+ log_error("Ignoring empty string in config file %s.", -+ _lvmconf); -+ continue; -+ } -+ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) -+ if (strcasecmp(str, _features[i].feature) == 0) -+ _feature_mask |= _features[i].thin_feature; -+ } -+ } -+ _feature_mask = ~_feature_mask; -+ for (i = 0; i < sizeof(_features)/sizeof(*_features); i++) -+ if ((_attrs & _features[i].thin_feature) && -+ !(_feature_mask & _features[i].thin_feature)) -+ log_very_verbose("Target "THIN_MODULE " %s support disabled by %s", -+ _features[i].feature, _lvmconf); -+ } -+ *attributes = _attrs & _feature_mask; -+ } - - return _present; - } -@@ -671,5 +714,9 @@ int init_multiple_segtypes(struct cmd_context *cmd, struct segtype_library *segl - log_very_verbose("Initialised segtype: %s", segtype->name); - } - -+ -+ /* Reset mask for recalc */ -+ _feature_mask = 0; -+ - return 1; - } -diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c -index 096eba2..e4a574d 100644 ---- a/libdm/libdm-deptree.c -+++ b/libdm/libdm-deptree.c -@@ -2496,6 +2496,11 @@ int dm_tree_preload_children(struct dm_tree_node *dnode, - log_error("Unable to resume %s (%" PRIu32 - ":%" PRIu32 ")", child->name, child->info.major, - child->info.minor); -+ if (!_deactivate_node(child->name, child->info.major, child->info.minor, -+ &child->dtree->cookie, child->udev_flags, 0)) -+ log_error("Unable to deactivate %s (%" PRIu32 -+ ":%" PRIu32 ")", child->name, child->info.major, -+ child->info.minor); - r = 0; - continue; - } -diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c -index d47a857..b2a604d 100644 ---- a/liblvm/lvm_lv.c -+++ b/liblvm/lvm_lv.c -@@ -146,7 +146,7 @@ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) - { - struct lvcreate_params lp = { 0 }; - uint64_t extents; -- struct lv_list *lvl; -+ struct logical_volume *lv; - - if (vg_read_error(vg)) - return NULL; -@@ -162,11 +162,9 @@ lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) - _lv_set_default_params(&lp, vg, name, extents); - if (!_lv_set_default_linear_params(vg->cmd, &lp)) - return_NULL; -- if (!lv_create_single(vg, &lp)) -+ if (!(lv = lv_create_single(vg, &lp))) - return_NULL; -- if (!(lvl = find_lv_in_vg(vg, name))) -- return NULL; -- return (lv_t) lvl->lv; -+ return (lv_t) lv; - } - - /* -diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in -index 2659719..4fe9bdd 100644 ---- a/man/lvconvert.8.in -+++ b/man/lvconvert.8.in -@@ -40,7 +40,7 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot - .B lvconvert - .BR \-s | \-\-snapshot - .RB [ \-c | \-\-chunksize --.IR ChunkSize ] -+.IR ChunkSize [ bBsSkK ]] - .RB [ \-h | \-? | \-\-help ] - .RB [ \-\-noudevsync ] - .RB [ \-v | \-\-verbose ] -@@ -59,17 +59,6 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot - .RB [ \-\-version ] - .IR LogicalVolume [ Path ]... - .sp --.B lvconvert \-\-thinpool --.IR ThinPoolLogicalVolume { Name | Path } --.RB [ \-c | \-\-chunksize --.IR ChunkSize ] --.RB [ \-h | \-? | \-\-help ] --.RB [ \-v | \-\-verbose ] --.RB [ \-\-version ] --.RB [ \-Z | \-\-zero --.RI { y | n }] --.IR ThinMetadataLogicalVolume { Name | Path } --.sp - .B lvconvert \-\-repair - .RB [ \-h | \-? | \-\-help ] - .RB [ \-v | \-\-verbose ] -@@ -83,6 +72,31 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot - .RB [ \-\-version ] - .IR LogicalVolume [ Path ] - .RI [ PhysicalVolume [ Path ]...] -+.sp -+.B lvconvert \-\-thinpool -+.IR ThinPoolLogicalVolume { Name | Path } -+.RB [ \-c | \-\-chunksize -+.IR ChunkSize [ bBsSkKmMgG ]] -+.RB [ \-\-discards -+.RI { ignore | nopassdown | passdown }] -+.RB [[ \-\-poolmetadata -+.IR ThinPoolMetadataLogicalVolume { Name | Path }] -+| -+.RB [ \-\-poolmetadatasize -+.IR ThinPoolMetadataSize [ bBsSkKmMgG ]] -+.RB [ \-r | \-\-readahead -+.RI { ReadAheadSectors | auto | none }] -+.RB [ \-\-stripes -+.I Stripes -+.RB [ \-I | \-\-stripesize -+.IR StripeSize ]]] -+.RB [ \-Z | \-\-zero -+.RI { y | n }] -+.RB [ \-h | \-? | \-\-help ] -+.RB [ \-v | \-\-verbose ] -+.RB [ \-\-version ] -+.RI [ PhysicalVolume [ Path ][ :PE [ -PE ]]...] -+.sp - - .SH DESCRIPTION - lvconvert is used to change the segment type (i.e. linear, mirror, etc) or -@@ -102,8 +116,9 @@ the freed extents come first from the specified PhysicalVolumes. - See \fBlvm\fP(8) for common options. - .br - Exactly one of --.BR \-\-splitmirrors ", " \-\-mirrors ", " \-\-repair ", " \-\-snapshot --or \fB\-\-merge\fP arguments is required. -+.BR \-\-merge ", " \-\-mirrors ", " \-\-repair ", " \-\-replace -+.RB ", " \-\-snapshot ", " \-\-splitmirrors " or " \-\-thinpool -+arguments is required. - .TP - .BR \-m ", " \-\-mirrors " " \fIMirrors - Specifies the degree of the mirror you wish to create. -@@ -170,12 +185,28 @@ implementation and not with the original device-mapper mirror implementation. - Create a snapshot from existing logical volume using another - existing logical volume as its origin. - .TP --.BR \-c ", " \-\-chunksize " " \fIChunkSize --Power of 2 chunk size for the snapshot logical volume between 4KiB and 512KiB. -+.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ] -+Gives the size of chunk for snapshot and thin pool logical volumes. -+For snapshots the value must be power of 2 between 4KiB and 512KiB -+and the default value is 4. -+For thin pools the value must be between 64KiB and -+1GiB and the default value starts with 64 and scales -+up to fit the pool metadata size within 128MB, -+if the pool metadata size is not specified. -+Older dm thin pool target version (<1.4) requires the value to be power of 2. -+The newer version requires to be the multiple of 64KiB, however discard is -+not supported for non power of 2 values. -+Default unit is in kilobytes. -+.TP -+.BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown } -+Sets discards behavior for thin pool. -+Default is \fIpassdown\fP. - .TP - .BR \-Z ", " \-\-zero " {" \fIy | \fIn } - Controls zeroing of the first KB of data in the snapshot. - If the volume is read-only the snapshot will not be zeroed. -+For thin pool volumes it controls zeroing of provisioned blocks. -+Note: Provisioning of large zeroed chunks impacts performance. - .TP - .B \-\-merge - Merges a snapshot into its origin volume or merges a raid1 image that has -@@ -195,6 +226,35 @@ merge finishes, the merged snapshot is removed. Multiple snapshots may - be specified on the commandline or a @tag may be used to specify - multiple snapshots be merged to their respective origin. - .TP -+.BR \-\-poolmetadata " " \fIThinPoolMetadataLogicalVolume { \fIName | \fIPath } -+Specifies thin pool metadata logical volume. -+The size should be in between 2MiB and 16GiB. -+Thin pool is specified with the option -+\fB\-\-thinpool\fP. -+When the specified thin pool already exists, -+the thin pool's metadata volume will be swapped with the given LV. -+Properties of the thin pool like chunk size, discards or zero -+are preserved by default in this case. -+It can be useful for thin pool metadata repair or its offline resize, -+since the content of metadata becomes accessible for -+thin provisioning tools \fBthin_dump\fP(8) and \fBthin_restore\fP(8). -+.TP -+.BR \-\-poolmetadatasize " " \fIThinPoolMetadataSize [ \fIbBsSkKmMgG ] -+Sets the size of thin pool's metadata logical volume, -+if the pool metadata volume is undefined. -+Thin pool is specified with the option -+\fB\-\-thinpool\fP. -+Supported value is in the range between 2MiB and 16GiB. -+The default value is estimated with this formula -+(Pool_LV_size / Pool_LV_chunk_size * 64b). -+Default unit is megabytes. -+.TP -+.IR \fB\-r ", " \fB\-\-readahead " {" ReadAheadSectors | auto | none } -+Sets read ahead sector count of thin pool metadata logical volume. -+The default value is "auto" which allows the kernel to choose -+a suitable value automatically. -+"None" is equivalent to specifying zero. -+.TP - .B \-\-repair - Repair a mirror after suffering a disk failure. The mirror will be brought back - into a consistent state. By default, the original number of mirrors will be -@@ -210,6 +270,24 @@ Remove the specified device (\fIPhysicalVolume\fP) and replace it with one - that is available in the volume group or from the specific list provided. - This option is only available to RAID segment types - (e.g. "raid1", "raid5", etc). -+.TP -+.BR \-\-stripes " " \fIStripes -+Gives the number of stripes. -+This is equal to the number of physical volumes to scatter -+the logical volume. -+.TP -+.BR \-I ", " \-\-stripesize " " \fIStripeSize -+Gives the number of kilobytes for the granularity of the stripes. -+.br -+StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format. -+For metadata in LVM2 format, the stripe size may be a larger -+power of 2 but must not exceed the physical extent size. -+.TP -+.IR \fB\-\-thinpool " " ThinPoolLogicalVolume { Name | Path } -+Changes logical volume into a thin pool volume. The volume -+will store the pool's data. -+Thin pool metadata logical volume can be specified with the option -+\fB\-\-poolmetadata\fP or allocated with \fB\-\-poolmetadatasize\fP. - - .SH Examples - Converts the linear logical volume "vg00/lvol1" to a two-way mirror -@@ -304,4 +382,6 @@ available in the volume group. - .BR lvextend (8), - .BR lvreduce (8), - .BR lvdisplay (8), --.BR lvscan (8) -+.BR lvscan (8), -+.BR thin_dump(8), -+.BR thin_restore(8) -diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in -index fb54cc6..0616150 100644 ---- a/man/lvcreate.8.in -+++ b/man/lvcreate.8.in -@@ -53,11 +53,11 @@ lvcreate \- create a logical volume in an existing volume group - .RB [ \-t | \-\-test ] - .RB [ \-T | \-\-thin - .RB [ \-c | \-\-chunksize --.IR ChunkSize ] -+.IR ChunkSize [ bBsSkKmMgG ]] - .RB [ \-\-discards - .RI { ignore | nopassdown | passdown }] - .RB [ \-\-poolmetadatasize --.IR MetadataSize [ bBsSkKmMgG ]]] -+.IR ThinPoolMetadataSize [ bBsSkKmMgG ]]] - .RB [ \-\-thinpool - .IR ThinPoolLogicalVolume { Name | Path }] - .RB [ \-\-type -@@ -76,7 +76,7 @@ lvcreate \- create a logical volume in an existing volume group - .BR \-L | \-\-size - .IR LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]] - .RB [ \-c | \-\-chunksize --.IR ChunkSize ] -+.IR ChunkSize [ bBsSkK ]] - .RB [ \-\-noudevsync ] - .RB [ \-\-ignoremonitoring ] - .RB [ \-\-monitor " {" \fIy | \fIn }] -@@ -125,14 +125,14 @@ always assumed and it can't be overridden. If clustered locking is enabled, - \fB\-a\fIey\fR will activate exclusively on one node and \fB\-a\fIly\fR will - activate only on the local node. - .TP --.BR \-c ", " \-\-chunksize " " \fIChunkSize -+.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ] - Gives the size of chunk for snapshot and thin pool logical volumes. - For snapshots the value must be power of 2 between 4KiB and 512KiB - and the default value is 4. - For thin pools the value must be between 64KiB and --1048576KiB and the default value starts with 64 and scales -+1GiB and the default value starts with 64 and scales - up to fit the pool metadata size within 128MB, --if the poolmetadata size is not specified. -+if the pool metadata size is not specified. - Older dm thin pool target version (<1.4) requires the value to be power of 2. - The newer version requires to be the multiple of 64KiB, however discard is - not supported for non power of 2 values. -@@ -144,7 +144,7 @@ logical volumes. Default is no contiguous allocation based - on a next free principle. - .TP - .BR \-\-discards " {" \fIignore | \fInopassdown | \fIpassdown } --Set discards behavior. -+Set discards behavior for thin pool. - Default is \fIpassdown\fP. - .TP - .BR \-i ", " \-\-stripes " " \fIStripes -@@ -236,7 +236,7 @@ Set access permissions to read only or read and write. - .br - Default is read and write. - .TP --.IR \fB\-\-poolmetadatasize " " MetadataSize [ bBsSkKmMgG ] -+.IR \fB\-\-poolmetadatasize " " ThinPoolMetadataSize [ bBsSkKmMgG ] - Set the size of thin pool's metadata logical volume. - Supported value is in range between 2MiB and 16GiB. - Default value is (Pool_LV_size / Pool_LV_chunk_size * 64b). -@@ -364,7 +364,7 @@ a parity drive for a total of 4 devices) and a stripesize of 64KiB: - .B lvcreate \-\-type raid5 \-L 5G \-i 3 \-I 64 \-n my_lv vg00 - - Creates 100MiB pool logical volume for thin provisioning --build with 2 stripes 64KiB and chunk size 128KiB together with -+build with 2 stripes 64KiB and chunk size 256KiB together with - 1TiB thin provisioned logical volume "vg00/thin_lv": - .sp - .B lvcreate \-i 2 \-I 64 \-c 256 \-L100M \-T vg00/pool \-V 1T \-\-name thin_lv -diff --git a/man/vgcfgrestore.8.in b/man/vgcfgrestore.8.in -index 3b7b038..7b8dd59 100644 ---- a/man/vgcfgrestore.8.in -+++ b/man/vgcfgrestore.8.in -@@ -6,6 +6,7 @@ vgcfgrestore \- restore volume group descriptor area - .RB [ \-d | \-\-debug ] - .RB [ \-f | \-\-file - .RI < filename >] -+.RB [ \-\-force ] - .RB [ \-l [ l ]| \-\-list ] - .RB [ \-h | \-\-help ] - .RB [ \-M | \-\-metadatatype -@@ -32,6 +33,14 @@ May be used with the \fB\-f\fP option. Does not restore \fIVolumeGroupName\fP. - Name of LVM metadata backup file - Specifies a metadata backup or archive file to be used for restoring - VolumeGroupName. Often this file has been created with \fBvgcfgbackup\fP. -+.TP -+.B \-\-force -+To restore metadata with thin pool volumes, user currently -+needs to use this flag. The tool DOES NOT make any validation. -+.br -+WARNING: Restoring lvm2 metadata that are not matching thin pool -+kernel metadata may lead to the destruction of the pool content. -+Use with extreme caution. - .SH REPLACING PHYSICAL VOLUMES - \fBvgdisplay \-\-partial \-\-verbose\fP will show you the UUIDs and sizes of - any PVs that are no longer present. -diff --git a/test/api/thin_percent.c b/test/api/thin_percent.c -index 2c8b19b..ae511df 100644 ---- a/test/api/thin_percent.c -+++ b/test/api/thin_percent.c -@@ -23,6 +23,8 @@ int main(int argc, char *argv[]) - vg_t vg; - lv_t lv; - struct lvm_property_value v; -+ struct dm_list *lvsegs; -+ struct lvm_lvseg_list *lvl; - - handle = lvm_init(NULL); - assert(handle); -@@ -33,6 +35,14 @@ int main(int argc, char *argv[]) - lv = lvm_lv_from_name(vg, "pool"); - assert(lv); - -+ lvsegs = lvm_lv_list_lvsegs(lv); -+ assert(lvsegs && (dm_list_size(lvsegs) == 1)); -+ dm_list_iterate_items(lvl, lvsegs) { -+ v = lvm_lvseg_get_property(lvl->lvseg, "discards"); -+ assert(v.is_valid && v.is_string); -+ assert(strcmp(v.value.string, "passdown") == 0); -+ } -+ - v = lvm_lv_get_property(lv, "data_percent"); - assert(v.is_valid); - assert(v.value.integer == 25 * PERCENT_1); -diff --git a/test/api/thin_percent.sh b/test/api/thin_percent.sh -index 9287cf3..e14e807 100644 ---- a/test/api/thin_percent.sh -+++ b/test/api/thin_percent.sh -@@ -30,7 +30,7 @@ dd if=/dev/urandom of="$DM_DEV_DIR/$vg/thin" count=2 bs=256K - lvcreate -s $vg/thin -n snap - dd if=/dev/urandom of="$DM_DEV_DIR/$vg/snap" count=3 bs=256K - --lvs $vg -+lvs -o+discards $vg - - aux apitest thin_percent $vg - -diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh -index 97ccc09..4634aa2 100644 ---- a/test/shell/lvconvert-thin.sh -+++ b/test/shell/lvconvert-thin.sh -@@ -12,6 +12,13 @@ - - . lib/test - -+prepare_lvs() -+{ -+ lvremove -f $vg -+ lvcreate -L10M -n $lv1 $vg -+ lvcreate -L8M -n $lv2 $vg -+} -+ - # - # Main - # -@@ -19,25 +26,73 @@ aux have_thin 1 0 0 || skip - - aux prepare_pvs 4 64 - --vgcreate $vg -s 64K $(cat DEVICES) -+# build one large PV -+vgcreate $vg1 $(cut -d ' ' -f -3 DEVICES) -+lvcreate -s -l 100%FREE -n $lv $vg1 --virtualsize 64T -+aux lvmconf 'devices/filter = [ "a/dev\/mapper\/.*$/", "a/dev\/LVMTEST/", "r/.*/" ]' -+ -+pvcreate "$DM_DEV_DIR/$vg1/$lv" -+vgcreate $vg -s 64K $(cut -d ' ' -f 4 DEVICES) "$DM_DEV_DIR/$vg1/$lv" - - # create mirrored LVs for data and metadata volumes --lvcreate -aey -l8 -m1 --mirrorlog core -n $lv1 $vg --lvcreate -aey -l4 -m1 --mirrorlog core -n $lv2 $vg -+lvcreate -aey -L10M -m1 --mirrorlog core -n $lv1 $vg -+lvcreate -aey -L8M -m1 --mirrorlog core -n $lv2 $vg -+lvchange -an $vg/$lv1 -+ -+ -+# conversion fails for internal volumes -+not lvconvert --thinpool $vg/${lv1}_mimage_0 -+not lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/${lv2}_mimage_0 -+# can't use --readahead with --poolmetadata -+not lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 --readahead 512 -+ -+lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+ -+prepare_lvs -+lvconvert -c 64 --stripes 2 --thinpool $vg/$lv1 --readahead 48 -+ -+lvremove -f $vg -+lvcreate -L1T -n $lv1 $vg -+lvconvert -c 8M --thinpool $vg/$lv1 -+ -+lvremove -f $vg -+# test with bigger sizes -+lvcreate -L1T -n $lv1 $vg -+lvcreate -L8M -n $lv2 $vg -+lvcreate -L1M -n $lv3 $vg - --lvconvert -c 64K --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+# chunk size is bigger then size of thin pool data -+not lvconvert -c 1G --thinpool $vg/$lv3 -+# stripes can't be used with poolmetadata -+not lvconvert --stripes 2 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+# too small metadata (<2M) -+not lvconvert -c 64 --thinpool $vg/$lv1 --poolmetadata $vg/$lv3 -+# too small chunk size fails -+not lvconvert -c 4 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+# too big chunk size fails -+not lvconvert -c 2G --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+# negative chunk size fails -+not lvconvert -c -256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 -+# non power of 2 fails -+not lvconvert -c 88 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 - --lvcreate -V10M -T $vg/$lv1 --name $lv3 -+# Warning about smaller then suggested -+lvconvert -c 256 --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 |& tee err -+grep "WARNING: Chunk size is smaller" err - --# check lvrename work properly --lvrename $vg/$lv1 $vg/pool --check lv_field $vg/pool name "pool" -+lvremove -f $vg -+lvcreate -L1T -n $lv1 $vg -+lvcreate -L32G -n $lv2 $vg -+# Warning about bigger then needed -+lvconvert --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 |& tee err -+grep "WARNING: Maximum size" err - --lvrename $vg/$lv3 $vg/$lv4 --check lv_field $vg/$lv4 name "$lv4" -+lvremove -f $vg -+lvcreate -L24T -n $lv1 $vg -+# Warning about bigger then needed (24T data and 16G -> 128K chunk) -+lvconvert -c 64 --thinpool $vg/$lv1 |& tee err -+grep "WARNING: Chunk size is too small" err - --# not yet supported conversions --not lvconvert -m 1 $vg/pool --not lvconvert -m 1 $vg/$lv3 -+#lvs -a -o+chunk_size,stripe_size,seg_pe_ranges - - vgremove -ff $vg -diff --git a/test/shell/thin-defaults.sh b/test/shell/thin-defaults.sh -new file mode 100644 -index 0000000..677d2f1 ---- /dev/null -+++ b/test/shell/thin-defaults.sh -@@ -0,0 +1,35 @@ -+#!/bin/bash -+# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -+# -+# This copyrighted material is made available to anyone wishing to use, -+# modify, copy, or redistribute it subject to the terms and conditions -+# of the GNU General Public License v.2. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software Foundation, -+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+# test defaults entered through lvm.conf -+ -+. lib/test -+ -+# -+# Main -+# -+aux have_thin 1 0 0 || skip -+ -+aux prepare_vg 2 -+ -+lvcreate -T -L8M $vg/pool0 -+ -+aux lvmconf "allocation/thin_pool_chunk_size = 128" \ -+ "allocation/thin_pool_discards = \"ignore\"" \ -+ "allocation/thin_pool_zero = 0" -+ -+lvcreate -T -L8M $vg/pool1 -+ -+check lv_field $vg/pool1 chunksize "128.00k" -+check lv_field $vg/pool1 discards "ignore" -+check lv_field $vg/pool1 zero 0 -+ -+vgremove -f $vg -diff --git a/test/shell/thin-restore.sh b/test/shell/thin-restore.sh -new file mode 100644 -index 0000000..7580ae4 ---- /dev/null -+++ b/test/shell/thin-restore.sh -@@ -0,0 +1,34 @@ -+#!/bin/bash -+# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -+# -+# This copyrighted material is made available to anyone wishing to use, -+# modify, copy, or redistribute it subject to the terms and conditions -+# of the GNU General Public License v.2. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software Foundation, -+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ -+# test restore operation of thin pool metadata -+ -+. lib/test -+ -+# -+# Main -+# -+aux have_thin 1 0 0 || skip -+ -+aux prepare_vg 2 -+ -+lvcreate -T -L8M $vg/pool -V10M -n $lv1 -+ -+vgcfgbackup -f backup $vg -+ -+# use of --force is mandatory -+not vgcfgrestore -f backup $vg -+ -+vgcfgrestore -f backup --force $vg -+ -+check lv_field $vg/pool transaction_id 1 -+ -+vgremove -f $vg -diff --git a/tools/args.h b/tools/args.h -index 0d9605a..d4d6c40 100644 ---- a/tools/args.h -+++ b/tools/args.h -@@ -73,6 +73,7 @@ arg(poll_ARG, '\0', "poll", yes_no_arg, 0) - arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0) - arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0) - arg(discards_ARG, '\0', "discards", discards_arg, 0) -+arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE) - arg(stripes_long_ARG, '\0', "stripes", int_arg, 0) - arg(sysinit_ARG, '\0', "sysinit", NULL, 0) - arg(thinpool_ARG, '\0', "thinpool", string_arg, 0) -diff --git a/tools/commands.h b/tools/commands.h -index 6415d34..986539e 100644 ---- a/tools/commands.h -+++ b/tools/commands.h -@@ -147,13 +147,16 @@ xx(lvconvert, - "--thinpool ThinPoolLogicalVolume[Path]\n" - "\t[--chunksize size]\n" - "\t[--discards {ignore|nopassdown|passdown}]\n" -- "\t[[--poolmetadatasize size] | --poolmetadata ThinMetadataLogicalVolume[Path]]\n" -+ "\t[--poolmetadata ThinMetadataLogicalVolume[Path] |\n" -+ "\t [--poolmetadatasize size]\n" -+ "\t [-r|--readahead ReadAheadSectors|auto|none]\n" -+ "\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n" - "\t[-Z|--zero {y|n}]\n" - "\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n", - - alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG, - merge_ARG, mirrorlog_ARG, mirrors_ARG, name_ARG, noudevsync_ARG, -- regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG, -+ readahead_ARG, regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG, - trackchanges_ARG, type_ARG, stripes_long_ARG, stripesize_ARG, test_ARG, - chunksize_ARG, discards_ARG, poolmetadata_ARG, poolmetadatasize_ARG, thinpool_ARG, - use_policies_ARG, yes_ARG, force_ARG, zero_ARG) -@@ -722,6 +725,7 @@ xx(vgcfgrestore, - "vgcfgrestore " "\n" - "\t[-d|--debug] " "\n" - "\t[-f|--file filename] " "\n" -+ "\t[--force]\n" - "\t[-l[l]|--list [--list]]" "\n" - "\t[-M|--metadatatype 1|2]" "\n" - "\t[-h|--help]" "\n" -@@ -730,7 +734,7 @@ xx(vgcfgrestore, - "\t[--version] " "\n" - "\tVolumeGroupName", - -- file_ARG, list_ARG, metadatatype_ARG, test_ARG) -+ file_ARG, force_long_ARG, list_ARG, metadatatype_ARG, test_ARG) - - xx(vgchange, - "Change volume group attributes", -diff --git a/tools/lvchange.c b/tools/lvchange.c -index 04facdd..7156eeb 100644 ---- a/tools/lvchange.c -+++ b/tools/lvchange.c -@@ -111,13 +111,7 @@ static int lvchange_pool_update(struct cmd_context *cmd, - if (arg_count(cmd, discards_ARG)) { - discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_IGNORE); - if (discards != first_seg(lv)->discards) { -- if ((discards != THIN_DISCARDS_IGNORE) && -- (first_seg(lv)->chunk_size & -- (first_seg(lv)->chunk_size - 1))) -- log_error("Cannot change discards state for " -- "logical volume \"%s\" " -- "with non power of 2 chunk size.", lv->name); -- else if (((discards == THIN_DISCARDS_IGNORE) || -+ if (((discards == THIN_DISCARDS_IGNORE) || - (first_seg(lv)->discards == THIN_DISCARDS_IGNORE)) && - lv_is_active(lv)) - log_error("Cannot change discards state for active " -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index 132a69d..c584180 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -39,8 +39,10 @@ struct lvconvert_params { - uint32_t keep_mimages; - uint32_t stripes; - uint32_t stripe_size; -+ uint32_t read_ahead; - - const struct segment_type *segtype; -+ unsigned target_attr; - - alloc_policy_t alloc; - -@@ -155,6 +157,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, - int pagesize = lvm_getpagesize(); - - memset(lp, 0, sizeof(*lp)); -+ lp->target_attr = ~0; - - if ((arg_count(cmd, snapshot_ARG) || arg_count(cmd, merge_ARG)) && - (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG) || -@@ -268,6 +271,8 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, - if (lp->merge) { /* Snapshot merge */ - if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) || - arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) || -+ arg_count(cmd, poolmetadata_ARG) || arg_count(cmd, poolmetadatasize_ARG) || -+ arg_count(cmd, readahead_ARG) || - arg_count(cmd, stripes_long_ARG) || arg_count(cmd, stripesize_ARG)) { - log_error("Only --background and --interval are valid " - "arguments for snapshot merge"); -@@ -335,53 +340,21 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, - return 0; - } - -+ if (!get_pool_params(cmd, -+ &lp->chunk_size, -+ &lp->discards, -+ &lp->poolmetadata_size, -+ &lp->zero)) -+ return_0; -+ - if (arg_count(cmd, poolmetadata_ARG)) { -- lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, ""); -- } else if (arg_count(cmd, poolmetadatasize_ARG)) { -- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { -- log_error("Negative pool metadata size is invalid."); -+ if (arg_count(cmd, poolmetadatasize_ARG)) { -+ log_error("--poolmetadatasize is invalid with --poolmetadata."); - return 0; - } -- lp->poolmetadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); -- -- if (lp->poolmetadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -- if (arg_count(cmd, poolmetadatasize_ARG)) -- log_warn("WARNING: Maximum supported pool metadata size is 16GB."); -- lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -- } else if (lp->poolmetadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { -- if (arg_count(cmd, poolmetadatasize_ARG)) -- log_warn("WARNING: Minimum supported pool metadata size is 2M."); -- lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; -- } -- -- log_verbose("Setting pool metadata size to %" PRIu64 " sectors.", -- lp->poolmetadata_size); -+ lp->pool_metadata_lv_name = arg_str_value(cmd, poolmetadata_ARG, ""); - } - -- if (arg_count(cmd, chunksize_ARG)) { -- if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { -- log_error("Negative chunk size is invalid."); -- return 0; -- } -- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, -- DM_THIN_MIN_DATA_BLOCK_SIZE); -- -- if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || -- (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { -- log_error("Chunk size must be in the range %uK to %uK.", -- (DM_THIN_MIN_DATA_BLOCK_SIZE / 2), -- (DM_THIN_MAX_DATA_BLOCK_SIZE / 2)); -- return 0; -- } -- } else -- lp->chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; -- -- log_verbose("Setting pool metadata chunk size to %u sectors.", -- lp->chunk_size); -- -- if (arg_count(cmd, zero_ARG)) -- lp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n"); -- - /* If --thinpool contains VG name, extract it. */ - if ((tmp_str = strchr(lp->pool_data_lv_name, (int) '/'))) { - if (!(lp->vg_name = extract_vgname(cmd, lp->pool_data_lv_name))) -@@ -460,7 +433,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, - } - - if (activation() && lp->segtype && lp->segtype->ops->target_present && -- !lp->segtype->ops->target_present(cmd, NULL, NULL)) { -+ !lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) { - log_error("%s: Required device-mapper target(s) not " - "detected in your kernel", lp->segtype->name); - return 0; -@@ -1826,12 +1799,20 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - { - int r = 0; - char *name; -+ const char *old_name; - int len; - struct lv_segment *seg; - struct logical_volume *data_lv; - struct logical_volume *metadata_lv; -+ struct logical_volume *pool_metadata_lv; -+ -+ if (!lv_is_visible(pool_lv)) { -+ log_error("Can't convert internal LV %s/%s.", -+ pool_lv->vg->name, pool_lv->name); -+ return 0; -+ } - -- if (lv_is_thin_type(pool_lv)) { -+ if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) { - log_error("Can't use thin logical volume %s/%s for thin pool data.", - pool_lv->vg->name, pool_lv->name); - return 0; -@@ -1839,19 +1820,48 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - - /* We are changing target type, so deactivate first */ - if (!deactivate_lv(cmd, pool_lv)) { -- log_error("Can't deactivate logical volume %s/%s.", -+ log_error("Aborting. Failed to deactivate logical volume %s/%s.", - pool_lv->vg->name, pool_lv->name); - return 0; - } - -+ len = strlen(pool_lv->name) + 16; -+ if (!(name = dm_pool_alloc(pool_lv->vg->vgmem, len))) { -+ log_error("Can't allocate new name."); -+ return 0; -+ } -+ -+ if (dm_snprintf(name, len, "%s_tmeta", pool_lv->name) < 0) { -+ log_error("Failed to create layer name."); -+ return 0; -+ } -+ - if (lp->pool_metadata_lv_name) { -+ if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) { -+ log_error("Can't use --stripes and --stripesize with --poolmetadata."); -+ return 0; -+ } -+ if (arg_count(cmd, readahead_ARG)) { -+ log_error("Can't use --readahead with --poolmetadata."); -+ return 0; -+ } - metadata_lv = find_lv(pool_lv->vg, lp->pool_metadata_lv_name); - if (!metadata_lv) { -- log_error("Unknown metadata LV %s", lp->pool_metadata_lv_name); -+ log_error("Unknown metadata LV %s.", lp->pool_metadata_lv_name); -+ return 0; -+ } -+ if (!lv_is_visible(metadata_lv)) { -+ log_error("Can't convert internal LV %s/%s.", -+ metadata_lv->vg->name, metadata_lv->name); -+ return 0; -+ } -+ if (metadata_lv->status & LOCKED) { -+ log_error("Can't convert locked LV %s/%s.", -+ metadata_lv->vg->name, metadata_lv->name); - return 0; - } - if (metadata_lv == pool_lv) { -- log_error("Can't use same LV for thin data and metadata LV %s", -+ log_error("Can't use same LV for thin pool data and metadata LV %s.", - lp->pool_metadata_lv_name); - return 0; - } -@@ -1861,37 +1871,95 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - metadata_lv->vg->name, metadata_lv->name); - return 0; - } -- } else if (arg_count(cmd, poolmetadatasize_ARG)) { -- /* FIXME: allocate metadata LV! */ -- metadata_lv = NULL; -- log_error("Uncreated metadata."); -- return 0; -- } else { -- log_error("Uknown metadata."); -- return 0; -- } - -- len = strlen(pool_lv->name) + 16; -- if (!(name = dm_pool_alloc(pool_lv->vg->vgmem, len))) { -- log_error("Cannot allocate new name."); -- return 0; -- } -+ /* Swap normal LV with pool's metadata LV ? */ -+ if (lv_is_thin_pool(pool_lv)) { -+ if (!deactivate_lv(cmd, metadata_lv)) { -+ log_error("Aborting. Failed to deactivate thin metadata lv."); -+ return 0; -+ } -+ if (!arg_count(cmd, yes_ARG) && -+ yes_no_prompt("Do you want to swap metadata of %s/%s pool with " -+ "volume %s/%s? [y/n]: ", -+ pool_lv->vg->name, pool_lv->name, -+ pool_lv->vg->name, metadata_lv->name) == 'n') { -+ log_error("Conversion aborted."); -+ return 0; -+ } -+ seg = first_seg(pool_lv); -+ /* Swap names between old and new metadata LV */ -+ if (!detach_pool_metadata_lv(seg, &pool_metadata_lv)) -+ return_0; -+ old_name = metadata_lv->name; -+ if (!lv_rename_update(cmd, metadata_lv, "pvmove_tmeta", 0)) -+ return_0; -+ if (!lv_rename_update(cmd, pool_metadata_lv, old_name, 0)) -+ return_0; - -- if (!lv_is_active(metadata_lv)) { -- if (!deactivate_lv(cmd, metadata_lv)) { -- log_error("Can't deactivate logical volume %s/%s.", -- metadata_lv->vg->name, metadata_lv->name); -- return 0; -+ if (!arg_count(cmd, chunksize_ARG)) -+ lp->chunk_size = seg->chunk_size; -+ else if ((lp->chunk_size != seg->chunk_size) && -+ !arg_count(cmd, force_ARG) && -+ yes_no_prompt("Do you really want to change chunk size %s to %s for %s/%s " -+ "pool volume? [y/n]: ", display_size(cmd, seg->chunk_size), -+ display_size(cmd, lp->chunk_size), -+ pool_lv->vg->name, pool_lv->name) == 'n') { -+ log_error("Conversion aborted."); -+ return 0; -+ } -+ if (!arg_count(cmd, discards_ARG)) -+ lp->discards = seg->discards; -+ if (!arg_count(cmd, zero_ARG)) -+ lp->zero = seg->zero_new_blocks; -+ -+ goto mda_write; - } -- if (!activate_lv_local(cmd, metadata_lv)) { -+ -+ if (!lv_is_active(metadata_lv) && -+ !activate_lv_local(cmd, metadata_lv)) { - log_error("Aborting. Failed to activate thin metadata lv."); - return 0; - } -- } -+ if (!set_lv(cmd, metadata_lv, UINT64_C(0), 0)) { -+ log_error("Aborting. Failed to wipe thin metadata lv."); -+ return 0; -+ } - -- if (!set_lv(cmd, metadata_lv, UINT64_C(0), 0)) { -- log_error("Aborting. Failed to wipe thin metadata lv."); -- return 0; -+ lp->poolmetadata_size = -+ (uint64_t) metadata_lv->le_count * metadata_lv->vg->extent_size; -+ if (lp->poolmetadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -+ log_warn("WARNING: Maximum size used by metadata is %s, rest is unused.", -+ display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)); -+ lp->poolmetadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -+ } else if (lp->poolmetadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { -+ log_error("Logical volume %s/%s is too small (<%s) for metadata.", -+ metadata_lv->vg->name, metadata_lv->name, -+ display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)); -+ return 0; -+ } -+ if (!update_pool_params(cmd, lp->target_attr, -+ pool_lv->le_count, pool_lv->vg->extent_size, -+ &lp->chunk_size, &lp->discards, -+ &lp->poolmetadata_size)) -+ return_0; -+ } else { -+ if (!update_pool_params(cmd, lp->target_attr, -+ pool_lv->le_count, pool_lv->vg->extent_size, -+ &lp->chunk_size, &lp->discards, -+ &lp->poolmetadata_size)) -+ return_0; -+ -+ if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size)) -+ return_0; -+ /* Hmm _read_activation_params */ -+ lp->read_ahead = arg_uint_value(cmd, readahead_ARG, -+ cmd->default_settings.read_ahead); -+ -+ if (!(metadata_lv = alloc_pool_metadata(pool_lv, lp->alloc, name, -+ lp->pvh, lp->read_ahead, -+ lp->stripes, lp->stripe_size, -+ lp->poolmetadata_size))) -+ return_0; - } - - if (!deactivate_lv(cmd, metadata_lv)) { -@@ -1900,14 +1968,6 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - return 0; - } - -- if (dm_snprintf(name, len, "%s_tmeta", pool_lv->name) < 0) -- return_0; -- -- /* Rename deactivated metadata LV to have _tmeta suffix */ -- /* Implicit checks if metadata_lv is visible */ -- if (!lv_rename_update(cmd, metadata_lv, name, 0)) -- return_0; -- - /* - * Since we wish to have underlaying dev, to match _tdata - * rename data LV first, also checks for visible LV -@@ -1925,18 +1985,26 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - seg->segtype = lp->segtype; - seg->lv->status |= THIN_POOL; - -- seg->chunk_size = lp->chunk_size; -- seg->zero_new_blocks = lp->zero ? 1 : 0; -- seg->discards = lp->discards; -+ /* Drop reference as attach_pool_data_lv() takes it again */ -+ remove_seg_from_segs_using_this_lv(data_lv, seg); -+ if (!attach_pool_data_lv(seg, data_lv)) -+ return_0; -+ - seg->low_water_mark = 0; - seg->transaction_id = 0; - -- if (!attach_pool_metadata_lv(seg, metadata_lv)) -+mda_write: -+ seg->chunk_size = lp->chunk_size; -+ seg->discards = lp->discards; -+ seg->zero_new_blocks = lp->zero ? 1 : 0; -+ -+ /* Rename deactivated metadata LV to have _tmeta suffix */ -+ /* Implicit checks if metadata_lv is visible */ -+ if (strcmp(metadata_lv->name, name) && -+ !lv_rename_update(cmd, metadata_lv, name, 0)) - return_0; - -- /* Drop reference as attach_pool_data_lv() takes it again */ -- remove_seg_from_segs_using_this_lv(data_lv, seg); -- if (!attach_pool_data_lv(seg, data_lv)) -+ if (!attach_pool_metadata_lv(seg, metadata_lv)) - return_0; - - if (!vg_write(pool_lv->vg) || !vg_commit(pool_lv->vg)) -@@ -1945,6 +2013,11 @@ static int _lvconvert_thinpool(struct cmd_context *cmd, - if (!activate_lv_excl(cmd, pool_lv)) { - log_error("Failed to activate pool logical volume %s/%s.", - pool_lv->vg->name, pool_lv->name); -+ /* Deactivate subvolumes */ -+ if (!deactivate_lv(cmd, seg_lv(seg, 0))) -+ log_error("Failed to deactivate pool data logical volume."); -+ if (!deactivate_lv(cmd, seg->metadata_lv)) -+ log_error("Failed to deactivate pool metadata logical volume."); - goto out; - } - -diff --git a/tools/lvcreate.c b/tools/lvcreate.c -index 3ea8f46..1fcbde3 100644 ---- a/tools/lvcreate.c -+++ b/tools/lvcreate.c -@@ -234,7 +234,6 @@ static int _update_extents_params(struct volume_group *vg, - { - uint32_t pv_extent_count; - struct logical_volume *origin = NULL; -- int changed = 0; - uint32_t size_rest; - uint32_t stripesize_extents; - -@@ -308,38 +307,11 @@ static int _update_extents_params(struct volume_group *vg, - } - - if (lp->create_thin_pool) { -- if (!arg_count(vg->cmd, poolmetadatasize_ARG)) { -- /* Defaults to nr_pool_blocks * 64b */ -- lp->poolmetadatasize = (uint64_t) lp->extents * vg->extent_size / -- (uint64_t) (lp->chunk_size * (SECTOR_SIZE / UINT64_C(64))); -- -- /* Check if we could eventually use bigger chunk size */ -- if (!arg_count(vg->cmd, chunksize_ARG)) { -- while ((lp->poolmetadatasize > -- (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) && -- (lp->chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) { -- lp->chunk_size <<= 1; -- lp->poolmetadatasize >>= 1; -- changed++; -- } -- if (changed) -- log_verbose("Changed chunksize to %u sectors.", -- lp->chunk_size); -- } -- } -- -- if (lp->poolmetadatasize > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -- if (arg_count(vg->cmd, poolmetadatasize_ARG)) -- log_warn("WARNING: Maximum supported pool metadata size is 16GB."); -- lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -- } else if (lp->poolmetadatasize < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { -- if (arg_count(vg->cmd, poolmetadatasize_ARG)) -- log_warn("WARNING: Minimum supported pool metadata size is 2M."); -- lp->poolmetadatasize = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; -- } -- -- log_verbose("Setting pool metadata size to %" PRIu64 " sectors.", -- lp->poolmetadatasize); -+ if (!update_pool_params(vg->cmd, lp->target_attr, -+ lp->extents, vg->extent_size, -+ &lp->chunk_size, &lp->discards, -+ &lp->poolmetadatasize)) -+ return_0; - - if (!(lp->poolmetadataextents = - extents_from_size(vg->cmd, lp->poolmetadatasize, vg->extent_size))) -@@ -386,16 +358,9 @@ static int _read_size_params(struct lvcreate_params *lp, - if (lp->thin && (arg_count(cmd, size_ARG) || arg_count(cmd, extents_ARG))) - lp->create_thin_pool = 1; - -- if (arg_count(cmd, poolmetadatasize_ARG)) { -- if (!seg_is_thin(lp)) { -- log_error("--poolmetadatasize may only be specified when allocating the thin pool."); -- return 0; -- } -- if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { -- log_error("Negative poolmetadatasize is invalid."); -- return 0; -- } -- lp->poolmetadatasize = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); -+ if (arg_count(cmd, poolmetadatasize_ARG) && !seg_is_thin(lp)) { -+ log_error("--poolmetadatasize may only be specified when allocating the thin pool."); -+ return 0; - } - - /* Size returned in kilobyte units; held in sectors */ -@@ -679,11 +644,11 @@ static int _lvcreate_params(struct lvcreate_params *lp, - struct arg_value_group_list *current_group; - const char *segtype_str; - const char *tag; -- unsigned attr = 0; - - memset(lp, 0, sizeof(*lp)); - memset(lcp, 0, sizeof(*lcp)); - dm_list_init(&lp->tags); -+ lp->target_attr = ~0; - - /* - * Check selected options are compatible and determine segtype -@@ -796,7 +761,7 @@ static int _lvcreate_params(struct lvcreate_params *lp, - } - - if (activation() && lp->segtype->ops->target_present && -- !lp->segtype->ops->target_present(cmd, NULL, &attr)) { -+ !lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) { - log_error("%s: Required device-mapper target(s) not " - "detected in your kernel", lp->segtype->name); - return 0; -@@ -812,16 +777,23 @@ static int _lvcreate_params(struct lvcreate_params *lp, - } - } - -+ /* -+ * Should we zero the lv. -+ */ -+ lp->zero = strcmp(arg_str_value(cmd, zero_ARG, -+ (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n"); -+ - if (!_lvcreate_name_params(lp, cmd, &argc, &argv) || - !_read_size_params(lp, lcp, cmd) || - !get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) || -+ (lp->create_thin_pool && -+ !get_pool_params(cmd, &lp->chunk_size, &lp->discards, -+ &lp->poolmetadatasize, &lp->zero)) || - !_read_mirror_params(lp, cmd) || - !_read_raid_params(lp, cmd)) - return_0; - -- if (lp->create_thin_pool) -- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN); -- else if (arg_count(cmd, discards_ARG)) { -+ if (!lp->create_thin_pool && arg_count(cmd, discards_ARG)) { - log_error("--discards is only available for thin pool creation."); - return 0; - } -@@ -831,58 +803,27 @@ static int _lvcreate_params(struct lvcreate_params *lp, - else if (lp->thin && !lp->create_thin_pool) { - if (arg_count(cmd, chunksize_ARG)) - log_warn("WARNING: Ignoring --chunksize when using an existing pool."); -- } else if (lp->snapshot || lp->create_thin_pool) { -+ } else if (lp->snapshot) { - if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { - log_error("Negative chunk size is invalid"); - return 0; - } -- if (lp->snapshot) { -- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8); -- if (lp->chunk_size < 8 || lp->chunk_size > 1024 || -- (lp->chunk_size & (lp->chunk_size - 1))) { -- log_error("Chunk size must be a power of 2 in the " -- "range 4K to 512K"); -- return 0; -- } -- } else { -- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, -- DM_THIN_MIN_DATA_BLOCK_SIZE); -- if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || -- (lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { -- log_error("Chunk size must be in the range %uK to %uK", -- (DM_THIN_MIN_DATA_BLOCK_SIZE / 2), -- (DM_THIN_MAX_DATA_BLOCK_SIZE / 2)); -- return 0; -- } -- if (!(attr & THIN_FEATURE_BLOCK_SIZE) && -- (lp->chunk_size & (lp->chunk_size - 1))) { -- log_error("Chunk size must be a power of 2 for this thin target version."); -- return 0; -- } else if (lp->chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) { -- log_error("Chunk size must be multiple of %uK.", -- DM_THIN_MIN_DATA_BLOCK_SIZE / 2); -- return 0; -- } else if ((lp->discards != THIN_DISCARDS_IGNORE) && -- (lp->chunk_size & (lp->chunk_size - 1))) { -- log_warn("WARNING: Using discards ignore for chunk size non power of 2."); -- lp->discards = THIN_DISCARDS_IGNORE; -- } -+ lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8); -+ if (lp->chunk_size < 8 || lp->chunk_size > 1024 || -+ (lp->chunk_size & (lp->chunk_size - 1))) { -+ log_error("Chunk size must be a power of 2 in the " -+ "range 4K to 512K"); -+ return 0; - } -- log_verbose("Setting chunksize to %u sectors.", lp->chunk_size); -+ log_verbose("Setting chunksize to %s.", display_size(cmd, lp->chunk_size)); - - if (!lp->thin && lp->snapshot && !(lp->segtype = get_segtype_from_string(cmd, "snapshot"))) - return_0; -- } else if (arg_count(cmd, chunksize_ARG)) { -+ } else if (arg_count(cmd, chunksize_ARG) && !lp->create_thin_pool) { - log_error("-c is only available with snapshots and thin pools"); - return 0; - } - -- /* -- * Should we zero the lv. -- */ -- lp->zero = strcmp(arg_str_value(cmd, zero_ARG, -- (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n"); -- - if (lp->mirrors > DEFAULT_MIRROR_MAX_IMAGES) { - log_error("Only up to %d images in mirror supported currently.", - DEFAULT_MIRROR_MAX_IMAGES); -diff --git a/tools/toollib.c b/tools/toollib.c -index 3fe1c14..5fe94e0 100644 ---- a/tools/toollib.c -+++ b/tools/toollib.c -@@ -15,6 +15,7 @@ - - #include "tools.h" - #include -+#include - - const char *command_name(struct cmd_context *cmd) - { -@@ -1521,6 +1522,200 @@ int get_activation_monitoring_mode(struct cmd_context *cmd, - return 1; - } - -+int get_pool_params(struct cmd_context *cmd, -+ uint32_t *chunk_size, -+ thin_discards_t *discards, -+ uint64_t *pool_metadata_size, -+ int *zero) -+{ -+ const char *dstr; -+ -+ if (arg_count(cmd, zero_ARG)) { -+ *zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n"); -+ log_very_verbose("Setting pool zeroing: %u", *zero); -+ } else -+ *zero = find_config_tree_int(cmd, -+ "allocation/thin_pool_zero", -+ DEFAULT_THIN_POOL_ZERO); -+ -+ if (arg_count(cmd, discards_ARG)) { -+ *discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, 0); -+ log_very_verbose("Setting pool discards: %s", -+ get_pool_discards_name(*discards)); -+ } else { -+ dstr = find_config_tree_str(cmd, -+ "allocation/thin_pool_discards", -+ DEFAULT_THIN_POOL_DISCARDS); -+ if (!get_pool_discards(dstr, discards)) -+ return_0; -+ } -+ -+ if (arg_count(cmd, chunksize_ARG)) { -+ if (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS) { -+ log_error("Negative chunk size is invalid."); -+ return 0; -+ } -+ *chunk_size = arg_uint_value(cmd, chunksize_ARG, -+ DM_THIN_MIN_DATA_BLOCK_SIZE); -+ log_very_verbose("Setting pool chunk size: %s", -+ display_size(cmd, *chunk_size)); -+ } else -+ *chunk_size = find_config_tree_int(cmd, -+ "allocation/thin_pool_chunk_size", -+ DEFAULT_THIN_POOL_CHUNK_SIZE) * 2; -+ -+ if ((*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) || -+ (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) { -+ log_error("Chunk size must be in the range %s to %s.", -+ display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE), -+ display_size(cmd, DM_THIN_MAX_DATA_BLOCK_SIZE)); -+ return 0; -+ } -+ -+ if (arg_sign_value(cmd, poolmetadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { -+ log_error("Negative pool metadata size is invalid."); -+ return 0; -+ } -+ *pool_metadata_size = arg_uint64_value(cmd, poolmetadatasize_ARG, UINT64_C(0)); -+ -+ return 1; -+} -+ -+int update_pool_params(struct cmd_context *cmd, unsigned attr, -+ uint32_t data_extents, uint32_t extent_size, -+ uint32_t *chunk_size, thin_discards_t *discards, -+ uint64_t *pool_metadata_size) -+{ -+ size_t estimate_chunk_size; -+ -+ if (!(attr & THIN_FEATURE_BLOCK_SIZE) && -+ (*chunk_size & (*chunk_size - 1))) { -+ log_error("Chunk size must be a power of 2 for this thin target version."); -+ return 0; -+ } else if (*chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) { -+ log_error("Chunk size must be multiple of %s.", -+ display_size(cmd, DM_THIN_MIN_DATA_BLOCK_SIZE)); -+ return 0; -+ } else if ((*discards != THIN_DISCARDS_IGNORE) && -+ (*chunk_size & (*chunk_size - 1))) { -+ log_warn("WARNING: Using discards ignore for chunk size non power of 2."); -+ *discards = THIN_DISCARDS_IGNORE; -+ } -+ -+ if (!*pool_metadata_size) { -+ /* Defaults to nr_pool_blocks * 64b converted to size in sectors */ -+ *pool_metadata_size = (uint64_t) data_extents * extent_size / -+ (*chunk_size * (SECTOR_SIZE / UINT64_C(64))); -+ /* Check if we could eventually use bigger chunk size */ -+ if (!arg_count(cmd, chunksize_ARG)) { -+ while ((*pool_metadata_size > -+ (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) && -+ (*chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) { -+ *chunk_size <<= 1; -+ *pool_metadata_size >>= 1; -+ } -+ log_verbose("Setting chunk size to %s.", -+ display_size(cmd, *chunk_size)); -+ } else if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -+ /* Suggest bigger chunk size */ -+ estimate_chunk_size = (uint64_t) data_extents * extent_size / -+ (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE * -+ (SECTOR_SIZE / UINT64_C(64))); -+ log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.", -+ display_size(cmd, 1 << (ffs(estimate_chunk_size) + 1))); -+ } -+ -+ /* Round up to extent size */ -+ if (*pool_metadata_size % extent_size) -+ *pool_metadata_size += extent_size - *pool_metadata_size % extent_size; -+ } else { -+ estimate_chunk_size = (uint64_t) data_extents * extent_size / -+ (*pool_metadata_size * (SECTOR_SIZE / UINT64_C(64))); -+ /* Check to eventually use bigger chunk size */ -+ if (!arg_count(cmd, chunksize_ARG)) { -+ *chunk_size = estimate_chunk_size; -+ -+ if (*chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) -+ *chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; -+ else if (*chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) -+ *chunk_size = DM_THIN_MAX_DATA_BLOCK_SIZE; -+ -+ log_verbose("Setting chunk size %s.", -+ display_size(cmd, *chunk_size)); -+ } else if (*chunk_size < estimate_chunk_size) { -+ /* Suggest bigger chunk size */ -+ log_warn("WARNING: Chunk size is smaller then suggested minimum size %s.", -+ display_size(cmd, estimate_chunk_size)); -+ } -+ } -+ -+ if ((uint64_t) *chunk_size > (uint64_t) data_extents * extent_size) { -+ log_error("Chunk size is bigger then pool data size."); -+ return 0; -+ } -+ -+ if (*pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -+ if (arg_count(cmd, poolmetadatasize_ARG)) -+ log_warn("WARNING: Maximum supported pool metadata size is %s.", -+ display_size(cmd, 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)); -+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -+ } else if (*pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { -+ if (arg_count(cmd, poolmetadatasize_ARG)) -+ log_warn("WARNING: Minimum supported pool metadata size is %s.", -+ display_size(cmd, 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)); -+ *pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; -+ } -+ -+ log_verbose("Setting pool metadata size to %s.", -+ display_size(cmd, *pool_metadata_size)); -+ -+ return 1; -+} -+ -+struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv, -+ alloc_policy_t alloc, -+ const char *name, -+ struct dm_list *pvh, -+ uint32_t read_ahead, -+ uint32_t stripes, -+ uint32_t stripe_size, -+ uint64_t size) -+{ -+ struct logical_volume *metadata_lv; -+ struct lvcreate_params lvc; -+ -+ /* FIXME: Make lvm2api usable */ -+ memset(&lvc, 0, sizeof(lvc)); -+ -+ if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size, -+ pool_lv->vg->extent_size))) -+ return_0; -+ -+ if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped"))) -+ return_0; -+ -+ dm_list_init(&lvc.tags); -+ -+ /* FIXME: allocate properly space for metadata_lv */ -+ lvc.activate = CHANGE_ALY; -+ lvc.alloc = alloc; -+ lvc.lv_name = name; -+ lvc.major = -1; -+ lvc.minor = -1; -+ lvc.permission = LVM_READ | LVM_WRITE; -+ lvc.pvh = pvh; -+ lvc.read_ahead = read_ahead; -+ lvc.stripe_size = stripe_size; -+ lvc.stripes = stripes; -+ lvc.vg_name = pool_lv->vg->name; -+ lvc.zero = 1; -+ -+ if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc))) -+ return_0; -+ -+ return metadata_lv; -+} -+ - /* - * Generic stripe parameter checks. - */ -diff --git a/tools/toollib.h b/tools/toollib.h -index b3b0a7c..80c01fd 100644 ---- a/tools/toollib.h -+++ b/tools/toollib.h -@@ -111,6 +111,20 @@ int pvcreate_params_validate(struct cmd_context *cmd, - - int get_activation_monitoring_mode(struct cmd_context *cmd, - int *monitoring_mode); -+int get_pool_params(struct cmd_context *cmd, -+ uint32_t *chunk_size, -+ thin_discards_t *discards, -+ uint64_t *pool_metadata_size, -+ int *zero); -+int update_pool_params(struct cmd_context *cmd, unsigned attr, -+ uint32_t data_extents, uint32_t extent_size, -+ uint32_t *chunk_size, thin_discards_t *discards, -+ uint64_t *pool_metadata_size); -+struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv, -+ alloc_policy_t alloc, const char *name, -+ struct dm_list *pvh, uint32_t read_ahead, -+ uint32_t stripes, uint32_t stripe_size, -+ uint64_t size); - int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes, - uint32_t *stripe_size); - -diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c -index d62df99..20ca16b 100644 ---- a/tools/vgcfgrestore.c -+++ b/tools/vgcfgrestore.c -@@ -62,8 +62,9 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) - - if (!(arg_count(cmd, file_ARG) ? - backup_restore_from_file(cmd, vg_name, -- arg_str_value(cmd, file_ARG, "")) : -- backup_restore(cmd, vg_name))) { -+ arg_str_value(cmd, file_ARG, ""), -+ arg_count(cmd, force_long_ARG)) : -+ backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) { - unlock_vg(cmd, VG_ORPHANS); - unlock_vg(cmd, vg_name); - log_error("Restore failed."); diff --git a/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch b/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch deleted file mode 100644 index 33ab47f..0000000 --- a/lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch +++ /dev/null @@ -1,48 +0,0 @@ -commit 8dedeaa0183d2c87764a4012e443af9597d28575 -Author: Peter Rajnoha -Date: Wed Oct 31 14:15:54 2012 +0100 - - 0 ---- - WHATS_NEW | 3 +++ - scripts/lvm2_monitoring_systemd_red_hat.service.in | 7 ++++--- - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index d0e0cd4..12307ed 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,8 @@ - Version 2.02.99 - - =================================== -+ Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. -+ Remove dependency on fedora-storage-init.service in lvm2 systemd units. -+ Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. - Initialize lvmetad lazily to avoid early socket access on config overrides. - Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. - -diff --git a/scripts/lvm2_monitoring_systemd_red_hat.service.in b/scripts/lvm2_monitoring_systemd_red_hat.service.in -index 6c4c55f..e6b4814 100644 ---- a/scripts/lvm2_monitoring_systemd_red_hat.service.in -+++ b/scripts/lvm2_monitoring_systemd_red_hat.service.in -@@ -1,8 +1,8 @@ - [Unit] - Description=Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling - Documentation=man:dmeventd(8) man:lvcreate(8) man:lvchange(8) man:vgchange(8) --Requires=dm-event.socket --After=dm-event.socket fedora-storage-init.service fedora-storage-init-late.service lvm2-activation.service lvm2-lvmetad.service -+Requires=dm-event.socket lvm2-lvmetad.socket -+After=dm-event.socket lvm2-lvmetad.socket lvm2-activation.service lvm2-lvmetad.service - Before=local-fs.target - DefaultDependencies=no - Conflicts=shutdown.target -@@ -11,7 +11,8 @@ Conflicts=shutdown.target - Type=oneshot - Environment=LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES=1 - ExecStart=@sbindir@/lvm vgchange --monitor y --ExecStop=@sbindir@/lvm vgchange --monitor n -+# The lvmetad must be disabled here, it needs https://bugzilla.redhat.com/show_bug.cgi?id=843587 to be resolved first. -+ExecStop=@sbindir@/lvm vgchange --monitor n --config 'global{use_lvmetad=0}' - RemainAfterExit=yes - - [Install] diff --git a/lvm2-enable-lvmetad-by-default.patch b/lvm2-enable-lvmetad-by-default.patch index e728616..a0e0ad8 100644 --- a/lvm2-enable-lvmetad-by-default.patch +++ b/lvm2-enable-lvmetad-by-default.patch @@ -1,12 +1,12 @@ - doc/example.conf.in | 2 +- - lib/commands/toolcontext.c | 2 +- + conf/example.conf.in | 2 +- + lib/config/config_settings.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -diff --git a/doc/example.conf.in b/doc/example.conf.in -index 10cfe16..442ad64 100644 ---- a/doc/example.conf.in -+++ b/doc/example.conf.in -@@ -491,7 +491,7 @@ global { +diff --git a/conf/example.conf.in b/conf/example.conf.in +index 2032a81..0997aa4 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -550,7 +550,7 @@ global { # # If lvmetad has been running while use_lvmetad was 0, it MUST be stopped # before changing use_lvmetad to 1 and started again afterwards. @@ -15,16 +15,16 @@ index 10cfe16..442ad64 100644 # Full path of the utility called to check that a thin metadata device # is in a state that allows it to be used. -diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c -index d72b0c0..d7f8ece 100644 ---- a/lib/commands/toolcontext.c -+++ b/lib/commands/toolcontext.c -@@ -413,7 +413,7 @@ static int _process_config(struct cmd_context *cmd) - lvmetad_set_socket(lvmetad_socket); - cn = find_config_tree_node(cmd, "devices/global_filter"); - lvmetad_set_token(cn ? cn->v : NULL); -- lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 0)); -+ lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 1)); - lvmetad_init(cmd); - - return 1; +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index 16a9437..17f43c6 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -156,7 +156,7 @@ cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, + cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_SEGTYPE, vsn(2, 2, 87), NULL) + cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID10_SEGTYPE, vsn(2, 2, 99), NULL) + cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_path", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH, vsn(2, 2, 89), NULL) +-cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), NULL) ++cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 93), NULL) + cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), NULL) + cfg_array(global_thin_check_options_CFG, "thin_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_CHECK_OPTIONS, vsn(2, 2, 96), NULL) + cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S", vsn(2, 2, 99), NULL) diff --git a/lvm2-set-default-preferred_names.patch b/lvm2-set-default-preferred_names.patch index 5e1e1b6..f8f53f0 100644 --- a/lvm2-set-default-preferred_names.patch +++ b/lvm2-set-default-preferred_names.patch @@ -1,5 +1,5 @@ ---- LVM2.2.02.58/doc/example.conf.in 2010-01-07 19:54:21.000000000 +0000 -+++ LVM2.2.02.58-new/doc/example.conf.in 2010-01-20 18:30:32.000000000 +0000 +--- LVM2.2.02.58/conf/example.conf.in 2010-01-07 19:54:21.000000000 +0000 ++++ LVM2.2.02.58-new/conf/example.conf.in 2010-01-20 18:30:32.000000000 +0000 @@ -23,10 +23,10 @@ # same block device and the tools need to display a name for device, # all the pathnames are matched against each item in the following diff --git a/lvm2.spec b/lvm2.spec index d17d125..b6cbad2 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -1,4 +1,4 @@ -%define device_mapper_version 1.02.77 +%define device_mapper_version 1.02.78 %define enable_thin 1 %define enable_lvmetad 1 @@ -36,41 +36,14 @@ Summary: Userland logical volume management tools Name: lvm2 -Version: 2.02.98 -Release: 10%{?dist} +Version: 2.02.99 +Release: 1%{?dist} License: GPLv2 Group: System Environment/Base URL: http://sources.redhat.com/lvm2 Source0: ftp://sources.redhat.com/pub/lvm2/LVM2.%{version}.tgz Patch0: lvm2-set-default-preferred_names.patch Patch1: lvm2-enable-lvmetad-by-default.patch -Patch2: lvm2-2_02_99-python-remove-liblvm-object.patch -Patch3: lvm2-2_02_99-python-whitespace-and-conditional-cleanup.patch -Patch4: lvm2-2_02_99-python-update-example-to-work-with-lvm-object-removal.patch -Patch5: lvm2-2_02_99-python-implement-proper-refcounting-for-parent-objects.patch -Patch6: lvm2-2_02_99-properly-set-cookie_set-var-on-dm_task_set_cookie-call.patch -Patch7: lvm2-2_02_99-hardcode-use_lvmetad0-if-cluster-locking-used-and-issue-warning-msg.patch -Patch8: lvm2-2_02_99-init-lvmetad-lazily-to-avoid-early-socket-access-on-config-overrides.patch -Patch9: lvm2-2_02_99-various-updates-and-fixes-for-systemd-units.patch -Patch10: lvm2-2_02_99-exit-pvscan-cache-immediately-if-cluster-locking-used-or-lvmetad-not-used.patch -Patch11: lvm2-2_02_99-skip-mlocking-verctors-on-arm-arch.patch -Patch12: lvm2-2_02_99-fix-autoactivation-to-not-autoactivate-vg-lv-on-each-pv-change.patch -Patch13: lvm2-2_02_99-synchronize-with-udev-in-pvscan-cache-and-fix-dangling-udev_sync-cookies.patch -Patch14: lvm2-2_02_99-also-autoactivate-on-coldplug.patch -Patch15: lvm2-2_02_99-fire-pvscan-cache-on-change-event-for-md-devs.patch -Patch16: lvm2-2_02_99-various-thin-support-related-fixes.patch -Patch17: lvm2-2_02_99-fix-lv_is_active-in-lvcreate.patch -Patch18: lvm2-2_02_99-fix-crash-in-pvscan-cache-aay-triggered-by-non-mda-pv.patch -Patch19: lvm2-2_02_99-avoid-global-lock-in-pvs-when-lvmetad-is-in-use.patch -Patch20: lvm2-2_02_99-fix-possible-deadlock-in-lvmetad-for-parallel-update-and-query.patch -Patch21: lvm2-2_02_99-fix-possible-race-in-lvmetad-remove_metadata.patch -Patch22: lvm2-2_02_99-lvmetad-fix-a-race-in-metadata-update.patch -Patch23: lvm2-2_02_99-fix-handling-of-reappeared-and-missing-pvs-in-lvmetad.patch -Patch24: lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch -Patch25: lvm2-2_02_99-add-dm-disable-udev-env-var-and-fix-noudevsync-arg.patch -Patch26: lvm2-2_02_99-fix-premature-dm-version-checking-which-caused-useless-mapper-control-access.patch -Patch27: lvm2-2_02_99-close-dmeventd-fifo-fds-on-exec.patch -Patch28: lvm2-2_02_99-fix-dmsetup-splitname-to-not-fail-if-used-without-c-switch.patch BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel BuildRequires: ncurses-devel @@ -107,33 +80,6 @@ or more physical volumes and creating one or more logical volumes %setup -q -n LVM2.%{version} %patch0 -p1 -b .preferred_names %patch1 -p1 -b .enable_lvmetad -%patch2 -p1 -b .python_liblvm_object -%patch3 -p1 -b .python_cleanup -%patch4 -p1 -b .python_fix_example -%patch5 -p1 -b .python_refcounting -%patch6 -p1 -b .cookie_flags -%patch7 -p1 -b .cluster_lvmetad -%patch8 -p1 -b .lvmetad_lazy_init -%patch9 -p1 -b .systemd_fixes -%patch10 -p1 -b .pvscan_immediate -%patch11 -p1 -b .arm_vectors -%patch12 -p1 -b .autoactivation -%patch13 -p1 -b .dangling_cookies -%patch14 -p1 -b .coldplug -%patch15 -p1 -b .autoactivation_on_md -%patch16 -p1 -b .various_thin_fixes -%patch17 -p1 -b .lv_is_active -%patch18 -p1 -b .pvscan_cache_aay_crash -%patch19 -p1 -b .avoid_global_lock -%patch20 -p1 -b .lvmetad_deadlock -%patch21 -p1 -b .lvmetad_race_on_remove -%patch22 -p1 -b .lvmetad_race_on_update -%patch23 -p1 -b .lvmetad_missing_reappear_pv -%patch24 -p1 -b .blkdeactivate -%patch25 -p1 -b .dm_disable_udev -%patch26 -p1 -b .premature_dm_version -%patch27 -p1 -b .dmeventd_fd_cloexec -%patch28 -p1 -b .dmsetup_splitname %build %define _default_pid_dir /run @@ -306,6 +252,8 @@ rm -rf $RPM_BUILD_ROOT %dir %{_sysconfdir}/lvm %ghost %{_sysconfdir}/lvm/cache/.cache %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf +%dir %{_sysconfdir}/lvm/profile +%{_sysconfdir}/lvm/profile/default.profile %dir %{_sysconfdir}/lvm/backup %dir %{_sysconfdir}/lvm/cache %dir %{_sysconfdir}/lvm/archive @@ -627,8 +575,218 @@ the device-mapper event library. %{_libdir}/pkgconfig/devmapper-event.pc %changelog -* Thu May 30 2013 Peter Rajnoha - 2.02.98-10 +* Thu Jul 25 2013 Peter Rajnoha - 2.02.99-1 +- o Features/Extensions/Additions: +- Add support for poolmetadataspare LV, that will be used for pool recovery. +- Improve activation order when creating thin pools in non-clustered VG. +- Add lvm2-activation-net systemd unit to activate LVs on net-attached storage. +- Automatically flag thin snapshots to be skipped during activation. +- Add support for persistent flagging of LVs to be skipped during activation. +- Make selected thinp settings customizable by a profile. +- Support storing profile name in metadata for both VGs and LVs. +- Add support for configuration profiles. +- Add support for thin volumes in vgsplit. +- Add lvresize support for online thin pool metadata volume resize. +- Add detection for thin pool metadata resize kernel support. +- Add vg->vg_ondisk / lv_ondisk() holding committed metadata. +- Add detection of mounted fs also for vgchange deactivation. +- Avoid a global lock in pvs when lvmetad is in use. +- Detect maximum usable size for snapshot for lvresize. +- Improve RAID kernel status retrieval to include sync_action/mismatch_cnt. +- Add external origin support for lvcreate. +- Support automatic config validation. +- Add PV header extension: extension version, flags and bootloader areas. +- Initial support for lvconvert of thin external origin. +- Improve activation code for better support of stacked devices. +- vgimport '--force' now allows import of VGs with missing PVs. +- Allow removal or replacement of RAID LV components that are error segments. +- Make 'vgreduce --removemissing' able to handle RAID LVs with missing PVs. +- Add lvconvert support to swap thin pool metadata volume. +- Allow vgcfgrestore of lvm2 metadata with thin volumes if --force is used. +- Give precedence to EMC power2 devices with duplicate PVIDs. +- Recognise Storage Class Memory (IBM S/390) devices in filter. +- Recognise STEC skd devices in filter. +- Recognise Violin Memory vtms devices in filter. +- Support discards for non-power-of-2 thin pool chunks. +- Automatically restore MISSING PVs with no MDAs. +- Support allocation of pool metadata with lvconvert command. +- Detect mounted fs also via reading /proc/self/mountinfo. +- o Command Interface/Options: +- Support ARG_GROUPABLE with merge_synonym (for --raidwritemostly). +- Add --ignoreactivationskip to lvcreate/vgchange/lvchange to ignore skip flag. +- Add --setactivationskip to lvcreate/lvchange to set activation skip flag. +- Add --type profilable to lvm dumpconfig to show profilable config settings. +- Add --mergedconfig to lvm dumpconfig for merged --config/--profile/lvm.conf. +- Support changing VG/LV profiles: vgchange/lvchange --profile/--detachprofile. +- Add new --profile command line arg to select a configuration profile for use. +- For creation of snapshot require size for at least 3 chunks. +- Do not accept size parameters bigger then 16EiB. +- Accept --yes in all commands so test scripts can be simpler. +- Add lvcreate/lvchange --[raid]{min|max}recoveryrate for raid LVs. +- Add lvchange --[raid]writemostly/writebehind support for RAID1 +- Add lvchange --[raid]syncaction for scrubbing of RAID LVs. +- Add --validate option to lvm dumpconfig to validate current config on demand. +- Add --ignoreadvanced and --ignoreunsupported switch to lvm dumpconfig. +- Add --withcomments and --withversions switch to lvm dumpconfig. +- Add --type {current|default|missing|new} and --atversion to lvm dumpconfig. +- Add --bootloaderareasize to pvcreate and vgconvert to create bootloader area. +- Do not take a free lv name argument for lvconvert --thinpool option. +- Allow lvconvert --stripes/stripesize only with --mirrors/--repair/--thinpool. +- Do not ignore -f in lvconvert --repair -y -f for mirror and raid volumes. +- Support use of option --yes for lvchange --persistent. +- Fix clvmd support for option -d and properly use its argument. +- o Reporting: +- Issue an error msg if lvconvert --type used incorrectly with other options. +- Use LOG_DEBUG/ERR msg severity instead default for lvm2-activation-generator. +- Add LV report fields: raid_mismatch_count/raid_sync_action/raid_write_behind. +- Add LV reporting fields raid_min_recovery_rate, raid_max_recovery_rate. +- Add sync_percent as alias for copy_percent LV reporting field. +- Add lv_ prefix to modules reporting field. +- Use units B or b (never E) with no decimal places when displaying sizes < 1k. +- List thin-pool and thin modules for thin volumes. +- Add 's(k)ip activation' bit to lvs -o lv_attr to indicate skip flag attached. +- Improve error loging when user tries to interrupt commands. +- Add vgs/lvs -o vg_profile/lv_profile to report profiles attached to VG/LV. +- Report lvs volume type 'e' with higher priority. +- Report lvs volume type 'o' also for external origin volumes. +- Report lvs target type 't' only for thin pools and thin volumes. +- Add "active" LV reporting field to show activation state. +- Add "monitor" segment reporting field to show dmevent monitoring status. +- Add explicit message about unsupported pvmove for thin/thinpool volumes. +- Add pvs -o pv_ba_start,pv_ba_size to report bootloader area start and size. +- Fix pvs -o pv_free reporting for PVs with zero PE count. +- Report blank origin_size field if the LV doesn't have an origin instead of 0. +- Report partial and in-sync RAID attribute based on kernel status +- Log output also to syslog when abort_on_internal_error is set. +- Change lvs heading Copy% to Cpy%Sync and print RAID4/5/6 sync% there too. +- Report error for nonexisting devices in dmeventd communication. +- Reduce some log_error messages to log_warn where we don't fail. +- o Configuration: +- Add activation/auto_set_activation_skip to control activation skip flagging. +- Add default.profile configuration profile and install it on make install. +- Add config/profile_dir to set working directory to load profiles from. +- Use mirror_segtype_default if type not specified for linear->mirror upconvert. +- Refine lvm.conf and man page documentation for autoactivation feature. +- Override system's global_filter settings for vgimportclone. +- Find newest timestamp of merged config files. +- Add 'config' section to lvm.conf to set the way the LVM configuration is handled. +- Add global/raid10_segtype_default to lvm.conf. +- Accept activation/raid_region_size in preference to mirror_region_size config. +- Add log/debug_classes to lvm.conf to control debug log messages. +- Allow empty activation/{auto_activation|read_only|}_volume_list config option. +- Add lvm.conf option global/thin_disabled_features. +- Add lvm.conf thin pool allocation settings thin_pool_{chunk_size|discards|zero}. +- Relax ignore_suspended_devices to read from mirrors that don't have a device marked failed. +- o Documentation: +- Add man page entries for profile configuration and related options. +- Document lvextend --use-policies option in man. +- Improve lvcreate, lvconvert and lvm man pages. +- o API/interfaces: +- liblvm/python API: Additions: PV create/removal/resize/listing +- liblvm/python API: Additions: LV attr/origin/Thin pool/Thin LV creation +- Fix exported symbols regex for non-GNU busybox sed. +- Add LV snapshot support to liblvm and python-lvm. +- Fix lvm2app to return all property sizes in bytes (not sectors). +- Fix lvm2app and return lvseg discards property as string. +- Remove python liblvm object. systemdir can only be changed using env var now. +- Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. +- Add dm_get_status_snapshot() for parsing snapshot status. +- Append discards and read-only fields to exported struct dm_status_thin_pool. +- Validate passed params to dm_get_status_raid/thin/thin_pool(). +- Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. +- Add dm_mountinfo_read() for parsing /proc/self/mountinfo. +- Add dm_config_write_{node_out/one_node_out} for enhanced config output. +- Add dm_config_value_is_bool to check for boolean value in supported formats. +- Add DM_ARRAY_SIZE public macro. +- Add DM_TO_STRING public macro. +- Implement ref-counting for parents in python lib. +- o Fixes (general): +- Do not zero init 4KB of thin snapshot for non-zeroing thin pool (2.02.94). +- Correct thin creation error paths. +- Add whole log_lv and metadata_lv sub volumes when creating partial tree. +- Properly use snapshot layer for origin which is also thin volume. +- Avoid generating metadata backup when calling update_pool_lv(). +- Send thin messages also for active thin pool and inactive thin volume. +- Avoid creation of multiple archives for one command. +- Avoid flushing thin pool when just requesting transaction_id. +- Fix use of too big chunks of memory when communication with lvmetad. +- Also filter partitions on mpath components if multipath_component_detection=1. +- Do not use persistent filter with lvmetad. +- Move syslog code out of signal handle in dmeventd. +- Fix lvresize --use-policies of VALID but 100% full snapshot. +- Skip monitoring of snapshots that are already bigger then origin. +- Refuse to init a snapshot merge in lvconvert if there's no kernel support. +- Fix alignment of PV data area if detected alignment less than 1 MB (2.02.74). +- Fix premature DM version checking which caused useless mapper/control access. +- Fix creation and removal of clustered snapshot. +- Fix clvmd caching of metadata when suspending inactive volumes. +- Fix lvmetad error path in lvmetad_vg_lookup() for null vgname. +- Fix clvmd _cluster_request() return code in memory fail path. +- Fix vgextend to not allow a PV with 0 MDAs to be used while already in a VG. +- Fix PV alignment to incorporate alignment offset if the PV has zero MDAs. +- Fix missing cleanup of flags when the LV is detached from pool. +- Fix check for some forbidden discards conversion of thin pools. +- Fix blkdeactivate to handle nested mountpoints and mangled mount paths. +- Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. +- Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. +- Limit RAID device replacement to repair only if LV is not in-sync. +- Disallow RAID device replacement or repair on inactive LVs. +- Unlock vg mutex in error path when lvmetad tries to lock_vg. +- Detect key string duplication failure in config_make_nodes_v in libdaemon. +- Disallow pvmove on RAID LVs until they are addressed properly +- Recognize DM_DISABLE_UDEV environment variable for a complete fallback. +- Do not verify udev operations if --noudevsync command option is used. +- When no --stripes argument is given when creating a RAID10 volume, default to 2 stripes. +- Do not allow lvconvert --splitmirrors on RAID10 logical volumes. +- Skip mlocking [vectors] on arm architecture. +- Repair a mirrored log before the mirror itself when both fail. +- Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. +- Exit pvscan --cache immediately if cluster locking used or lvmetad not used. +- Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. +- Avoid trying to read a mirror that has a failed device in its mirrored log. +- Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68). +- Fix segfault for truncated string token in config file after the first '"'. +- Fix config node lookup inside empty sections to not return the section itself. +- Fix parsing of 64bit snapshot status in dmeventd snapshot plugin. +- Always return success on dmeventd -V command call. +- o Fixes (segfaults/crashes/deadlocks/races): +- Fix segfault when reporting raid_syncaction for older kernels. +- Fix vgcfgrestore crash when specified incorrect vg name. +- Avoid crash-inducing race in lvmetad when VG disappears during rename. +- Fix possible race while removing metadata from lvmetad. +- Fix possible deadlock when querying and updating lvmetad at the same time. +- Check for memory failure of dm_config_write_node() in lvmetad. +- Fix crash in pvscan --cache -aay triggered by non-mda PV. +- Prevent double free error after dmeventd call of _fill_device_data(). +- o Fixes (resource leaks/memleaks): +- Release memory allocated with _cached_info(). +- Release memory and unblock signals in lock_vol error path. +- Fix memory resource leak in memlocking error path. +- Fix memleak in dmeventd thin plugin in device list obtaining err path. +- Fix socket leak on error path in lvmetad's handle_connect. +- Fix memleak on error path for lvmetad's pv_found. +- Fix memleak in device_is_usable mirror testing function. +- Fix memory leak on error path for pvcreate with invalid uuid. +- Fix resource leak in error path of dmeventd's umount of thin volume. +- Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). +- o Testing: +- Fix test for active snapshot in cluster before resizing it. +- Add python-lvm unit test case +- o Other: +- Use local activation for clearing snapshot COW device. +- Add configure --with-default-profile-subdir to select dir to keep profiles in. +- Creation of snapshot takes at most 100% origin coverage. +- Use LC_ALL to set locale in daemons and fsadm instead of lower priority LANG. +- Remove dependency on fedora-storage-init.service in lvm2 systemd units. +- Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. +- Optimize out setting the same value of read_ahead. +- Automatically deactivate failed preloaded dm tree node. +- Process thin messages once to active thin pool target for dm_tree. +- Move common functionality for thin lvcreate and lvconvert to toollib. +- o Packaging: +- Add /etc/lvm/profile dir and /etc/lvm/profile/default.profile to lvm2 package. - Do not include /lib/udev and /lib/udev/rules.d in device-mapper package. +- Fix some incorrect changelog dates. * Tue May 14 2013 Peter Rajnoha - 2.02.98-9 - Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68). @@ -1036,7 +1194,7 @@ the device-mapper event library. - Add dm-event and lvm2-monitor unit files for use with systemd. - Add sysvinit subpackage for legacy SysV init script support. -* Wed Jul 8 2011 Alasdair Kergon - 2.02.86-1 +* Fri Jul 8 2011 Alasdair Kergon - 2.02.86-1 - Fix activation sequences to avoid trapped I/O with multiple LVs. - Fix activation sequences to avoid allocating tables while devs suspended. - Remove unnecessary warning in pvcreate for MD linear devices. @@ -2203,7 +2361,7 @@ the device-mapper event library. - Modify lvremove to prompt for removal if LV active on other cluster nodes. - Add '-f' to vgremove to force removal of VG even if LVs exist. -* Thu Aug 24 2007 Alasdair Kergon - 2.02.28-1 +* Fri Aug 24 2007 Alasdair Kergon - 2.02.28-1 - vgscan and pvscan now trigger clvmd -R, which should now work. - Fix clvmd logging so you can get lvm-level debugging out of it. - Allow clvmd debug to be turned on in a running daemon using clvmd -d [-C]. @@ -2367,7 +2525,7 @@ the device-mapper event library. * Mon Nov 20 2006 Alasdair Kergon - 2.02.15-1 - New upstream - see WHATS_NEW. -* Fri Nov 11 2006 Alasdair Kergon - 2.02.14-1 +* Sat Nov 11 2006 Alasdair Kergon - 2.02.14-1 - New upstream - see WHATS_NEW. * Mon Oct 30 2006 Alasdair Kergon - 2.02.13-2 @@ -2565,7 +2723,7 @@ the device-mapper event library. * Wed Sep 15 2004 Alasdair Kergon - 2.00.23-1 - Various minor upstream fixes. -* Thu Sep 3 2004 Alasdair Kergon - 2.00.22-1 +* Fri Sep 3 2004 Alasdair Kergon - 2.00.22-1 - Permission fix included upstream; use different endian conversion macros. * Thu Sep 2 2004 Jeremy Katz - 2.00.21-2 diff --git a/sources b/sources index 9ac0417..125dd04 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -1ce5b7f9981e1d02dfd1d3857c8d9fbe LVM2.2.02.98.tgz +8600d999d04d826138d9fbb5d2d8cc34 LVM2.2.02.99.tgz diff --git a/upstream b/upstream index d3455b4..255cf2d 100644 --- a/upstream +++ b/upstream @@ -1 +1 @@ -LVM2.2.02.98.tgz +LVM2.2.02.99.tgz