From 78c74f155c97d0fe62b694d872005a461adfdb5a Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Fri, 29 Mar 2024 16:01:15 +0300 Subject: [PATCH] import lvm2-2.03.14-14.el8 --- .gitignore | 1 + .lvm2.metadata | 1 + .../0001-Revert-new-udev-autoactivation.patch | 545 ++ ...an-only-add-device-args-to-dev-cache.patch | 450 ++ ...n-fix-messages-from-coverity-changes.patch | 34 + ...gimportdevices-skip-lvmlockd-locking.patch | 39 + ...0005-hints-remove-the-cmd-hints-list.patch | 95 + ...ter-sysfs-skip-when-device-id-is-set.patch | 422 ++ ...-lvmdevices-increase-open-file-limit.patch | 61 + ...port-old-kernels-without-sys-dev-blo.patch | 73 + ...e_id-match-different-dm-device-names.patch | 155 + ...ice_id-fix-search-on-filtered-device.patch | 134 + ...ce_id-searched_devnames-improvements.patch | 102 + ...-pv-ext-flags-work-with-devices-file.patch | 40 + .../0013-display-ignore-reportformat.patch | 91 + SOURCES/0014-fix-spelling-of-pruning.patch | 25 + SOURCES/0015-man-lvmautoactivation.patch | 416 ++ ...icesfile-devname.sh-drop-mdadm-chunk.patch | 25 + ...evices-file-don-t-write-in-test-mode.patch | 26 + ...out-unrecognized-journal-option-valu.patch | 24 + ...-wwid-with-spaces-or-control-charact.patch | 50 + ...-section-about-static-autoactivation.patch | 96 + ...0022-lvcreate-include-recent-options.patch | 35 + ...ation-replace-systemctl-with-journal.patch | 26 + SOURCES/0024-make-generate.patch | 196 + ...te-overwrite-partition-header-with-f.patch | 141 + ...check-error-exit-if-update-is-needed.patch | 166 + ...te-overwrite-partition-header-with-f.patch | 140 + ...multipath-components-based-on-matchi.patch | 462 ++ ...md-components-when-duplicate-pvs-are.patch | 268 + ...vices-fix-checks-when-adding-entries.patch | 246 + ...-make-deldev-work-for-missing-device.patch | 106 + ...-do-not-clear-PVID-of-unread-devices.patch | 144 + ...ache-mention-writecache-memory-usage.patch | 35 + ...itecache-display-block-size-from-lvs.patch | 102 + ...vices-simplify-dev_cache_get_by_devt.patch | 148 + ...op-incorrect-paths-from-aliases-list.patch | 467 ++ ...vices-initial-use-of-existing-option.patch | 70 + ...038-devices-fix-dev_name-assumptions.patch | 270 + ...cache-aliases-handling-from-label-sc.patch | 272 + .../0040-writecache-check-memory-usage.patch | 101 + ...ange-messages-about-filtered-devices.patch | 108 + ...ces-fix-incorrect-deviceidtype-usage.patch | 31 + ...-error-from-vgcreate-init_vg_sanlock.patch | 32 + ...move-extraneous-unlock-in-vgchange-u.patch | 45 + ...filter-mpath-use-multipath-blacklist.patch | 458 ++ ...mprove-description-of-devices-option.patch | 28 + SOURCES/0047-vdo-support-vdosettings.patch | 576 ++ ...ault-when-handling-selection-with-hi.patch | 45 + ...e-move-clean-up-after-command-is-run.patch | 39 + ...l-if-devicesfile-filename-doesn-t-ex.patch | 53 + ...handle-other-wwid-types-in-blacklist.patch | 52 + ...o-fix-conversion-of-vdo_slab_size_mb.patch | 56 + ...-mpath-get-wwids-from-sysfs-vpd_pg83.patch | 741 +++ ...ake-rpm-with-VERSION_DM-without-dash.patch | 29 + ...-when-devicesfile-name-doesn-t-exist.patch | 246 + ...component_detection-0-to-duplicate-P.patch | 55 + ...-pvcreate-uuid-matching-pvid-entry-w.patch | 66 + ...rt-correct-test-support-for-vdo-pool.patch | 57 + ...usd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch | 32 + ...change-result-when-devices-are-not-a.patch | 442 ++ ...fix-locking-when-creating-devices-fi.patch | 76 + ...ge-processing-on-thin-pool-extension.patch | 132 + SOURCES/0064-vdo-fix-vdosettings-parser.patch | 52 + SOURCES/0065-make-generate.patch | 921 +++ SOURCES/0066-vdo-use-single-validator.patch | 90 + ...fines-also-for-configuration-defines.patch | 295 + ...report-supported-range-in-error-path.patch | 144 + ...069-vdo-ensure-VDO-config-is-removed.patch | 35 + ...o-fix-conversion-of-vdo_slab_size_mb.patch | 50 + SOURCES/0071-tests-add-lvm_vdo_wrapper.patch | 396 ++ SOURCES/0072-tests-update-for-wrapper.patch | 84 + ...sd-Change-unit-test-vdo-minimum-size.patch | 73 + ...x-conversion-of-vdo_slab_size_mb-2nd.patch | 31 + .../0075-vdo-update-info-about-memory.patch | 49 + ...0076-vdo-check-vdo-memory-constrains.patch | 246 + ...ing-to-extent-size-aligned-virtual-s.patch | 79 + ...78-vdo-support-v4-kernel-target-line.patch | 172 + ...0079-vdo-enhance-lvcreate-validation.patch | 171 + ...-code-for-better-error-path-handling.patch | 58 + ...ly-verbose-log-level-for-reformating.patch | 55 + ...0082-vdo-reset-errno-before-strtoull.patch | 27 + ...extend-volume-and-pool-without-flush.patch | 66 + ...sts-vdo-emulation-without-vdo-binary.patch | 52 + ...e_mapper-add-parser-for-vdo-metadata.patch | 373 ++ ...v_manager-accept-misalined-vdo-pools.patch | 78 + ...device_mapper-vdo-V4-avoid-messaging.patch | 49 + .../0088-vdo-replace-errors-with-debug.patch | 121 + ...do-enhance-detection-of-virtual-size.patch | 98 + .../0090-vdo-improve-validation-message.patch | 32 + SOURCES/0091-vdo-fix-reader-error-path.patch | 28 + ...-memory-only-in-non-critical-section.patch | 38 + ...vdo-read-live-vdo-size-configuration.patch | 192 + ...vcreate-fix-error-path-return-values.patch | 45 + ...ix-and-enhance-vdo-constain-checking.patch | 228 + ...esize-requires-active-vdopool-volume.patch | 37 + SOURCES/0097-tests-vdo-resizing.patch | 37 + ...8-tests-check-failing-vdo-conversion.patch | 40 + ...9-vdo-use-fixed-size-vdopool-wrapper.patch | 38 + .../0100-vdo-document-feature-option.patch | 48 + ...-fix-and-enhance-vdo-metadata-reader.patch | 65 + ...-tests-cleanup-some-shellcheck-warns.patch | 31 + SOURCES/0103-vdo-enhance-lvm_vdo_import.patch | 564 ++ ...4-vdo-man-updates-for-lvm_import_vdo.patch | 54 + ...sts-vdo-manager-wrapper-tool-updates.patch | 68 + ...date-test-to-handle-different-status.patch | 40 + SOURCES/0107-tests-updates.patch | 158 + SOURCES/0108-WHATS_NEW-update.patch | 28 + ...o-correct-the-converted-virtual-size.patch | 55 + ...t-for-automatic-virtual-size-correct.patch | 71 + ...eck_point_frequence-is-unused-option.patch | 174 + SOURCES/0112-vdo-indent-for-lvdisplay.patch | 35 + ...vm_import_vdo-correct-parsing-output.patch | 50 + .../0114-lvm_import_vdo-spelling-fixes.patch | 104 + SOURCES/0115-vdo-support-version-4.patch | 90 + SOURCES/0116-vdo-use-long-verbose.patch | 28 + ...ort_vdo.sh-with-main-as-of-970e4d295.patch | 542 ++ SOURCES/0118-man-Fix-typo.patch | 25 + .../0119-doc-fix-typos-in-documentation.patch | 649 ++ ...Fix-doubled-filename-in-vgcfgrestore.patch | 26 + .../0121-man-add-inte-g-rity-to-man-lvs.patch | 26 + ...0-will-always-take-rimage_0-even-if-.patch | 48 + ...t-fix-lvconvert-m-0-for-in-sync-legs.patch | 52 + ...-RAID1-allocator-uses-one-disk-for-b.patch | 79 + ...s-to-lvs-command-output-in-case-Raid.patch | 58 + ...-Install-and-package-etc-lvm-devices.patch | 25 + SOURCES/lvm2-rhel8.patch | 18 + .../lvm2-test-skip-problematic-tests.patch | 39 + SPECS/lvm2.spec | 5335 +++++++++++++++++ 129 files changed, 22864 insertions(+) create mode 100644 .gitignore create mode 100644 .lvm2.metadata create mode 100644 SOURCES/0001-Revert-new-udev-autoactivation.patch create mode 100644 SOURCES/0002-Revert-pvscan-only-add-device-args-to-dev-cache.patch create mode 100644 SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch create mode 100644 SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch create mode 100644 SOURCES/0005-hints-remove-the-cmd-hints-list.patch create mode 100644 SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch create mode 100644 SOURCES/0007-lvmdevices-increase-open-file-limit.patch create mode 100644 SOURCES/0008-filter-sysfs-support-old-kernels-without-sys-dev-blo.patch create mode 100644 SOURCES/0009-device_id-match-different-dm-device-names.patch create mode 100644 SOURCES/0010-device_id-fix-search-on-filtered-device.patch create mode 100644 SOURCES/0011-device_id-searched_devnames-improvements.patch create mode 100644 SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch create mode 100644 SOURCES/0013-display-ignore-reportformat.patch create mode 100644 SOURCES/0014-fix-spelling-of-pruning.patch create mode 100644 SOURCES/0015-man-lvmautoactivation.patch create mode 100644 SOURCES/0017-tests-devicesfile-devname.sh-drop-mdadm-chunk.patch create mode 100644 SOURCES/0018-devices-file-don-t-write-in-test-mode.patch create mode 100644 SOURCES/0019-print-warning-about-unrecognized-journal-option-valu.patch create mode 100644 SOURCES/0020-device_id-handle-wwid-with-spaces-or-control-charact.patch create mode 100644 SOURCES/0021-man-add-section-about-static-autoactivation.patch create mode 100644 SOURCES/0022-lvcreate-include-recent-options.patch create mode 100644 SOURCES/0023-man-lvmautoactivation-replace-systemctl-with-journal.patch create mode 100644 SOURCES/0024-make-generate.patch create mode 100644 SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch create mode 100644 SOURCES/0026-lvmdevices-check-error-exit-if-update-is-needed.patch create mode 100644 SOURCES/0027-Revert-pvcreate-overwrite-partition-header-with-f.patch create mode 100644 SOURCES/0028-devices-exclude-multipath-components-based-on-matchi.patch create mode 100644 SOURCES/0029-devices-exclude-md-components-when-duplicate-pvs-are.patch create mode 100644 SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch create mode 100644 SOURCES/0031-lvmdevices-make-deldev-work-for-missing-device.patch create mode 100644 SOURCES/0032-devices-file-do-not-clear-PVID-of-unread-devices.patch create mode 100644 SOURCES/0033-man-lvmcache-mention-writecache-memory-usage.patch create mode 100644 SOURCES/0034-writecache-display-block-size-from-lvs.patch create mode 100644 SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch create mode 100644 SOURCES/0036-devices-drop-incorrect-paths-from-aliases-list.patch create mode 100644 SOURCES/0037-devices-initial-use-of-existing-option.patch create mode 100644 SOURCES/0038-devices-fix-dev_name-assumptions.patch create mode 100644 SOURCES/0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch create mode 100644 SOURCES/0040-writecache-check-memory-usage.patch create mode 100644 SOURCES/0041-change-messages-about-filtered-devices.patch create mode 100644 SOURCES/0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch create mode 100644 SOURCES/0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch create mode 100644 SOURCES/0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch create mode 100644 SOURCES/0045-filter-mpath-use-multipath-blacklist.patch create mode 100644 SOURCES/0046-improve-description-of-devices-option.patch create mode 100644 SOURCES/0047-vdo-support-vdosettings.patch create mode 100644 SOURCES/0048-toollib-fix-segfault-when-handling-selection-with-hi.patch create mode 100644 SOURCES/0049-devices-file-move-clean-up-after-command-is-run.patch create mode 100644 SOURCES/0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch create mode 100644 SOURCES/0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch create mode 100644 SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch create mode 100644 SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch create mode 100644 SOURCES/0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch create mode 100644 SOURCES/0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch create mode 100644 SOURCES/0057-apply-multipath_component_detection-0-to-duplicate-P.patch create mode 100644 SOURCES/0058-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch create mode 100644 SOURCES/0059-lvconvert-correct-test-support-for-vdo-pool.patch create mode 100644 SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch create mode 100644 SOURCES/0061-vgimportdevices-change-result-when-devices-are-not-a.patch create mode 100644 SOURCES/0062-vgimportdevices-fix-locking-when-creating-devices-fi.patch create mode 100644 SOURCES/0063-thin-fix-message-processing-on-thin-pool-extension.patch create mode 100644 SOURCES/0064-vdo-fix-vdosettings-parser.patch create mode 100644 SOURCES/0065-make-generate.patch create mode 100644 SOURCES/0066-vdo-use-single-validator.patch create mode 100644 SOURCES/0067-vdo-use-defines-also-for-configuration-defines.patch create mode 100644 SOURCES/0068-vdo-report-supported-range-in-error-path.patch create mode 100644 SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch create mode 100644 SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch create mode 100644 SOURCES/0071-tests-add-lvm_vdo_wrapper.patch create mode 100644 SOURCES/0072-tests-update-for-wrapper.patch create mode 100644 SOURCES/0073-lvmdbusd-Change-unit-test-vdo-minimum-size.patch create mode 100644 SOURCES/0074-vdo-fix-conversion-of-vdo_slab_size_mb-2nd.patch create mode 100644 SOURCES/0075-vdo-update-info-about-memory.patch create mode 100644 SOURCES/0076-vdo-check-vdo-memory-constrains.patch create mode 100644 SOURCES/0077-vdo-add-reformating-to-extent-size-aligned-virtual-s.patch create mode 100644 SOURCES/0078-vdo-support-v4-kernel-target-line.patch create mode 100644 SOURCES/0079-vdo-enhance-lvcreate-validation.patch create mode 100644 SOURCES/0080-vdo-suffle-code-for-better-error-path-handling.patch create mode 100644 SOURCES/0081-vdo-use-only-verbose-log-level-for-reformating.patch create mode 100644 SOURCES/0082-vdo-reset-errno-before-strtoull.patch create mode 100644 SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch create mode 100644 SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch create mode 100644 SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch create mode 100644 SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch create mode 100644 SOURCES/0087-device_mapper-vdo-V4-avoid-messaging.patch create mode 100644 SOURCES/0088-vdo-replace-errors-with-debug.patch create mode 100644 SOURCES/0089-vdo-enhance-detection-of-virtual-size.patch create mode 100644 SOURCES/0090-vdo-improve-validation-message.patch create mode 100644 SOURCES/0091-vdo-fix-reader-error-path.patch create mode 100644 SOURCES/0092-vdo-check-memory-only-in-non-critical-section.patch create mode 100644 SOURCES/0093-vdo-read-live-vdo-size-configuration.patch create mode 100644 SOURCES/0094-lvcreate-fix-error-path-return-values.patch create mode 100644 SOURCES/0095-vdo-fix-and-enhance-vdo-constain-checking.patch create mode 100644 SOURCES/0096-vdo-resize-requires-active-vdopool-volume.patch create mode 100644 SOURCES/0097-tests-vdo-resizing.patch create mode 100644 SOURCES/0098-tests-check-failing-vdo-conversion.patch create mode 100644 SOURCES/0099-vdo-use-fixed-size-vdopool-wrapper.patch create mode 100644 SOURCES/0100-vdo-document-feature-option.patch create mode 100644 SOURCES/0101-vdo-fix-and-enhance-vdo-metadata-reader.patch create mode 100644 SOURCES/0102-tests-cleanup-some-shellcheck-warns.patch create mode 100644 SOURCES/0103-vdo-enhance-lvm_vdo_import.patch create mode 100644 SOURCES/0104-vdo-man-updates-for-lvm_import_vdo.patch create mode 100644 SOURCES/0105-tests-vdo-manager-wrapper-tool-updates.patch create mode 100644 SOURCES/0106-tests-update-test-to-handle-different-status.patch create mode 100644 SOURCES/0107-tests-updates.patch create mode 100644 SOURCES/0108-WHATS_NEW-update.patch create mode 100644 SOURCES/0109-lvm_import_vdo-correct-the-converted-virtual-size.patch create mode 100644 SOURCES/0110-tests-update-test-for-automatic-virtual-size-correct.patch create mode 100644 SOURCES/0111-vdo-check_point_frequence-is-unused-option.patch create mode 100644 SOURCES/0112-vdo-indent-for-lvdisplay.patch create mode 100644 SOURCES/0113-vdo-lvm_import_vdo-correct-parsing-output.patch create mode 100644 SOURCES/0114-lvm_import_vdo-spelling-fixes.patch create mode 100644 SOURCES/0115-vdo-support-version-4.patch create mode 100644 SOURCES/0116-vdo-use-long-verbose.patch create mode 100644 SOURCES/0117-vdo-Sync-lvm_import_vdo.sh-with-main-as-of-970e4d295.patch create mode 100644 SOURCES/0118-man-Fix-typo.patch create mode 100644 SOURCES/0119-doc-fix-typos-in-documentation.patch create mode 100644 SOURCES/0120-archiving-Fix-doubled-filename-in-vgcfgrestore.patch create mode 100644 SOURCES/0121-man-add-inte-g-rity-to-man-lvs.patch create mode 100644 SOURCES/0122-Fix-lvconvert-m-0-will-always-take-rimage_0-even-if-.patch create mode 100644 SOURCES/0123-lvconvert-fix-lvconvert-m-0-for-in-sync-legs.patch create mode 100644 SOURCES/0124-Fix-multisegment-RAID1-allocator-uses-one-disk-for-b.patch create mode 100644 SOURCES/0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch create mode 100644 SOURCES/0130-spec-Install-and-package-etc-lvm-devices.patch create mode 100644 SOURCES/lvm2-rhel8.patch create mode 100644 SOURCES/lvm2-test-skip-problematic-tests.patch create mode 100644 SPECS/lvm2.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49c2c57 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/LVM2.2.03.14.tgz diff --git a/.lvm2.metadata b/.lvm2.metadata new file mode 100644 index 0000000..db0e692 --- /dev/null +++ b/.lvm2.metadata @@ -0,0 +1 @@ +e5d4364e823d72b9a08b3aecc13cd677972830f0 SOURCES/LVM2.2.03.14.tgz diff --git a/SOURCES/0001-Revert-new-udev-autoactivation.patch b/SOURCES/0001-Revert-new-udev-autoactivation.patch new file mode 100644 index 0000000..971fc3a --- /dev/null +++ b/SOURCES/0001-Revert-new-udev-autoactivation.patch @@ -0,0 +1,545 @@ +From 63c4458aaf67d114c677baf657a7e9e43440f349 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 20 Dec 2021 14:22:02 -0600 +Subject: [PATCH 01/54] Revert "new udev autoactivation" + +This reverts commit 67722b312390cdab29c076c912e14bd739c5c0f6. +--- + scripts/Makefile.in | 1 + + test/shell/udev-pvscan-vgchange.sh | 403 ----------------------------- + udev/69-dm-lvm.rules.in | 87 ------- + udev/Makefile.in | 2 +- + 5 files changed, 4 insertions(+), 492 deletions(-) + delete mode 100644 test/shell/udev-pvscan-vgchange.sh + delete mode 100644 udev/69-dm-lvm.rules.in + +diff --git a/scripts/Makefile.in b/scripts/Makefile.in +index 0d7f45680..ee0acb6f6 100644 +--- a/scripts/Makefile.in ++++ b/scripts/Makefile.in +@@ -92,6 +92,7 @@ install_systemd_generators: + install_systemd_units: install_dbus_service + @echo " [INSTALL] systemd_units" + $(Q) $(INSTALL_DIR) $(systemd_unit_dir) ++ $(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service + ifeq ("@BUILD_DMEVENTD@", "yes") + $(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket + $(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service +diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh +deleted file mode 100644 +index c81acf0ce..000000000 +--- a/test/shell/udev-pvscan-vgchange.sh ++++ /dev/null +@@ -1,403 +0,0 @@ +-#!/usr/bin/env bash +- +-# Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +- +-test_description='udev rule and systemd unit run vgchange' +- +-SKIP_WITH_LVMPOLLD=1 +-SKIP_WITH_LVMLOCKD=1 +- +-. lib/inittest +- +-# +-# $ cat /tmp/devs +-# /dev/sdb +-# /dev/sdc +-# /dev/sdd +-# +-# Specify this file as LVM_TEST_DEVICE_LIST=/tmp/devs +-# when running the test. +-# +-# This test will wipe these devices. +-# +- +-if [ -z ${LVM_TEST_DEVICE_LIST+x} ]; then echo "LVM_TEST_DEVICE_LIST is unset" && skip; else echo "LVM_TEST_DEVICE_LIST is set to '$LVM_TEST_DEVICE_LIST'"; fi +- +-test -e "$LVM_TEST_DEVICE_LIST" || skip +- +-num_devs=$(cat $LVM_TEST_DEVICE_LIST | wc -l) +- +-RUNDIR="/run" +-test -d "$RUNDIR" || RUNDIR="/var/run" +-PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online" +-VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online" +-PVS_LOOKUP_DIR="$RUNDIR/lvm/pvs_lookup" +- +-_clear_online_files() { +- # wait till udev is finished +- aux udev_wait +- rm -f "$PVS_ONLINE_DIR"/* +- rm -f "$VGS_ONLINE_DIR"/* +- rm -f "$PVS_LOOKUP_DIR"/* +-} +- +-test -d "$PVS_ONLINE_DIR" || mkdir -p "$PVS_ONLINE_DIR" +-test -d "$VGS_ONLINE_DIR" || mkdir -p "$VGS_ONLINE_DIR" +-test -d "$PVS_LOOKUP_DIR" || mkdir -p "$PVS_LOOKUP_DIR" +-_clear_online_files +- +-aux prepare_real_devs +- +-aux lvmconf 'devices/dir = "/dev"' +-aux lvmconf 'devices/use_devicesfile = 1' +-DFDIR="$LVM_SYSTEM_DIR/devices" +-DF="$DFDIR/system.devices" +-mkdir $DFDIR || true +-not ls $DF +- +-get_real_devs +- +-wipe_all() { +- for dev in "${REAL_DEVICES[@]}"; do +- wipefs -a $dev +- done +-} +- +-# udevadm trigger runs udev rule which runs systemd-run --no-wait vgchange -aay +-# Because of --no-wait, we need to wait for the transient systemd +-# service to be gone before checking the effects of the vgchange. +- +-wait_lvm_activate() { +- local vgw=$1 +- local wait=0 +- +- while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do +- sleep .2 +- wait=$(( wait + 1 )) +- done +-} +- +-# Test requires 3 devs +-test $num_devs -gt 2 || skip +-BDEV1=$(basename "$dev1") +-BDEV2=$(basename "$dev2") +-BDEV3=$(basename "$dev3") +- +-wipe_all +-touch $DF +-for dev in "${REAL_DEVICES[@]}"; do +- pvcreate $dev +-done +- +-# 1 dev, 1 vg, 1 lv +- +-vgcreate $vg1 "$dev1" +-lvcreate -l1 -an -n $lv1 $vg1 "$dev1" +- +-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}') +- +-_clear_online_files +-udevadm trigger --settle -c add /sys/block/$BDEV1 +- +-wait_lvm_activate $vg1 +- +-ls "$RUNDIR/lvm/pvs_online/$PVID1" +-ls "$RUNDIR/lvm/vgs_online/$vg1" +-journalctl -u lvm-activate-$vg1 | tee out || true +-grep "now active" out +-check lv_field $vg1/$lv1 lv_active "active" +- +-vgchange -an $vg1 +-vgremove -y $vg1 +- +- +-# 2 devs, 1 vg, 2 lvs +- +-vgcreate $vg2 "$dev1" "$dev2" +-lvcreate -l1 -an -n $lv1 $vg2 "$dev1" +-lvcreate -l1 -an -n $lv2 $vg2 "$dev2" +- +-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}') +-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}') +- +-_clear_online_files +- +-udevadm trigger --settle -c add /sys/block/$BDEV1 +-ls "$RUNDIR/lvm/pvs_online/$PVID1" +-not ls "$RUNDIR/lvm/vgs_online/$vg2" +-journalctl -u lvm-activate-$vg2 | tee out || true +-not grep "now active" out +-check lv_field $vg2/$lv1 lv_active "" +-check lv_field $vg2/$lv2 lv_active "" +- +-udevadm trigger --settle -c add /sys/block/$BDEV2 +-ls "$RUNDIR/lvm/pvs_online/$PVID2" +-ls "$RUNDIR/lvm/vgs_online/$vg2" +- +-wait_lvm_activate $vg2 +- +-journalctl -u lvm-activate-$vg2 | tee out || true +-grep "now active" out +-check lv_field $vg2/$lv1 lv_active "active" +-check lv_field $vg2/$lv2 lv_active "active" +- +-vgchange -an $vg2 +-vgremove -y $vg2 +- +- +-# 3 devs, 1 vg, 4 lvs, concurrent pvscans +-# (attempting to have the pvscans run concurrently and race +-# to activate the VG) +- +-vgcreate $vg3 "$dev1" "$dev2" "$dev3" +-lvcreate -l1 -an -n $lv1 $vg3 "$dev1" +-lvcreate -l1 -an -n $lv2 $vg3 "$dev2" +-lvcreate -l1 -an -n $lv3 $vg3 "$dev3" +-lvcreate -l8 -an -n $lv4 -i 2 $vg3 "$dev1" "$dev2" +- +-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}') +-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}') +-PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}') +- +-_clear_online_files +- +-udevadm trigger -c add /sys/block/$BDEV1 & +-udevadm trigger -c add /sys/block/$BDEV2 & +-udevadm trigger -c add /sys/block/$BDEV3 +- +-aux udev_wait +-wait_lvm_activate $vg3 +- +-ls "$RUNDIR/lvm/pvs_online/$PVID1" +-ls "$RUNDIR/lvm/pvs_online/$PVID2" +-ls "$RUNDIR/lvm/pvs_online/$PVID3" +-ls "$RUNDIR/lvm/vgs_online/$vg3" +-journalctl -u lvm-activate-$vg3 | tee out || true +-grep "now active" out +-check lv_field $vg3/$lv1 lv_active "active" +-check lv_field $vg3/$lv2 lv_active "active" +-check lv_field $vg3/$lv3 lv_active "active" +-check lv_field $vg3/$lv4 lv_active "active" +- +-vgchange -an $vg3 +-vgremove -y $vg3 +- +- +-# 3 devs, 1 vg, 4 lvs, concurrent pvscans, metadata on only 1 PV +- +-wipe_all +-rm $DF +-touch $DF +-pvcreate --metadatacopies 0 "$dev1" +-pvcreate --metadatacopies 0 "$dev2" +-pvcreate "$dev3" +- +-vgcreate $vg4 "$dev1" "$dev2" "$dev3" +-lvcreate -l1 -an -n $lv1 $vg4 "$dev1" +-lvcreate -l1 -an -n $lv2 $vg4 "$dev2" +-lvcreate -l1 -an -n $lv3 $vg4 "$dev3" +-lvcreate -l8 -an -n $lv4 -i 2 $vg4 "$dev1" "$dev2" +- +-PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}') +-PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}') +-PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}') +- +-_clear_online_files +- +-udevadm trigger -c add /sys/block/$BDEV1 & +-udevadm trigger -c add /sys/block/$BDEV2 & +-udevadm trigger -c add /sys/block/$BDEV3 +- +-aux udev_wait +-wait_lvm_activate $vg4 +- +-ls "$RUNDIR/lvm/pvs_online/$PVID1" +-ls "$RUNDIR/lvm/pvs_online/$PVID2" +-ls "$RUNDIR/lvm/pvs_online/$PVID3" +-ls "$RUNDIR/lvm/vgs_online/$vg4" +-journalctl -u lvm-activate-$vg4 | tee out || true +-grep "now active" out +-check lv_field $vg4/$lv1 lv_active "active" +-check lv_field $vg4/$lv2 lv_active "active" +-check lv_field $vg4/$lv3 lv_active "active" +-check lv_field $vg4/$lv4 lv_active "active" +- +-vgchange -an $vg4 +-vgremove -y $vg4 +- +- +-# 3 devs, 3 vgs, 2 lvs in each vg, concurrent pvscans +- +-wipe_all +-rm $DF +-touch $DF +- +-vgcreate $vg5 "$dev1" +-vgcreate $vg6 "$dev2" +-vgcreate $vg7 "$dev3" +-lvcreate -l1 -an -n $lv1 $vg5 +-lvcreate -l1 -an -n $lv2 $vg5 +-lvcreate -l1 -an -n $lv1 $vg6 +-lvcreate -l1 -an -n $lv2 $vg6 +-lvcreate -l1 -an -n $lv1 $vg7 +-lvcreate -l1 -an -n $lv2 $vg7 +- +-_clear_online_files +- +-udevadm trigger -c add /sys/block/$BDEV1 & +-udevadm trigger -c add /sys/block/$BDEV2 & +-udevadm trigger -c add /sys/block/$BDEV3 +- +-aux udev_wait +-wait_lvm_activate $vg5 +-wait_lvm_activate $vg6 +-wait_lvm_activate $vg7 +- +-ls "$RUNDIR/lvm/vgs_online/$vg5" +-ls "$RUNDIR/lvm/vgs_online/$vg6" +-ls "$RUNDIR/lvm/vgs_online/$vg7" +-journalctl -u lvm-activate-$vg5 | tee out || true +-grep "now active" out +-journalctl -u lvm-activate-$vg6 | tee out || true +-grep "now active" out +-journalctl -u lvm-activate-$vg7 | tee out || true +-grep "now active" out +-check lv_field $vg5/$lv1 lv_active "active" +-check lv_field $vg5/$lv2 lv_active "active" +-check lv_field $vg6/$lv1 lv_active "active" +-check lv_field $vg6/$lv2 lv_active "active" +-check lv_field $vg7/$lv1 lv_active "active" +-check lv_field $vg7/$lv2 lv_active "active" +- +-vgchange -an $vg5 +-vgremove -y $vg5 +-vgchange -an $vg6 +-vgremove -y $vg6 +-vgchange -an $vg7 +-vgremove -y $vg7 +- +-# 3 devs, 1 vg, 1000 LVs +- +-wipe_all +-rm $DF +-touch $DF +-pvcreate --metadatacopies 0 "$dev1" +-pvcreate "$dev2" +-pvcreate "$dev3" +-vgcreate -s 128K $vg8 "$dev1" "$dev2" "$dev3" +- +-# Number of LVs to create +-TEST_DEVS=1000 +-# On low-memory boxes let's not stress too much +-test "$(aux total_mem)" -gt 524288 || TEST_DEVS=256 +- +-vgcfgbackup -f data $vg8 +- +-# Generate a lot of devices (size of 1 extent) +-awk -v TEST_DEVS=$TEST_DEVS '/^\t\}/ { +- printf("\t}\n\tlogical_volumes {\n"); +- cnt=0; +- for (i = 0; i < TEST_DEVS; i++) { +- printf("\t\tlvol%06d {\n", i); +- printf("\t\t\tid = \"%06d-1111-2222-3333-2222-1111-%06d\"\n", i, i); +- print "\t\t\tstatus = [\"READ\", \"WRITE\", \"VISIBLE\"]"; +- print "\t\t\tsegment_count = 1"; +- print "\t\t\tsegment1 {"; +- print "\t\t\t\tstart_extent = 0"; +- print "\t\t\t\textent_count = 1"; +- print "\t\t\t\ttype = \"striped\""; +- print "\t\t\t\tstripe_count = 1"; +- print "\t\t\t\tstripes = ["; +- print "\t\t\t\t\t\"pv0\", " cnt++; +- printf("\t\t\t\t]\n\t\t\t}\n\t\t}\n"); +- } +- } +- {print} +-' data >data_new +- +-vgcfgrestore -f data_new $vg8 +- +-_clear_online_files +- +-udevadm trigger -c add /sys/block/$BDEV1 & +-udevadm trigger -c add /sys/block/$BDEV2 & +-udevadm trigger -c add /sys/block/$BDEV3 +- +-aux udev_wait +-wait_lvm_activate $vg8 +- +-ls "$RUNDIR/lvm/vgs_online/$vg8" +-journalctl -u lvm-activate-$vg8 | tee out || true +-grep "now active" out +- +-num_active=$(lvs $vg8 --noheading -o active | grep active | wc -l) +- +-test $num_active -eq $TEST_DEVS +- +-vgchange -an $vg8 +-vgremove -y $vg8 +- +-# 1 pv on an md dev, 1 vg +- +-wait_md_create() { +- local md=$1 +- +- while :; do +- if ! grep "$(basename $md)" /proc/mdstat; then +- echo "$md not ready" +- cat /proc/mdstat +- sleep 2 +- else +- break +- fi +- done +- echo "$md" > WAIT_MD_DEV +-} +- +-test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \ +- modprobe raid1 || skip +- +-mddev="/dev/md33" +-not grep $mddev /proc/mdstat || skip +- +-wipe_all +-rm $DF +-touch $DF +- +-mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev1" "$dev2" +-wait_md_create "$mddev" +-vgcreate $vg9 "$mddev" +- +-PVIDMD=`pvs $mddev --noheading -o uuid | tr -d - | awk '{print $1}'` +-BDEVMD=$(basename "$mddev") +- +-lvcreate -l1 -an -n $lv1 $vg9 +-lvcreate -l1 -an -n $lv2 $vg9 +- +-_clear_online_files +- +-udevadm trigger --settle -c add /sys/block/$BDEVMD +- +-wait_lvm_activate $vg9 +- +-ls "$RUNDIR/lvm/vgs_online/$vg9" +-journalctl -u lvm-activate-$vg9 | tee out || true +-grep "now active" out +-check lv_field $vg9/$lv1 lv_active "active" +-check lv_field $vg9/$lv2 lv_active "active" +- +-vgchange -an $vg9 +-vgremove -y $vg9 +- +-mdadm --stop "$mddev" +-aux udev_wait +-wipe_all +- +diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in +deleted file mode 100644 +index 39e5b9807..000000000 +--- a/udev/69-dm-lvm.rules.in ++++ /dev/null +@@ -1,87 +0,0 @@ +-# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved. +-# +-# This file is part of LVM. +-# +-# This rule requires blkid to be called on block devices before so only devices +-# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member"). +- +-SUBSYSTEM!="block", GOTO="lvm_end" +-(LVM_EXEC_RULE) +- +-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end" +- +-# Only process devices already marked as a PV - this requires blkid to be called before. +-ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end" +-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end" +-ACTION=="remove", GOTO="lvm_end" +- +-# Create /dev/disk/by-id/lvm-pv-uuid- symlink for each PV +-ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}" +- +-# If the PV is a special device listed below, scan only if the device is +-# properly activated. These devices are not usable after an ADD event, +-# but they require an extra setup and they are ready after a CHANGE event. +-# Also support coldplugging with ADD event but only if the device is already +-# properly activated. +-# This logic should be eventually moved to rules where those particular +-# devices are processed primarily (MD and loop). +- +-# DM device: +-KERNEL!="dm-[0-9]*", GOTO="next" +-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan" +-GOTO="lvm_end" +- +-# MD device: +-LABEL="next" +-KERNEL!="md[0-9]*", GOTO="next" +-IMPORT{db}="LVM_MD_PV_ACTIVATED" +-ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan" +-ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan" +-ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan" +-ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0" +-GOTO="lvm_end" +- +-# Loop device: +-LABEL="next" +-KERNEL!="loop[0-9]*", GOTO="next" +-ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan" +-ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan" +-ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0" +-GOTO="lvm_end" +- +-LABEL="next" +-ACTION!="add", GOTO="lvm_end" +- +-LABEL="lvm_scan" +- +-ENV{SYSTEMD_READY}="1" +- +-# pvscan will check if this device completes a VG, +-# i.e. all PVs in the VG are now present with the +-# arrival of this PV. If so, it prints to stdout: +-# LVM_VG_NAME_COMPLETE='foo' +-# +-# When the VG is complete it can be activated, so +-# vgchange -aay is run. It is run via +-# systemd since it can take longer to run than +-# udev wants to block when processing rules. +-# (if there are hundreds of LVs to activate, +-# the vgchange can take many seconds.) +-# +-# pvscan only reads the single device specified, +-# and uses temp files under /run/lvm to check if +-# other PVs in the VG are present. +-# +-# If event_activation=0 in lvm.conf, this pvscan +-# (using checkcomplete) will do nothing, so that +-# no event-based autoactivation will be happen. +-# +-# TODO: adjust the output of vgchange -aay so that +-# it's better suited to appearing in the journal. +- +-IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}" +-ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay --nohints $env{LVM_VG_NAME_COMPLETE}" +-GOTO="lvm_end" +- +-LABEL="lvm_end" +- +diff --git a/udev/Makefile.in b/udev/Makefile.in +index e777dda16..e32cba921 100644 +--- a/udev/Makefile.in ++++ b/udev/Makefile.in +@@ -18,7 +18,7 @@ top_builddir = @top_builddir@ + include $(top_builddir)/make.tmpl + + DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules +-LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules ++LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules + + DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}') + +-- +2.34.3 + diff --git a/SOURCES/0002-Revert-pvscan-only-add-device-args-to-dev-cache.patch b/SOURCES/0002-Revert-pvscan-only-add-device-args-to-dev-cache.patch new file mode 100644 index 0000000..9f309a3 --- /dev/null +++ b/SOURCES/0002-Revert-pvscan-only-add-device-args-to-dev-cache.patch @@ -0,0 +1,450 @@ +From 2091305b796d5552fd991c527a0359a0b4d8fde0 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 20 Dec 2021 13:38:23 -0600 +Subject: [PATCH 02/54] Revert "pvscan: only add device args to dev cache" + +This reverts commit 33e47182f773c1a902b533580b63a803906de55d. +--- + lib/device/dev-cache.c | 204 +++----------------------------- + lib/device/dev-cache.h | 6 +- + lib/device/device_id.c | 27 ++--- + lib/device/device_id.h | 1 - + test/shell/devicesfile-basic.sh | 2 +- + tools/pvscan.c | 58 ++++----- + 6 files changed, 52 insertions(+), 246 deletions(-) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index 33b75a9a9..c6e5f68cf 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1852,7 +1852,7 @@ int setup_devices_file(struct cmd_context *cmd) + * Add all system devices to dev-cache, and attempt to + * match all devices_file entries to dev-cache entries. + */ +-int setup_devices(struct cmd_context *cmd) ++static int _setup_devices(struct cmd_context *cmd, int no_file_match) + { + int file_exists; + int lock_mode = 0; +@@ -1979,6 +1979,13 @@ int setup_devices(struct cmd_context *cmd) + */ + dev_cache_scan(cmd); + ++ /* ++ * The caller uses "no_file_match" if it wants to match specific devs ++ * itself, instead of matching everything in device_ids_match. ++ */ ++ if (no_file_match && cmd->enable_devices_file) ++ return 1; ++ + /* + * Match entries from cmd->use_devices with device structs in dev-cache. + */ +@@ -1987,6 +1994,16 @@ int setup_devices(struct cmd_context *cmd) + return 1; + } + ++int setup_devices(struct cmd_context *cmd) ++{ ++ return _setup_devices(cmd, 0); ++} ++ ++int setup_devices_no_file_match(struct cmd_context *cmd) ++{ ++ return _setup_devices(cmd, 1); ++} ++ + /* + * The alternative to setup_devices() when the command is interested + * in using only one PV. +@@ -2055,188 +2072,3 @@ int setup_device(struct cmd_context *cmd, const char *devname) + return 1; + } + +-/* +- * pvscan --cache is specialized/optimized to look only at command args, +- * so this just sets up the devices file, then individual devices are +- * added to dev-cache and matched with device_ids later in pvscan. +- */ +- +-int setup_devices_for_pvscan_cache(struct cmd_context *cmd) +-{ +- if (cmd->enable_devices_list) { +- if (!_setup_devices_list(cmd)) +- return_0; +- return 1; +- } +- +- if (!setup_devices_file(cmd)) +- return_0; +- +- if (!cmd->enable_devices_file) +- return 1; +- +- if (!devices_file_exists(cmd)) { +- log_debug("Devices file not found, ignoring."); +- cmd->enable_devices_file = 0; +- return 1; +- } +- +- if (!lock_devices_file(cmd, LOCK_SH)) { +- log_error("Failed to lock the devices file to read."); +- return 0; +- } +- +- if (!device_ids_read(cmd)) { +- log_error("Failed to read the devices file."); +- unlock_devices_file(cmd); +- return 0; +- } +- +- unlock_devices_file(cmd); +- return 1; +-} +- +- +-/* Get a device name from a devno. */ +- +-static char *_get_devname_from_devno(struct cmd_context *cmd, dev_t devno) +-{ +- char path[PATH_MAX]; +- char devname[PATH_MAX]; +- char namebuf[NAME_LEN]; +- char line[1024]; +- int major = MAJOR(devno); +- int minor = MINOR(devno); +- int line_major; +- int line_minor; +- uint64_t line_blocks; +- DIR *dir; +- struct dirent *dirent; +- FILE *fp; +- +- /* +- * $ ls /sys/dev/block/8:0/device/block/ +- * sda +- */ +- if (major_is_scsi_device(cmd->dev_types, major)) { +- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/device/block", +- dm_sysfs_dir(), major, minor) < 0) { +- return NULL; +- } +- +- if (!(dir = opendir(path))) +- return NULL; +- +- while ((dirent = readdir(dir))) { +- if (dirent->d_name[0] == '.') +- continue; +- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", dirent->d_name) < 0) { +- devname[0] = '\0'; +- stack; +- } +- break; +- } +- closedir(dir); +- +- if (devname[0]) { +- log_debug("Found %s for %d:%d from sys", devname, major, minor); +- return _strdup(devname); +- } +- return NULL; +- } +- +- /* +- * $ cat /sys/dev/block/253:3/dm/name +- * mpatha +- */ +- if (major == cmd->dev_types->device_mapper_major) { +- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/dm/name", +- dm_sysfs_dir(), major, minor) < 0) { +- return NULL; +- } +- +- if (!get_sysfs_value(path, namebuf, sizeof(namebuf), 0)) +- return NULL; +- +- if (dm_snprintf(devname, sizeof(devname), "/dev/mapper/%s", namebuf) < 0) { +- devname[0] = '\0'; +- stack; +- } +- +- if (devname[0]) { +- log_debug("Found %s for %d:%d from sys", devname, major, minor); +- return _strdup(devname); +- } +- return NULL; +- } +- +- /* +- * /proc/partitions lists +- * major minor #blocks name +- */ +- +- if (!(fp = fopen("/proc/partitions", "r"))) +- return NULL; +- +- while (fgets(line, sizeof(line), fp)) { +- if (sscanf(line, "%u %u %llu %s", &line_major, &line_minor, (unsigned long long *)&line_blocks, namebuf) != 4) +- continue; +- if (line_major != major) +- continue; +- if (line_minor != minor) +- continue; +- +- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", namebuf) < 0) { +- devname[0] = '\0'; +- stack; +- } +- break; +- } +- fclose(fp); +- +- if (devname[0]) { +- log_debug("Found %s for %d:%d from proc", devname, major, minor); +- return _strdup(devname); +- } +- +- /* +- * If necessary, this could continue searching by stat'ing /dev entries. +- */ +- +- return NULL; +-} +- +-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname) +-{ +- struct stat buf; +- struct device *dev; +- +- if (stat(devname, &buf) < 0) { +- log_error("Cannot access device %s.", devname); +- return 0; +- } +- +- if (!S_ISBLK(buf.st_mode)) { +- log_error("Invaild device type %s.", devname); +- return 0; +- } +- +- if (!_insert_dev(devname, buf.st_rdev)) +- return_0; +- +- if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname))) +- return_0; +- +- return 1; +-} +- +-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno) +-{ +- const char *devname; +- +- if (!(devname = _get_devname_from_devno(cmd, devno))) +- return_0; +- +- return setup_devname_in_dev_cache(cmd, devname); +-} +- +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 143848d6d..635dc4fc9 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -77,11 +77,7 @@ int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor); + + int setup_devices_file(struct cmd_context *cmd); + int setup_devices(struct cmd_context *cmd); ++int setup_devices_no_file_match(struct cmd_context *cmd); + int setup_device(struct cmd_context *cmd, const char *devname); + +-/* Normal device setup functions are split up for pvscan optimization. */ +-int setup_devices_for_pvscan_cache(struct cmd_context *cmd); +-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname); +-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno); +- + #endif +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 167bf661b..eb06109ff 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1534,22 +1534,6 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev) + * passes the filter. + */ + +-void device_ids_match_device_list(struct cmd_context *cmd) +-{ +- struct dev_use *du; +- +- dm_list_iterate_items(du, &cmd->use_devices) { +- if (du->dev) +- continue; +- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) { +- log_warn("Device not found for %s.", du->devname); +- } else { +- /* Should we set dev->id? Which idtype? Use --deviceidtype? */ +- du->dev->flags |= DEV_MATCHED_USE_ID; +- } +- } +-} +- + void device_ids_match(struct cmd_context *cmd) + { + struct dev_iter *iter; +@@ -1557,7 +1541,16 @@ void device_ids_match(struct cmd_context *cmd) + struct device *dev; + + if (cmd->enable_devices_list) { +- device_ids_match_device_list(cmd); ++ dm_list_iterate_items(du, &cmd->use_devices) { ++ if (du->dev) ++ continue; ++ if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) { ++ log_warn("Device not found for %s.", du->devname); ++ } else { ++ /* Should we set dev->id? Which idtype? Use --deviceidtype? */ ++ du->dev->flags |= DEV_MATCHED_USE_ID; ++ } ++ } + return; + } + +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index 0ada35c94..939b3a0f4 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -32,7 +32,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid, + void device_id_pvremove(struct cmd_context *cmd, struct device *dev); + void device_ids_match(struct cmd_context *cmd); + int device_ids_match_dev(struct cmd_context *cmd, struct device *dev); +-void device_ids_match_device_list(struct cmd_context *cmd); + void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate); + int device_ids_version_unchanged(struct cmd_context *cmd); + void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate); +diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh +index 9c3455c76..7ba9e2c7f 100644 +--- a/test/shell/devicesfile-basic.sh ++++ b/test/shell/devicesfile-basic.sh +@@ -283,7 +283,7 @@ not ls "$RUNDIR/lvm/pvs_online/$PVID3" + # arg in devices list + _clear_online_files + pvscan --devices "$dev3" --cache -aay "$dev3" +-pvscan --devices "$dev4","$dev3" --cache -aay "$dev4" ++pvscan --devices "$dev4" --cache -aay "$dev4" + check lv_field $vg2/$lv2 lv_active "active" + vgchange -an $vg2 + +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 95d593d57..8e2611361 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -857,21 +857,11 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname, + + devno = MKDEV(file_major, file_minor); + +- if (!setup_devno_in_dev_cache(cmd, devno)) { +- log_error_pvscan(cmd, "No device set up for %d:%d PVID %s", file_major, file_minor, pvid); +- goto bad; +- } +- + if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) { + log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid); + goto bad; + } + +- /* +- * Do not need to match device_id here, see comment after +- * get_devs_from_saved_vg about relying on pvid online file. +- */ +- + name1 = dev_name(dev); + name2 = pvl->pv->device_hint; + +@@ -1109,11 +1099,17 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp, + * PROCESS_SKIP_SCAN: we have already done lvmcache_label_scan + * so tell process_each to skip it. + */ ++ if (do_all) ++ read_flags |= PROCESS_SKIP_SCAN; + ++ /* ++ * When the command is processing specific devs (not all), it ++ * has done setup_devices_no_file_match() to avoid matching ids ++ * fo all devs unnecessarily, but now that we're falling back ++ * to process_each_vg() we need to complete the id matching. ++ */ + if (!do_all) +- lvmcache_label_scan(cmd); +- +- read_flags |= PROCESS_SKIP_SCAN; ++ device_ids_match(cmd); + + ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, read_flags, 0, handle, _pvscan_aa_single); + } +@@ -1196,15 +1192,11 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args, + /* in common usage, no dev will be found for a devno */ + + dm_list_iterate_items(arg, pvscan_args) { +- if (arg->devname) { +- if (!setup_devname_in_dev_cache(cmd, arg->devname)) +- log_error_pvscan(cmd, "No device set up for name arg %s", arg->devname); ++ if (arg->devname) + arg->dev = dev_cache_get(cmd, arg->devname, NULL); +- } else if (arg->devno) { +- if (!setup_devno_in_dev_cache(cmd, arg->devno)) +- log_error_pvscan(cmd, "No device set up for devno arg %d", (int)arg->devno); ++ else if (arg->devno) + arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL); +- } else ++ else + return_0; + } + +@@ -1680,13 +1672,11 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv, + cmd->pvscan_cache_single = 1; + + /* +- * Special pvscan-specific setup steps to avoid looking +- * at any devices except for device args. +- * Read devices file and determine if devices file will be used. +- * Does not do dev_cache_scan (adds nothing to dev-cache), and +- * does not do any device id matching. ++ * "no_file_match" means that when the devices file is used, ++ * setup_devices will skip matching devs to devices file entries. ++ * Specific devs must be matched later with device_ids_match_dev(). + */ +- if (!setup_devices_for_pvscan_cache(cmd)) { ++ if (!setup_devices_no_file_match(cmd)) { + log_error_pvscan(cmd, "Failed to set up devices."); + return 0; + } +@@ -1745,21 +1735,17 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv, + log_debug("pvscan_cache_args: filter devs nodata"); + + /* +- * Match dev args with the devices file because special/optimized +- * device setup was used above which does not check the devices file. +- * If a match fails here do not exclude it, that will be done below by +- * passes_filter() which runs filter-deviceid. The +- * relax_deviceid_filter case needs to be able to work around ++ * Match dev args with the devices file because ++ * setup_devices_no_file_match() was used above which skipped checking ++ * the devices file. If a match fails here do not exclude it, that ++ * will be done below by passes_filter() which runs filter-deviceid. ++ * The relax_deviceid_filter case needs to be able to work around + * unmatching devs. + */ +- + if (cmd->enable_devices_file) { +- dm_list_iterate_items(devl, &pvscan_devs) ++ dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) + device_ids_match_dev(cmd, devl->dev); +- + } +- if (cmd->enable_devices_list) +- device_ids_match_device_list(cmd); + + if (cmd->enable_devices_file && device_ids_use_devname(cmd)) { + relax_deviceid_filter = 1; +-- +2.34.3 + diff --git a/SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch b/SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch new file mode 100644 index 0000000..7756188 --- /dev/null +++ b/SOURCES/0003-pvscan-fix-messages-from-coverity-changes.patch @@ -0,0 +1,34 @@ +From a5a2d5fa1ec47a5a548db4cf435dc84de7ce7c31 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 20 Oct 2021 16:12:41 -0500 +Subject: [PATCH 03/54] pvscan: fix messages from coverity changes + +--- + tools/pvscan.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 8e2611361..f60c4a2ca 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -1354,7 +1354,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs + devsize = dev->size; + if (!devsize && + !dev_get_size(dev, &devsize)) { +- log_print("pvscan[%d] PV %s can get device size.", getpid(), dev_name(dev)); ++ log_print_pvscan(cmd, "PV %s missing device size.", dev_name(dev)); + release_vg(vg); + continue; + } +@@ -1786,7 +1786,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv, + int has_pvid; + + if (!label_read_pvid(devl->dev, &has_pvid)) { +- log_print("pvscan[%d] %s cannot read.", getpid(), dev_name(devl->dev)); ++ log_print_pvscan(cmd, "%s cannot read label.", dev_name(devl->dev)); + dm_list_del(&devl->list); + continue; + } +-- +2.34.3 + diff --git a/SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch b/SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch new file mode 100644 index 0000000..450ead9 --- /dev/null +++ b/SOURCES/0004-vgimportdevices-skip-lvmlockd-locking.patch @@ -0,0 +1,39 @@ +From 074fce5c73c55e7a1547d5efff65a9f96e6db3b1 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 25 Oct 2021 12:11:17 -0500 +Subject: [PATCH 04/54] vgimportdevices: skip lvmlockd locking + +Help bootstrapping existing shared vgs into the devices file. +Reading the vg in vgimportdevices would require locking to be +started, but vgchange lockstart won't see the vg if it's not +in the devices file. The lvmlockd locks are not protecting +vg modifications so skipping them here won't be a problem. +--- + tools/vgimportdevices.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index 3f315f98f..2580613c4 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -172,6 +172,17 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + cmd->filter_regex_with_devices_file = 1; + cmd->create_edit_devices_file = 1; + ++ /* ++ * This helps a user bootstrap existing shared VGs into the devices ++ * file. Reading the vg to import devices requires locking, but ++ * lockstart won't find the vg before it's in the devices file. ++ * So, allow importing devices without an lvmlockd lock (in a ++ * a shared vg the vg metadata won't be updated with device ids, ++ * so the lvmlockd lock isn't protecting vg modification.) ++ */ ++ cmd->lockd_gl_disable = 1; ++ cmd->lockd_vg_disable = 1; ++ + /* + * For each VG: + * device_id_add() each PV in the VG +-- +2.34.3 + diff --git a/SOURCES/0005-hints-remove-the-cmd-hints-list.patch b/SOURCES/0005-hints-remove-the-cmd-hints-list.patch new file mode 100644 index 0000000..ea26c2a --- /dev/null +++ b/SOURCES/0005-hints-remove-the-cmd-hints-list.patch @@ -0,0 +1,95 @@ +From 00ebabfe6e1ebfceffcef335d44a6156a1c15418 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 1 Nov 2021 16:01:09 -0500 +Subject: [PATCH 05/54] hints: remove the cmd hints list + +which is no longer used after commit +"toollib: remove all devices list from process_each_pv" +--- + lib/commands/toolcontext.c | 2 -- + lib/commands/toolcontext.h | 1 - + lib/label/hints.c | 1 - + lib/label/label.c | 8 ++------ + 4 files changed, 2 insertions(+), 10 deletions(-) + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index 105aecd5d..1b7170de1 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -1605,7 +1605,6 @@ struct cmd_context *create_config_context(void) + + dm_list_init(&cmd->config_files); + dm_list_init(&cmd->tags); +- dm_list_init(&cmd->hints); + + if (!_init_lvm_conf(cmd)) + goto_out; +@@ -1670,7 +1669,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd, + dm_list_init(&cmd->formats); + dm_list_init(&cmd->segtypes); + dm_list_init(&cmd->tags); +- dm_list_init(&cmd->hints); + dm_list_init(&cmd->config_files); + label_init(); + +diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h +index 701b7a739..356c79f8a 100644 +--- a/lib/commands/toolcontext.h ++++ b/lib/commands/toolcontext.h +@@ -206,7 +206,6 @@ struct cmd_context { + * Devices and filtering. + */ + struct dev_filter *filter; +- struct dm_list hints; + struct dm_list use_devices; /* struct dev_use for each entry in devices file */ + const char *md_component_checks; + const char *search_for_devnames; /* config file setting */ +diff --git a/lib/label/hints.c b/lib/label/hints.c +index 3dba9f8ec..e444a0c82 100644 +--- a/lib/label/hints.c ++++ b/lib/label/hints.c +@@ -365,7 +365,6 @@ static void _unlock_hints(struct cmd_context *cmd) + + void hints_exit(struct cmd_context *cmd) + { +- free_hints(&cmd->hints); + if (_hints_fd == -1) + return; + _unlock_hints(cmd); +diff --git a/lib/label/label.c b/lib/label/label.c +index 3cd912270..479a5037a 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -1207,8 +1207,6 @@ int label_scan(struct cmd_context *cmd) + (unsigned long long)want_size_kb); + } + +- dm_list_init(&cmd->hints); +- + /* + * If we're using hints to limit which devs we scanned, verify + * that those hints were valid, and if not we need to scan the +@@ -1220,18 +1218,16 @@ int label_scan(struct cmd_context *cmd) + _scan_list(cmd, cmd->filter, &all_devs, 0, NULL); + /* scan_devs are the devs that have been scanned */ + dm_list_splice(&scan_devs, &all_devs); +- free_hints(&hints_list); + using_hints = 0; + create_hints = 0; + /* invalid hints means a new dev probably appeared and + we should search for any missing pvids again. */ + unlink_searched_devnames(cmd); +- } else { +- /* The hints may be used by another device iteration. */ +- dm_list_splice(&cmd->hints, &hints_list); + } + } + ++ free_hints(&hints_list); ++ + /* + * Check if the devices_file content is up to date and + * if not update it. +-- +2.34.3 + diff --git a/SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch b/SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch new file mode 100644 index 0000000..7afc6a9 --- /dev/null +++ b/SOURCES/0006-filter-sysfs-skip-when-device-id-is-set.patch @@ -0,0 +1,422 @@ +From f73be4480a5dd104a77e3ef84d7dcc80b834e593 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 2 Nov 2021 15:42:26 -0500 +Subject: [PATCH 06/54] filter-sysfs: skip when device id is set + +When a device id is set for a device, using an idtype other +than devname, it means that sysfs has been used with the device +to match the device id. So, checking for a sysfs entry for the +device in filter-sysfs is redundant. For any other cases not +covered by this (e.g. devname ids), have filter-sysfs simply +stat /sys/dev/block/major:minor to test if the device exists +in sysfs. + +The extensive processing done by filter-sysfs init is removed. +It was taking an immense amount of time with many devices, e.g. +. 1024 PVs in 520 VGs +. 520 concurrent vgchange -ay commands +. vgchange scans only PVs in the named VG (based on pvs_online + files from a pending patch) + +A large number of the vgchange commands were taking over 1 min, +and nearly half of that time was used by filter-sysfs init. +With this patch, the vgchange commands take about half the time. +--- + lib/commands/toolcontext.c | 24 ++- + lib/filters/filter-sysfs.c | 296 +++---------------------------------- + 2 files changed, 32 insertions(+), 288 deletions(-) + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index 1b7170de1..a0c78ddd6 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -1143,19 +1143,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd) + * Update MAX_FILTERS definition above when adding new filters. + */ + +- /* +- * sysfs filter. Only available on 2.6 kernels. Non-critical. +- * Listed first because it's very efficient at eliminating +- * unavailable devices. +- * +- * TODO: I suspect that using the lvm_type and device_id +- * filters before this one may be more efficient. +- */ +- if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) { +- if ((filters[nr_filt] = sysfs_filter_create())) +- nr_filt++; +- } +- + /* internal filter used by command processing. */ + if (!(filters[nr_filt] = internal_filter_create())) { + log_error("Failed to create internal device filter"); +@@ -1195,6 +1182,17 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd) + } + nr_filt++; + ++ /* ++ * sysfs filter. Only available on 2.6 kernels. Non-critical. ++ * Eliminates unavailable devices. ++ * TODO: this may be unnecessary now with device ids ++ * (currently not used for devs match to device id using syfs) ++ */ ++ if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) { ++ if ((filters[nr_filt] = sysfs_filter_create())) ++ nr_filt++; ++ } ++ + /* usable device filter. Required. */ + if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_NO_LVMETAD))) { + log_error("Failed to create usabled device filter"); +diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c +index 32ac324dd..672211057 100644 +--- a/lib/filters/filter-sysfs.c ++++ b/lib/filters/filter-sysfs.c +@@ -17,288 +17,49 @@ + + #ifdef __linux__ + +-#include +-#include +- +-static int _locate_sysfs_blocks(const char *sysfs_dir, char *path, size_t len, +- unsigned *sysfs_depth) ++static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) + { ++ char path[PATH_MAX]; ++ const char *sysfs_dir; + struct stat info; +- unsigned i; +- static const struct dir_class { +- const char path[32]; +- int depth; +- } classes[] = { +- /* +- * unified classification directory for all kernel subsystems +- * +- * /sys/subsystem/block/devices +- * |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda +- * |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1 +- * `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0 +- * +- */ +- { "subsystem/block/devices", 0 }, +- +- /* +- * block subsystem as a class +- * +- * /sys/class/block +- * |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda +- * |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1 +- * `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0 +- * +- */ +- { "class/block", 0 }, +- +- /* +- * old block subsystem layout with nested directories +- * +- * /sys/block/ +- * |-- sda +- * | |-- capability +- * | |-- dev +- * ... +- * | |-- sda1 +- * | | |-- dev +- * ... +- * | +- * `-- sr0 +- * |-- capability +- * |-- dev +- * ... +- * +- */ +- +- { "block", 1 } +- }; +- +- for (i = 0; i < DM_ARRAY_SIZE(classes); ++i) +- if ((dm_snprintf(path, len, "%s%s", sysfs_dir, classes[i].path) >= 0) && +- (stat(path, &info) == 0)) { +- *sysfs_depth = classes[i].depth; +- return 1; +- } +- +- return 0; +-} +- +-/*---------------------------------------------------------------- +- * We need to store a set of dev_t. +- *--------------------------------------------------------------*/ +-struct entry { +- struct entry *next; +- dev_t dev; +-}; +- +-#define SET_BUCKETS 64 +-struct dev_set { +- struct dm_pool *mem; +- const char *sys_block; +- unsigned sysfs_depth; +- int initialised; +- struct entry *slots[SET_BUCKETS]; +-}; +- +-static struct dev_set *_dev_set_create(struct dm_pool *mem, +- const char *sys_block, +- unsigned sysfs_depth) +-{ +- struct dev_set *ds; +- +- if (!(ds = dm_pool_zalloc(mem, sizeof(*ds)))) +- return NULL; +- +- ds->mem = mem; +- if (!(ds->sys_block = dm_pool_strdup(mem, sys_block))) +- return NULL; +- +- ds->sysfs_depth = sysfs_depth; +- ds->initialised = 0; +- +- return ds; +-} +- +-static unsigned _hash_dev(dev_t dev) +-{ +- return (major(dev) ^ minor(dev)) & (SET_BUCKETS - 1); +-} + +-/* +- * Doesn't check that the set already contains dev. +- */ +-static int _set_insert(struct dev_set *ds, dev_t dev) +-{ +- struct entry *e; +- unsigned h = _hash_dev(dev); +- +- if (!(e = dm_pool_alloc(ds->mem, sizeof(*e)))) +- return 0; +- +- e->next = ds->slots[h]; +- e->dev = dev; +- ds->slots[h] = e; +- +- return 1; +-} ++ dev->filtered_flags &= ~DEV_FILTERED_SYSFS; + +-static int _set_lookup(struct dev_set *ds, dev_t dev) +-{ +- unsigned h = _hash_dev(dev); +- struct entry *e; ++ /* ++ * Any kind of device id other than devname has been set ++ * using sysfs so we know that sysfs info exists for dev. ++ */ ++ if (dev->id && dev->id->idtype && (dev->id->idtype != DEV_ID_TYPE_DEVNAME)) ++ return 1; + +- for (e = ds->slots[h]; e; e = e->next) +- if (e->dev == dev) ++ sysfs_dir = dm_sysfs_dir(); ++ if (sysfs_dir && *sysfs_dir) { ++ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", ++ sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) { ++ log_debug("failed to create sysfs path"); + return 1; +- +- return 0; +-} +- +-/*---------------------------------------------------------------- +- * filter methods +- *--------------------------------------------------------------*/ +-static int _parse_dev(const char *file, FILE *fp, dev_t *result) +-{ +- unsigned major, minor; +- char buffer[64]; +- +- if (!fgets(buffer, sizeof(buffer), fp)) { +- log_error("Empty sysfs device file: %s", file); +- return 0; +- } +- +- if (sscanf(buffer, "%u:%u", &major, &minor) != 2) { +- log_error("Incorrect format for sysfs device file: %s.", file); +- return 0; +- } +- +- *result = makedev(major, minor); +- return 1; +-} +- +-static int _read_dev(const char *file, dev_t *result) +-{ +- int r; +- FILE *fp; +- +- if (!(fp = fopen(file, "r"))) { +- log_sys_error("fopen", file); +- return 0; +- } +- +- r = _parse_dev(file, fp, result); +- +- if (fclose(fp)) +- log_sys_error("fclose", file); +- +- return r; +-} +- +-/* +- * Recurse through sysfs directories, inserting any devs found. +- */ +-static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth) +-{ +- struct dirent *d; +- DIR *dr; +- struct stat info; +- char path[PATH_MAX]; +- char file[PATH_MAX]; +- dev_t dev = { 0 }; +- int r = 1; +- +- if (!(dr = opendir(dir))) { +- log_sys_error("opendir", dir); +- return 0; +- } +- +- while ((d = readdir(dr))) { +- if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) +- continue; +- +- if (dm_snprintf(path, sizeof(path), "%s/%s", dir, +- d->d_name) < 0) { +- log_warn("WARNING: sysfs path name too long: %s in %s.", +- d->d_name, dir); +- continue; + } + +- /* devices have a "dev" file */ +- if (dm_snprintf(file, sizeof(file), "%s/dev", path) < 0) { +- log_warn("WARNING: sysfs path name too long: %s in %s.", +- d->d_name, dir); +- continue; +- } +- +- if (!stat(file, &info)) { +- /* recurse if we found a device and expect subdirs */ +- if (sysfs_depth) +- _read_devs(ds, path, sysfs_depth - 1); +- +- /* add the device we have found */ +- if (_read_dev(file, &dev)) +- _set_insert(ds, dev); ++ if (lstat(path, &info)) { ++ log_debug_devs("%s: Skipping (sysfs)", dev_name(dev)); ++ dev->filtered_flags |= DEV_FILTERED_SYSFS; ++ return 0; + } + } + +- if (closedir(dr)) +- log_sys_debug("closedir", dir); +- +- return r; +-} +- +-static int _init_devs(struct dev_set *ds) +-{ +- if (!_read_devs(ds, ds->sys_block, ds->sysfs_depth)) { +- ds->initialised = -1; +- return 0; +- } +- +- ds->initialised = 1; +- +- return 1; +-} +- +- +-static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) +-{ +- struct dev_set *ds = (struct dev_set *) f->private; +- +- dev->filtered_flags &= ~DEV_FILTERED_SYSFS; +- +- if (!ds->initialised) +- _init_devs(ds); +- +- /* Pass through if initialisation failed */ +- if (ds->initialised != 1) +- return 1; +- +- if (!_set_lookup(ds, dev->dev)) { +- log_debug_devs("%s: Skipping (sysfs)", dev_name(dev)); +- dev->filtered_flags |= DEV_FILTERED_SYSFS; +- return 0; +- } +- + return 1; + } + + static void _destroy(struct dev_filter *f) + { +- struct dev_set *ds = (struct dev_set *) f->private; +- + if (f->use_count) + log_error(INTERNAL_ERROR "Destroying sysfs filter while in use %u times.", f->use_count); +- +- dm_pool_destroy(ds->mem); ++ free(f); + } + + struct dev_filter *sysfs_filter_create(void) + { + const char *sysfs_dir = dm_sysfs_dir(); +- char sys_block[PATH_MAX]; +- unsigned sysfs_depth; +- struct dm_pool *mem; +- struct dev_set *ds; + struct dev_filter *f; + + if (!*sysfs_dir) { +@@ -306,26 +67,12 @@ struct dev_filter *sysfs_filter_create(void) + return NULL; + } + +- if (!_locate_sysfs_blocks(sysfs_dir, sys_block, sizeof(sys_block), &sysfs_depth)) +- return NULL; +- +- if (!(mem = dm_pool_create("sysfs", 256))) { +- log_error("sysfs pool creation failed"); +- return NULL; +- } +- +- if (!(ds = _dev_set_create(mem, sys_block, sysfs_depth))) { +- log_error("sysfs dev_set creation failed"); +- goto bad; +- } +- +- if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) ++ if (!(f = zalloc(sizeof(*f)))) + goto_bad; + + f->passes_filter = _accept_p; + f->destroy = _destroy; + f->use_count = 0; +- f->private = ds; + f->name = "sysfs"; + + log_debug_devs("Sysfs filter initialised."); +@@ -333,7 +80,6 @@ struct dev_filter *sysfs_filter_create(void) + return f; + + bad: +- dm_pool_destroy(mem); + return NULL; + } + +-- +2.34.3 + diff --git a/SOURCES/0007-lvmdevices-increase-open-file-limit.patch b/SOURCES/0007-lvmdevices-increase-open-file-limit.patch new file mode 100644 index 0000000..435d851 --- /dev/null +++ b/SOURCES/0007-lvmdevices-increase-open-file-limit.patch @@ -0,0 +1,61 @@ +From f732f3d53faee3732d0f4a666c378709e6c2f5e9 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 29 Oct 2021 14:49:36 -0500 +Subject: [PATCH 07/54] lvmdevices: increase open file limit + +--- + lib/label/label.c | 4 ++-- + lib/label/label.h | 2 ++ + tools/lvmdevices.c | 3 +++ + 3 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/lib/label/label.c b/lib/label/label.c +index 479a5037a..9fac3e464 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -891,7 +891,7 @@ static int _setup_bcache(void) + + #define BASE_FD_COUNT 32 /* Number of open files we want apart from devs */ + +-static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs) ++void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs) + { + #ifdef HAVE_PRLIMIT + struct rlimit old = { 0 }, new; +@@ -1165,7 +1165,7 @@ int label_scan(struct cmd_context *cmd) + * which we want to keep open) is higher than the current + * soft limit. + */ +- _prepare_open_file_limit(cmd, dm_list_size(&scan_devs)); ++ prepare_open_file_limit(cmd, dm_list_size(&scan_devs)); + + /* + * Do the main scan. +diff --git a/lib/label/label.h b/lib/label/label.h +index 8b510eb79..34563efd0 100644 +--- a/lib/label/label.h ++++ b/lib/label/label.h +@@ -134,4 +134,6 @@ void dev_invalidate(struct device *dev); + void dev_set_last_byte(struct device *dev, uint64_t offset); + void dev_unset_last_byte(struct device *dev); + ++void prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_devs); ++ + #endif +diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c +index 8d9634848..3f104f7de 100644 +--- a/tools/lvmdevices.c ++++ b/tools/lvmdevices.c +@@ -176,6 +176,9 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + log_error("Failed to read the devices file."); + return ECMD_FAILED; + } ++ ++ prepare_open_file_limit(cmd, dm_list_size(&cmd->use_devices)); ++ + dev_cache_scan(cmd); + device_ids_match(cmd); + +-- +2.34.3 + diff --git a/SOURCES/0008-filter-sysfs-support-old-kernels-without-sys-dev-blo.patch b/SOURCES/0008-filter-sysfs-support-old-kernels-without-sys-dev-blo.patch new file mode 100644 index 0000000..d334f92 --- /dev/null +++ b/SOURCES/0008-filter-sysfs-support-old-kernels-without-sys-dev-blo.patch @@ -0,0 +1,73 @@ +From fad2b3dc8c44ba1222508ee78b5f161994efe638 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 9 Nov 2021 11:54:48 -0600 +Subject: [PATCH 08/54] filter-sysfs: support old kernels without sys/dev/block + +rhel5 for example doesn't have /sys/dev/block +--- + lib/filters/filter-sysfs.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c +index 672211057..d8de7940b 100644 +--- a/lib/filters/filter-sysfs.c ++++ b/lib/filters/filter-sysfs.c +@@ -15,6 +15,8 @@ + #include "lib/misc/lib.h" + #include "lib/filters/filter.h" + ++static int _sys_dev_block_found; ++ + #ifdef __linux__ + + static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) +@@ -23,6 +25,9 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic + const char *sysfs_dir; + struct stat info; + ++ if (!_sys_dev_block_found) ++ return 1; ++ + dev->filtered_flags &= ~DEV_FILTERED_SYSFS; + + /* +@@ -57,6 +62,26 @@ static void _destroy(struct dev_filter *f) + free(f); + } + ++static void _check_sys_dev_block(void) ++{ ++ char path[PATH_MAX]; ++ const char *sysfs_dir; ++ struct stat info; ++ ++ sysfs_dir = dm_sysfs_dir(); ++ if (sysfs_dir && *sysfs_dir) { ++ if (dm_snprintf(path, sizeof(path), "%sdev/block", sysfs_dir) < 0) ++ return; ++ ++ if (lstat(path, &info)) { ++ log_debug("filter-sysfs disabled: /sys/dev/block not found"); ++ _sys_dev_block_found = 0; ++ } else { ++ _sys_dev_block_found = 1; ++ } ++ } ++} ++ + struct dev_filter *sysfs_filter_create(void) + { + const char *sysfs_dir = dm_sysfs_dir(); +@@ -67,6 +92,9 @@ struct dev_filter *sysfs_filter_create(void) + return NULL; + } + ++ /* support old kernels that don't have this */ ++ _check_sys_dev_block(); ++ + if (!(f = zalloc(sizeof(*f)))) + goto_bad; + +-- +2.34.3 + diff --git a/SOURCES/0009-device_id-match-different-dm-device-names.patch b/SOURCES/0009-device_id-match-different-dm-device-names.patch new file mode 100644 index 0000000..f1d6c1c --- /dev/null +++ b/SOURCES/0009-device_id-match-different-dm-device-names.patch @@ -0,0 +1,155 @@ +From 459d931a9bfe4c9adcbbf2e76fdf35fda5b13c61 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 12 Nov 2021 16:42:51 -0600 +Subject: [PATCH 09/54] device_id: match different dm device names + +If a devices file entry for a dm device is using the devname +for the device id, then recognize different dm names as matching. +--- + lib/device/device_id.c | 81 +++++++++++++++++++++++++++++++++++------- + 1 file changed, 69 insertions(+), 12 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index eb06109ff..dea739fc4 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1360,6 +1360,10 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, + + static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idtype, int major) + { ++ /* devname can be used with any kind of device */ ++ if (idtype == DEV_ID_TYPE_DEVNAME) ++ return 1; ++ + if (idtype == DEV_ID_TYPE_MPATH_UUID || + idtype == DEV_ID_TYPE_CRYPT_UUID || + idtype == DEV_ID_TYPE_LVMLV_UUID) +@@ -1388,6 +1392,43 @@ static int _idtype_compatible_with_major_number(struct cmd_context *cmd, int idt + return 1; + } + ++static int _match_dm_devnames(struct cmd_context *cmd, struct device *dev, ++ struct dev_id *id, struct dev_use *du) ++{ ++ struct stat buf; ++ ++ if (MAJOR(dev->dev) != cmd->dev_types->device_mapper_major) ++ return 0; ++ ++ if (id->idname && du->idname && !strcmp(id->idname, du->idname)) ++ return 1; ++ ++ if (du->idname && !strcmp(du->idname, dev_name(dev))) { ++ log_debug("Match device_id %s %s to %s: ignoring idname %s", ++ idtype_to_str(du->idtype), du->idname, dev_name(dev), id->idname ?: "."); ++ return 1; ++ } ++ ++ if (!du->idname) ++ return 0; ++ ++ /* detect that a du entry is for a dm device */ ++ ++ if (!strncmp(du->idname, "/dev/dm-", 8) || !strncmp(du->idname, "/dev/mapper/", 12)) { ++ if (stat(du->idname, &buf)) ++ return 0; ++ ++ if ((MAJOR(buf.st_rdev) == cmd->dev_types->device_mapper_major) && ++ (MINOR(buf.st_rdev) == MINOR(dev->dev))) { ++ log_debug("Match device_id %s %s to %s: using other dm name, ignoring %s", ++ idtype_to_str(du->idtype), du->idname, dev_name(dev), id->idname ?: "."); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ + /* + * check for dev->ids entry with du->idtype, if found compare it, + * if not, system_read of this type and add entry to dev->ids, compare it. +@@ -1408,35 +1449,52 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct + * so we can skip trying to match certain du entries based simply on + * the major number of dev. + */ +- if (!_idtype_compatible_with_major_number(cmd, du->idtype, (int)MAJOR(dev->dev))) ++ if (!_idtype_compatible_with_major_number(cmd, du->idtype, (int)MAJOR(dev->dev))) { ++ /* ++ log_debug("Mismatch device_id %s %s to %s: wrong major", ++ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev)); ++ */ + return 0; ++ } + + if (!dev_get_partition_number(dev, &part)) { +- log_debug("compare %s failed to get dev partition", dev_name(dev)); ++ /* ++ log_debug("Mismatch device_id %s %s to %s: no partition", ++ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev)); ++ */ + return 0; + } + if (part != du->part) { + /* +- log_debug("compare mis %s %s part %d to %s part %d", +- idtype_to_str(du->idtype), du->idname ?: ".", du->part, dev_name(dev), part); ++ log_debug("Mismatch device_id %s %s to %s: wrong partition %d vs %d", ++ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), du->part, part); + */ + return 0; + } + + dm_list_iterate_items(id, &dev->ids) { + if (id->idtype == du->idtype) { +- if (id->idname && !strcmp(id->idname, du->idname)) { ++ if ((id->idtype == DEV_ID_TYPE_DEVNAME) && _match_dm_devnames(cmd, dev, id, du)) { ++ /* dm devs can have differing names that we know still match */ ++ du->dev = dev; ++ dev->id = id; ++ dev->flags |= DEV_MATCHED_USE_ID; ++ log_debug("Match device_id %s %s to %s: dm names", ++ idtype_to_str(du->idtype), du->idname, dev_name(dev)); ++ return 1; ++ ++ } else if (id->idname && !strcmp(id->idname, du->idname)) { + du->dev = dev; + dev->id = id; + dev->flags |= DEV_MATCHED_USE_ID; + log_debug("Match device_id %s %s to %s", + idtype_to_str(du->idtype), du->idname, dev_name(dev)); + return 1; ++ + } else { + /* +- log_debug("compare mis %s %s to %s %s", +- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), +- ((id->idtype != DEV_ID_TYPE_DEVNAME) && id->idname) ? id->idname : ""); ++ log_debug("Mismatch device_id %s %s to %s: idname %s", ++ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), id->idname ?: ":"); + */ + return 0; + } +@@ -1456,7 +1514,7 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct + id->dev = dev; + dm_list_add(&dev->ids, &id->list); + /* +- log_debug("compare mis %s %s to %s no idtype", ++ log_debug("Mismatch device_id %s %s to %s: no idtype", + idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev)); + */ + return 0; +@@ -1481,9 +1539,8 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct + } + + /* +- log_debug("compare mis %s %s to %s %s", +- idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), +- ((id->idtype != DEV_ID_TYPE_DEVNAME) && id->idname) ? id->idname : ""); ++ log_debug("Mismatch device_id %s %s to %s: idname %s", ++ idtype_to_str(du->idtype), du->idname ?: ".", dev_name(dev), idname); + */ + return 0; + } +-- +2.34.3 + diff --git a/SOURCES/0010-device_id-fix-search-on-filtered-device.patch b/SOURCES/0010-device_id-fix-search-on-filtered-device.patch new file mode 100644 index 0000000..b8c9ed4 --- /dev/null +++ b/SOURCES/0010-device_id-fix-search-on-filtered-device.patch @@ -0,0 +1,134 @@ +From 5533cd7bf4c1edc5d8fb0e95d2f83b2b2d446339 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 16 Nov 2021 09:29:24 -0600 +Subject: [PATCH 10/54] device_id: fix search on filtered device + +When devnames are used as device ids and devnames change, +then new devices need to be located for the PVs. If the old +devname is now used by a filtered device, this was preventing +the code from searching for the new device, so the PV was +reported as missing. +--- + lib/device/device_id.c | 16 ++++++- + test/shell/devicesfile-devname.sh | 69 +++++++++++++++++++++++++++++++ + 2 files changed, 83 insertions(+), 2 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index dea739fc4..48f1682a3 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -2025,12 +2025,19 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l + search_auto = !strcmp(cmd->search_for_devnames, "auto"); + + dm_list_iterate_items(du, &cmd->use_devices) { +- if (du->dev) +- continue; + if (!du->pvid) + continue; + if (du->idtype != DEV_ID_TYPE_DEVNAME) + continue; ++ ++ /* ++ * if the old incorrect devname is now a device that's ++ * filtered and not scanned, e.g. an mpath component, ++ * then we want to look for the pvid on a new device. ++ */ ++ if (du->dev && !du->dev->filtered_flags) ++ continue; ++ + if (!(dil = dm_pool_zalloc(cmd->mem, sizeof(*dil)))) + continue; + +@@ -2055,6 +2062,11 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l + * the searched file, so a subsequent lvm command will do the search + * again. In future perhaps we could add a policy to automatically + * remove a devices file entry that's not been found for some time. ++ * ++ * TODO: like the hint file, add a hash of all devnames to the searched ++ * file so it can be ignored and removed if the devs/hash change. ++ * If hints are enabled, the hints invalidation could also remove the ++ * searched file. + */ + if (_searched_devnames_exists(cmd)) { + log_debug("Search for PVIDs skipped for %s", _searched_file); +diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh +index f95be52b1..a99fe3e9a 100644 +--- a/test/shell/devicesfile-devname.sh ++++ b/test/shell/devicesfile-devname.sh +@@ -545,4 +545,73 @@ grep "$PVID2" "$DF" |tee out + grep "$dev2" out + not grep "$dev1" out + ++vgchange -an $vg1 ++vgchange -an $vg2 ++vgremove -ff $vg1 ++vgremove -ff $vg2 ++ ++# devnames change so the new devname now refers to a filtered device, ++# e.g. an mpath or md component, which is not scanned ++ ++wait_md_create() { ++ local md=$1 ++ ++ while :; do ++ if ! grep "$(basename $md)" /proc/mdstat; then ++ echo "$md not ready" ++ cat /proc/mdstat ++ sleep 2 ++ else ++ break ++ fi ++ done ++ echo "$md" > WAIT_MD_DEV ++} ++ ++aux wipefs_a "$dev1" ++aux wipefs_a "$dev2" ++aux wipefs_a "$dev3" ++aux wipefs_a "$dev4" ++ ++mddev="/dev/md33" ++not grep $mddev /proc/mdstat || skip ++ ++rm "$DF" ++touch "$DF" ++vgcreate $vg1 "$dev1" "$dev2" ++cat "$DF" ++cp "$DF" "$ORIG" ++ ++# PVID with dashes for matching pvs -o+uuid output ++OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'` ++OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'` ++ ++# PVID without dashes for matching devices file fields ++PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'` ++PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'` ++ ++mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev3" "$dev4" ++wait_md_create "$mddev" ++ ++sed -e "s|DEVNAME=$dev1|DEVNAME=$dev3|" "$ORIG" > tmp1.devices ++sed -e "s|IDNAME=$dev1|IDNAME=$dev3|" tmp1.devices > "$DF" ++cat "$DF" ++pvs -o+uuid |tee out ++grep "$dev1" out ++grep "$dev2" out ++grep "$OPVID1" out ++grep "$OPVID2" out ++not grep "$dev3" out ++not grep "$dev4" out ++ ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++grep "$PVID1" "$DF" ++grep "$PVID2" "$DF" ++not grep "$dev3" "$DF" ++not grep "$dev4" "$DF" ++ ++mdadm --stop "$mddev" ++aux udev_wait ++ + vgremove -ff $vg1 +-- +2.34.3 + diff --git a/SOURCES/0011-device_id-searched_devnames-improvements.patch b/SOURCES/0011-device_id-searched_devnames-improvements.patch new file mode 100644 index 0000000..7c3f423 --- /dev/null +++ b/SOURCES/0011-device_id-searched_devnames-improvements.patch @@ -0,0 +1,102 @@ +From 39adf3e513ac7b1cbbbf0189f973573ade3c8939 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 16 Nov 2021 11:26:41 -0600 +Subject: [PATCH 11/54] device_id: searched_devnames improvements + +Remove the searched_devnames file in a couple more places: +. When hints need refreshing it's possible that a missing + devices file entry could be found by searching devices + again. +. When a devices file entry devname is first found to be + incorrect, a new search for missing entries may be + useful. +--- + lib/device/device_id.c | 28 ++++++++++++++++++++++++++-- + lib/label/hints.c | 10 ++++++++++ + 2 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 48f1682a3..ce7ded154 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -74,6 +74,8 @@ void unlink_searched_devnames(struct cmd_context *cmd) + + if (unlink(_searched_file)) + log_debug("unlink %s errno %d", _searched_file, errno); ++ else ++ log_debug("unlink %s", _searched_file); + } + + static int _searched_devnames_exists(struct cmd_context *cmd) +@@ -780,7 +782,7 @@ static void _device_ids_update_try(struct cmd_context *cmd) + + /* Defer updates to non-pvscan-cache commands. */ + if (cmd->pvscan_cache_single) { +- log_print("pvscan[%d] skip updating devices file.", getpid()); ++ log_print("Devices file update skipped."); + return; + } + +@@ -1441,8 +1443,22 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct + const char *idname; + int part; + +- if (!du->idname || !du->idtype) ++ /* ++ * The idname will be removed from an entry with devname type when the ++ * devname is read and found to hold a different PVID than the PVID in ++ * the entry. At that point we only have the PVID and no known ++ * location for it. ++ */ ++ if (!du->idname || !du->idtype) { ++ /* ++ log_debug("Mismatch device_id %s %s %s to %s", ++ du->idtype ? idtype_to_str(du->idtype) : "idtype_missing", ++ du->idname ? du->idname : "idname_missing", ++ du->devname ? du->devname : "devname_missing", ++ dev_name(dev)); ++ */ + return 0; ++ } + + /* + * Some idtypes can only match devices with a specific major number, +@@ -1957,6 +1973,14 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + *device_ids_invalid = 1; + } + ++ /* ++ * When a new devname/pvid mismatch is discovered, a new search for the ++ * pvid should be permitted (searched_devnames may exist to suppress ++ * searching for other pvids.) ++ */ ++ if (update_file) ++ unlink_searched_devnames(cmd); ++ + /* FIXME: for wrong devname cases, wait to write new until device_ids_find_renamed_devs? */ + + /* +diff --git a/lib/label/hints.c b/lib/label/hints.c +index e444a0c82..3ce9634f2 100644 +--- a/lib/label/hints.c ++++ b/lib/label/hints.c +@@ -1390,6 +1390,16 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints, + log_debug("get_hints: needs refresh"); + free_hints(&hints_list); + ++ /* ++ * This is not related to hints, and is probably unnecessary, ++ * but it could possibly help. When hints become invalid it's ++ * usually becaues devs on the system have changed, and that ++ * also means that a missing devices file entry might be found ++ * by searching devices again. (the searched_devnames ++ * mechanism should eventually be replaced) ++ */ ++ unlink_searched_devnames(cmd); ++ + if (!_lock_hints(cmd, LOCK_EX, NONBLOCK)) + return 0; + +-- +2.34.3 + diff --git a/SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch b/SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch new file mode 100644 index 0000000..dcf9507 --- /dev/null +++ b/SOURCES/0012-tests-pv-ext-flags-work-with-devices-file.patch @@ -0,0 +1,40 @@ +From 9c9bf13186d387d807f279c112745768c8b32513 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 16 Nov 2021 14:21:07 -0600 +Subject: [PATCH 12/54] tests pv-ext-flags: work with devices file + +--- + test/shell/pv-ext-flags.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/shell/pv-ext-flags.sh b/test/shell/pv-ext-flags.sh +index 3e6bcff76..ae4d6b7ff 100644 +--- a/test/shell/pv-ext-flags.sh ++++ b/test/shell/pv-ext-flags.sh +@@ -57,9 +57,11 @@ dd if="$dev1" of=dev1_backup bs=1M + + # pvcreate and pvremove can be forced even if the PV is marked as used + pvremove -ff -y "$dev1" ++lvmdevices --deldev "$dev1" || true + dd if=dev1_backup of="$dev1" bs=1M + pvcreate -ff -y "$dev1" + dd if=dev1_backup of="$dev1" bs=1M ++lvmdevices --adddev "$dev1" || true + + # prepare a VG with $dev1 and $dev both having 1 MDA + aux enable_dev "$dev2" +@@ -116,9 +118,11 @@ dd if="$dev1" of=dev1_backup bs=1M + + # pvcreate and pvremove can be forced even if the PV is marked as used + pvremove -ff -y "$dev1" ++lvmdevices --deldev "$dev1" || true + dd if=dev1_backup of="$dev1" bs=1M + pvcreate -ff -y "$dev1" + dd if=dev1_backup of="$dev1" bs=1M ++lvmdevices --adddev "$dev1" || true + + # prepare a VG with $dev1 and $dev both having 1 MDA + aux enable_dev "$dev2" +-- +2.34.3 + diff --git a/SOURCES/0013-display-ignore-reportformat.patch b/SOURCES/0013-display-ignore-reportformat.patch new file mode 100644 index 0000000..33b7e28 --- /dev/null +++ b/SOURCES/0013-display-ignore-reportformat.patch @@ -0,0 +1,91 @@ +From 594c1fec1644fdf291aa0ff23de20db65c4cfadf Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 17 Nov 2021 10:40:27 -0600 +Subject: [PATCH 13/54] display: ignore --reportformat + +Using the option would do nothing useful but would +print extraneous braces. +--- + tools/command-lines.in | 12 ++++++------ + tools/lvmcmdline.c | 15 +++++++++++++++ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/tools/command-lines.in b/tools/command-lines.in +index 10b23e75d..00ac08934 100644 +--- a/tools/command-lines.in ++++ b/tools/command-lines.in +@@ -1359,10 +1359,10 @@ OO: --aligned, --all, --binary, --colon, --columns, + --configreport ConfigReport, --foreign, --history, --ignorelockingfailure, + --logonly, --maps, --noheadings, + --nosuffix, --options String, --sort String, --readonly, +---reportformat ReportFmt, --segments, --select String, --separator String, ++--segments, --select String, --separator String, + --shared, --unbuffered, --units Units + OP: VG|LV|Tag ... +-IO: --partial, --ignoreskippedcluster ++IO: --partial, --ignoreskippedcluster, --reportformat ReportFmt + ID: lvdisplay_general + + --- +@@ -1590,10 +1590,10 @@ pvdisplay + OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport, + --foreign, --ignorelockingfailure, + --logonly, --maps, --noheadings, --nosuffix, --options String, +---readonly, --reportformat ReportFmt, --select String, --separator String, --shared, ++--readonly, --select String, --separator String, --shared, + --short, --sort String, --unbuffered, --units Units + OP: PV|Tag ... +-IO: --ignoreskippedcluster ++IO: --ignoreskippedcluster, --reportformat ReportFmt + ID: pvdisplay_general + + --- +@@ -1809,10 +1809,10 @@ vgdisplay + OO: --activevolumegroups, --aligned, --binary, --colon, --columns, + --configreport ConfigReport, --foreign, --ignorelockingfailure, + --logonly, --noheadings, --nosuffix, +---options String, --readonly, --reportformat ReportFmt, --select String, ++--options String, --readonly, --select String, + --shared, --short, --separator String, --sort String, --unbuffered, --units Units + OP: VG|Tag ... +-IO: --partial, --ignoreskippedcluster ++IO: --partial, --ignoreskippedcluster, --reportformat ReportFmt + ID: vgdisplay_general + + --- +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index 1e12bedca..1727ba089 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -3058,6 +3058,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + int i; + int skip_hyphens; + int refresh_done = 0; ++ int io; + + /* Avoid excessive access to /etc/localtime and set TZ variable for glibc + * so it does not need to check /etc/localtime everytime that needs that info */ +@@ -3140,6 +3141,20 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + if (!(cmd->command = _find_command(cmd, cmd->name, &argc, argv))) + return EINVALID_CMD_LINE; + ++ /* ++ * If option --foo is set which is listed in IO (ignore option) in ++ * command-lines.in, then unset foo. Commands won't usually use an ++ * ignored option, but there can be shared code that checks for --foo, ++ * and should not find it to be set. ++ */ ++ for (io = 0; io < cmd->command->io_count; io++) { ++ int opt = cmd->command->ignore_opt_args[io].opt; ++ if (arg_is_set(cmd, opt)) { ++ log_debug("Ignore opt %d", opt); ++ cmd->opt_arg_values[opt].count = 0; ++ } ++ } ++ + /* + * Remaining position args after command name and --options are removed. + */ +-- +2.34.3 + diff --git a/SOURCES/0014-fix-spelling-of-pruning.patch b/SOURCES/0014-fix-spelling-of-pruning.patch new file mode 100644 index 0000000..61afdb4 --- /dev/null +++ b/SOURCES/0014-fix-spelling-of-pruning.patch @@ -0,0 +1,25 @@ +From 7ac0b3c119b1cbb8e0b4969ece0b279637ace8c3 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 19 Nov 2021 12:02:35 -0600 +Subject: [PATCH 14/54] fix spelling of pruning + +--- + lib/format_text/archive.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c +index 09a472b4c..2e8792a93 100644 +--- a/lib/format_text/archive.c ++++ b/lib/format_text/archive.c +@@ -219,7 +219,7 @@ static void _remove_expired(const char *dir, const char *vgname, + + sum /= 1024 * 1024; + if (sum > 128 || archives_size > 8192) +- log_print_unless_silent("Consider prunning %s VG archive with more then %u MiB in %u files (check archiving is needed in lvm.conf).", ++ log_print_unless_silent("Consider pruning %s VG archive with more then %u MiB in %u files (check archiving is needed in lvm.conf).", + vgname, (unsigned)sum, archives_size); + } + +-- +2.34.3 + diff --git a/SOURCES/0015-man-lvmautoactivation.patch b/SOURCES/0015-man-lvmautoactivation.patch new file mode 100644 index 0000000..6abef88 --- /dev/null +++ b/SOURCES/0015-man-lvmautoactivation.patch @@ -0,0 +1,416 @@ +From 25dbe3dd825a629ff7f67cb43342cc345071d3f7 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 24 Nov 2021 16:03:39 -0600 +Subject: [PATCH 15/54] man: lvmautoactivation + +new topical man page describing autoactivation +--- + man/Makefile.in | 2 +- + man/lvm.8_main | 1 + + man/lvmautoactivation.7_main | 280 +++++++++++++++++++++++++++++++++++ + man/pvscan.8_des | 63 ++++---- + 4 files changed, 309 insertions(+), 37 deletions(-) + create mode 100644 man/lvmautoactivation.7_main + +diff --git a/man/Makefile.in b/man/Makefile.in +index 40248d640..ba6f2046f 100644 +--- a/man/Makefile.in ++++ b/man/Makefile.in +@@ -33,7 +33,7 @@ CMIRRORDMAN = cmirrord.8 + LVMDBUSDMAN = lvmdbusd.8 + + MAN5=lvm.conf.5 +-MAN7=lvmsystemid.7 lvmreport.7 lvmraid.7 ++MAN7=lvmsystemid.7 lvmreport.7 lvmraid.7 lvmautoactivation.7 + + MAN8=lvm.8 lvmdump.8 lvm-fullreport.8 lvm-lvpoll.8 \ + lvcreate.8 lvchange.8 lvmconfig.8 lvconvert.8 lvdisplay.8 \ +diff --git a/man/lvm.8_main b/man/lvm.8_main +index 6f86d0353..a008a3bc0 100644 +--- a/man/lvm.8_main ++++ b/man/lvm.8_main +@@ -579,6 +579,7 @@ Prepends source file name and code line number with libdm debugging. + .BR lvmraid (7), + .BR lvmthin (7), + .BR lvmcache (7), ++.BR lvmautoactivation (7), + .P + .BR dmsetup (8), + .BR dmstats (8), +diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main +new file mode 100644 +index 000000000..87c15a3d1 +--- /dev/null ++++ b/man/lvmautoactivation.7_main +@@ -0,0 +1,280 @@ ++.TH "LVMAUTOACTIVATION" "7" "LVM TOOLS #VERSION#" "Red Hat, Inc" "\"" ++. ++.SH NAME ++. ++lvmautoactivation \(em LVM autoactivation ++. ++.SH DESCRIPTION ++. ++Autoactivation is the activation of LVs performed automatically by the ++system in response to LVM devices being attached to the machine. When all ++PVs in a VG have been attached, the VG is complete, and LVs in the VG are ++activated. ++.P ++Autoactivation of VGs, or specific LVs, can be prevented using vgchange or ++lvchange --setautoactivation n. The lvm.conf auto_activation_volume_list ++is another way to limit autoactivation. ++.P ++The most common form of autoactivation is "event based", in which complete ++VGs are activated in response to uevents which occur during system startup ++or at any time after the system has started. Another form of ++autoactivation is "service based" in which complete VGs are activated at a ++fixed point during system startup by a systemd service, and are not ++activated in response to uevents. This can be controlled with the ++lvm.conf setting event_activation. ++.P ++Event based autoactivation is driven by udev, udev rules, and systemd. ++When a device is attached to a machine, a uevent is generated by the ++kernel to notify userspace of the new device. systemd-udev runs udev ++rules to process the new device. Udev rules use blkid to identify the ++device as an LVM PV and then execute the lvm-specific udev rule for the ++device, which triggers autoactivation. ++.P ++There are two variations of event based autoactivation that may be used a ++system, depending on the LVM udev rule that is installed (found in ++/lib/udev/rules.d/.) The following summarizes the steps in each rule ++which lead to autoactivation: ++.P ++.B 69-dm-lvm-metad.rules ++. ++.IP \[bu] 2 ++device /dev/name with major:minor X:Y is attached to the machine ++. ++.IP \[bu] 2 ++systemd/udev runs blkid to identify /dev/name as an LVM PV ++. ++.IP \[bu] 2 ++udev rule 69-dm-lvm-metad.rules is run for /dev/name ++. ++.IP \[bu] 2 ++the lvm udev rule runs the systemd service lvm2-pvscan@X:Yservice ++. ++.IP \[bu] 2 ++the lvm2-pvscan service runs: ++.br ++pvscan --cache -aay --major X --minor Y ++. ++.IP \[bu] 2 ++pvscan reads the device, records that the PV is online ++(see pvs_online), and checks if the VG is complete. ++. ++.IP \[bu] 2 ++if the VG is complete, pvscan creates the vgs_online temp file, ++and activates the VG. ++. ++.IP \[bu] 2 ++the activation command output can be seen from ++systemctl status lvm2-pvscan* ++.P ++.B 69-dm-lvm.rules ++. ++.IP \[bu] 2 ++device /dev/name with major:minor X:Y is attached to the machine ++. ++.IP \[bu] 2 ++systemd/udev runs blkid to identify /dev/name as an LVM PV ++. ++.IP \[bu] 2 ++udev rule 69-dm-lvm.rules is run for /dev/name ++. ++.IP \[bu] 2 ++the lvm udev rule runs: ++.br ++pvscan --cache --listvg --checkcomplete --vgonline ++.br ++--autoactivation event --udevoutput --journal=output /dev/name ++. ++.IP \[bu] 2 ++pvscan reads the device, records that the PV is online ++(see pvs_online), and checks if the VG is complete. ++. ++.IP \[bu] 2 ++if the VG is complete, pvscan creates the vgs_online temp file, ++and prints the name of the VG for the udev rule to import: ++LVM_VG_NAME_COMPLETE='vgname' ++. ++.IP \[bu] 2 ++if the lvm udev rule sees LVM_VG_NAME_COMPLETE from pvscan, ++it activates the VG using a transient systemd service named ++lvm-activate-. ++. ++.IP \[bu] 2 ++the lvm-activate- service runs ++.br ++vgchange -aay --autoactivation event ++. ++.IP \[bu] 2 ++the activation command output can be seen from ++systemctl status lvm-activate- ++.P ++. ++.SS pvscan options ++.P ++.B --cache ++.br ++Read the arg (and only that device), and record that ++the PV is online by creating the /run/lvm/pvs_online/ ++file containing the name of the VG and the device for the PV. ++.P ++.B -aay ++.br ++Activate the VG from the pvscan command ++(includes implicit --checkcomplete and --vgonline.) ++.P ++.B --checkcomplete ++.br ++Check if the VG is complete, i.e. all PVs are present on ++the system, by checking /run/lvm/pvs_online/ files. ++.P ++.B --vgonline ++.br ++Create /run/lvm/vgs_online/ if the VG is complete ++(used to ensure only one command performs activation.) ++.P ++.B --autoactivation event ++.br ++Inform the command it is used for event based autoactivation. ++.P ++.B --listvg ++.br ++Print the name of the VG using the device. ++.P ++.B --udevoutput ++.br ++Only print output that can be imported to the udev rule, ++using the udev environment key format, i.e. NAME='value'. ++.P ++.B --journal=output ++.br ++Send standard command output to the journal (when stdout ++is reserved for udev output.) ++.P ++.SS Temp files ++.P ++Autoactivation commands use a number of temp files in /run/lvm (with the ++expectation that /run is cleared between boots.) ++.P ++.B pvs_online ++.br ++pvscan --cache creates a file here for each PV that is attached. The file ++is named with the PVID and contains the VG name and device information. ++The existence of the file is used to determine when all PVs for a given VG ++are present. The device information in these files is also used to ++optimize locating devices for a VG when the VG is activated. ++.P ++.B pvs_lookup ++.br ++pvscan --cache creates a file here named for a VG (if one doesn't already ++exist.) The file contains a list of PVIDs in the VG. This is needed when ++a PV is processed which has no VG metadata, in which case the list of ++PVIDs from the lookup file is used to check if the VG is complete. ++.P ++.B vgs_online ++.br ++The first activation command (pvscan or vgchange) to create a file here, ++named for the VG, will activate the VG. This resolves a race when ++concurrent commands attempt to activate a VG at once. ++. ++.SH EXAMPLES ++.P ++VG "vg" contains two PVs: ++.nf ++$ pvs -o name,vgname,uuid /dev/sdb /dev/sdc ++ PV VG PV UUID ++ /dev/sdb vg 1uKpaT-lFOZ-NLHX-j4jI-OBi1-QpdE-HZ5hZY ++ /dev/sdc vg 5J3tM8-aIPe-2vbd-DBe7-bvRq-TGj0-DaKV2G ++.fi ++.P ++use of --cache: ++.nf ++$ pvscan --cache /dev/sdb ++ pvscan[12922] PV /dev/sdb online. ++$ pvscan --cache /dev/sdc ++ pvscan[12923] PV /dev/sdc online. ++ ++$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY ++8:16 ++vg:vg ++dev:/dev/sdb ++$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G ++8:32 ++vg:vg ++dev:/dev/sdc ++.fi ++.P ++use of -aay: ++.nf ++$ pvscan --cache -aay /dev/sdb ++ pvscan[12935] PV /dev/sdb online, VG vg incomplete (need 1). ++$ pvscan --cache -aay /dev/sdc ++ pvscan[12936] PV /dev/sdc online, VG vg is complete. ++ pvscan[12936] VG vg run autoactivation. ++ 1 logical volume(s) in volume group "vg" now active ++ ++$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY ++8:16 ++vg:vg ++dev:/dev/sdb ++$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G ++8:32 ++vg:vg ++dev:/dev/sdc ++$ ls /run/lvm/vgs_online/vg ++/run/lvm/vgs_online/vg ++.fi ++.P ++use of --listvg: ++.nf ++$ pvscan --cache --listvg /dev/sdb ++ VG vg ++$ pvscan --cache --listvg /dev/sdc ++ VG vg ++ ++$ cat /run/lvm/pvs_online/1uKpaTlFOZNLHXj4jIOBi1QpdEHZ5hZY ++8:16 ++vg:vg ++dev:/dev/sdb ++$ cat /run/lvm/pvs_online/5J3tM8aIPe2vbdDBe7bvRqTGj0DaKV2G ++8:32 ++vg:vg ++dev:/dev/sdc ++.fi ++.P ++use of --checkcomplete: ++.nf ++$ pvscan --cache --listvg --checkcomplete --vgonline /dev/sdb ++ pvscan[12996] PV /dev/sdb online, VG vg incomplete (need 1). ++ VG vg incomplete ++$ pvscan --cache --listvg --checkcomplete --vgonline /dev/sdc ++ pvscan[12997] PV /dev/sdc online, VG vg is complete. ++ VG vg complete ++.fi ++.P ++use of --udevoutput: ++.nf ++$ pvscan --cache --listvg --checkcomplete --vgonline --udevoutput /dev/sdb ++LVM_VG_NAME_INCOMPLETE='vg' ++$ pvscan --cache --listvg --checkcomplete --vgonline --udevoutput /dev/sdc ++LVM_VG_NAME_COMPLETE='vg' ++.fi ++.P ++use of --listlvs: ++.nf ++$ lvs -o name,devices vg ++ LV Devices ++ lvol0 /dev/sdb(0) ++ lvol1 /dev/sdc(0) ++ lvol2 /dev/sdb(1),/dev/sdc(1) ++ ++$ pvscan --cache --listlvs --checkcomplete /dev/sdb ++ pvscan[13288] PV /dev/sdb online, VG vg incomplete (need 1). ++ VG vg incomplete ++ LV vg/lvol0 complete ++ LV vg/lvol2 incomplete ++$ pvscan --cache --listlvs --checkcomplete /dev/sdc ++ pvscan[13289] PV /dev/sdc online, VG vg is complete. ++ VG vg complete ++ LV vg/lvol1 complete ++ LV vg/lvol2 complete ++.fi ++ +diff --git a/man/pvscan.8_des b/man/pvscan.8_des +index b20b987da..4c5929955 100644 +--- a/man/pvscan.8_des ++++ b/man/pvscan.8_des +@@ -4,56 +4,47 @@ like + or + .BR pvdisplay (8). + .P +-When the --cache and -aay options are used, pvscan records which PVs are +-available on the system, and activates LVs in completed VGs. A VG is +-complete when pvscan sees that the final PV in the VG has appeared. This +-is used by event-based system startup (systemd, udev) to activate LVs. +-.P +-The four main variations of this are: ++When --cache is used, pvscan updates runtime lvm state on the system, or ++with -aay performs autoactivation. + .P + .B pvscan --cache + .I device + .P +-If device is present, lvm adds a record that the PV on device is online. ++If device is present, lvm records that the PV on device is online. + If device is not present, lvm removes the online record for the PV. +-In most cases, the pvscan will only read the named devices. ++pvscan only reads the named device. + .P +-.B pvscan --cache -aay +-.IR device ... ++.B pvscan --cache + .P +-This begins by performing the same steps as above. Afterward, if the VG +-for the specified PV is complete, then pvscan will activate LVs in the VG +-(the same as vgchange -aay vgname would do.) ++Updates the runtime state for all lvm devices. + .P +-.B pvscan --cache ++.B pvscan --cache -aay ++.I device + .P +-This first clears all existing PV online records, then scans all devices +-on the system, adding PV online records for any PVs that are found. ++Performs the --cache steps for the device, then checks if the VG using the ++device is complete. If so, LVs in the VG are autoactivated, the same as ++vgchange -aay vgname would do. (A device name may be replaced with major ++and minor numbers.) + .P + .B pvscan --cache -aay + .P +-This begins by performing the same steps as pvscan --cache. Afterward, it +-activates LVs in any complete VGs. ++Performs the --cache steps for all devices, then autoactivates any complete VGs. + .P +-To prevent devices from being scanned by pvscan --cache, add them +-to +-.BR lvm.conf (5) +-.B devices/global_filter. +-For more information, see: +-.br +-.B lvmconfig --withcomments devices/global_filter ++.B pvscan --cache --listvg|--listlvs ++.I device ++.P ++Performs the --cache steps for the device, then prints the name of the VG ++using the device, or the names of LVs using the device. --checkcomplete ++is usually included to check if all PVs for the VG or LVs are online. ++When this command is called by a udev rule, the output must conform to ++udev rule specifications (see --udevoutput.) The udev rule will use the ++results to perform autoactivation. + .P +-Auto-activation of VGs or LVs can be enabled/disabled using: +-.br ++Autoactivation of VGs or LVs can be enabled/disabled using vgchange or ++lvchange with --setautoactivation y|n, or by adding names to + .BR lvm.conf (5) + .B activation/auto_activation_volume_list + .P +-For more information, see: +-.br +-.B lvmconfig --withcomments activation/auto_activation_volume_list +-.P +-To disable auto-activation, explicitly set this list to an empty list, +-i.e. auto_activation_volume_list = [ ]. +-.P +-When this setting is undefined (e.g. commented), then all LVs are +-auto-activated. ++See ++.BR lvmautoactivation (7) ++for more information about how pvscan is used for autoactivation. +-- +2.34.3 + diff --git a/SOURCES/0017-tests-devicesfile-devname.sh-drop-mdadm-chunk.patch b/SOURCES/0017-tests-devicesfile-devname.sh-drop-mdadm-chunk.patch new file mode 100644 index 0000000..a4147e6 --- /dev/null +++ b/SOURCES/0017-tests-devicesfile-devname.sh-drop-mdadm-chunk.patch @@ -0,0 +1,25 @@ +From 10a4478e9b778dd8d4ff9737a503474b00ce9510 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 1 Dec 2021 08:56:05 -0600 +Subject: [PATCH 17/54] tests devicesfile-devname.sh drop mdadm chunk + +--- + test/shell/devicesfile-devname.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh +index a99fe3e9a..338637275 100644 +--- a/test/shell/devicesfile-devname.sh ++++ b/test/shell/devicesfile-devname.sh +@@ -590,7 +590,7 @@ OPVID2=`pvs "$dev2" --noheading -o uuid | awk '{print $1}'` + PVID1=`pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}'` + PVID2=`pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}'` + +-mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev3" "$dev4" ++mdadm --create --metadata=1.0 "$mddev" --level 1 --raid-devices=2 "$dev3" "$dev4" + wait_md_create "$mddev" + + sed -e "s|DEVNAME=$dev1|DEVNAME=$dev3|" "$ORIG" > tmp1.devices +-- +2.34.3 + diff --git a/SOURCES/0018-devices-file-don-t-write-in-test-mode.patch b/SOURCES/0018-devices-file-don-t-write-in-test-mode.patch new file mode 100644 index 0000000..3e79410 --- /dev/null +++ b/SOURCES/0018-devices-file-don-t-write-in-test-mode.patch @@ -0,0 +1,26 @@ +From 04770589b49effdb064c9b3790e8dd2fee2c3547 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 1 Dec 2021 10:08:08 -0600 +Subject: [PATCH 18/54] devices file: don't write in test mode + +--- + lib/device/device_id.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index ce7ded154..4c2b5a3dd 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -673,6 +673,9 @@ int device_ids_write(struct cmd_context *cmd) + cmd->enable_devices_file = 1; + } + ++ if (test_mode()) ++ return 1; ++ + if (_devices_file_version[0]) { + if (sscanf(_devices_file_version, "%u.%u.%u", &df_major, &df_minor, &df_counter) != 3) { + /* don't update a file we can't parse */ +-- +2.34.3 + diff --git a/SOURCES/0019-print-warning-about-unrecognized-journal-option-valu.patch b/SOURCES/0019-print-warning-about-unrecognized-journal-option-valu.patch new file mode 100644 index 0000000..177f936 --- /dev/null +++ b/SOURCES/0019-print-warning-about-unrecognized-journal-option-valu.patch @@ -0,0 +1,24 @@ +From 604fd528fb4f00a9f77e084a1b22eff2aeef0259 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 2 Dec 2021 12:40:52 -0600 +Subject: [PATCH 19/54] print warning about unrecognized journal option value + +--- + lib/log/log.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/log/log.c b/lib/log/log.c +index 7b4d537b3..5771a1d01 100644 +--- a/lib/log/log.c ++++ b/lib/log/log.c +@@ -892,6 +892,7 @@ uint32_t log_journal_str_to_val(const char *str) + return LOG_JOURNAL_OUTPUT; + if (!strcasecmp(str, "debug")) + return LOG_JOURNAL_DEBUG; ++ log_warn("Ignoring unrecognized journal value."); + return 0; + } + +-- +2.34.3 + diff --git a/SOURCES/0020-device_id-handle-wwid-with-spaces-or-control-charact.patch b/SOURCES/0020-device_id-handle-wwid-with-spaces-or-control-charact.patch new file mode 100644 index 0000000..007cd75 --- /dev/null +++ b/SOURCES/0020-device_id-handle-wwid-with-spaces-or-control-charact.patch @@ -0,0 +1,50 @@ +From 357a807e81bbd1430b045eb2601a64b17d588400 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 2 Dec 2021 13:30:36 -0600 +Subject: [PATCH 20/54] device_id: handle wwid with spaces or control + characters + +non-standard wwid can be reported from sysfs with spaces/etc. +replace with "_" +--- + lib/device/device_id.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 4c2b5a3dd..0621bc858 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -304,6 +304,7 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u + { + char sysbuf[PATH_MAX] = { 0 }; + const char *idname = NULL; ++ int i; + + if (idtype == DEV_ID_TYPE_SYS_WWID) { + read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)); +@@ -311,10 +312,6 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u + if (!sysbuf[0]) + read_sys_block(cmd, dev, "wwid", sysbuf, sizeof(sysbuf)); + +- /* scsi_debug wwid begins "t10.Linux scsi_debug ..." */ +- if (strstr(sysbuf, "scsi_debug")) +- sysbuf[0] = '\0'; +- + /* qemu wwid begins "t10.ATA QEMU HARDDISK ..." */ + if (strstr(sysbuf, "QEMU HARDDISK")) + sysbuf[0] = '\0'; +@@ -355,6 +352,11 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u + return idname; + } + ++ for (i = 0; i < strlen(sysbuf); i++) { ++ if (isblank(sysbuf[i]) || isspace(sysbuf[i]) || iscntrl(sysbuf[i])) ++ sysbuf[i] = '_'; ++ } ++ + if (!sysbuf[0]) + goto_bad; + +-- +2.34.3 + diff --git a/SOURCES/0021-man-add-section-about-static-autoactivation.patch b/SOURCES/0021-man-add-section-about-static-autoactivation.patch new file mode 100644 index 0000000..f5494dc --- /dev/null +++ b/SOURCES/0021-man-add-section-about-static-autoactivation.patch @@ -0,0 +1,96 @@ +From 7631c5b826b5a3eddfcd22db9b80574b249794c1 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 6 Dec 2021 13:20:32 -0600 +Subject: [PATCH 21/54] man: add section about static autoactivation + +--- + man/lvmautoactivation.7_main | 48 ++++++++++++++++++++++++++++++------ + 1 file changed, 41 insertions(+), 7 deletions(-) + +diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main +index 87c15a3d1..bf885991d 100644 +--- a/man/lvmautoactivation.7_main ++++ b/man/lvmautoactivation.7_main +@@ -14,14 +14,16 @@ activated. + Autoactivation of VGs, or specific LVs, can be prevented using vgchange or + lvchange --setautoactivation n. The lvm.conf auto_activation_volume_list + is another way to limit autoactivation. ++. ++.SS event autoactivation + .P + The most common form of autoactivation is "event based", in which complete + VGs are activated in response to uevents which occur during system startup + or at any time after the system has started. Another form of +-autoactivation is "service based" in which complete VGs are activated at a +-fixed point during system startup by a systemd service, and are not +-activated in response to uevents. This can be controlled with the +-lvm.conf setting event_activation. ++autoactivation is "static" in which complete VGs are activated at a fixed ++point during system startup by a systemd service, and not in response to ++events. This can be controlled with the lvm.conf setting ++event_activation. + .P + Event based autoactivation is driven by udev, udev rules, and systemd. + When a device is attached to a machine, a uevent is generated by the +@@ -30,8 +32,8 @@ rules to process the new device. Udev rules use blkid to identify the + device as an LVM PV and then execute the lvm-specific udev rule for the + device, which triggers autoactivation. + .P +-There are two variations of event based autoactivation that may be used a +-system, depending on the LVM udev rule that is installed (found in ++There are two variations of event baed autoactivation that may be used on ++a system, depending on the LVM udev rule that is installed (found in + /lib/udev/rules.d/.) The following summarizes the steps in each rule + which lead to autoactivation: + .P +@@ -149,7 +151,7 @@ using the udev environment key format, i.e. NAME='value'. + Send standard command output to the journal (when stdout + is reserved for udev output.) + .P +-.SS Temp files ++.SS run files + .P + Autoactivation commands use a number of temp files in /run/lvm (with the + expectation that /run is cleared between boots.) +@@ -175,6 +177,38 @@ The first activation command (pvscan or vgchange) to create a file here, + named for the VG, will activate the VG. This resolves a race when + concurrent commands attempt to activate a VG at once. + . ++.SS static autoactivation ++.P ++When event autoactivation is disabled by setting lvm.conf ++event_activation=0, autoactivation is performed at one or more static ++points during system startup. At these points, a vgchange -aay command is ++run to activate complete VGs from devices that are present on the system ++at that time. pvscan commands (and lvm2-pvscan services) do not perform ++autoactivation in this mode. pvscan commands may still be run from ++uevents but will do nothing when they read the event_activation=0 setting. ++.P ++The static vgchange -aay commands are run by three systemd services at ++three points during startup: lvm2-activation-early, lvm2-activation, and ++lvm2-activation-net. These static activation services are "generated ++services", so the service files are created at run time by the ++lvm2-activation-generator command (run by systemd). ++lvm2-activation-generator creates the services if lvm.conf ++event_activation=0. ++.P ++The limitation of this method is that devices may not be attached to the ++system (or set up) at a reliable point in time during startup, and they ++may not be present when the services run vgchange. In this case, the VGs ++will not be autoactivated. So, the timing of device attachment/setup ++determines whether static autoactivation will produce the same results as ++event autoactivation. For this reason, static autoactivation is not ++recommended. ++.P ++Sometimes, static autoactivation is mistakenly expected to disable all ++autoactivation of particular VGs. This may appear to be effective if those ++VGs are slow to be attached or set up. But, the only correct and reliable ++way to disable autoactivation is using vgchange/lvchange ++--setautoactivation n, or lvm.conf auto_activation_volume_list. ++. + .SH EXAMPLES + .P + VG "vg" contains two PVs: +-- +2.34.3 + diff --git a/SOURCES/0022-lvcreate-include-recent-options.patch b/SOURCES/0022-lvcreate-include-recent-options.patch new file mode 100644 index 0000000..3ad1a54 --- /dev/null +++ b/SOURCES/0022-lvcreate-include-recent-options.patch @@ -0,0 +1,35 @@ +From af4bfa1f1f84194000bc50f43ddc906c0cd4b104 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 13 Dec 2021 08:59:31 -0600 +Subject: [PATCH 22/54] lvcreate: include recent options + +The permitted option list in lvcreate has not kept +up with command-lines.in. +--- + tools/lvcreate.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index 0121c09a8..79af42685 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -824,12 +824,16 @@ static int _lvcreate_params(struct cmd_context *cmd, + autobackup_ARG,\ + available_ARG,\ + contiguous_ARG,\ ++ devices_ARG,\ ++ devicesfile_ARG,\ + ignoreactivationskip_ARG,\ + ignoremonitoring_ARG,\ ++ journal_ARG,\ + metadataprofile_ARG,\ + monitor_ARG,\ + mirrors_ARG,\ + name_ARG,\ ++ nohints_ARG,\ + noudevsync_ARG,\ + permission_ARG,\ + persistent_ARG,\ +-- +2.34.3 + diff --git a/SOURCES/0023-man-lvmautoactivation-replace-systemctl-with-journal.patch b/SOURCES/0023-man-lvmautoactivation-replace-systemctl-with-journal.patch new file mode 100644 index 0000000..c5af575 --- /dev/null +++ b/SOURCES/0023-man-lvmautoactivation-replace-systemctl-with-journal.patch @@ -0,0 +1,26 @@ +From 61833dd5b6117e8ace84289cff656d1dfb0ed123 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 14 Dec 2021 12:02:08 -0600 +Subject: [PATCH 23/54] man lvmautoactivation: replace systemctl with + journalctl + +--- + man/lvmautoactivation.7_main | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/lvmautoactivation.7_main b/man/lvmautoactivation.7_main +index bf885991d..54dab718b 100644 +--- a/man/lvmautoactivation.7_main ++++ b/man/lvmautoactivation.7_main +@@ -107,7 +107,7 @@ vgchange -aay --autoactivation event + . + .IP \[bu] 2 + the activation command output can be seen from +-systemctl status lvm-activate- ++journalctl -u lvm-activate- + .P + . + .SS pvscan options +-- +2.34.3 + diff --git a/SOURCES/0024-make-generate.patch b/SOURCES/0024-make-generate.patch new file mode 100644 index 0000000..54cc1cf --- /dev/null +++ b/SOURCES/0024-make-generate.patch @@ -0,0 +1,196 @@ +From 4b26fb3543049f3d179b620ff937c44e922ada58 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Tue, 4 Jan 2022 17:15:56 +0100 +Subject: [PATCH 24/54] make: generate + +--- + man/lvdisplay.8_pregen | 12 -------- + man/pvdisplay.8_pregen | 12 -------- + man/pvscan.8_pregen | 63 ++++++++++++++++++------------------------ + man/vgdisplay.8_pregen | 12 -------- + 4 files changed, 27 insertions(+), 72 deletions(-) + +diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen +index a1740ebed..04aab4c09 100644 +--- a/man/lvdisplay.8_pregen ++++ b/man/lvdisplay.8_pregen +@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format. + .br + [ \fB--readonly\fP ] + .br +-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ] +-.br + [ \fB--segments\fP ] + .br + [ \fB--separator\fP \fIString\fP ] +@@ -332,16 +330,6 @@ device-mapper kernel driver, so this option is unable to report whether + or not LVs are actually in use. + . + .HP +-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP +-.br +-Overrides current output format for reports which is defined globally by +-the report/output_format setting in \fBlvm.conf\fP(5). +-\fBbasic\fP is the original format with columns and rows. +-If there is more than one report per command, each report is prefixed +-with the report name for identification. \fBjson\fP produces report +-output in JSON format. See \fBlvmreport\fP(7) for more information. +-. +-.HP + \fB--segments\fP + .br + . +diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen +index 22a0992b5..2f26a8727 100644 +--- a/man/pvdisplay.8_pregen ++++ b/man/pvdisplay.8_pregen +@@ -61,8 +61,6 @@ and more, using a more compact and configurable output format. + .br + [ \fB--readonly\fP ] + .br +-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ] +-.br + [ \fB--separator\fP \fIString\fP ] + .br + [ \fB--shared\fP ] +@@ -320,16 +318,6 @@ device-mapper kernel driver, so this option is unable to report whether + or not LVs are actually in use. + . + .HP +-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP +-.br +-Overrides current output format for reports which is defined globally by +-the report/output_format setting in \fBlvm.conf\fP(5). +-\fBbasic\fP is the original format with columns and rows. +-If there is more than one report per command, each report is prefixed +-with the report name for identification. \fBjson\fP produces report +-output in JSON format. See \fBlvmreport\fP(7) for more information. +-. +-.HP + \fB-S\fP|\fB--select\fP \fIString\fP + .br + Select objects for processing and reporting based on specified criteria. +diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen +index 9eb6b5bf9..1c96d5aab 100644 +--- a/man/pvscan.8_pregen ++++ b/man/pvscan.8_pregen +@@ -91,59 +91,50 @@ like + or + .BR pvdisplay (8). + .P +-When the --cache and -aay options are used, pvscan records which PVs are +-available on the system, and activates LVs in completed VGs. A VG is +-complete when pvscan sees that the final PV in the VG has appeared. This +-is used by event-based system startup (systemd, udev) to activate LVs. +-.P +-The four main variations of this are: ++When --cache is used, pvscan updates runtime lvm state on the system, or ++with -aay performs autoactivation. + .P + .B pvscan --cache + .I device + .P +-If device is present, lvm adds a record that the PV on device is online. ++If device is present, lvm records that the PV on device is online. + If device is not present, lvm removes the online record for the PV. +-In most cases, the pvscan will only read the named devices. ++pvscan only reads the named device. + .P +-.B pvscan --cache -aay +-.IR device ... ++.B pvscan --cache + .P +-This begins by performing the same steps as above. Afterward, if the VG +-for the specified PV is complete, then pvscan will activate LVs in the VG +-(the same as vgchange -aay vgname would do.) ++Updates the runtime state for all lvm devices. + .P +-.B pvscan --cache ++.B pvscan --cache -aay ++.I device + .P +-This first clears all existing PV online records, then scans all devices +-on the system, adding PV online records for any PVs that are found. ++Performs the --cache steps for the device, then checks if the VG using the ++device is complete. If so, LVs in the VG are autoactivated, the same as ++vgchange -aay vgname would do. (A device name may be replaced with major ++and minor numbers.) + .P + .B pvscan --cache -aay + .P +-This begins by performing the same steps as pvscan --cache. Afterward, it +-activates LVs in any complete VGs. ++Performs the --cache steps for all devices, then autoactivates any complete VGs. + .P +-To prevent devices from being scanned by pvscan --cache, add them +-to +-.BR lvm.conf (5) +-.B devices/global_filter. +-For more information, see: +-.br +-.B lvmconfig --withcomments devices/global_filter ++.B pvscan --cache --listvg|--listlvs ++.I device + .P +-Auto-activation of VGs or LVs can be enabled/disabled using: +-.br ++Performs the --cache steps for the device, then prints the name of the VG ++using the device, or the names of LVs using the device. --checkcomplete ++is usually included to check if all PVs for the VG or LVs are online. ++When this command is called by a udev rule, the output must conform to ++udev rule specifications (see --udevoutput.) The udev rule will use the ++results to perform autoactivation. ++.P ++Autoactivation of VGs or LVs can be enabled/disabled using vgchange or ++lvchange with --setautoactivation y|n, or by adding names to + .BR lvm.conf (5) + .B activation/auto_activation_volume_list + .P +-For more information, see: +-.br +-.B lvmconfig --withcomments activation/auto_activation_volume_list +-.P +-To disable auto-activation, explicitly set this list to an empty list, +-i.e. auto_activation_volume_list = [ ]. +-.P +-When this setting is undefined (e.g. commented), then all LVs are +-auto-activated. ++See ++.BR lvmautoactivation (7) ++for more information about how pvscan is used for autoactivation. + . + .SH USAGE + . +diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen +index 9c694921d..0a12b3c39 100644 +--- a/man/vgdisplay.8_pregen ++++ b/man/vgdisplay.8_pregen +@@ -58,8 +58,6 @@ and more, using a more compact and configurable output format. + .br + [ \fB--readonly\fP ] + .br +-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ] +-.br + [ \fB--shared\fP ] + .br + [ \fB--separator\fP \fIString\fP ] +@@ -312,16 +310,6 @@ device-mapper kernel driver, so this option is unable to report whether + or not LVs are actually in use. + . + .HP +-\fB--reportformat\fP \fBbasic\fP|\fBjson\fP +-.br +-Overrides current output format for reports which is defined globally by +-the report/output_format setting in \fBlvm.conf\fP(5). +-\fBbasic\fP is the original format with columns and rows. +-If there is more than one report per command, each report is prefixed +-with the report name for identification. \fBjson\fP produces report +-output in JSON format. See \fBlvmreport\fP(7) for more information. +-. +-.HP + \fB-S\fP|\fB--select\fP \fIString\fP + .br + Select objects for processing and reporting based on specified criteria. +-- +2.34.3 + diff --git a/SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch b/SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch new file mode 100644 index 0000000..e3a9f54 --- /dev/null +++ b/SOURCES/0025-pvcreate-overwrite-partition-header-with-f.patch @@ -0,0 +1,141 @@ +From a5c37afdca97d6565ea02bc4bc7d52f360823cd3 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 8 Sep 2021 16:30:11 -0500 +Subject: [PATCH 25/54] pvcreate: overwrite partition header with -f + +$ pvcreate /dev/sdc + Cannot use /dev/sdc: device is partitioned +$ pvcreate -f /dev/sdc + Physical volume "/dev/sdc" successfully created. +--- + lib/commands/toolcontext.h | 1 + + lib/filters/filter-partitioned.c | 3 +++ + man/pvcreate.8_des | 7 ++++--- + test/shell/test-partition.sh | 12 ++++++++++-- + tools/toollib.c | 10 ++++++++++ + 5 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h +index 356c79f8a..b83883fb8 100644 +--- a/lib/commands/toolcontext.h ++++ b/lib/commands/toolcontext.h +@@ -201,6 +201,7 @@ struct cmd_context { + unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */ + unsigned backup_disabled:1; /* skip repeated debug message */ + unsigned event_activation:1; /* whether event_activation is set */ ++ unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */ + + /* + * Devices and filtering. +diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c +index 642553ef2..8f468a567 100644 +--- a/lib/filters/filter-partitioned.c ++++ b/lib/filters/filter-partitioned.c +@@ -27,6 +27,9 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter + if (cmd->filter_nodata_only) + return 1; + ++ if (cmd->filter_partitioned_skip) ++ return 1; ++ + dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED; + + ret = dev_is_partitioned(cmd, dev); +diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des +index 69bd133aa..4048eb71c 100644 +--- a/man/pvcreate.8_des ++++ b/man/pvcreate.8_des +@@ -7,9 +7,10 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8) + to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM + disk label from the device. + .P +-The force option will create a PV without confirmation. Repeating the +-force option (\fB-ff\fP) will forcibly create a PV, overriding checks that +-normally prevent it, e.g. if the PV is already in a VG. ++The force option will create a PV without confirmation, and will overwrite ++partition headers. Repeating the force option (\fB-ff\fP) will override other ++checks that would normally prevent a pvcreate, e.g. if the PV is already in a ++VG. + .P + .B Metadata location, size, and alignment + .P +diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh +index 0e92f00db..3a45f9089 100644 +--- a/test/shell/test-partition.sh ++++ b/test/shell/test-partition.sh +@@ -16,7 +16,6 @@ + # + + +- + SKIP_WITH_LVMPOLLD=1 + + LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]" +@@ -25,7 +24,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]" + + which sfdisk || skip + +-aux prepare_pvs 1 30 ++aux prepare_pvs 2 30 + + pvs "$dev1" + +@@ -33,3 +32,12 @@ pvs "$dev1" + echo "1 2" | sfdisk --force "$dev1" + + not pvs "$dev1" ++ ++wipefs -a "$dev2" ++echo "1 2" | sfdisk --force "$dev2" ++partprobe ++not pvcreate "$dev2" ++pvcreate -f "$dev2" ++pvs "$dev2" ++pvremove "$dev2" ++ +diff --git a/tools/toollib.c b/tools/toollib.c +index d6f48aad2..80d3de57c 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -5243,6 +5243,10 @@ int pvcreate_each_device(struct cmd_context *cmd, + if (cmd->enable_devices_file && !pp->is_remove) + cmd->filter_deviceid_skip = 1; + ++ /* pvcreate -f overwrites partitions */ ++ if (pp->force && !pp->is_remove) ++ cmd->filter_partitioned_skip = 1; ++ + log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs)); + label_scan_devs(cmd, cmd->filter, &scan_devs); + +@@ -5257,6 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd, + } + } + cmd->filter_deviceid_skip = 0; ++ cmd->filter_partitioned_skip = 0; + + /* + * Can the command continue if some specified devices were not found? +@@ -5469,6 +5474,9 @@ do_command: + if (cmd->enable_devices_file && !pp->is_remove) + cmd->filter_deviceid_skip = 1; + ++ if (pp->force && !pp->is_remove) ++ cmd->filter_partitioned_skip = 1; ++ + log_debug("Rescanning and filtering device args with exclusive open"); + if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) { + log_debug("Failed to rescan devs excl"); +@@ -5482,7 +5490,9 @@ do_command: + dm_list_add(&pp->arg_fail, &pd->list); + } + } ++ + cmd->filter_deviceid_skip = 0; ++ cmd->filter_partitioned_skip = 0; + + if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) { + log_debug("No devices to process."); +-- +2.34.3 + diff --git a/SOURCES/0026-lvmdevices-check-error-exit-if-update-is-needed.patch b/SOURCES/0026-lvmdevices-check-error-exit-if-update-is-needed.patch new file mode 100644 index 0000000..485b697 --- /dev/null +++ b/SOURCES/0026-lvmdevices-check-error-exit-if-update-is-needed.patch @@ -0,0 +1,166 @@ +From bb477d63e336a10e5959962a9f26a028ea9e55eb Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 13 Jan 2022 14:52:54 -0600 +Subject: [PATCH 26/54] lvmdevices check: error exit if update is needed + +. error exit means that lvmdevices --update would make a change. + +. remove check of PART field from --check because it isn't used. + +. unlink searched_devnames file to ensure check|update will search +--- + lib/device/device_id.c | 3 ++- + test/shell/devicesfile-realdevs.sh | 8 +++---- + tools/args.h | 3 ++- + tools/lvmdevices.c | 37 +++++++++++++----------------- + 4 files changed, 24 insertions(+), 27 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 0621bc858..a33dcebe0 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -2271,7 +2271,8 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l + continue; + } + +- log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname); ++ if (!noupdate) ++ log_warn("Devices file PVID %s updating IDNAME to %s.", dev->pvid, devname); + + free(du->idname); + free(du->devname); +diff --git a/test/shell/devicesfile-realdevs.sh b/test/shell/devicesfile-realdevs.sh +index 8d4aa3e67..23d4bedb4 100644 +--- a/test/shell/devicesfile-realdevs.sh ++++ b/test/shell/devicesfile-realdevs.sh +@@ -423,7 +423,7 @@ sed "s/$pvid1/badpvid/" "$DF.orig" |tee $DF + not grep $pvid1 $DF + grep $did1 $DF + +-lvmdevices --check 2>&1|tee out ++not lvmdevices --check 2>&1|tee out + grep $dev1 out + grep badpvid out + grep $pvid1 out +@@ -493,7 +493,7 @@ rm $DF + d1=$(basename $dev1) + d3=$(basename $dev3) + sed "s/$d1/$d3/" "$DF.orig" |tee $DF +-lvmdevices --check 2>&1 |tee out ++not lvmdevices --check 2>&1 |tee out + grep $dev1 out + + lvmdevices --update +@@ -515,7 +515,7 @@ sed "s/$d1/tmp/" "$DF.orig" |tee ${DF}_1 + sed "s/$d2/$d1/" "${DF}_1" |tee ${DF}_2 + sed "s/tmp/$d2/" "${DF}_2" |tee $DF + rm ${DF}_1 ${DF}_2 +-lvmdevices --check 2>&1 |tee out ++not lvmdevices --check 2>&1 |tee out + grep $dev1 out + grep $dev2 out + +@@ -536,7 +536,7 @@ rm $DF + d1=$(basename $dev1) + d3=$(basename $dev3) + sed "s/$d1/$d3/" "$DF.orig" |tee $DF +-lvmdevices --check 2>&1 |tee out ++not lvmdevices --check 2>&1 |tee out + grep $dev1 out + + pvs -o+uuid,deviceid | grep $vg |tee out +diff --git a/tools/args.h b/tools/args.h +index 774ce33f4..9a7bf81b2 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -153,7 +153,8 @@ arg(cachesize_ARG, '\0', "cachesize", sizemb_VAL, 0, 0, + "The size of cache to use.\n") + + arg(check_ARG, '\0', "check", 0, 0, 0, +- "Check the content of the devices file.\n") ++ "Checks the content of the devices file.\n" ++ "Reports incorrect device names or PVIDs for entries.\n") + + arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0, + "The command profile to use for command configuration.\n" +diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c +index 3f104f7de..c50c09f90 100644 +--- a/tools/lvmdevices.c ++++ b/tools/lvmdevices.c +@@ -128,7 +128,6 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + struct device *dev; + struct dev_use *du, *du2; + const char *deviceidtype; +- int changes = 0; + + dm_list_init(&search_pvids); + dm_list_init(&found_devs); +@@ -184,8 +183,11 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + + if (arg_is_set(cmd, check_ARG) || arg_is_set(cmd, update_ARG)) { + int search_count = 0; ++ int update_needed = 0; + int invalid = 0; + ++ unlink_searched_devnames(cmd); ++ + label_scan_setup_bcache(); + + dm_list_iterate_items(du, &cmd->use_devices) { +@@ -225,6 +227,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + * run just above. + */ + device_ids_validate(cmd, NULL, &invalid, 1); ++ if (invalid) ++ update_needed = 1; + + /* + * Find and fix any devname entries that have moved to a +@@ -240,33 +244,24 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + label_scan_invalidate(du->dev); + } + +- /* +- * check du->part +- */ +- dm_list_iterate_items(du, &cmd->use_devices) { +- int part = 0; +- if (!du->dev) +- continue; +- dev = du->dev; +- +- dev_get_partition_number(dev, &part); +- +- if (part != du->part) { +- log_warn("Device %s partition %u has incorrect PART in devices file (%u)", +- dev_name(dev), part, du->part); +- du->part = part; +- changes++; +- } +- } +- + if (arg_is_set(cmd, update_ARG)) { +- if (invalid || !dm_list_empty(&found_devs)) { ++ if (update_needed || !dm_list_empty(&found_devs)) { + if (!device_ids_write(cmd)) + goto_bad; + log_print("Updated devices file to version %s", devices_file_version()); + } else { + log_print("No update for devices file is needed."); + } ++ } else { ++ /* ++ * --check exits with an error if the devices file ++ * needs updates, i.e. running --update would make ++ * changes. ++ */ ++ if (update_needed) { ++ log_error("Updates needed for devices file."); ++ goto bad; ++ } + } + goto out; + } +-- +2.34.3 + diff --git a/SOURCES/0027-Revert-pvcreate-overwrite-partition-header-with-f.patch b/SOURCES/0027-Revert-pvcreate-overwrite-partition-header-with-f.patch new file mode 100644 index 0000000..337a61d --- /dev/null +++ b/SOURCES/0027-Revert-pvcreate-overwrite-partition-header-with-f.patch @@ -0,0 +1,140 @@ +From 9375aebad1db72267dd67e3ed768aa3b0e698d52 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 18 Jan 2022 12:16:52 -0600 +Subject: [PATCH 27/54] Revert "pvcreate: overwrite partition header with -f" + +This reverts commit a5c37afdca97d6565ea02bc4bc7d52f360823cd3. + +This commit did not properly recognize GPT cases. +--- + lib/commands/toolcontext.h | 1 - + lib/filters/filter-partitioned.c | 3 --- + man/pvcreate.8_des | 7 +++---- + test/shell/test-partition.sh | 12 ++---------- + tools/toollib.c | 10 ---------- + 5 files changed, 5 insertions(+), 28 deletions(-) + +diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h +index b83883fb8..356c79f8a 100644 +--- a/lib/commands/toolcontext.h ++++ b/lib/commands/toolcontext.h +@@ -201,7 +201,6 @@ struct cmd_context { + unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */ + unsigned backup_disabled:1; /* skip repeated debug message */ + unsigned event_activation:1; /* whether event_activation is set */ +- unsigned filter_partitioned_skip:1; /* don't use filter-partitioned */ + + /* + * Devices and filtering. +diff --git a/lib/filters/filter-partitioned.c b/lib/filters/filter-partitioned.c +index 8f468a567..642553ef2 100644 +--- a/lib/filters/filter-partitioned.c ++++ b/lib/filters/filter-partitioned.c +@@ -27,9 +27,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter + if (cmd->filter_nodata_only) + return 1; + +- if (cmd->filter_partitioned_skip) +- return 1; +- + dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED; + + ret = dev_is_partitioned(cmd, dev); +diff --git a/man/pvcreate.8_des b/man/pvcreate.8_des +index 4048eb71c..69bd133aa 100644 +--- a/man/pvcreate.8_des ++++ b/man/pvcreate.8_des +@@ -7,10 +7,9 @@ Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8) + to add the PV to an existing VG. Use \fBpvremove\fP(8) to remove the LVM + disk label from the device. + .P +-The force option will create a PV without confirmation, and will overwrite +-partition headers. Repeating the force option (\fB-ff\fP) will override other +-checks that would normally prevent a pvcreate, e.g. if the PV is already in a +-VG. ++The force option will create a PV without confirmation. Repeating the ++force option (\fB-ff\fP) will forcibly create a PV, overriding checks that ++normally prevent it, e.g. if the PV is already in a VG. + .P + .B Metadata location, size, and alignment + .P +diff --git a/test/shell/test-partition.sh b/test/shell/test-partition.sh +index 3a45f9089..0e92f00db 100644 +--- a/test/shell/test-partition.sh ++++ b/test/shell/test-partition.sh +@@ -16,6 +16,7 @@ + # + + ++ + SKIP_WITH_LVMPOLLD=1 + + LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]" +@@ -24,7 +25,7 @@ LVM_TEST_CONFIG_DEVICES="types = [\"device-mapper\", 142]" + + which sfdisk || skip + +-aux prepare_pvs 2 30 ++aux prepare_pvs 1 30 + + pvs "$dev1" + +@@ -32,12 +33,3 @@ pvs "$dev1" + echo "1 2" | sfdisk --force "$dev1" + + not pvs "$dev1" +- +-wipefs -a "$dev2" +-echo "1 2" | sfdisk --force "$dev2" +-partprobe +-not pvcreate "$dev2" +-pvcreate -f "$dev2" +-pvs "$dev2" +-pvremove "$dev2" +- +diff --git a/tools/toollib.c b/tools/toollib.c +index 80d3de57c..d6f48aad2 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -5243,10 +5243,6 @@ int pvcreate_each_device(struct cmd_context *cmd, + if (cmd->enable_devices_file && !pp->is_remove) + cmd->filter_deviceid_skip = 1; + +- /* pvcreate -f overwrites partitions */ +- if (pp->force && !pp->is_remove) +- cmd->filter_partitioned_skip = 1; +- + log_debug("Scanning and filtering device args (%u).", dm_list_size(&scan_devs)); + label_scan_devs(cmd, cmd->filter, &scan_devs); + +@@ -5261,7 +5257,6 @@ int pvcreate_each_device(struct cmd_context *cmd, + } + } + cmd->filter_deviceid_skip = 0; +- cmd->filter_partitioned_skip = 0; + + /* + * Can the command continue if some specified devices were not found? +@@ -5474,9 +5469,6 @@ do_command: + if (cmd->enable_devices_file && !pp->is_remove) + cmd->filter_deviceid_skip = 1; + +- if (pp->force && !pp->is_remove) +- cmd->filter_partitioned_skip = 1; +- + log_debug("Rescanning and filtering device args with exclusive open"); + if (!label_scan_devs_excl(cmd, cmd->filter, &rescan_devs)) { + log_debug("Failed to rescan devs excl"); +@@ -5490,9 +5482,7 @@ do_command: + dm_list_add(&pp->arg_fail, &pd->list); + } + } +- + cmd->filter_deviceid_skip = 0; +- cmd->filter_partitioned_skip = 0; + + if (dm_list_empty(&pp->arg_process) && dm_list_empty(&remove_duplicates)) { + log_debug("No devices to process."); +-- +2.34.3 + diff --git a/SOURCES/0028-devices-exclude-multipath-components-based-on-matchi.patch b/SOURCES/0028-devices-exclude-multipath-components-based-on-matchi.patch new file mode 100644 index 0000000..8646d04 --- /dev/null +++ b/SOURCES/0028-devices-exclude-multipath-components-based-on-matchi.patch @@ -0,0 +1,462 @@ +From 5403a6f05987b21addb50c9b056e36567d631df7 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 17 Nov 2021 17:10:45 -0600 +Subject: [PATCH 28/54] devices: exclude multipath components based on matching + wwid + +If multipath component devices get through the filter and +cause lvm to see duplicate PVs, then check the wwid of the +devs and drop the component devices as if they had been +filtered. If a dm mpath device was found among the duplicates +then use that as the PV, otherwise do not use any of the +components as the PV. + +"duplicate PVs" associated with multipath configs will no +longer stop commands from working. +--- + lib/cache/lvmcache.c | 186 +++++++++++++++++++++++++- + lib/device/dev-mpath.c | 71 ++++++++++ + lib/device/dev-type.h | 2 + + lib/device/device_id.c | 4 +- + lib/device/device_id.h | 2 + + test/shell/duplicate-pvs-multipath.sh | 67 ++++++++++ + 6 files changed, 323 insertions(+), 9 deletions(-) + create mode 100644 test/shell/duplicate-pvs-multipath.sh + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index bee63ebb4..a0811d4ea 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -625,6 +625,102 @@ static void _warn_unused_duplicates(struct cmd_context *cmd) + } + } + ++static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid, ++ struct dm_list *altdevs, struct device **dev_mpath) ++{ ++ struct device_list *devl; ++ struct device *dev_mp = NULL; ++ struct device *dev1 = NULL; ++ struct device *dev; ++ const char *wwid1 = NULL; ++ const char *wwid; ++ int diff_wwid = 0; ++ int same_wwid = 0; ++ int dev_is_mp; ++ ++ *dev_mpath = NULL; ++ ++ /* This function only makes sense with more than one dev. */ ++ if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) { ++ log_debug("Skip multipath component checks with single device for PVID %s", pvid); ++ return 0; ++ } ++ ++ log_debug("Checking for multipath components for duplicate PVID %s", pvid); ++ ++ if (info) { ++ dev = info->dev; ++ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL); ++ ++ if (dev_is_mp) { ++ if ((wwid1 = dev_mpath_component_wwid(cmd, dev))) { ++ dev_mp = dev; ++ dev1 = dev; ++ } ++ } else { ++ if ((wwid1 = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID))) ++ dev1 = dev; ++ } ++ } ++ ++ dm_list_iterate_items(devl, altdevs) { ++ dev = devl->dev; ++ dev_is_mp = (cmd->dev_types->device_mapper_major == MAJOR(dev->dev)) && dev_has_mpath_uuid(cmd, dev, NULL); ++ ++ if (dev_is_mp) ++ wwid = dev_mpath_component_wwid(cmd, dev); ++ else ++ wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID); ++ ++ if (!wwid && wwid1) { ++ log_print("Different wwids for duplicate PVs %s %s %s none", ++ dev_name(dev1), wwid1, dev_name(dev)); ++ diff_wwid++; ++ continue; ++ } ++ ++ if (!wwid) ++ continue; ++ ++ if (!wwid1) { ++ wwid1 = wwid; ++ dev1 = dev; ++ continue; ++ } ++ ++ /* Different wwids indicates these are not multipath components. */ ++ if (strcmp(wwid1, wwid)) { ++ log_print("Different wwids for duplicate PVs %s %s %s %s", ++ dev_name(dev1), wwid1, dev_name(dev), wwid); ++ diff_wwid++; ++ continue; ++ } ++ ++ /* Different mpath devs with the same wwid shouldn't happen. */ ++ if (dev_is_mp && dev_mp) { ++ log_print("Found multiple multipath devices for PVID %s WWID %s: %s %s", ++ pvid, wwid1, dev_name(dev_mp), dev_name(dev)); ++ continue; ++ } ++ ++ log_debug("Same wwids for duplicate PVs %s %s", dev_name(dev1), dev_name(dev)); ++ same_wwid++; ++ ++ /* Save the mpath device so it can be used as the PV. */ ++ if (dev_is_mp) ++ dev_mp = dev; ++ } ++ ++ if (diff_wwid || !same_wwid) ++ return 0; ++ ++ if (dev_mp) ++ log_debug("Found multipath device %s for PVID %s WWID %s.", dev_name(dev_mp), pvid, wwid1); ++ ++ *dev_mpath = dev_mp; ++ return 1; ++} ++ + /* + * If we've found devices with the same PVID, decide which one + * to use. +@@ -680,6 +776,8 @@ static void _choose_duplicates(struct cmd_context *cmd, + struct device_list *devl, *devl_safe, *devl_add, *devl_del; + struct lvmcache_info *info; + struct device *dev1, *dev2; ++ struct device *dev_mpath; ++ struct device *dev_drop; + const char *device_id = NULL, *device_id_type = NULL; + const char *idname1 = NULL, *idname2 = NULL; + uint32_t dev1_major, dev1_minor, dev2_major, dev2_minor; +@@ -702,6 +800,7 @@ static void _choose_duplicates(struct cmd_context *cmd, + next: + dm_list_init(&altdevs); + pvid = NULL; ++ dev_mpath = NULL; + + dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) { + if (!pvid) { +@@ -720,23 +819,97 @@ next: + return; + } + ++ info = lvmcache_info_from_pvid(pvid, NULL, 0); ++ + /* +- * Get rid of any md components before comparing alternatives. +- * (Since an md component can never be used, it's not an +- * option to use like other kinds of alternatives.) ++ * Usually and ideally, components of md and multipath devs should have ++ * been excluded by filters, and not scanned for a PV. In some unusual ++ * cases the components can get through the filters, and a PV can be ++ * found on them. Detecting the same PVID on both the component and ++ * the md/mpath device gives us a last chance to drop the component. ++ * An md/mpath component device is completely ignored, as if it had ++ * been filtered, and not kept in the list unused duplicates. + */ + +- info = lvmcache_info_from_pvid(pvid, NULL, 0); ++ /* ++ * Get rid of multipath components based on matching wwids. ++ */ ++ if (_all_multipath_components(cmd, info, pvid, &altdevs, &dev_mpath)) { ++ if (info && dev_mpath && (info->dev != dev_mpath)) { ++ /* ++ * info should be dropped from lvmcache and info->dev ++ * should be treated as if it had been excluded by a filter. ++ * dev_mpath should be added to lvmcache by the caller. ++ */ ++ dev_drop = info->dev; ++ ++ /* Have caller add dev_mpath to lvmcache. */ ++ log_debug("Using multipath device %s for PVID %s.", dev_name(dev_mpath), pvid); ++ if ((devl_add = zalloc(sizeof(*devl_add)))) { ++ devl_add->dev = dev_mpath; ++ dm_list_add(add_cache_devs, &devl_add->list); ++ } ++ ++ /* Remove dev_mpath from altdevs. */ ++ if ((devl = _get_devl_in_device_list(dev_mpath, &altdevs))) ++ dm_list_del(&devl->list); ++ ++ /* Remove info from lvmcache that came from the component dev. */ ++ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid); ++ lvmcache_del(info); ++ info = NULL; ++ ++ /* Make the component dev look like it was filtered. */ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; ++ } ++ ++ if (info && !dev_mpath) { ++ /* ++ * Only mpath component devs were found and no actual ++ * multipath dev, so drop the component from lvmcache. ++ */ ++ dev_drop = info->dev; ++ ++ log_debug("Ignoring multipath component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid); ++ lvmcache_del(info); ++ info = NULL; ++ ++ /* Make the component dev look like it was filtered. */ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; ++ } ++ ++ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) { ++ /* ++ * The altdevs are all mpath components that should look ++ * like they were filtered, they are not in lvmcache. ++ */ ++ dev_drop = devl->dev; ++ ++ log_debug("Ignoring multipath component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid); ++ dm_list_del(&devl->list); ++ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; ++ } ++ goto next; ++ } ++ ++ /* ++ * Get rid of any md components. ++ * FIXME: use a function like _all_multipath_components to pick the actual md device. ++ */ + if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) { + /* does not go in del_cache_devs which become unused_duplicates */ +- log_debug_cache("PV %s drop MD component from scan selection %s", pvid, dev_name(info->dev)); ++ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid); + lvmcache_del(info); + info = NULL; + } + + dm_list_iterate_items_safe(devl, devl_safe, &altdevs) { + if (dev_is_md_component(cmd, devl->dev, NULL, 1)) { +- log_debug_cache("PV %s drop MD component from scan duplicates %s", pvid, dev_name(devl->dev)); ++ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid); + dm_list_del(&devl->list); + } + } +@@ -744,7 +917,6 @@ next: + if (dm_list_empty(&altdevs)) + goto next; + +- + /* + * Find the device for the pvid that's currently in lvmcache. + */ +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index ba7bf9740..cbbad9dc9 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -482,3 +482,74 @@ found: + return 1; + } + ++const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev) ++{ ++ char slaves_path[PATH_MAX]; ++ char wwid_path[PATH_MAX]; ++ char sysbuf[PATH_MAX] = { 0 }; ++ char *slave_name; ++ const char *wwid = NULL; ++ struct stat info; ++ DIR *dr; ++ struct dirent *de; ++ ++ /* /sys/dev/block/253:7/slaves/sda/device/wwid */ ++ ++ if (dm_snprintf(slaves_path, sizeof(slaves_path), "%s/dev/block/%d:%d/slaves", ++ dm_sysfs_dir(), (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) { ++ log_warn("Sysfs path to check mpath components is too long."); ++ return NULL; ++ } ++ ++ if (stat(slaves_path, &info)) ++ return NULL; ++ ++ if (!S_ISDIR(info.st_mode)) { ++ log_warn("Path %s is not a directory.", slaves_path); ++ return NULL; ++ } ++ ++ /* Get wwid from first component */ ++ ++ if (!(dr = opendir(slaves_path))) { ++ log_debug("Device %s has no slaves dir", dev_name(dev)); ++ return NULL; ++ } ++ ++ while ((de = readdir(dr))) { ++ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) ++ continue; ++ ++ /* slave_name "sda" */ ++ slave_name = de->d_name; ++ ++ /* read /sys/block/sda/device/wwid */ ++ ++ if (dm_snprintf(wwid_path, sizeof(wwid_path), "%s/block/%s/device/wwid", ++ dm_sysfs_dir(), slave_name) < 0) { ++ log_warn("Failed to create sysfs wwid path for %s", slave_name); ++ continue; ++ } ++ ++ get_sysfs_value(wwid_path, sysbuf, sizeof(sysbuf), 0); ++ if (!sysbuf[0]) ++ continue; ++ ++ if (strstr(sysbuf, "scsi_debug")) { ++ int i; ++ for (i = 0; i < strlen(sysbuf); i++) { ++ if (sysbuf[i] == ' ') ++ sysbuf[i] = '_'; ++ } ++ } ++ ++ if ((wwid = dm_pool_strdup(cmd->mem, sysbuf))) ++ break; ++ } ++ if (closedir(dr)) ++ stack; ++ ++ return wwid; ++} ++ ++ +diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h +index f3521c6e0..36fb8f258 100644 +--- a/lib/device/dev-type.h ++++ b/lib/device/dev-type.h +@@ -63,6 +63,8 @@ int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *signature + int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full); + int dasd_is_cdl_formatted(struct device *dev); + ++const char *dev_mpath_component_wwid(struct cmd_context *cmd, struct device *dev); ++ + int dev_is_lvm1(struct device *dev, char *buf, int buflen); + int dev_is_pool(struct device *dev, char *buf, int buflen); + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index a33dcebe0..625576ec6 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -243,7 +243,7 @@ static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix) + } + + /* the dm uuid uses the wwid of the underlying dev */ +-static int _dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out) ++int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out) + { + char sysbuf[PATH_MAX] = { 0 }; + const char *idname; +@@ -988,7 +988,7 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_ + } + + if (MAJOR(dev->dev) == cmd->dev_types->device_mapper_major) { +- if (_dev_has_mpath_uuid(cmd, dev, &idname)) { ++ if (dev_has_mpath_uuid(cmd, dev, &idname)) { + idtype = DEV_ID_TYPE_MPATH_UUID; + goto id_done; + } +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index 939b3a0f4..4cf1374c8 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -55,4 +55,6 @@ void unlink_searched_devnames(struct cmd_context *cmd); + + int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize); + ++int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out); ++ + #endif +diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh +new file mode 100644 +index 000000000..a145e4afb +--- /dev/null ++++ b/test/shell/duplicate-pvs-multipath.sh +@@ -0,0 +1,67 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++test_description='udev rule and systemd unit run vgchange' ++ ++SKIP_WITH_LVMPOLLD=1 ++SKIP_WITH_LVMLOCKD=1 ++ ++. lib/inittest ++ ++# FIXME: skip until mpath/scsi_debug cleanup works after a failure ++skip ++ ++modprobe --dry-run scsi_debug || skip ++multipath -l || skip ++multipath -l | grep scsi_debug && skip ++ ++# Turn off multipath_component_detection so that the duplicate ++# resolution of mpath components is used. ++aux lvmconf 'devices/multipath_component_detection = 0' ++# Prevent wwids from being used for filtering. ++aux lvmconf 'devices/multipath_wwids_file = "/dev/null"' ++# Need to use /dev/mapper/mpath ++aux lvmconf 'devices/dir = "/dev"' ++aux lvmconf 'devices/scan = "/dev"' ++# Could set filter to $MP and the component /dev/sd devs ++aux lvmconf "devices/filter = [ \"a|.*|\" ]" ++aux lvmconf "devices/global_filter = [ \"a|.*|\" ]" ++ ++modprobe scsi_debug dev_size_mb=100 num_tgts=1 vpd_use_hostno=0 add_host=4 delay=20 max_luns=2 no_lun_0=1 ++sleep 2 ++ ++multipath -r ++sleep 2 ++ ++MPB=$(multipath -l | grep scsi_debug | cut -f1 -d ' ') ++echo $MPB ++MP=/dev/mapper/$MPB ++echo $MP ++ ++pvcreate $MP ++vgcreate $vg1 $MP ++lvcreate -l1 $vg1 ++vgchange -an $vg1 ++ ++pvs |tee out ++grep $MP out ++for i in $(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /); do ++ not grep /dev/$i out; ++done ++ ++vgchange -an $vg1 ++vgremove -y $vg1 ++ ++sleep 2 ++multipath -f $MP ++sleep 1 ++rmmod scsi_debug +-- +2.34.3 + diff --git a/SOURCES/0029-devices-exclude-md-components-when-duplicate-pvs-are.patch b/SOURCES/0029-devices-exclude-md-components-when-duplicate-pvs-are.patch new file mode 100644 index 0000000..6dbb455 --- /dev/null +++ b/SOURCES/0029-devices-exclude-md-components-when-duplicate-pvs-are.patch @@ -0,0 +1,268 @@ +From 7b79acc6161b2cff81a03848c160dd6993a4477b Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 22 Nov 2021 15:10:43 -0600 +Subject: [PATCH 29/54] devices: exclude md components when duplicate pvs are + seen + +Improve handling of md components that get through the +filter, like the previous improvement for multipath. +If md components get through the filter and trigger +duplicate PV code, then eliminate any devs entirely +that are not an md device. +--- + lib/cache/lvmcache.c | 168 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 149 insertions(+), 19 deletions(-) + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index a0811d4ea..0e62cd267 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -673,7 +673,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in + wwid = device_id_system_read(cmd, dev, DEV_ID_TYPE_SYS_WWID); + + if (!wwid && wwid1) { +- log_print("Different wwids for duplicate PVs %s %s %s none", ++ log_debug("Different wwids for duplicate PVs %s %s %s none", + dev_name(dev1), wwid1, dev_name(dev)); + diff_wwid++; + continue; +@@ -690,7 +690,7 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in + + /* Different wwids indicates these are not multipath components. */ + if (strcmp(wwid1, wwid)) { +- log_print("Different wwids for duplicate PVs %s %s %s %s", ++ log_debug("Different wwids for duplicate PVs %s %s %s %s", + dev_name(dev1), wwid1, dev_name(dev), wwid); + diff_wwid++; + continue; +@@ -721,6 +721,52 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in + return 1; + } + ++static int _all_md_components(struct cmd_context *cmd, struct lvmcache_info *info, const char *pvid, ++ struct dm_list *altdevs, struct device **dev_md_out) ++{ ++ struct device_list *devl; ++ struct device *dev_md = NULL; ++ struct device *dev; ++ int real_dup = 0; ++ ++ *dev_md_out = NULL; ++ ++ /* There will often be no info struct because of the extra_md_checks function. */ ++ ++ if (info && (cmd->dev_types->md_major == MAJOR(info->dev->dev))) ++ dev_md = info->dev; ++ ++ dm_list_iterate_items(devl, altdevs) { ++ dev = devl->dev; ++ ++ if (cmd->dev_types->md_major == MAJOR(dev->dev)) { ++ if (dev_md) { ++ /* md devs themselves are dups */ ++ log_debug("Found multiple md devices for PVID %s: %s %s", ++ pvid, dev_name(dev_md), dev_name(dev)); ++ real_dup = 1; ++ break; ++ } else ++ dev_md = dev; ++ } else { ++ if (!dev_is_md_component(cmd, dev, NULL, 1)) { ++ /* md dev copied to another device */ ++ real_dup = 1; ++ break; ++ } ++ } ++ } ++ ++ if (real_dup) ++ return 0; ++ ++ if (dev_md) ++ log_debug("Found md device %s for PVID %s.", dev_name(dev_md), pvid); ++ ++ *dev_md_out = dev_md; ++ return 1; ++} ++ + /* + * If we've found devices with the same PVID, decide which one + * to use. +@@ -776,7 +822,7 @@ static void _choose_duplicates(struct cmd_context *cmd, + struct device_list *devl, *devl_safe, *devl_add, *devl_del; + struct lvmcache_info *info; + struct device *dev1, *dev2; +- struct device *dev_mpath; ++ struct device *dev_mpath, *dev_md; + struct device *dev_drop; + const char *device_id = NULL, *device_id_type = NULL; + const char *idname1 = NULL, *idname2 = NULL; +@@ -801,6 +847,7 @@ next: + dm_list_init(&altdevs); + pvid = NULL; + dev_mpath = NULL; ++ dev_md = NULL; + + dm_list_iterate_items_safe(devl, devl_safe, &_initial_duplicates) { + if (!pvid) { +@@ -829,6 +876,11 @@ next: + * the md/mpath device gives us a last chance to drop the component. + * An md/mpath component device is completely ignored, as if it had + * been filtered, and not kept in the list unused duplicates. ++ * ++ * One issue related to eliminating mpath/md duplicate PVs here is ++ * that it occurs after label_scan, and hints are created based ++ * on what label_scan finds, so hints are disabled due to duplicate ++ * PVs that are later resolved here. + */ + + /* +@@ -898,24 +950,89 @@ next: + + /* + * Get rid of any md components. +- * FIXME: use a function like _all_multipath_components to pick the actual md device. + */ +- if (info && dev_is_md_component(cmd, info->dev, NULL, 1)) { +- /* does not go in del_cache_devs which become unused_duplicates */ +- log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(info->dev), pvid); +- lvmcache_del(info); +- info = NULL; +- } ++ if (_all_md_components(cmd, info, pvid, &altdevs, &dev_md)) { ++ if (info && dev_md && (info->dev != dev_md)) { ++ /* ++ * info should be dropped from lvmcache and info->dev ++ * should be treated as if it had been excluded by a filter. ++ * dev_md should be added to lvmcache by the caller. ++ * Often this info struct has been removed by ++ * lvmcache_extra_md_component_checks. ++ */ ++ dev_drop = info->dev; + +- dm_list_iterate_items_safe(devl, devl_safe, &altdevs) { +- if (dev_is_md_component(cmd, devl->dev, NULL, 1)) { +- log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(devl->dev), pvid); +- dm_list_del(&devl->list); ++ /* Have caller add dev_md to lvmcache. */ ++ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid); ++ if ((devl_add = zalloc(sizeof(*devl_add)))) { ++ devl_add->dev = dev_md; ++ dm_list_add(add_cache_devs, &devl_add->list); ++ } ++ ++ /* Remove dev_md from altdevs. */ ++ if ((devl = _get_devl_in_device_list(dev_md, &altdevs))) ++ dm_list_del(&devl->list); ++ ++ /* Remove info from lvmcache that came from the component dev. */ ++ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid); ++ lvmcache_del(info); ++ info = NULL; ++ ++ /* Make the component dev look like it was filtered. */ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; + } +- } + +- if (dm_list_empty(&altdevs)) ++ if (!info && dev_md) { ++ /* ++ * The info struct was from a component and was dropped ++ * and the actual md dev was found on initial_duplicates ++ * and the caller should add it to lvmcache. ++ */ ++ ++ /* Have caller add dev_md to lvmcache. */ ++ log_debug("Using md device %s for PVID %s.", dev_name(dev_md), pvid); ++ if ((devl_add = zalloc(sizeof(*devl_add)))) { ++ devl_add->dev = dev_md; ++ dm_list_add(add_cache_devs, &devl_add->list); ++ } ++ ++ /* Remove dev_md from altdevs. */ ++ if ((devl = _get_devl_in_device_list(dev_md, &altdevs))) ++ dm_list_del(&devl->list); ++ } ++ ++ if (info && !dev_md) { ++ /* ++ * Only md component devs were found and no actual ++ * md dev, so drop the component from lvmcache. ++ */ ++ dev_drop = info->dev; ++ ++ log_debug("Ignoring md component %s with PVID %s (dropping info)", dev_name(dev_drop), pvid); ++ lvmcache_del(info); ++ info = NULL; ++ ++ /* Make the component dev look like it was filtered. */ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; ++ } ++ ++ dm_list_iterate_items_safe(devl, devl_safe, &altdevs) { ++ /* ++ * The altdevs are all md components that should look ++ * like they were filtered, they are not in lvmcache. ++ */ ++ dev_drop = devl->dev; ++ ++ log_debug("Ignoring md component %s with PVID %s (dropping duplicate)", dev_name(dev_drop), pvid); ++ dm_list_del(&devl->list); ++ ++ cmd->filter->wipe(cmd, cmd->filter, dev_drop, NULL); ++ dev_drop->flags &= ~DEV_SCAN_FOUND_LABEL; ++ } + goto next; ++ } + + /* + * Find the device for the pvid that's currently in lvmcache. +@@ -1321,6 +1438,18 @@ int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, con + * times it can be a clue that label_scan mistakenly read the pv from an md + * component device instead of from the md device itself. So for unmatching + * sizes, we do a full md component check on the device. ++ * ++ * It might be nice to do this checking in the filter (when passes_filter is ++ * called after the initial read), but that doesn't work because passes_filter ++ * is called before _text_read so metadata/pvsummary info is not yet available ++ * which this function uses. ++ * ++ * The unique value of this function is that it can eliminate md components ++ * without there being duplicate PVs. But, there will often be duplicate PVs, ++ * handled by _all_md_components(), where other devs with the same pvid will be ++ * in _initial_duplicates. One could be the md device itself which will be ++ * added to lvmcache by choose_duplicates, and other duplicates that are ++ * components will be dropped. + */ + + void lvmcache_extra_md_component_checks(struct cmd_context *cmd) +@@ -1382,7 +1511,8 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd) + */ + if (pvsize && devsize && (pvsize != devsize)) + do_check_size = 1; +- if (device_hint && !strncmp(device_hint, "/dev/md", 7)) ++ if (device_hint && !strncmp(device_hint, "/dev/md", 7) && ++ (MAJOR(info->dev->dev) != cmd->dev_types->md_major)) + do_check_name = 1; + + if (!do_check_size && !do_check_name) +@@ -1412,11 +1542,11 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd) + device_hint ?: "none", dev_name(dev)); + + if (dev_is_md_component(cmd, dev, NULL, 1)) { +- log_debug("dropping PV from md component %s", dev_name(dev)); ++ log_debug("Ignoring PV from md component %s with PVID %s (metadata %s %llu)", ++ dev_name(dev), dev->pvid, device_hint ?: "none", (unsigned long long)pvsize); + dev->flags &= ~DEV_SCAN_FOUND_LABEL; + /* lvmcache_del will also delete vginfo if info was last one */ + lvmcache_del(info); +- lvmcache_del_dev_from_duplicates(dev); + cmd->filter->wipe(cmd, cmd->filter, dev, NULL); + } + } +-- +2.34.3 + diff --git a/SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch b/SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch new file mode 100644 index 0000000..75eb9b1 --- /dev/null +++ b/SOURCES/0030-lvmdevices-fix-checks-when-adding-entries.patch @@ -0,0 +1,246 @@ +From 4e72068216b006edc69c8bafba5198051e3ed1dd Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 25 Jan 2022 11:35:36 -0600 +Subject: [PATCH 30/54] lvmdevices: fix checks when adding entries + +Removes some incorrect and unnecessary checks for other entries +when adding a new devices. The removed checks and corrections were +mostly redundant with what is already done by device id matching. +Other checking is reworked so the warnings are a bit different. +--- + lib/device/device_id.c | 153 +++++++++++++---------------------------- + 1 file changed, 48 insertions(+), 105 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 625576ec6..ccc5f43a1 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -935,6 +935,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_ + struct dev_use *du, *update_du = NULL, *du_dev, *du_pvid, *du_devname, *du_devid; + struct dev_id *id; + int found_id = 0; ++ int part = 0; ++ ++ if (!dev_get_partition_number(dev, &part)) ++ return_0; + + /* + * When enable_devices_file=0 and pending_devices_file=1 we let +@@ -953,10 +957,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_ + */ + memcpy(&pvid, pvid_arg, ID_LEN); + +- du_dev = get_du_for_dev(cmd, dev); +- du_pvid = get_du_for_pvid(cmd, pvid); +- du_devname = _get_du_for_devname(cmd, dev_name(dev)); +- + /* + * Choose the device_id type for the device being added. + * +@@ -1072,6 +1072,9 @@ id_done: + idtype = 0; + + /* ++ * "dev" is the device we are adding. ++ * "id" is the device_id it's using, set in dev->id. ++ * + * Update the cmd->use_devices list for the new device. The + * use_devices list will be used to update the devices file. + * +@@ -1083,23 +1086,57 @@ id_done: + * those other entries to fix any incorrect info. + */ + ++ /* Is there already an entry matched to this device? */ ++ du_dev = get_du_for_dev(cmd, dev); ++ ++ /* Is there already an entry matched to this device's pvid? */ ++ du_pvid = get_du_for_pvid(cmd, pvid); ++ ++ /* Is there already an entry using this device's name? */ ++ du_devname = _get_du_for_devname(cmd, dev_name(dev)); ++ ++ /* Is there already an entry using the device_id for this device? */ + du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname); + + if (du_dev) +- log_debug("device_id_add %s pvid %s matches du_dev %p dev %s", ++ log_debug("device_id_add %s pvid %s matches entry %p dev %s", + dev_name(dev), pvid, du_dev, dev_name(du_dev->dev)); + if (du_pvid) +- log_debug("device_id_add %s pvid %s matches du_pvid %p dev %s pvid %s", ++ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same pvid %s", + dev_name(dev), pvid, du_pvid, du_pvid->dev ? dev_name(du_pvid->dev) : ".", + du_pvid->pvid); + if (du_devid) +- log_debug("device_id_add %s pvid %s matches du_devid %p dev %s pvid %s", ++ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same device_id %d %s", + dev_name(dev), pvid, du_devid, du_devid->dev ? dev_name(du_devid->dev) : ".", +- du_devid->pvid); ++ du_devid->idtype, du_devid->idname); + if (du_devname) +- log_debug("device_id_add %s pvid %s matches du_devname %p dev %s pvid %s", ++ log_debug("device_id_add %s pvid %s matches entry %p dev %s with same devname %s", + dev_name(dev), pvid, du_devname, du_devname->dev ? dev_name(du_devname->dev) : ".", +- du_devname->pvid); ++ du_devname->devname); ++ ++ if (du_pvid && (du_pvid->dev != dev)) ++ log_warn("WARNING: adding device %s with PVID %s which is already used for %s.", ++ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device"); ++ ++ if (du_devid && (du_devid->dev != dev)) { ++ if (!du_devid->dev) { ++ log_warn("WARNING: adding device %s with idname %s which is already used for missing device.", ++ dev_name(dev), id->idname); ++ } else { ++ int ret1, ret2; ++ dev_t devt1, devt2; ++ /* Check if both entries are partitions of the same device. */ ++ ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1); ++ ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2); ++ if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) { ++ log_debug("Using separate entries for partitions of same device %s part %d %s part %d.", ++ dev_name(dev), part, dev_name(du_devid->dev), du_devid->part); ++ } else { ++ log_warn("WARNING: adding device %s with idname %s which is already used for %s.", ++ dev_name(dev), id->idname, dev_name(du_devid->dev)); ++ } ++ } ++ } + + /* + * If one of the existing entries (du_dev, du_pvid, du_devid, du_devname) +@@ -1112,29 +1149,6 @@ id_done: + dm_list_del(&update_du->list); + update_matching_kind = "device"; + update_matching_name = dev_name(dev); +- +- if (du_devid && (du_devid != du_dev)) { +- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate device ID.", +- dev_name(dev), id->idname, +- (du_pvid && du_pvid->dev) ? dev_name(du_pvid->dev) : "none", +- du_pvid ? du_pvid->idname : ""); +- } +- +- if (du_pvid && (du_pvid != du_dev)) { +- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s", +- dev_name(dev), id->idname, +- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname, +- pvid); +- } +- +- if (du_devname && (du_devname != du_dev)) { +- /* clear devname in another entry with our devname */ +- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.", +- du_devname->pvid, du_devname->devname); +- free(du_devname->devname); +- du_devname->devname = NULL; +- } +- + } else if (du_pvid) { + /* + * If the device_id of the existing entry for PVID is the same +@@ -1154,11 +1168,6 @@ id_done: + update_matching_kind = "PVID"; + update_matching_name = pvid; + } else { +- log_warn("WARNING: device %s (%s) and %s (%s) have duplicate PVID %s", +- dev_name(dev), id->idname, +- du_pvid->dev ? dev_name(du_pvid->dev) : "none", du_pvid->idname, +- pvid); +- + if (!cmd->current_settings.yes && + yes_no_prompt("Add device with duplicate PV to devices file?") == 'n') { + log_print("Device not added."); +@@ -1166,21 +1175,6 @@ id_done: + return 1; + } + } +- +- if (du_devid && (du_devid != du_pvid)) { +- /* warn about another entry using the same device_id */ +- log_warn("WARNING: duplicate device_id %s for PVIDs %s %s", +- du_devid->idname, du_devid->pvid, du_pvid->pvid); +- } +- +- if (du_devname && (du_devname != du_pvid)) { +- /* clear devname in another entry with our devname */ +- log_warn("Devices file PVID %s clearing wrong DEVNAME %s.", +- du_devname->pvid, du_devname->devname); +- free(du_devname->devname); +- du_devname->devname = NULL; +- } +- + } else if (du_devid) { + /* + * Do we create a new du or update the existing du? +@@ -1195,64 +1189,13 @@ id_done: + * the same device_id (create a new du for dev.) + * If not, then update the existing du_devid. + */ +- +- if (du_devid->dev != dev) +- check_idname = device_id_system_read(cmd, du_devid->dev, id->idtype); +- +- if (check_idname && !strcmp(check_idname, id->idname)) { +- int ret1, ret2; +- dev_t devt1, devt2; +- +- /* +- * two different devices have the same device_id, +- * create a new du for the device being added +- */ +- +- /* dev_is_partitioned() the dev open to read it. */ +- if (!label_scan_open(du_devid->dev)) +- log_warn("Cannot open %s", dev_name(du_devid->dev)); +- +- if (dev_is_partitioned(cmd, du_devid->dev)) { +- /* Check if existing entry is whole device and new entry is a partition of it. */ +- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1); +- if ((ret1 == 2) && (devt1 == du_devid->dev->dev)) +- log_warn("Remove partitioned device %s from devices file.", dev_name(du_devid->dev)); +- } else { +- /* Check if both entries are partitions of the same device. */ +- ret1 = dev_get_primary_dev(cmd->dev_types, dev, &devt1); +- ret2 = dev_get_primary_dev(cmd->dev_types, du_devid->dev, &devt2); +- +- if ((ret1 == 2) && (ret2 == 2) && (devt1 == devt2)) { +- log_warn("Partitions %s %s have same device_id %s", +- dev_name(dev), dev_name(du_devid->dev), id->idname); +- } else { +- log_warn("Duplicate device_id %s %s for %s and %s", +- idtype_to_str(id->idtype), check_idname, +- dev_name(dev), dev_name(du_devid->dev)); +- } +- } +- } else { ++ if (du_devid->dev == dev) { + /* update the existing entry with matching devid */ + update_du = du_devid; + dm_list_del(&update_du->list); + update_matching_kind = "device_id"; + update_matching_name = id->idname; + } +- +- if (du_devname && (du_devname != du_devid)) { +- /* clear devname in another entry with our devname */ +- log_warn("Devices file PVID %s clearing wrong DEVNAME %s", +- du_devname->pvid, du_devname->devname); +- free(du_devname->devname); +- du_devname->devname = NULL; +- } +- +- } else if (du_devname) { +- /* clear devname in another entry with our devname */ +- log_warn("Devices file PVID %s clearing wrong DEVNAME %s", +- du_devname->pvid, du_devname->devname); +- free(du_devname->devname); +- du_devname->devname = NULL; + } + + free((void *)check_idname); +-- +2.34.3 + diff --git a/SOURCES/0031-lvmdevices-make-deldev-work-for-missing-device.patch b/SOURCES/0031-lvmdevices-make-deldev-work-for-missing-device.patch new file mode 100644 index 0000000..633e1d4 --- /dev/null +++ b/SOURCES/0031-lvmdevices-make-deldev-work-for-missing-device.patch @@ -0,0 +1,106 @@ +From df2b1555aff71452cde156badec70117065c9e2c Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 3 Feb 2022 16:56:03 -0600 +Subject: [PATCH 31/54] lvmdevices: make deldev work for missing device + +--- + lib/device/device_id.c | 6 +++--- + lib/device/device_id.h | 1 + + tools/lvmdevices.c | 33 ++++++++++++++++----------------- + 3 files changed, 20 insertions(+), 20 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index ccc5f43a1..aeaa1ffc6 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -894,7 +894,7 @@ struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid) + return NULL; + } + +-static struct dev_use *_get_du_for_devname(struct cmd_context *cmd, const char *devname) ++struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname) + { + struct dev_use *du; + +@@ -1093,7 +1093,7 @@ id_done: + du_pvid = get_du_for_pvid(cmd, pvid); + + /* Is there already an entry using this device's name? */ +- du_devname = _get_du_for_devname(cmd, dev_name(dev)); ++ du_devname = get_du_for_devname(cmd, dev_name(dev)); + + /* Is there already an entry using the device_id for this device? */ + du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname); +@@ -1514,7 +1514,7 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev) + struct dev_use *du; + + /* First check the du entry with matching devname since it's likely correct. */ +- if ((du = _get_du_for_devname(cmd, dev_name(dev)))) { ++ if ((du = get_du_for_devname(cmd, dev_name(dev)))) { + if (_match_du_to_dev(cmd, du, dev)) + return 1; + } +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index 4cf1374c8..2cd2fd7c6 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -40,6 +40,7 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, + + struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev); + struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid); ++struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname); + + char *devices_file_version(void); + int devices_file_exists(struct cmd_context *cmd); +diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c +index c50c09f90..662b35f9a 100644 +--- a/tools/lvmdevices.c ++++ b/tools/lvmdevices.c +@@ -383,28 +383,27 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + * No filter because we always want to allow removing a device + * by name from the devices file. + */ +- if (!(dev = dev_cache_get(cmd, devname, NULL))) { +- log_error("No device found for %s.", devname); +- goto bad; +- } +- +- /* +- * dev_cache_scan uses sysfs to check if an LV is using each dev +- * and sets this flag is so. +- */ +- if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) { +- if (!arg_count(cmd, yes_ARG) && +- yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') { +- log_error("Device not removed."); +- goto bad; ++ if ((dev = dev_cache_get(cmd, devname, NULL))) { ++ /* ++ * dev_cache_scan uses sysfs to check if an LV is using each dev ++ * and sets this flag is so. ++ */ ++ if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) { ++ if (!arg_count(cmd, yes_ARG) && ++ yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') { ++ log_error("Device not removed."); ++ goto bad; ++ } + } ++ if ((du = get_du_for_dev(cmd, dev))) ++ goto dev_del; + } + +- if (!(du = get_du_for_dev(cmd, dev))) { +- log_error("Device not found in devices file."); ++ if (!(du = get_du_for_devname(cmd, devname))) { ++ log_error("No devices file entry for %s.", devname); + goto bad; + } +- ++ dev_del: + dm_list_del(&du->list); + free_du(du); + device_ids_write(cmd); +-- +2.34.3 + diff --git a/SOURCES/0032-devices-file-do-not-clear-PVID-of-unread-devices.patch b/SOURCES/0032-devices-file-do-not-clear-PVID-of-unread-devices.patch new file mode 100644 index 0000000..ca4d5eb --- /dev/null +++ b/SOURCES/0032-devices-file-do-not-clear-PVID-of-unread-devices.patch @@ -0,0 +1,144 @@ +From 08a5619a1d7a5a8dd6e0df6e4dedec47ce2533b7 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 10 Feb 2022 14:00:25 -0600 +Subject: [PATCH 32/54] devices file: do not clear PVID of unread devices + +In a certain disconnected state, a block device is present on +the system, can be opened, reports a valid size, reports the +correct device id (wwid), and matches a devices file entry. +But, reading the device can still fail. In this case, +device_ids_validate() was misinterpreting the read error as +the device having no data/label on it (and no PVID). +The validate function would then clear the PVID from the +devices file entry for the device, thinking that it was +fixing the devices file (making it consistent with the on disk +state.) Fix this by not attempting to check and correct a +devices file entry that cannot be read. Also make this case +explicit in the hints validation code (which was doing the +right thing but indirectly.) +--- + lib/device/device.h | 1 + + lib/device/device_id.c | 14 ++++++++++++++ + lib/label/hints.c | 14 ++++++++++++++ + lib/label/label.c | 8 ++++++++ + 4 files changed, 37 insertions(+) + +diff --git a/lib/device/device.h b/lib/device/device.h +index 9e471a9b5..8c3a8c30e 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -40,6 +40,7 @@ + #define DEV_IS_NVME 0x00040000 /* set if dev is nvme */ + #define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */ + #define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */ ++#define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */ + + /* + * Support for external device info. +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index aeaa1ffc6..7fe581571 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1724,6 +1724,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + if (scanned_devs && !dev_in_device_list(dev, scanned_devs)) + continue; + ++ /* ++ * The matched device could not be read so we do not have ++ * the PVID from disk and cannot verify the devices file entry. ++ */ ++ if (dev->flags & DEV_SCAN_NOT_READ) ++ continue; ++ + /* + * du and dev may have been matched, but the dev could still + * have been excluded by other filters during label scan. +@@ -1806,6 +1813,13 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + if (scanned_devs && !dev_in_device_list(dev, scanned_devs)) + continue; + ++ /* ++ * The matched device could not be read so we do not have ++ * the PVID from disk and cannot verify the devices file entry. ++ */ ++ if (dev->flags & DEV_SCAN_NOT_READ) ++ continue; ++ + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { + log_warn("Devices file %s is excluded by filter: %s.", + dev_name(dev), dev_filtered_reason(dev)); +diff --git a/lib/label/hints.c b/lib/label/hints.c +index 3ce9634f2..95d5d77b8 100644 +--- a/lib/label/hints.c ++++ b/lib/label/hints.c +@@ -234,6 +234,7 @@ static int _touch_newhints(void) + return_0; + if (fclose(fp)) + stack; ++ log_debug("newhints created"); + return 1; + } + +@@ -504,6 +505,19 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) + if (!hint->chosen) + continue; + ++ /* ++ * label_scan was unable to read the dev so we don't know its pvid. ++ * Since we are unable to verify the hint is correct, it's possible ++ * that the PVID is actually found on a different device, so don't ++ * depend on hints. (This would also fail the following pvid check.) ++ */ ++ if (dev->flags & DEV_SCAN_NOT_READ) { ++ log_debug("Uncertain hint for unread device %d:%d %s", ++ major(hint->devt), minor(hint->devt), dev_name(dev)); ++ ret = 0; ++ continue; ++ } ++ + if (strcmp(dev->pvid, hint->pvid)) { + log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s", + major(hint->devt), minor(hint->devt), dev_name(dev), +diff --git a/lib/label/label.c b/lib/label/label.c +index 9fac3e464..354ab35e2 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -686,6 +686,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + + dm_list_iterate_items_safe(devl, devl2, devs) { + ++ devl->dev->flags &= ~DEV_SCAN_NOT_READ; ++ + /* + * If we prefetch more devs than blocks in the cache, then the + * cache will wait for earlier reads to complete, toss the +@@ -701,6 +703,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + log_debug_devs("Scan failed to open %s.", dev_name(devl->dev)); + dm_list_del(&devl->list); + dm_list_add(&reopen_devs, &devl->list); ++ devl->dev->flags |= DEV_SCAN_NOT_READ; + continue; + } + } +@@ -724,6 +727,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + log_debug_devs("Scan failed to read %s.", dev_name(devl->dev)); + scan_read_errors++; + scan_failed_count++; ++ devl->dev->flags |= DEV_SCAN_NOT_READ; + lvmcache_del_dev(devl->dev); + if (bb) + bcache_put(bb); +@@ -1113,6 +1117,10 @@ int label_scan(struct cmd_context *cmd) + * filter", and this result needs to be cleared (wiped) so that the + * complete set of filters (including those that require data) can be + * checked in _process_block, where headers have been read. ++ * ++ * FIXME: devs that are filtered with data in _process_block ++ * are not moved to the filtered_devs list like devs filtered ++ * here without data. Does that have any effect? + */ + log_debug_devs("Filtering devices to scan (nodata)"); + +-- +2.34.3 + diff --git a/SOURCES/0033-man-lvmcache-mention-writecache-memory-usage.patch b/SOURCES/0033-man-lvmcache-mention-writecache-memory-usage.patch new file mode 100644 index 0000000..a8314e4 --- /dev/null +++ b/SOURCES/0033-man-lvmcache-mention-writecache-memory-usage.patch @@ -0,0 +1,35 @@ +From cdefd8635de24200b55822fa0b6bc23a638fb87a Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 21 Feb 2022 11:35:58 -0600 +Subject: [PATCH 33/54] man lvmcache: mention writecache memory usage + +--- + man/lvmcache.7_main | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main +index 48cf7b492..73680235b 100644 +--- a/man/lvmcache.7_main ++++ b/man/lvmcache.7_main +@@ -240,6 +240,18 @@ The writecache block size should be chosen to match the xfs sectsz value. + It is also possible to specify a sector size of 4096 to mkfs.xfs when + creating the file system. In this case the writecache block size of 4096 + can be used. ++.P ++.SS dm-writecache memory usage ++.P ++The amount of main system memory used by dm-writecache can be a factor ++when selecting the writecache cachevol size and the writecache block size. ++.P ++.IP \[bu] 2 ++writecache block size 4096: each 100 GiB of writecache cachevol uses ++slighly over 2 GiB of system memory. ++.IP \[bu] 2 ++writecache block size 512: each 100 GiB of writecache cachevol uses ++a little over 16 GiB of system memory. + . + .SS dm-writecache settings + . +-- +2.34.3 + diff --git a/SOURCES/0034-writecache-display-block-size-from-lvs.patch b/SOURCES/0034-writecache-display-block-size-from-lvs.patch new file mode 100644 index 0000000..5167d68 --- /dev/null +++ b/SOURCES/0034-writecache-display-block-size-from-lvs.patch @@ -0,0 +1,102 @@ +From c047ff61f68d1b853569b153251f8bc5f88e23cd Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 21 Feb 2022 16:09:57 -0600 +Subject: [PATCH 34/54] writecache: display block size from lvs + +lvs was missing the ability to display writecache block size. +now possible with lvs -o writecache_block_size +--- + lib/report/columns.h | 1 + + lib/report/properties.c | 2 ++ + lib/report/report.c | 20 ++++++++++++++++++++ + man/lvmcache.7_main | 4 ++++ + test/shell/writecache-cache-blocksize.sh | 2 ++ + 5 files changed, 29 insertions(+) + +diff --git a/lib/report/columns.h b/lib/report/columns.h +index 12b78b766..7e450dace 100644 +--- a/lib/report/columns.h ++++ b/lib/report/columns.h +@@ -108,6 +108,7 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal + FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0) + FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0) + FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0) ++FIELD(LVS, lv, NUM, "WCacheBlkSize", lvid, 0, writecache_block_size, writecache_block_size, "The writecache block size", 0) + /* + * End of LVS type fields + */ +diff --git a/lib/report/properties.c b/lib/report/properties.c +index 12ea890f4..6f302360f 100644 +--- a/lib/report/properties.c ++++ b/lib/report/properties.c +@@ -353,6 +353,8 @@ GET_PV_STR_PROPERTY_FN(pv_device_id_type, pv->device_id_type) + #define _writecache_writeback_blocks_get prop_not_implemented_get + #define _writecache_error_set prop_not_implemented_set + #define _writecache_error_get prop_not_implemented_get ++#define _writecache_block_size_set prop_not_implemented_set ++#define _writecache_block_size_get prop_not_implemented_get + + #define _vdo_operating_mode_set prop_not_implemented_set + #define _vdo_operating_mode_get prop_not_implemented_get +diff --git a/lib/report/report.c b/lib/report/report.c +index 60df417a4..c06b22674 100644 +--- a/lib/report/report.c ++++ b/lib/report/report.c +@@ -3346,6 +3346,26 @@ static int _integritymismatches_disp(struct dm_report *rh __attribute__((unused) + return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64)); + } + ++static int _writecache_block_size_disp(struct dm_report *rh __attribute__((unused)), ++ struct dm_pool *mem, ++ struct dm_report_field *field, ++ const void *data, ++ void *private __attribute__((unused))) ++{ ++ struct logical_volume *lv = (struct logical_volume *) data; ++ uint32_t bs = 0; ++ ++ if (lv_is_writecache(lv)) { ++ struct lv_segment *seg = first_seg(lv); ++ bs = seg->writecache_block_size; ++ } ++ ++ if (!bs) ++ return dm_report_field_int32(rh, field, &GET_TYPE_RESERVED_VALUE(num_undef_32)); ++ ++ return dm_report_field_uint32(rh, field, &bs); ++} ++ + static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem, + struct dm_report_field *field, + const void *data, void *private) +diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main +index 73680235b..519e352cb 100644 +--- a/man/lvmcache.7_main ++++ b/man/lvmcache.7_main +@@ -241,6 +241,10 @@ It is also possible to specify a sector size of 4096 to mkfs.xfs when + creating the file system. In this case the writecache block size of 4096 + can be used. + .P ++The writecache block size is displayed by the command: ++.br ++lvs -o writecacheblocksize VG/LV ++.P + .SS dm-writecache memory usage + .P + The amount of main system memory used by dm-writecache can be a factor +diff --git a/test/shell/writecache-cache-blocksize.sh b/test/shell/writecache-cache-blocksize.sh +index 2579ef7b7..4e17effe5 100644 +--- a/test/shell/writecache-cache-blocksize.sh ++++ b/test/shell/writecache-cache-blocksize.sh +@@ -222,6 +222,8 @@ vgextend $vg "$dev2" + lvcreate -n $lv1 -l 8 -an $vg "$dev1" + lvcreate -n $lv2 -l 4 -an $vg "$dev2" + lvconvert --yes --type writecache --cachevol $lv2 --cachesettings "block_size=4096" $vg/$lv1 ++lvs -o writecacheblocksize $vg/$lv1 |tee out ++grep 4096 out + lvchange -ay $vg/$lv1 + mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1" |tee out + grep "sectsz=4096" out +-- +2.34.3 + diff --git a/SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch b/SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch new file mode 100644 index 0000000..2f8a911 --- /dev/null +++ b/SOURCES/0035-devices-simplify-dev_cache_get_by_devt.patch @@ -0,0 +1,148 @@ +From 8552290efae4905fd1a942be8e752842b11f1881 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 24 Feb 2022 15:57:29 -0600 +Subject: [PATCH 35/54] devices: simplify dev_cache_get_by_devt + +remove unused args, and no callers need or want a +repeated dev_cache_scan if there is no dev from the +lookup. +--- + lib/device/dev-cache.c | 60 ++++-------------------------------------- + lib/device/dev-cache.h | 2 +- + lib/label/label.c | 2 +- + tools/pvscan.c | 6 ++--- + 4 files changed, 10 insertions(+), 60 deletions(-) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index c6e5f68cf..cc1af7c7a 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1577,63 +1577,13 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + return dev; + } + +-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered) ++struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt) + { +- char path[PATH_MAX]; +- const char *sysfs_dir; +- struct stat info; +- struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev); +- int ret; +- +- if (filtered) +- *filtered = 0; +- +- if (!d) { +- sysfs_dir = dm_sysfs_dir(); +- if (sysfs_dir && *sysfs_dir) { +- /* First check if dev is sysfs to avoid useless scan */ +- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", +- sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) { +- log_error("dm_snprintf partition failed."); +- return NULL; +- } +- +- if (lstat(path, &info)) { +- log_debug("No sysfs entry for %d:%d errno %d at %s.", +- (int)MAJOR(dev), (int)MINOR(dev), errno, path); +- return NULL; +- } +- } +- +- log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d", +- (int)MAJOR(dev), (int)MINOR(dev)); +- dev_cache_scan(cmd); +- d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev); +- +- if (!d) +- return NULL; +- } +- +- if (d->flags & DEV_REGULAR) +- return d; +- +- if (!f) +- return d; +- +- ret = f->passes_filter(cmd, f, d, NULL); +- +- if (ret == -EAGAIN) { +- log_debug_devs("get device by number defer filter %s", dev_name(d)); +- d->flags |= DEV_FILTER_AFTER_SCAN; +- ret = 1; +- } +- +- if (ret) +- return d; +- +- if (filtered) +- *filtered = 1; ++ struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt); + ++ if (dev) ++ return dev; ++ log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt)); + return NULL; + } + +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 635dc4fc9..7305eeb0e 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -54,7 +54,7 @@ int dev_cache_has_scanned(void); + int dev_cache_add_dir(const char *path); + struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f); + +-struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered); ++struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt); + + struct device *dev_hash_get(const char *name); + +diff --git a/lib/label/label.c b/lib/label/label.c +index 354ab35e2..ffe925254 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -1443,7 +1443,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv + if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) { + /* FIXME: Still unclear what is it supposed to find */ + devt = MKDEV(lvinfo.major, lvinfo.minor); +- if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL))) ++ if ((dev = dev_cache_get_by_devt(cmd, devt))) + label_scan_invalidate(dev); + } + } +diff --git a/tools/pvscan.c b/tools/pvscan.c +index f60c4a2ca..160a2c9a0 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -857,7 +857,7 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname, + + devno = MKDEV(file_major, file_minor); + +- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) { ++ if (!(dev = dev_cache_get_by_devt(cmd, devno))) { + log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid); + goto bad; + } +@@ -1195,7 +1195,7 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args, + if (arg->devname) + arg->dev = dev_cache_get(cmd, arg->devname, NULL); + else if (arg->devno) +- arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL); ++ arg->dev = dev_cache_get_by_devt(cmd, arg->devno); + else + return_0; + } +@@ -1257,7 +1257,7 @@ static void _set_pv_devices_online(struct cmd_context *cmd, struct volume_group + + devno = MKDEV(major, minor); + +- if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) { ++ if (!(dev = dev_cache_get_by_devt(cmd, devno))) { + log_print_pvscan(cmd, "VG %s PV %s no device found for %d:%d", + vg->name, pvid, major, minor); + pvl->pv->status |= MISSING_PV; +-- +2.34.3 + diff --git a/SOURCES/0036-devices-drop-incorrect-paths-from-aliases-list.patch b/SOURCES/0036-devices-drop-incorrect-paths-from-aliases-list.patch new file mode 100644 index 0000000..010f2f3 --- /dev/null +++ b/SOURCES/0036-devices-drop-incorrect-paths-from-aliases-list.patch @@ -0,0 +1,467 @@ +From 8ba6259b24cd4b99e061f2610c5cd0bcde890039 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 24 Feb 2022 16:03:21 -0600 +Subject: [PATCH 36/54] devices: drop incorrect paths from aliases list + +along with some basic checks for cases when a device +has no aliases. + +lvm itself creates many situations where a struct device +has no valid paths, when it activates and opens an LV, +does something with it, e.g. zeroing, and then closes +and deactivates it. (dev-cache is intended for PVs, and +the use of LVs should be moved out of dev-cache in a +future patch.) +--- + lib/device/dev-cache.c | 223 ++++++++++++++++++++++++++--------------- + lib/device/dev-cache.h | 2 +- + lib/device/dev-io.c | 34 ++++--- + lib/device/device.h | 3 - + 4 files changed, 164 insertions(+), 98 deletions(-) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index cc1af7c7a..58e67e130 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash) + goto out; + } + +- if (!(path = dm_pool_strdup(_cache.mem, path)) || ++ if (!(path = _strdup(path)) || + !(sl = _zalloc(sizeof(*sl)))) { + log_error("Failed to add allias to dev cache."); + return 0; +@@ -1162,6 +1162,17 @@ static int _insert(const char *path, const struct stat *info, + return 1; + } + ++static void _drop_all_aliases(struct device *dev) ++{ ++ struct dm_str_list *strl, *strl2; ++ ++ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { ++ log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str); ++ dm_hash_remove(_cache.names, strl->str); ++ dm_list_del(&strl->list); ++ } ++} ++ + void dev_cache_scan(struct cmd_context *cmd) + { + log_debug_devs("Creating list of system devices."); +@@ -1371,59 +1382,6 @@ int dev_cache_add_dir(const char *path) + return 1; + } + +-/* Check cached device name is still valid before returning it */ +-/* This should be a rare occurrence */ +-/* set quiet if the cache is expected to be out-of-date */ +-/* FIXME Make rest of code pass/cache struct device instead of dev_name */ +-const char *dev_name_confirmed(struct device *dev, int quiet) +-{ +- struct stat buf; +- const char *name; +- int r; +- +- if ((dev->flags & DEV_REGULAR)) +- return dev_name(dev); +- +- while ((r = stat(name = dm_list_item(dev->aliases.n, +- struct dm_str_list)->str, &buf)) || +- (buf.st_rdev != dev->dev)) { +- if (r < 0) { +- if (quiet) +- log_sys_debug("stat", name); +- else +- log_sys_error("stat", name); +- } +- if (quiet) +- log_debug_devs("Path %s no longer valid for device(%d,%d)", +- name, (int) MAJOR(dev->dev), +- (int) MINOR(dev->dev)); +- else +- log_warn("Path %s no longer valid for device(%d,%d)", +- name, (int) MAJOR(dev->dev), +- (int) MINOR(dev->dev)); +- +- /* Remove the incorrect hash entry */ +- dm_hash_remove(_cache.names, name); +- +- /* Leave list alone if there isn't an alternative name */ +- /* so dev_name will always find something to return. */ +- /* Otherwise add the name to the correct device. */ +- if (dm_list_size(&dev->aliases) > 1) { +- dm_list_del(dev->aliases.n); +- if (!r) +- _insert(name, &buf, 0, obtain_device_list_from_udev()); +- continue; +- } +- +- /* Scanning issues this inappropriately sometimes. */ +- log_debug_devs("Aborting - please provide new pathname for what " +- "used to be %s", name); +- return NULL; +- } +- +- return dev_name(dev); +-} +- + struct device *dev_hash_get(const char *name) + { + return (struct device *) dm_hash_lookup(_cache.names, name); +@@ -1452,26 +1410,23 @@ static void _remove_alias(struct device *dev, const char *name) + * deactivated LV. Those old paths are all invalid and are dropped here. + */ + +-static void _verify_aliases(struct device *dev, const char *newname) ++static void _verify_aliases(struct device *dev) + { + struct dm_str_list *strl, *strl2; + struct stat st; + + dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { +- /* newname was just stat'd and added by caller */ +- if (newname && !strcmp(strl->str, newname)) +- continue; +- + if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) { +- log_debug("Drop invalid path %s for %d:%d (new path %s).", +- strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: ""); ++ log_debug("Drop alias for %d:%d invalid path %s %d:%d.", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str, ++ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev)); + dm_hash_remove(_cache.names, strl->str); + dm_list_del(&strl->list); + } + } + } + +-struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) ++static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing) + { + struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name); + struct stat st; +@@ -1485,13 +1440,18 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + if (dev && (dev->flags & DEV_REGULAR)) + return dev; + ++ if (dev && dm_list_empty(&dev->aliases)) { ++ /* shouldn't happen */ ++ log_warn("Ignoring dev with no valid paths for %s.", name); ++ return NULL; ++ } ++ + /* +- * The requested path is invalid, remove any dev-cache +- * info for it. ++ * The requested path is invalid, remove any dev-cache info for it. + */ + if (stat(name, &st)) { + if (dev) { +- log_print("Device path %s is invalid for %d:%d %s.", ++ log_debug("Device path %s is invalid for %d:%d %s.", + name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); + + dm_hash_remove(_cache.names, name); +@@ -1499,11 +1459,17 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + _remove_alias(dev, name); + + /* Remove any other names in dev->aliases that are incorrect. */ +- _verify_aliases(dev, NULL); ++ _verify_aliases(dev); + } + return NULL; + } + ++ if (dev && dm_list_empty(&dev->aliases)) { ++ /* shouldn't happen */ ++ log_warn("Ignoring dev with no valid paths for %s.", name); ++ return NULL; ++ } ++ + if (!S_ISBLK(st.st_mode)) { + log_debug("Not a block device %s.", name); + return NULL; +@@ -1514,26 +1480,110 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + * Remove incorrect info and then add new dev-cache entry. + */ + if (dev && (st.st_rdev != dev->dev)) { +- log_debug("Device path %s does not match %d:%d %s.", +- name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); ++ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev); ++ ++ /* ++ * lvm commands create this condition when they ++ * activate/deactivate LVs combined with creating new LVs. ++ * The command does not purge dev structs when deactivating ++ * an LV (which it probably should do), but the better ++ * approach would be not using dev-cache at all for LVs. ++ */ + +- dm_hash_remove(_cache.names, name); ++ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev), ++ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name); + +- _remove_alias(dev, name); ++ _drop_all_aliases(dev); + +- /* Remove any other names in dev->aliases that are incorrect. */ +- _verify_aliases(dev, NULL); ++ if (dev_by_devt) { ++ log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.", ++ (int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt), ++ (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name); + +- /* Add new dev-cache entry next. */ +- dev = NULL; ++ _drop_all_aliases(dev_by_devt); ++ } ++ ++#if 0 ++ /* ++ * I think only lvm's own dm devs should be added here, so use ++ * a warning to look for any other unknown cases. ++ */ ++ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) { ++ log_warn("WARNING: new device appeared %d:%d %s", ++ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); ++ } ++#endif ++ ++ if (!_insert_dev(name, st.st_rdev)) ++ return_NULL; ++ ++ /* Get the struct dev that was just added. */ ++ dev = (struct device *) dm_hash_lookup(_cache.names, name); ++ ++ if (!dev) { ++ log_error("Failed to get device %s", name); ++ return NULL; ++ } ++ ++ goto out; + } + ++ if (dev && dm_list_empty(&dev->aliases)) { ++ /* shouldn't happen */ ++ log_warn("Ignoring dev with no valid paths for %s.", name); ++ return NULL; ++ } ++ ++ if (!dev && existing) ++ return_NULL; ++ + /* +- * Either add a new struct dev for st_rdev and name, +- * or add name as a new alias for an existing struct dev +- * for st_rdev. ++ * This case should never be hit for a PV. It should only ++ * happen when the command is opening a new LV it has created. ++ * Add an arg to all callers indicating when the arg should be ++ * new (for an LV) and not existing. ++ * FIXME: fix this further by not using dev-cache struct devs ++ * at all for new dm devs (LVs) that lvm uses. Make the ++ * dev-cache contain only devs for PVs. ++ * Places to fix that use a dev for LVs include: ++ * . lv_resize opening lv to discard ++ * . wipe_lv opening lv to zero it ++ * . _extend_sanlock_lv opening lv to extend it ++ * . _write_log_header opening lv to write header ++ * Also, io to LVs should not go through bcache. ++ * bcache should contain only labels and metadata ++ * scanned from PVs. + */ + if (!dev) { ++ /* ++ * This case should only be used for new devices created by this ++ * command (opening LVs it's created), so if a dev exists for the ++ * dev_t referenced by the name, then drop all aliases for before ++ * _insert_dev adds the new name. lvm commands actually hit this ++ * fairly often when it uses some LV, deactivates the LV, then ++ * creates some new LV which ends up with the same major:minor. ++ * Without dropping the aliases, it's plausible that lvm commands ++ * could end up using the wrong dm device. ++ */ ++ struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev); ++ if (dev_by_devt) { ++ log_debug("Dropping aliases for %d:%d before adding new path %s.", ++ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); ++ _drop_all_aliases(dev_by_devt); ++ } ++ ++#if 0 ++ /* ++ * I think only lvm's own dm devs should be added here, so use ++ * a warning to look for any other unknown cases. ++ */ ++ if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) { ++ log_warn("WARNING: new device appeared %d:%d %s", ++ (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); ++ } ++#endif ++ + if (!_insert_dev(name, st.st_rdev)) + return_NULL; + +@@ -1544,10 +1594,9 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + log_error("Failed to get device %s", name); + return NULL; + } +- +- _verify_aliases(dev, name); + } + ++ out: + /* + * The caller passed a filter if they only want the dev if it + * passes filters. +@@ -1577,6 +1626,16 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d + return dev; + } + ++struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f) ++{ ++ return _dev_cache_get(cmd, name, f, 1); ++} ++ ++struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) ++{ ++ return _dev_cache_get(cmd, name, f, 0); ++} ++ + struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt) + { + struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt); +@@ -1653,8 +1712,10 @@ int dev_fd(struct device *dev) + + const char *dev_name(const struct device *dev) + { +- return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str : +- unknown_device_name(); ++ if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases)) ++ return dm_list_item(dev->aliases.n, struct dm_str_list)->str; ++ else ++ return unknown_device_name(); + } + + bool dev_cache_has_md_with_end_superblock(struct dev_types *dt) +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 7305eeb0e..51c3fc6c3 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -53,7 +53,7 @@ int dev_cache_has_scanned(void); + + int dev_cache_add_dir(const char *path); + struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f); +- ++struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f); + struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt); + + struct device *dev_hash_get(const char *name); +diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c +index b4f1930b1..811ad8978 100644 +--- a/lib/device/dev-io.c ++++ b/lib/device/dev-io.c +@@ -58,6 +58,9 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size) + const char *name = dev_name(dev); + struct stat info; + ++ if (dm_list_empty(&dev->aliases)) ++ return_0; ++ + if (dev->size_seqno == _dev_size_seqno) { + log_very_verbose("%s: using cached size %" PRIu64 " sectors", + name, dev->size); +@@ -87,7 +90,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size) + int do_close = 0; + + if (dm_list_empty(&dev->aliases)) +- return 0; ++ return_0; + + if (dev->size_seqno == _dev_size_seqno) { + log_very_verbose("%s: using cached size %" PRIu64 " sectors", +@@ -305,6 +308,13 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) + if ((flags & O_EXCL)) + need_excl = 1; + ++ if (dm_list_empty(&dev->aliases)) { ++ /* shouldn't happen */ ++ log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev)); ++ return 0; ++ } ++ name = dev_name(dev); ++ + if (dev->fd >= 0) { + if (((dev->flags & DEV_OPENED_RW) || !need_rw) && + ((dev->flags & DEV_OPENED_EXCL) || !need_excl)) { +@@ -314,7 +324,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) + + if (dev->open_count && !need_excl) + log_debug_devs("%s: Already opened read-only. Upgrading " +- "to read-write.", dev_name(dev)); ++ "to read-write.", name); + + /* dev_close_immediate will decrement this */ + dev->open_count++; +@@ -327,11 +337,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) + + if (critical_section()) + /* FIXME Make this log_error */ +- log_verbose("dev_open(%s) called while suspended", +- dev_name(dev)); +- +- if (!(name = dev_name_confirmed(dev, quiet))) +- return_0; ++ log_verbose("dev_open(%s) called while suspended", name); + + #ifdef O_DIRECT_SUPPORT + if (direct) { +@@ -372,9 +378,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) + } + #endif + if (quiet) +- log_sys_debug("open", name); ++ log_debug("Failed to open device path %s (%d).", name, errno); + else +- log_sys_error("open", name); ++ log_error("Failed to open device path %s (%d).", name, errno); + + dev->flags |= DEV_OPEN_FAILURE; + return 0; +@@ -415,10 +421,12 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) + if ((flags & O_CREAT) && !(flags & O_TRUNC)) + dev->end = lseek(dev->fd, (off_t) 0, SEEK_END); + +- log_debug_devs("Opened %s %s%s%s", dev_name(dev), +- dev->flags & DEV_OPENED_RW ? "RW" : "RO", +- dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "", +- dev->flags & DEV_O_DIRECT ? " O_DIRECT" : ""); ++ if (!quiet) { ++ log_debug_devs("Opened %s %s%s%s", name, ++ dev->flags & DEV_OPENED_RW ? "RW" : "RO", ++ dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "", ++ dev->flags & DEV_O_DIRECT ? " O_DIRECT" : ""); ++ } + + dev->flags &= ~DEV_OPEN_FAILURE; + return 1; +diff --git a/lib/device/device.h b/lib/device/device.h +index 8c3a8c30e..572994bb9 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -204,9 +204,6 @@ struct device *dev_create_file(const char *filename, struct device *dev, + struct dm_str_list *alias, int use_malloc); + void dev_destroy_file(struct device *dev); + +-/* Return a valid device name from the alias list; NULL otherwise */ +-const char *dev_name_confirmed(struct device *dev, int quiet); +- + int dev_mpath_init(const char *config_wwids_file); + void dev_mpath_exit(void); + +-- +2.34.3 + diff --git a/SOURCES/0037-devices-initial-use-of-existing-option.patch b/SOURCES/0037-devices-initial-use-of-existing-option.patch new file mode 100644 index 0000000..79fe5f3 --- /dev/null +++ b/SOURCES/0037-devices-initial-use-of-existing-option.patch @@ -0,0 +1,70 @@ +From 7dc7ab8e99005da29aba22df2bb67e58e19a50f0 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 24 Feb 2022 16:10:37 -0600 +Subject: [PATCH 37/54] devices: initial use of existing option + +Use dev_cache_get_existing() in a few common, high level +locations where it's obvious that only existing dev-cache +entries are wanted. This can be expanded and used in more +locations (or dev_cache_get can stop creating new entries.) +--- + lib/device/device_id.c | 4 ++-- + tools/toollib.c | 6 +++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 7fe581571..bcb2e6bcf 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1565,7 +1565,7 @@ void device_ids_match(struct cmd_context *cmd) + dm_list_iterate_items(du, &cmd->use_devices) { + if (du->dev) + continue; +- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) { ++ if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) { + log_warn("Device not found for %s.", du->devname); + } else { + /* Should we set dev->id? Which idtype? Use --deviceidtype? */ +@@ -1603,7 +1603,7 @@ void device_ids_match(struct cmd_context *cmd) + * the du/dev pairs in preparation for using the filters. + */ + if (du->devname && +- (dev = dev_cache_get(cmd, du->devname, NULL))) { ++ (dev = dev_cache_get_existing(cmd, du->devname, NULL))) { + /* On successful match, du, dev, and id are linked. */ + if (_match_du_to_dev(cmd, du, dev)) + continue; +diff --git a/tools/toollib.c b/tools/toollib.c +index d6f48aad2..16be336d4 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1434,7 +1434,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv, + goto out; + } + +- if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) { ++ if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) { + log_error("Failed to find device " + "\"%s\".", argv[opt]); + ret_max = ECMD_FAILED; +@@ -3870,7 +3870,7 @@ static int _get_arg_devices(struct cmd_context *cmd, + return ECMD_FAILED; + } + +- if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) { ++ if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) { + log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str)); + ret_max = EINIT_FAILED; + } else { +@@ -5206,7 +5206,7 @@ int pvcreate_each_device(struct cmd_context *cmd, + struct device *dev; + + /* No filter used here */ +- if (!(dev = dev_cache_get(cmd, pd->name, NULL))) { ++ if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) { + log_error("No device found for %s.", pd->name); + dm_list_del(&pd->list); + dm_list_add(&pp->arg_fail, &pd->list); +-- +2.34.3 + diff --git a/SOURCES/0038-devices-fix-dev_name-assumptions.patch b/SOURCES/0038-devices-fix-dev_name-assumptions.patch new file mode 100644 index 0000000..4608b4c --- /dev/null +++ b/SOURCES/0038-devices-fix-dev_name-assumptions.patch @@ -0,0 +1,270 @@ +From 591b5f006fca7e06bfbf0d5512da3ae5b0f6bbdd Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 22 Feb 2022 15:03:11 -0600 +Subject: [PATCH 38/54] devices: fix dev_name assumptions + +dev_name(dev) returns "[unknown]" if there are no names +on dev->aliases. It's meant mainly for log messages. + +Many places assume a valid path name is returned, and +use it directly. A caller that wants to use the path +from dev_name() must first check if the dev has any +paths with dm_list_empty(&dev->aliases). +--- + lib/activate/dev_manager.c | 9 ++++++++- + lib/device/dev-type.c | 3 +++ + lib/device/device_id.c | 13 +++++++++++-- + lib/label/hints.c | 2 ++ + lib/label/label.c | 16 +++++++++++++++- + lib/locking/lvmlockd.c | 4 ++++ + lib/metadata/mirror.c | 17 +++++++++++++---- + lib/metadata/pv_list.c | 5 +++++ + lib/metadata/vg.c | 5 +++++ + test/shell/losetup-partscan.sh | 2 ++ + 10 files changed, 68 insertions(+), 8 deletions(-) + +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index a73a556b2..284254d68 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -2875,6 +2875,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg, + + /* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */ + for (s = start_area; s < areas; s++) { ++ ++ /* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases) ++ but this knot of logic is too complex to pull apart without careful deconstruction. */ ++ + if ((seg_type(seg, s) == AREA_PV && + (!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) || + !(name = dev_name(seg_dev(seg, s))) || !*name || +@@ -2893,7 +2897,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg, + return_0; + num_error_areas++; + } else if (seg_type(seg, s) == AREA_PV) { +- if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL, ++ struct device *dev = seg_dev(seg, s); ++ name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev); ++ ++ if (!dm_tree_node_add_target_area(node, name, NULL, + (seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s))))) + return_0; + num_existing_areas++; +diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c +index 0e77a009d..c67a86fa3 100644 +--- a/lib/device/dev-type.c ++++ b/lib/device/dev-type.c +@@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam + + /* TODO: Should we check for valid dev - _dev_is_valid(dev)? */ + ++ if (dm_list_empty(&dev->aliases)) ++ goto_out; ++ + if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) { + log_error("Failed to create a new blkid probe for device %s.", dev_name(dev)); + goto out; +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index bcb2e6bcf..82db6e4a5 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u + } + + else if (idtype == DEV_ID_TYPE_DEVNAME) { ++ if (dm_list_empty(&dev->aliases)) ++ goto_bad; + if (!(idname = strdup(dev_name(dev)))) + goto_bad; + return idname; +@@ -940,6 +942,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_ + if (!dev_get_partition_number(dev, &part)) + return_0; + ++ /* Ensure valid dev_name(dev) below. */ ++ if (dm_list_empty(&dev->aliases)) ++ return_0; ++ + /* + * When enable_devices_file=0 and pending_devices_file=1 we let + * pvcreate/vgcreate add new du's to cmd->use_devices. These du's may +@@ -1820,6 +1826,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + if (dev->flags & DEV_SCAN_NOT_READ) + continue; + ++ if (dm_list_empty(&dev->aliases)) ++ continue; ++ + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { + log_warn("Devices file %s is excluded by filter: %s.", + dev_name(dev), dev_filtered_reason(dev)); +@@ -2197,14 +2206,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l + dm_list_iterate_items(dil, &search_pvids) { + char *dup_devname1, *dup_devname2, *dup_devname3; + +- if (!dil->dev) { ++ if (!dil->dev || dm_list_empty(&dil->dev->aliases)) { + not_found++; + continue; + } +- found++; + + dev = dil->dev; + devname = dev_name(dev); ++ found++; + + if (!(du = get_du_for_pvid(cmd, dil->pvid))) { + /* shouldn't happen */ +diff --git a/lib/label/hints.c b/lib/label/hints.c +index 95d5d77b8..2a7b3dca7 100644 +--- a/lib/label/hints.c ++++ b/lib/label/hints.c +@@ -498,6 +498,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) + if (!(iter = dev_iter_create(NULL, 0))) + return 0; + while ((dev = dev_iter_get(cmd, iter))) { ++ if (dm_list_empty(&dev->aliases)) ++ continue; + if (!(hint = _find_hint_name(hints, dev_name(dev)))) + continue; + +diff --git a/lib/label/label.c b/lib/label/label.c +index ffe925254..cf707f7a3 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -1565,10 +1565,24 @@ int label_scan_open_rw(struct device *dev) + + int label_scan_reopen_rw(struct device *dev) + { ++ const char *name; + int flags = 0; + int prev_fd = dev->bcache_fd; + int fd; + ++ if (dm_list_empty(&dev->aliases)) { ++ log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd); ++ return 0; ++ } ++ ++ name = dev_name(dev); ++ if (!name || name[0] != '/') { ++ log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd); ++ return 0; ++ } ++ + if (!(dev->flags & DEV_IN_BCACHE)) { + if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) { + /* shouldn't happen */ +@@ -1598,7 +1612,7 @@ int label_scan_reopen_rw(struct device *dev) + flags |= O_NOATIME; + flags |= O_RDWR; + +- fd = open(dev_name(dev), flags, 0777); ++ fd = open(name, flags, 0777); + if (fd < 0) { + log_error("Failed to open rw %s errno %d di %d fd %d.", + dev_name(dev), errno, dev->bcache_di, dev->bcache_fd); +diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c +index b598df3d6..60c80f1b1 100644 +--- a/lib/locking/lvmlockd.c ++++ b/lib/locking/lvmlockd.c +@@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg, + + i = 0; + dm_list_iterate_items(pvl, &vg->pvs) { ++ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) ++ continue; + lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv)); + if (!lock_pvs->path[i]) { + log_error("Fail to allocate PV path for VG %s", vg->name); +@@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg, + + dm_list_iterate_items(pvl, &vg->pvs) { + if (lv_is_on_pv(lv, pvl->pv)) { ++ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) ++ continue; + lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv)); + if (!lock_pvs->path[i]) { + log_error("Fail to allocate PV path for LV %s/%s", +diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c +index e2bf191a1..46da57948 100644 +--- a/lib/metadata/mirror.c ++++ b/lib/metadata/mirror.c +@@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv, + const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr) + { + struct lv_segment *seg; ++ struct device *dev; + + dm_list_iterate_items(seg, &lv_mirr->segments) { + if (!seg_is_mirrored(seg)) + continue; +- if (seg_type(seg, 0) == AREA_PV) +- return dev_name(seg_dev(seg, 0)); +- if (seg_type(seg, 0) == AREA_LV) +- return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0)); ++ if (seg_type(seg, 0) == AREA_PV) { ++ dev = seg_dev(seg, 0); ++ if (!dev || dm_list_empty(&dev->aliases)) ++ return NULL; ++ return dev_name(dev); ++ } ++ if (seg_type(seg, 0) == AREA_LV) { ++ dev = seg_dev(first_seg(seg_lv(seg, 0)), 0); ++ if (!dev || dm_list_empty(&dev->aliases)) ++ return NULL; ++ return dev_name(dev); ++ } + } + + return NULL; +diff --git a/lib/metadata/pv_list.c b/lib/metadata/pv_list.c +index 813e8e525..fc3667db0 100644 +--- a/lib/metadata/pv_list.c ++++ b/lib/metadata/pv_list.c +@@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl, + struct pv_list *new_pvl = NULL, *pvl2; + struct dm_list *pe_ranges; + ++ if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) { ++ log_error("Failed to create PV entry for missing device."); ++ return 0; ++ } ++ + pvname = pv_dev_name(pvl->pv); + if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) { + log_warn("WARNING: Physical volume %s not allocatable.", pvname); +diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c +index 85482552a..adc954bab 100644 +--- a/lib/metadata/vg.c ++++ b/lib/metadata/vg.c +@@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, + return r; + } + ++ if (!pv->dev || dm_list_empty(&pv->dev->aliases)) { ++ log_error("No device found for PV."); ++ return r; ++ } ++ + log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv)); + + if (pv_pe_alloc_count(pv)) { +diff --git a/test/shell/losetup-partscan.sh b/test/shell/losetup-partscan.sh +index 99f552ad1..670568945 100644 +--- a/test/shell/losetup-partscan.sh ++++ b/test/shell/losetup-partscan.sh +@@ -33,6 +33,8 @@ aux udev_wait + ls -la "${LOOP}"* + test -e "${LOOP}p1" + ++aux lvmconf 'devices/scan = "/dev"' ++ + aux extend_filter "a|$LOOP|" + aux extend_devices "$LOOP" + +-- +2.34.3 + diff --git a/SOURCES/0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch b/SOURCES/0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch new file mode 100644 index 0000000..49a63fe --- /dev/null +++ b/SOURCES/0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch @@ -0,0 +1,272 @@ +From 932b9720bb074e49ac920642b3fe9c3d84019787 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 28 Feb 2022 17:37:12 -0600 +Subject: [PATCH 39/54] devices: use dev-cache aliases handling from label scan + functions + +The label scan functions where doing some device alias validation +which is now better handled by the dev-cache layer, so just use +that. +--- + lib/device/dev-cache.c | 4 +- + lib/device/dev-cache.h | 1 + + lib/label/label.c | 143 ++++++++++------------------------------- + 3 files changed, 36 insertions(+), 112 deletions(-) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index 58e67e130..b0759b06c 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1410,7 +1410,7 @@ static void _remove_alias(struct device *dev, const char *name) + * deactivated LV. Those old paths are all invalid and are dropped here. + */ + +-static void _verify_aliases(struct device *dev) ++void dev_cache_verify_aliases(struct device *dev) + { + struct dm_str_list *strl, *strl2; + struct stat st; +@@ -1459,7 +1459,7 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, + _remove_alias(dev, name); + + /* Remove any other names in dev->aliases that are incorrect. */ +- _verify_aliases(dev); ++ dev_cache_verify_aliases(dev); + } + return NULL; + } +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 51c3fc6c3..321a56d7b 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -55,6 +55,7 @@ int dev_cache_add_dir(const char *path); + struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f); + struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f); + struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt); ++void dev_cache_verify_aliases(struct device *dev); + + struct device *dev_hash_get(const char *name); + +diff --git a/lib/label/label.c b/lib/label/label.c +index cf707f7a3..06958b502 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -458,7 +458,6 @@ static int _scan_dev_open(struct device *dev) + const char *name; + const char *modestr; + struct stat sbuf; +- int retried = 0; + int flags = 0; + int fd, di; + +@@ -478,14 +477,23 @@ static int _scan_dev_open(struct device *dev) + return 0; + } + ++ next_name: + /* + * All the names for this device (major:minor) are kept on + * dev->aliases, the first one is the primary/preferred name. ++ * ++ * The default name preferences in dev-cache mean that the first ++ * name in dev->aliases is not a symlink for scsi devices, but is ++ * the /dev/mapper/ symlink for mpath devices. ++ * ++ * If preferred names are set to symlinks, should this ++ * first attempt to open using a non-symlink? ++ * ++ * dm_list_first() returns NULL if the list is empty. + */ + if (!(name_list = dm_list_first(&dev->aliases))) { +- /* Shouldn't happen */ +- log_error("Device open %s %d:%d has no path names.", +- dev_name(dev), (int)MAJOR(dev->dev), (int)MINOR(dev->dev)); ++ log_error("Device open %d:%d has no path names.", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev)); + return 0; + } + name_sl = dm_list_item(name_list, struct dm_str_list); +@@ -513,50 +521,34 @@ static int _scan_dev_open(struct device *dev) + modestr = "ro"; + } + +-retry_open: +- + fd = open(name, flags, 0777); +- + if (fd < 0) { + if ((errno == EBUSY) && (flags & O_EXCL)) { + log_error("Can't open %s exclusively. Mounted filesystem?", + dev_name(dev)); ++ return 0; + } else { +- int major, minor; +- + /* +- * Shouldn't happen, if it does, print stat info to help figure +- * out what's wrong. ++ * drop name from dev->aliases and use verify_aliases to ++ * drop any other invalid aliases before retrying open with ++ * any remaining valid paths. + */ +- +- major = (int)MAJOR(dev->dev); +- minor = (int)MINOR(dev->dev); +- +- log_error("Device open %s %d:%d failed errno %d", name, major, minor, errno); +- +- if (stat(name, &sbuf)) { +- log_debug_devs("Device open %s %d:%d stat failed errno %d", +- name, major, minor, errno); +- } else if (sbuf.st_rdev != dev->dev) { +- log_debug_devs("Device open %s %d:%d stat %d:%d does not match.", +- name, major, minor, +- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev)); +- } +- +- if (!retried) { +- /* +- * FIXME: remove this, the theory for this retry is that +- * there may be a udev race that we can sometimes mask by +- * retrying. This is here until we can figure out if it's +- * needed and if so fix the real problem. +- */ +- usleep(5000); +- log_debug_devs("Device open %s retry", dev_name(dev)); +- retried = 1; +- goto retry_open; +- } ++ log_debug("Drop alias for %d:%d failed open %s (%d)", ++ (int)MAJOR(dev->dev), (int)MINOR(dev->dev), name, errno); ++ dev_cache_failed_path(dev, name); ++ dev_cache_verify_aliases(dev); ++ goto next_name; + } +- return 0; ++ } ++ ++ /* Verify that major:minor from the path still match dev. */ ++ if ((fstat(fd, &sbuf) < 0) || (sbuf.st_rdev != dev->dev)) { ++ log_warn("Invalid path %s for device %d:%d, trying different path.", ++ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)); ++ (void)close(fd); ++ dev_cache_failed_path(dev, name); ++ dev_cache_verify_aliases(dev); ++ goto next_name; + } + + dev->flags |= DEV_IN_BCACHE; +@@ -604,37 +596,6 @@ static int _scan_dev_close(struct device *dev) + return 1; + } + +-static void _drop_bad_aliases(struct device *dev) +-{ +- struct dm_str_list *strl, *strl2; +- const char *name; +- struct stat sbuf; +- int major = (int)MAJOR(dev->dev); +- int minor = (int)MINOR(dev->dev); +- int bad; +- +- dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { +- name = strl->str; +- bad = 0; +- +- if (stat(name, &sbuf)) { +- bad = 1; +- log_debug_devs("Device path check %d:%d %s stat failed errno %d", +- major, minor, name, errno); +- } else if (sbuf.st_rdev != dev->dev) { +- bad = 1; +- log_debug_devs("Device path check %d:%d %s stat %d:%d does not match.", +- major, minor, name, +- (int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev)); +- } +- +- if (bad) { +- log_debug_devs("Device path check %d:%d dropping path %s.", major, minor, name); +- dev_cache_failed_path(dev, name); +- } +- } +-} +- + // Like bcache_invalidate, only it throws any dirty data away if the + // write fails. + static void _invalidate_di(struct bcache *cache, int di) +@@ -662,10 +623,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + char headers_buf[HEADERS_BUF_SIZE]; + struct dm_list wait_devs; + struct dm_list done_devs; +- struct dm_list reopen_devs; + struct device_list *devl, *devl2; + struct block *bb; +- int retried_open = 0; + int scan_read_errors = 0; + int scan_process_errors = 0; + int scan_failed_count = 0; +@@ -676,7 +635,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + + dm_list_init(&wait_devs); + dm_list_init(&done_devs); +- dm_list_init(&reopen_devs); + + log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs)); + +@@ -700,9 +658,9 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + + if (!_in_bcache(devl->dev)) { + if (!_scan_dev_open(devl->dev)) { +- log_debug_devs("Scan failed to open %s.", dev_name(devl->dev)); ++ log_debug_devs("Scan failed to open %d:%d %s.", ++ (int)MAJOR(devl->dev->dev), (int)MINOR(devl->dev->dev), dev_name(devl->dev)); + dm_list_del(&devl->list); +- dm_list_add(&reopen_devs, &devl->list); + devl->dev->flags |= DEV_SCAN_NOT_READ; + continue; + } +@@ -786,41 +744,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f, + if (!dm_list_empty(devs)) + goto scan_more; + +- /* +- * We're done scanning all the devs. If we failed to open any of them +- * the first time through, refresh device paths and retry. We failed +- * to open the devs on the reopen_devs list. +- * +- * FIXME: it's not clear if or why this helps. +- */ +- if (!dm_list_empty(&reopen_devs)) { +- if (retried_open) { +- /* Don't try again. */ +- scan_failed_count += dm_list_size(&reopen_devs); +- dm_list_splice(&done_devs, &reopen_devs); +- goto out; +- } +- retried_open = 1; +- +- dm_list_iterate_items_safe(devl, devl2, &reopen_devs) { +- _drop_bad_aliases(devl->dev); +- +- if (dm_list_empty(&devl->dev->aliases)) { +- log_warn("WARNING: Scan ignoring device %d:%d with no paths.", +- (int)MAJOR(devl->dev->dev), +- (int)MINOR(devl->dev->dev)); +- +- dm_list_del(&devl->list); +- lvmcache_del_dev(devl->dev); +- scan_failed_count++; +- } +- } +- +- /* Put devs that failed to open back on the original list to retry. */ +- dm_list_splice(devs, &reopen_devs); +- goto scan_more; +- } +-out: + log_debug_devs("Scanned devices: read errors %d process errors %d failed %d", + scan_read_errors, scan_process_errors, scan_failed_count); + +-- +2.34.3 + diff --git a/SOURCES/0040-writecache-check-memory-usage.patch b/SOURCES/0040-writecache-check-memory-usage.patch new file mode 100644 index 0000000..774e7a7 --- /dev/null +++ b/SOURCES/0040-writecache-check-memory-usage.patch @@ -0,0 +1,101 @@ +From 10a598075a0fdf6d93cc2fefa73fc4a5f1d0de48 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 1 Mar 2022 14:31:39 -0600 +Subject: [PATCH 40/54] writecache: check memory usage + +warn if writecache neds > 50% of system memory, and +confirm if writecache needs > 90% of system memory. +--- + tools/lvconvert.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index 34b82ea02..a90946173 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -6072,6 +6072,69 @@ bad: + return 0; + } + ++static int _check_writecache_memory(struct cmd_context *cmd, struct logical_volume *lv_fast, ++ uint32_t block_size_sectors) ++{ ++ char line[128]; ++ FILE *fp; ++ uint64_t cachevol_size_bytes = lv_fast->size * SECTOR_SIZE; ++ uint64_t need_mem_bytes = 0; ++ uint64_t proc_mem_bytes = 0; ++ uint64_t need_mem_gb; ++ uint64_t proc_mem_gb; ++ unsigned long long proc_mem_kb = 0; ++ ++ if (!(fp = fopen("/proc/meminfo", "r"))) ++ goto skip_proc; ++ ++ while (fgets(line, sizeof(line), fp)) { ++ if (strncmp(line, "MemTotal:", 9)) ++ continue; ++ if (sscanf(line, "%*s%llu%*s", &proc_mem_kb) != 1) ++ break; ++ break; ++ } ++ (void)fclose(fp); ++ ++ proc_mem_bytes = proc_mem_kb * 1024; ++ ++ skip_proc: ++ /* dm-writecache memory consumption per block is 88 bytes */ ++ if (block_size_sectors == 8) { ++ need_mem_bytes = cachevol_size_bytes * 88 / 4096; ++ } else if (block_size_sectors == 1) { ++ need_mem_bytes = cachevol_size_bytes * 88 / 512; ++ } else { ++ /* shouldn't happen */ ++ log_warn("Unknown memory usage for unknown writecache block_size_sectors %u", block_size_sectors); ++ return 1; ++ } ++ ++ need_mem_gb = need_mem_bytes / 1073741824; ++ proc_mem_gb = proc_mem_bytes / 1073741824; ++ ++ /* ++ * warn if writecache needs > 50% of main memory, and ++ * confirm if writecache needs > 90% of main memory. ++ */ ++ if (need_mem_bytes >= (proc_mem_bytes / 2)) { ++ log_warn("WARNING: writecache size %s will use %llu GiB of system memory (%llu GiB).", ++ display_size(cmd, lv_fast->size), ++ (unsigned long long)need_mem_gb, ++ (unsigned long long)proc_mem_gb); ++ ++ if (need_mem_gb >= (proc_mem_gb * 9 / 10)) { ++ if (!arg_is_set(cmd, yes_ARG) && ++ yes_no_prompt("Continue adding writecache? [y/n]: ") == 'n') { ++ log_error("Conversion aborted."); ++ return 0; ++ } ++ } ++ } ++ ++ return 1; ++} ++ + int lvconvert_writecache_attach_single(struct cmd_context *cmd, + struct logical_volume *lv, + struct processing_handle *handle) +@@ -6160,6 +6223,12 @@ int lvconvert_writecache_attach_single(struct cmd_context *cmd, + goto_bad; + } + ++ if (!_check_writecache_memory(cmd, lv_fast, block_size_sectors)) { ++ if (!is_active && !deactivate_lv(cmd, lv)) ++ stack; ++ goto_bad; ++ } ++ + if (!is_active) { + if (!deactivate_lv(cmd, lv)) { + log_error("Failed to deactivate LV after checking block size %s", display_lvname(lv)); +-- +2.34.3 + diff --git a/SOURCES/0041-change-messages-about-filtered-devices.patch b/SOURCES/0041-change-messages-about-filtered-devices.patch new file mode 100644 index 0000000..e1b7aa0 --- /dev/null +++ b/SOURCES/0041-change-messages-about-filtered-devices.patch @@ -0,0 +1,108 @@ +From 090dc0c320f0abee8ab79f4eaea6561c195b5009 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 31 Mar 2022 11:38:08 -0500 +Subject: [PATCH 41/54] change messages about filtered devices + +Change messages that refer to devices being "excluded by filters" +to say just "excluded". This will avoid mistaking the word +"filters" with the lvm.conf filter setting. +--- + lib/device/device_id.c | 6 +++--- + tools/lvmdevices.c | 4 ++-- + tools/pvscan.c | 4 ++-- + tools/vgimportclone.c | 4 ++-- + 4 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 82db6e4a5..6133e700a 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1744,7 +1744,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + * probably wants to do something about it. + */ + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { +- log_warn("Devices file %s is excluded by filter: %s.", ++ log_warn("Devices file %s is excluded: %s.", + dev_name(dev), dev_filtered_reason(dev)); + continue; + } +@@ -1830,7 +1830,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + continue; + + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { +- log_warn("Devices file %s is excluded by filter: %s.", ++ log_warn("Devices file %s is excluded: %s.", + dev_name(dev), dev_filtered_reason(dev)); + /* FIXME: what if this dev is wrongly matched and should be checked below? */ + continue; +@@ -2266,7 +2266,7 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l + + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) { + /* I don't think this would happen */ +- log_warn("WARNING: new device %s for PVID %s does not pass filter %s.", ++ log_warn("WARNING: new device %s for PVID %s is excluded: %s.", + dev_name(dev), dil->pvid, dev_filtered_reason(dev)); + if (du) /* Should not happen 'du' is NULL */ + du->dev = NULL; +diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c +index 662b35f9a..8521b89ea 100644 +--- a/tools/lvmdevices.c ++++ b/tools/lvmdevices.c +@@ -112,7 +112,7 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear + dev = devl->dev; + cmd->filter->wipe(cmd, cmd->filter, dev, NULL); + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) { +- log_warn("WARNING: PVID %s found on %s which is excluded by filter: %s", ++ log_warn("WARNING: PVID %s found on %s which is excluded: %s", + dev->pvid, dev_name(dev), dev_filtered_reason(dev)); + dm_list_del(&devl->list); + } +@@ -310,7 +310,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv) + cmd->filter_deviceid_skip = 1; + + if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) { +- log_warn("WARNING: adding device %s that is excluded by filter: %s.", ++ log_warn("WARNING: adding device %s that is excluded: %s.", + dev_name(dev), dev_filtered_reason(dev)); + } + +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 160a2c9a0..50d46051a 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -1756,7 +1756,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv, + + dm_list_iterate_items_safe(devl, devl2, &pvscan_devs) { + if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) { +- log_print_pvscan(cmd, "%s excluded by filters: %s.", ++ log_print_pvscan(cmd, "%s excluded: %s.", + dev_name(devl->dev), dev_filtered_reason(devl->dev)); + dm_list_del(&devl->list); + } +@@ -1813,7 +1813,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv, + + /* Applies all filters, including those that need data from dev. */ + if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) { +- log_print_pvscan(cmd, "%s excluded by filters: %s.", ++ log_print_pvscan(cmd, "%s excluded: %s.", + dev_name(devl->dev), dev_filtered_reason(devl->dev)); + dm_list_del(&devl->list); + } +diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c +index 23bb6271f..cab501619 100644 +--- a/tools/vgimportclone.c ++++ b/tools/vgimportclone.c +@@ -311,8 +311,8 @@ int vgimportclone(struct cmd_context *cmd, int argc, char **argv) + */ + dm_list_iterate_items(devl, &vp.new_devs) { + if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, "persistent")) { +- /* FIXME: print which filter */ +- log_error("Device %s was excluded by filters.", dev_name(devl->dev)); ++ log_error("Device %s is excluded: %s.", ++ dev_name(devl->dev), dev_filtered_reason(devl->dev)); + goto out; + } + } +-- +2.34.3 + diff --git a/SOURCES/0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch b/SOURCES/0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch new file mode 100644 index 0000000..fbf6ee7 --- /dev/null +++ b/SOURCES/0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch @@ -0,0 +1,31 @@ +From 4aa92f3e18cb49470ee9b5d928abe6b4c86f3074 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 6 Apr 2022 12:20:26 -0500 +Subject: [PATCH 42/54] vgimportdevices: fix incorrect deviceidtype usage + +When a VG has PVs with different device id types, +it would try to use the idtype of the previous PV +in the loop. This would produce an unncessary warning, +or could lead to using the devname idtype when a better +idtype is available. +--- + tools/vgimportdevices.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index 2580613c4..ea205d941 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -57,8 +57,7 @@ static int _vgimportdevices_single(struct cmd_context *cmd, + dm_list_iterate_items(pvl, &vg->pvs) { + pv = pvl->pv; + +- if (!idtypestr && pv->device_id_type) +- idtypestr = pv->device_id_type; ++ idtypestr = pv->device_id_type; + + memcpy(pvid, &pvl->pv->id.uuid, ID_LEN); + device_id_add(cmd, pv->dev, pvid, idtypestr, NULL); +-- +2.34.3 + diff --git a/SOURCES/0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch b/SOURCES/0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch new file mode 100644 index 0000000..f67d1a5 --- /dev/null +++ b/SOURCES/0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch @@ -0,0 +1,32 @@ +From 6de2a6a378a7673168fad34aebe8ddcb564a5911 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 8 Apr 2022 11:28:53 -0500 +Subject: [PATCH 43/54] lvmlockd: return error from vgcreate init_vg_sanlock + +in vgcreate for shared sanlock vg, if sanlock_write_resource +returns an unexpected error, then make init_vg_sanlock fail +which will cause the vgcreate to fail. +--- + daemons/lvmlockd/lvmlockd-sanlock.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c +index e595eeffd..d87d1093b 100644 +--- a/daemons/lvmlockd/lvmlockd-sanlock.c ++++ b/daemons/lvmlockd/lvmlockd-sanlock.c +@@ -684,10 +684,10 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar + break; + } + +- if (rv) { ++ if (rv < 0) { + log_error("clear lv resource area %llu error %d", + (unsigned long long)offset, rv); +- break; ++ return rv; + } + offset += align_size; + } +-- +2.34.3 + diff --git a/SOURCES/0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch b/SOURCES/0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch new file mode 100644 index 0000000..8009d2f --- /dev/null +++ b/SOURCES/0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch @@ -0,0 +1,45 @@ +From d96432835532fbcd8c72694c6ed68fca3ce98d5c Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 13 Apr 2022 12:16:57 -0500 +Subject: [PATCH 44/54] devices file: remove extraneous unlock in vgchange -u + +vgchange -u exit path was unlocking the devices file in cases +when it wasn't needed, which produced an warning. +--- + lib/device/device_id.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 6133e700a..20901ab90 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1272,15 +1272,15 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, + int update = 0; + + if (!cmd->enable_devices_file) +- goto out; ++ return; + + /* Without this setting there is no stacking LVs on PVs. */ + if (!cmd->scan_lvs) +- goto out; ++ return; + + /* Check if any devices file entries are stacked on LVs. */ + if (!_device_ids_use_lvmlv(cmd)) +- goto out; ++ return; + + memcpy(old_vgid, old_vg_id, ID_LEN); + memcpy(new_vgid, &vg->id, ID_LEN); +@@ -1310,7 +1310,6 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, + if (update && + !device_ids_write(cmd)) + stack; +- out: + unlock_devices_file(cmd); + } + +-- +2.34.3 + diff --git a/SOURCES/0045-filter-mpath-use-multipath-blacklist.patch b/SOURCES/0045-filter-mpath-use-multipath-blacklist.patch new file mode 100644 index 0000000..c2f921a --- /dev/null +++ b/SOURCES/0045-filter-mpath-use-multipath-blacklist.patch @@ -0,0 +1,458 @@ +From 5d40b91bd4aa8580ee1f40d467b848f7847f39e3 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 21 Apr 2022 13:45:01 -0500 +Subject: [PATCH 45/54] filter-mpath: use multipath blacklist + +Explicit wwid's from these sections control whether the +same wwid in /etc/multipath/wwids is recognized as a +multipath component. Other non-wwid keywords are not +used, and may require disabling the use of the multipath +wwids file in lvm.conf. +--- + lib/device/dev-mpath.c | 181 ++++++++++++++++++++++++-- + test/shell/duplicate-pvs-multipath.sh | 2 +- + test/shell/multipath-config.sh | 171 ++++++++++++++++++++++++ + 3 files changed, 342 insertions(+), 12 deletions(-) + create mode 100644 test/shell/multipath-config.sh + +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index cbbad9dc9..6eed03c5b 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -17,12 +17,14 @@ + #include "lib/activate/activate.h" + #include "lib/commands/toolcontext.h" + #include "lib/device/device_id.h" ++#include "lib/datastruct/str_list.h" + #ifdef UDEV_SYNC_SUPPORT + #include + #include "lib/device/dev-ext-udev-constants.h" + #endif + + #include ++#include + + #define MPATH_PREFIX "mpath-" + +@@ -35,15 +37,167 @@ + * If dm-3 is not an mpath device, then the constant "1" is stored in + * the hash table with the key of the dm minor number. + */ +-static struct dm_pool *_hash_mem; ++static struct dm_pool *_wwid_mem; + static struct dm_hash_table *_minor_hash_tab; + static struct dm_hash_table *_wwid_hash_tab; ++static struct dm_list _ignored; ++static struct dm_list _ignored_exceptions; + + #define MAX_WWID_LINE 512 + +-/* +- * do we need to check the multipath.conf blacklist? +- */ ++static void _read_blacklist_file(const char *path) ++{ ++ FILE *fp; ++ char line[MAX_WWID_LINE]; ++ char wwid[MAX_WWID_LINE]; ++ char *word, *p; ++ int section_black = 0; ++ int section_exceptions = 0; ++ int found_quote; ++ int found_three; ++ int i, j; ++ ++ if (!(fp = fopen(path, "r"))) ++ return; ++ ++ while (fgets(line, sizeof(line), fp)) { ++ word = NULL; ++ ++ /* skip initial white space on the line */ ++ for (i = 0; i < MAX_WWID_LINE; i++) { ++ if ((line[i] == '\n') || (line[i] == '\0')) ++ break; ++ if (isspace(line[i])) ++ continue; ++ word = &line[i]; ++ break; ++ } ++ ++ if (!word || word[0] == '#') ++ continue; ++ ++ /* identify the start of the section we want to read */ ++ if (strchr(word, '{')) { ++ if (!strncmp(word, "blacklist_exceptions", 20)) ++ section_exceptions = 1; ++ else if (!strncmp(word, "blacklist", 9)) ++ section_black = 1; ++ continue; ++ } ++ /* identify the end of the section we've been reading */ ++ if (strchr(word, '}')) { ++ section_exceptions = 0; ++ section_black = 0; ++ continue; ++ } ++ /* skip lines that are not in a section we want */ ++ if (!section_black && !section_exceptions) ++ continue; ++ ++ /* ++ * read a wwid from the blacklist{_exceptions} section. ++ * does not recognize other non-wwid entries in the ++ * section, and skips those (should the entire mp ++ * config filtering be disabled if non-wwids are seen? ++ */ ++ if (!(p = strstr(word, "wwid"))) ++ continue; ++ ++ i += 4; /* skip "wwid" */ ++ ++ /* ++ * copy wwid value from the line. ++ * the wwids copied here need to match the ++ * wwids read from /etc/multipath/wwids, ++ * which are matched to wwids from sysfs. ++ */ ++ ++ memset(wwid, 0, sizeof(wwid)); ++ found_quote = 0; ++ found_three = 0; ++ j = 0; ++ ++ for (; i < MAX_WWID_LINE; i++) { ++ if ((line[i] == '\n') || (line[i] == '\0')) ++ break; ++ if (!j && isspace(line[i])) ++ continue; ++ if (isspace(line[i])) ++ break; ++ /* quotes around wwid are optional */ ++ if ((line[i] == '"') && !found_quote) { ++ found_quote = 1; ++ continue; ++ } ++ /* second quote is end of wwid */ ++ if ((line[i] == '"') && found_quote) ++ break; ++ /* ignore first "3" in wwid */ ++ if ((line[i] == '3') && !found_three) { ++ found_three = 1; ++ continue; ++ } ++ ++ wwid[j] = line[i]; ++ j++; ++ } ++ ++ if (j < 8) ++ continue; ++ ++ log_debug("multipath wwid %s in %s %s", ++ wwid, section_exceptions ? "blacklist_exceptions" : "blacklist", path); ++ ++ if (section_exceptions) { ++ if (!str_list_add(_wwid_mem, &_ignored_exceptions, dm_pool_strdup(_wwid_mem, wwid))) ++ stack; ++ } else { ++ if (!str_list_add(_wwid_mem, &_ignored, dm_pool_strdup(_wwid_mem, wwid))) ++ stack; ++ } ++ } ++ ++ if (fclose(fp)) ++ stack; ++} ++ ++static void _read_wwid_exclusions(void) ++{ ++ char path[PATH_MAX] = { 0 }; ++ DIR *dir; ++ struct dirent *de; ++ struct dm_str_list *sl, *sl2; ++ int rem_count = 0; ++ ++ _read_blacklist_file("/etc/multipath.conf"); ++ ++ if ((dir = opendir("/etc/multipath/conf.d"))) { ++ while ((de = readdir(dir))) { ++ if (de->d_name[0] == '.') ++ continue; ++ snprintf(path, PATH_MAX-1, "/etc/multipath/conf.d/%s", de->d_name); ++ _read_blacklist_file(path); ++ } ++ closedir(dir); ++ } ++ ++ /* for each wwid in ignored_exceptions, remove it from ignored */ ++ ++ dm_list_iterate_items_safe(sl, sl2, &_ignored) { ++ if (str_list_match_item(&_ignored_exceptions, sl->str)) ++ str_list_del(&_ignored, sl->str); ++ } ++ ++ /* for each wwid in ignored, remove it from wwid_hash */ ++ ++ dm_list_iterate_items(sl, &_ignored) { ++ dm_hash_remove_binary(_wwid_hash_tab, sl->str, strlen(sl->str)); ++ rem_count++; ++ } ++ ++ if (rem_count) ++ log_debug("multipath config ignored %d wwids", rem_count); ++} + + static void _read_wwid_file(const char *config_wwids_file) + { +@@ -93,6 +247,9 @@ int dev_mpath_init(const char *config_wwids_file) + struct dm_hash_table *minor_tab; + struct dm_hash_table *wwid_tab; + ++ dm_list_init(&_ignored); ++ dm_list_init(&_ignored_exceptions); ++ + if (!(mem = dm_pool_create("mpath", 256))) { + log_error("mpath pool creation failed."); + return 0; +@@ -104,7 +261,7 @@ int dev_mpath_init(const char *config_wwids_file) + return 0; + } + +- _hash_mem = mem; ++ _wwid_mem = mem; + _minor_hash_tab = minor_tab; + + /* multipath_wwids_file="" disables the use of the file */ +@@ -116,16 +273,18 @@ int dev_mpath_init(const char *config_wwids_file) + if (!(wwid_tab = dm_hash_create(110))) { + log_error("mpath hash table creation failed."); + dm_hash_destroy(_minor_hash_tab); +- dm_pool_destroy(_hash_mem); ++ dm_pool_destroy(_wwid_mem); + _minor_hash_tab = NULL; +- _hash_mem = NULL; ++ _wwid_mem = NULL; + return 0; + } + + _wwid_hash_tab = wwid_tab; + +- if (config_wwids_file) ++ if (config_wwids_file) { + _read_wwid_file(config_wwids_file); ++ _read_wwid_exclusions(); ++ } + + return 1; + } +@@ -136,12 +295,12 @@ void dev_mpath_exit(void) + dm_hash_destroy(_minor_hash_tab); + if (_wwid_hash_tab) + dm_hash_destroy(_wwid_hash_tab); +- if (_hash_mem) +- dm_pool_destroy(_hash_mem); ++ if (_wwid_mem) ++ dm_pool_destroy(_wwid_mem); + + _minor_hash_tab = NULL; + _wwid_hash_tab = NULL; +- _hash_mem = NULL; ++ _wwid_mem = NULL; + } + + +diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh +index a145e4afb..59c15b0d4 100644 +--- a/test/shell/duplicate-pvs-multipath.sh ++++ b/test/shell/duplicate-pvs-multipath.sh +@@ -10,7 +10,7 @@ + # along with this program; if not, write to the Free Software Foundation, + # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +-test_description='udev rule and systemd unit run vgchange' ++test_description='duplicate pv detection of mpath components using wwid' + + SKIP_WITH_LVMPOLLD=1 + SKIP_WITH_LVMLOCKD=1 +diff --git a/test/shell/multipath-config.sh b/test/shell/multipath-config.sh +new file mode 100644 +index 000000000..ffb7d632a +--- /dev/null ++++ b/test/shell/multipath-config.sh +@@ -0,0 +1,171 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2021 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++test_description='using multipath blacklist' ++ ++SKIP_WITH_LVMPOLLD=1 ++SKIP_WITH_LVMLOCKD=1 ++ ++. lib/inittest ++ ++# FIXME: don't run this test by default because it destroys the ++# local multipath config, the timing of multipath/dm/lvm interactions ++# is fragile, and there's insufficient cleanup after a test fails. ++skip ++ ++systemctl stop multipathd ++multipath -F || true ++rm /etc/multipath/wwids || true ++rmmod scsi_debug || true ++rm /etc/multipath/conf.d/lvmtest.conf || true ++ ++modprobe --dry-run scsi_debug || skip ++multipath -l || skip ++multipath -l | grep scsi_debug && skip ++ls /etc/multipath/wwids && skip ++ ++# Need to use /dev/mapper/mpath ++aux lvmconf 'devices/dir = "/dev"' ++aux lvmconf 'devices/scan = "/dev"' ++# Could set filter to $MP and the component /dev/sd devs ++aux lvmconf "devices/filter = [ \"a|.*|\" ]" ++aux lvmconf "devices/global_filter = [ \"a|.*|\" ]" ++ ++modprobe scsi_debug dev_size_mb=16 num_tgts=1 ++sleep 2 ++ ++# Get scsi device name created by scsi_debug. ++# SD = sdh ++# SD_DEV = /dev/sdh ++ ++SD=$(grep -H scsi_debug /sys/block/sd*/device/model | cut -f4 -d /); ++echo $SD ++SD_DEV=/dev/$SD ++echo $SD_DEV ++ ++# if multipath claimed SD, then io will fail ++#dd if=$SD_DEV of=/dev/null bs=4k count=1 iflag=direct ++#dd if=/dev/zero of=$SD_DEV bs=4k count=1 oflag=direct ++ ++# check if multipathd claimed the scsi dev when it appears and create mp dm device ++sleep 2 ++multipath -l ++# create the mp dm device ++multipath $SD_DEV ++ ++# Get mpath device name created by multipath. ++# MP = mpatha ++# MP_DEV = /dev/maper/mpatha ++ ++MP=$(multipath -l | grep scsi_debug | cut -f1 -d ' ') ++echo $MP ++MP_DEV=/dev/mapper/$MP ++echo $MP_DEV ++ ++dd if=$MP_DEV of=/dev/null bs=4k count=1 iflag=direct ++dd if=/dev/zero of=$MP_DEV bs=4k count=1 oflag=direct ++ ++# Get wwid for the mp and sd dev. ++WWID=$(multipath -l $MP_DEV | head -1 | awk '{print $2}' | tr -d ')' | tr -d '(') ++echo $WWID ++ ++grep $WWID /etc/multipath/wwids ++ ++pvcreate $MP_DEV ++vgcreate $vg1 $MP_DEV ++ ++not pvs $SD_DEV ++pvs $MP_DEV ++ ++# remove mpath dm device then check that SD_DEV is ++# filtered based on /etc/multipath/wwids instead of ++# based on sysfs holder ++multipath -f $MP ++sleep 2 ++not pvs $SD_DEV ++multipath $SD_DEV ++sleep 2 ++multipath -l | grep $SD ++ ++# ++# Add the wwid to the blacklist, then restart multipath ++# so the sd dev should no longer be used by multipath, ++# but the sd dev wwid is still in /etc/multipath/wwids. ++# ++ ++mkdir /etc/multipath/conf.d/ || true ++rm -f /etc/multipath/conf.d/lvmtest.conf ++ ++cat < "/etc/multipath/conf.d/lvmtest.conf" ++blacklist { ++ wwid $WWID ++} ++EOF ++ ++cat /etc/multipath/conf.d/lvmtest.conf ++ ++multipath -r ++sleep 2 ++ ++grep $WWID /etc/multipath/wwids ++ ++multipath -l |tee out ++not grep $SD out ++not grep $MP out ++not grep $WWID out ++ ++not pvs $MP_DEV ++pvs $SD_DEV ++vgs $vg1 ++ ++# ++# Add the wwid to the blacklist_exceptions, in addition ++# to the blacklist, then restart multipath so the ++# sd dev should again be used by multipath. ++# ++ ++rm -f /etc/multipath/conf.d/lvmtest.conf ++ ++cat < "/etc/multipath/conf.d/lvmtest.conf" ++blacklist { ++wwid $WWID ++} ++blacklist_exceptions { ++wwid $WWID ++} ++EOF ++ ++cat /etc/multipath/conf.d/lvmtest.conf ++ ++multipath -r ++sleep 2 ++ ++grep $WWID /etc/multipath/wwids ++ ++multipath -l |tee out ++grep $SD out ++grep $MP out ++grep $WWID out ++ ++pvs $MP_DEV ++not pvs $SD_DEV ++vgs $vg1 ++lvs $vg1 ++ ++sleep 2 ++vgremove -ff $vg1 ++sleep 2 ++multipath -f $MP ++rm /etc/multipath/conf.d/lvmtest.conf ++rm /etc/multipath/wwids ++sleep 1 ++rmmod scsi_debug +-- +2.34.3 + diff --git a/SOURCES/0046-improve-description-of-devices-option.patch b/SOURCES/0046-improve-description-of-devices-option.patch new file mode 100644 index 0000000..3ec4a9e --- /dev/null +++ b/SOURCES/0046-improve-description-of-devices-option.patch @@ -0,0 +1,28 @@ +From e027f4da9bc7b4ed9b225af75089e3443595bf81 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 2 May 2022 09:46:28 -0500 +Subject: [PATCH 46/54] improve description of devices option + +--- + tools/args.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/args.h b/tools/args.h +index 9a7bf81b2..00a2ec817 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -235,8 +235,9 @@ arg(deviceidtype_ARG, '\0', "deviceidtype", string_VAL, 0, 0, + "then it will override the default type that lvm would use.\n") + + arg(devices_ARG, '\0', "devices", pv_VAL, ARG_GROUPABLE, 0, +- "Devices that the command can use. This option can be repeated\n" +- "or accepts a comma separated list of devices. This overrides\n" ++ "Restricts the devices that are visible and accessible to the command.\n" ++ "Devices not listed will appear to be missing. This option can be\n" ++ "repeated, or accepts a comma separated list of devices. This overrides\n" + "the devices file.\n") + + arg(devicesfile_ARG, '\0', "devicesfile", string_VAL, 0, 0, +-- +2.34.3 + diff --git a/SOURCES/0047-vdo-support-vdosettings.patch b/SOURCES/0047-vdo-support-vdosettings.patch new file mode 100644 index 0000000..e6d91f3 --- /dev/null +++ b/SOURCES/0047-vdo-support-vdosettings.patch @@ -0,0 +1,576 @@ +From 9c6954bc61b22ca03df8897d88eb9618e65fc3c6 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 13 Apr 2022 15:09:08 +0200 +Subject: [PATCH 47/54] vdo: support --vdosettings + +Allow to use --vdosettings with lvcreate,lvconvert,lvchange. +Support settings currenly only configurable via lvm.conf. +With lvchange we require inactivate LV for changes to be applied. + +Settings block_map_era_length has supported alias block_map_period. +--- + device_mapper/vdo/target.h | 6 +- + man/lvmvdo.7_main | 39 ++++++-- + test/shell/lvchange-vdo.sh | 8 ++ + test/shell/lvconvert-vdo.sh | 8 +- + test/shell/lvcreate-vdo.sh | 6 +- + tools/args.h | 9 ++ + tools/command-lines.in | 6 +- + tools/lvchange.c | 43 ++++++++- + tools/lvconvert.c | 9 +- + tools/lvcreate.c | 34 ++++--- + tools/toollib.c | 177 ++++++++++++++++++++++++++++++++++++ + tools/toollib.h | 6 ++ + 12 files changed, 312 insertions(+), 39 deletions(-) + +diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h +index 51dde3f4d..60c5bff56 100644 +--- a/device_mapper/vdo/target.h ++++ b/device_mapper/vdo/target.h +@@ -77,8 +77,10 @@ enum dm_vdo_write_policy { + struct dm_vdo_target_params { + uint32_t minimum_io_size; // in sectors + uint32_t block_map_cache_size_mb; +- uint32_t block_map_era_length; // format period +- ++ union { ++ uint32_t block_map_era_length; // format period ++ uint32_t block_map_period; // supported alias ++ }; + uint32_t check_point_frequency; + uint32_t index_memory_size_mb; // format + +diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main +index 3b77173c4..14bd640b5 100644 +--- a/man/lvmvdo.7_main ++++ b/man/lvmvdo.7_main +@@ -132,6 +132,19 @@ that can keep 100% incompressible data there. + # lvconvert --type vdo-pool -n vdo0 -V10G vg/ExistingLV + .fi + . ++.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV ++. ++Disable or enable the compression and deduplication for VDOPoolLV ++(the volume that maintains all VDO LV(s) associated with it). ++.P ++.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV ++.P ++.I Example ++.nf ++# lvchange --compression n vg/vdopool0 ++# lvchange --deduplication y vg/vdopool1 ++.fi ++. + .SS \n+[step]. Change the default settings used for creating a VDOPoolLV + . + VDO allows to set a large variety of options. Lots of these settings +@@ -173,17 +186,27 @@ EOF + # lvcreate --vdo -L10G --config 'allocation/vdo_cpu_threads=4' vg/vdopool1 + .fi + . +-.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV +-. +-Disable or enable the compression and deduplication for VDOPoolLV +-(the volume that maintains all VDO LV(s) associated with it). +-.P +-.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV ++.SS \n+[step]. Set or change VDO settings with option --vdosettings ++. ++Use the form 'option=value' or 'option1=value option2=value', ++or repeat --vdosettings for each option being set. ++Options are listed in the Example section above, for the full description see ++.BR lvm.conf (5). ++Options can omit 'vdo_' and 'vdo_use_' prefixes and all its underscores. ++So i.e. vdo_use_metadata_hints=1 and metadatahints=1 are equivalent. ++To change the option for an already existing VDOPoolLV use ++.BR lvchange (8) ++command. However not all option can be changed. ++Only compression and deduplication options can be also changed for an active VDO LV. ++Lowest priority options are specified with configuration file, ++then with --vdosettings and highest are expliction option --compression ++and --deduplication. + .P + .I Example ++.P + .nf +-# lvchange --compression n vg/vdopool0 +-# lvchange --deduplication y vg/vdopool1 ++# lvcreate --vdo -L10G --vdosettings 'ack_threads=1 hash_zone_threads=2' vg/vdopool0 ++# lvchange --vdosettings 'bio_threads=2 deduplication=1' vg/vdopool0 + .fi + . + .SS \n+[step]. Checking the usage of VDOPoolLV +diff --git a/test/shell/lvchange-vdo.sh b/test/shell/lvchange-vdo.sh +index 461b7821f..7cc44d6bc 100644 +--- a/test/shell/lvchange-vdo.sh ++++ b/test/shell/lvchange-vdo.sh +@@ -48,9 +48,17 @@ check grep_dmsetup status $vg-vdopool-vpool " online online " + lvchange --compression n --deduplication n $vg/vdopool + check grep_dmsetup status $vg-vdopool-vpool " offline offline " + ++# --vdosettings needs inactive LV ++not lvchange --vdosettings 'ack_threads=8' $vg/vdopool + + lvchange -an $vg/$lv1 + ++# With inactive vdo-pool changes are applied ++# explicit option --compression has highest priority ++lvchange --vdosettings 'ack_threads=5 compression=0' --compression y $vg/vdopool ++check lv_field $vg/$lv1 vdo_ack_threads "5" ++check lv_field $vg/$lv1 vdo_compression "enabled" ++ + # Test activation + lvchange -aly $vg/$lv1 + check active $vg $lv1 +diff --git a/test/shell/lvconvert-vdo.sh b/test/shell/lvconvert-vdo.sh +index 529f325bd..c42d8f25a 100644 +--- a/test/shell/lvconvert-vdo.sh ++++ b/test/shell/lvconvert-vdo.sh +@@ -28,12 +28,12 @@ lvcreate -L5G -n $lv1 $vg + not lvconvert --type vdo-pool $vg/$lv1 |& tee out + grep "WARNING" out + +- +-lvconvert -y --type vdo-pool $vg/$lv1 ++# Check --vdosettings is also applied to converted vdo-pool ++lvconvert -y --type vdo-pool --vdosettings 'ack_threads=5' $vg/$lv1 ++check lv_field $vg/$lv1 vdo_ack_threads "5" + lvremove -f $vg + +- +-# ++# + lvcreate -L5G -n $lv1 $vg + lvconvert -y --vdopool $vg/$lv1 + lvremove -f $vg +diff --git a/test/shell/lvcreate-vdo.sh b/test/shell/lvcreate-vdo.sh +index 44f8bf094..3e807ac94 100644 +--- a/test/shell/lvcreate-vdo.sh ++++ b/test/shell/lvcreate-vdo.sh +@@ -79,8 +79,12 @@ not fsck -n "$DM_DEV_DIR/mapper/$vg-${lv2}" + + lvremove -ff $vg + ++# Unknown settings does not pass ++# TODO: try to catch this in parser and 'fail' ++not lvcreate --type vdo --vdosettings 'ack_Xthreads=4' -L10G -V1T -ky -n $lv1 $vg + +-lvcreate --type vdo -L10G -V1T -ky -n $lv1 $vg ++lvcreate --type vdo --vdosettings 'ack_threads=4' -L10G -V1T -ky -n $lv1 $vg ++check lv_field $vg/$lv1 vdo_ack_threads "4" + lvs -a $vg + lvremove -ff $vg + +diff --git a/tools/args.h b/tools/args.h +index 00a2ec817..bfd848ce9 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -900,6 +900,15 @@ arg(vdopool_ARG, '\0', "vdopool", lv_VAL, 0, 0, + "The name of a VDO pool LV.\n" + "See \\fBlvmvdo\\fP(7) for more information about VDO usage.\n") + ++arg(vdosettings_ARG, '\0', "vdosettings", string_VAL, ARG_GROUPABLE, 0, ++ "Specifies tunable VDO options for VDO LVs.\n" ++ "Use the form 'option=value' or 'option1=value option2=value', or\n" ++ "repeat --vdosettings for each option being set.\n" ++ "These settings override the default VDO behaviors.\n" ++ "To remove vdosettings and revert to the default\n" ++ "VDO behaviors, use --vdosettings 'default'.\n" ++ "See \\fBlvmvdo\\fP(7) for more information.\n") ++ + arg(version_ARG, '\0', "version", 0, 0, 0, + "Display version information.\n") + +diff --git a/tools/command-lines.in b/tools/command-lines.in +index 00ac08934..08302b34f 100644 +--- a/tools/command-lines.in ++++ b/tools/command-lines.in +@@ -243,6 +243,7 @@ OO_LVCHANGE_META: --addtag Tag, --deltag Tag, + --setautoactivation Bool, --errorwhenfull Bool, --discards Discards, --zero Bool, + --cachemode CacheMode, --cachepolicy String, --cachesettings String, + --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB, ++--vdosettings String, + --writebehind Number, --writemostly WriteMostlyPV, --persistent n + + # It's unfortunate that activate needs to be optionally allowed here; +@@ -341,7 +342,8 @@ OO_LVCONVERT_CACHE: --cachemetadataformat CacheMetadataFormat, + --cachesettings String, --zero Bool + + OO_LVCONVERT_VDO: --metadataprofile String, --readahead Readahead, +---compression Bool, --deduplication Bool, --zero Bool ++--compression Bool, --deduplication Bool, --vdosettings String, ++--zero Bool + + OO_LVCONVERT: --alloc Alloc, --background, --force, --noudevsync + +@@ -839,7 +841,7 @@ OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksi + + OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool + +-OO_LVCREATE_VDO: --compression Bool, --deduplication Bool ++OO_LVCREATE_VDO: --compression Bool, --deduplication Bool, --vdosettings String + --- + + lvcreate --type error --size SizeMB VG +diff --git a/tools/lvchange.c b/tools/lvchange.c +index 0525bc53c..dc51786d7 100644 +--- a/tools/lvchange.c ++++ b/tools/lvchange.c +@@ -755,6 +755,43 @@ out: + return r; + } + ++static int _lvchange_vdo(struct cmd_context *cmd, ++ struct logical_volume *lv, ++ uint32_t *mr) ++{ ++ struct lv_segment *seg; ++ int updated = 0; ++ ++ seg = first_seg(lv); ++ ++ // With VDO LV given flip to VDO pool ++ if (seg_is_vdo(seg)) ++ seg = first_seg(seg_lv(seg, 0)); ++ ++ if (!get_vdo_settings(cmd, &seg->vdo_params, &updated)) ++ return_0; ++ ++ if ((updated & VDO_CHANGE_OFFLINE) && ++ lv_info(cmd, seg->lv, 1, NULL, 0, 0)) { ++ log_error("Cannot change VDO settings for active VDO pool %s.", ++ display_lvname(seg->lv)); ++ // TODO maybe add --force support with prompt here ++ log_print_unless_silent("VDO pool %s with all its LVs needs to be deactivated.", ++ display_lvname(seg->lv)); ++ return 0; ++ } ++ ++ if (updated) { ++ if (!dm_vdo_validate_target_params(&seg->vdo_params, 0 /* vdo_size */)) ++ return_0; ++ ++ /* Request caller to commit and reload metadata */ ++ *mr |= MR_RELOAD; ++ } ++ ++ return 1; ++} ++ + static int _lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv, + int arg, uint32_t *mr) + { +@@ -1154,6 +1191,7 @@ static int _option_requires_direct_commit(int opt_enum) + cachemode_ARG, + cachepolicy_ARG, + cachesettings_ARG, ++ vdosettings_ARG, + -1 + }; + +@@ -1354,7 +1392,10 @@ static int _lvchange_properties_single(struct cmd_context *cmd, + docmds++; + doit += _lvchange_cache(cmd, lv, &mr); + break; +- ++ case vdosettings_ARG: ++ docmds++; ++ doit += _lvchange_vdo(cmd, lv, &mr); ++ break; + default: + log_error(INTERNAL_ERROR "Failed to check for option %s", + arg_long_option_name(i)); +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index a90946173..3d4b24fe3 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -5456,13 +5456,8 @@ static int _lvconvert_to_vdopool_single(struct cmd_context *cmd, + if (!fill_vdo_target_params(cmd, &vdo_params, &vdo_pool_header_size, vg->profile)) + goto_out; + +- if (arg_is_set(cmd, compression_ARG)) +- vdo_params.use_compression = +- arg_int_value(cmd, compression_ARG, 0); +- +- if (arg_is_set(cmd, deduplication_ARG)) +- vdo_params.use_deduplication = +- arg_int_value(cmd, deduplication_ARG, 0); ++ if (!get_vdo_settings(cmd, &vdo_params, NULL)) ++ return_0; + + if (!activate_lv(cmd, lv)) { + log_error("Cannot activate %s.", display_lvname(lv)); +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index 79af42685..8de6f3408 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -698,6 +698,23 @@ static int _read_cache_params(struct cmd_context *cmd, + return 1; + } + ++static int _read_vdo_params(struct cmd_context *cmd, ++ struct lvcreate_params *lp) ++{ ++ if (!seg_is_vdo(lp)) ++ return 1; ++ ++ // prefiling settings here ++ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL)) ++ return_0; ++ ++ // override with optional vdo settings ++ if (!get_vdo_settings(cmd, &lp->vdo_params, NULL)) ++ return_0; ++ ++ return 1; ++} ++ + static int _read_activation_params(struct cmd_context *cmd, + struct volume_group *vg, + struct lvcreate_params *lp) +@@ -888,7 +905,8 @@ static int _lvcreate_params(struct cmd_context *cmd, + #define VDO_POOL_ARGS \ + vdopool_ARG,\ + compression_ARG,\ +- deduplication_ARG ++ deduplication_ARG,\ ++ vdosettings_ARG + + /* Cache and cache-pool segment type */ + if (seg_is_cache(lp)) { +@@ -1098,19 +1116,6 @@ static int _lvcreate_params(struct cmd_context *cmd, + zero_ARG, + -1)) + return_0; +- +- // FIXME: prefiling here - this is wrong place +- // but will work for this moment +- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL)) +- return_0; +- +- if (arg_is_set(cmd, compression_ARG)) +- lp->vdo_params.use_compression = +- arg_int_value(cmd, compression_ARG, 0); +- +- if (arg_is_set(cmd, deduplication_ARG)) +- lp->vdo_params.use_deduplication = +- arg_int_value(cmd, deduplication_ARG, 0); + } + + /* Check options shared between more segment types */ +@@ -1198,6 +1203,7 @@ static int _lvcreate_params(struct cmd_context *cmd, + &lp->pool_metadata_size, &lp->pool_metadata_spare, + &lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) || + !_read_cache_params(cmd, lp) || ++ !_read_vdo_params(cmd, lp) || + !_read_mirror_and_raid_params(cmd, lp)) + return_0; + +diff --git a/tools/toollib.c b/tools/toollib.c +index 16be336d4..697baee82 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1192,6 +1192,183 @@ out: + return ok; + } + ++/* ++ * Compare VDO option name, skip any '_' in name ++ * and also allow to use it without vdo_[use_] prefix ++ */ ++static int _compare_vdo_option(const char *b1, const char *b2) ++{ ++ if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix ++ b1 += 3; ++ ++ if ((tolower(*b1) != tolower(*b2)) && ++ (strncmp(b2, "use_", 4) == 0)) ++ b2 += 4; // try again with skipped prefix 'use_' ++ ++ while (*b1 && *b2) { ++ if (tolower(*b1) == tolower(*b2)) { ++ ++b1; ++ ++b2; ++ continue; // matching char ++ } ++ ++ if (*b1 == '_') ++ ++b1; // skip to next char ++ else if (*b2 == '_') ++ ++b2; // skip to next char ++ else ++ break; // mismatch ++ } ++ ++ return (*b1 || *b2) ? 0 : 1; ++} ++ ++#define CHECK_AND_SET(var, onoff) \ ++ option = #var;\ ++ if (_compare_vdo_option(cn->key, option)) {\ ++ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_INT))\ ++ goto err;\ ++ if (vtp->var != cn->v->v.i) {\ ++ vtp->var = cn->v->v.i;\ ++ u |= onoff;\ ++ }\ ++ continue;\ ++ } ++ ++#define DO_OFFLINE(var) \ ++ CHECK_AND_SET(var, VDO_CHANGE_OFFLINE) ++ ++#define DO_ONLINE(var) \ ++ CHECK_AND_SET(var, VDO_CHANGE_ONLINE) ++ ++int get_vdo_settings(struct cmd_context *cmd, ++ struct dm_vdo_target_params *vtp, ++ int *updated) ++{ ++ const char *str, *option = NULL; ++ struct arg_value_group_list *group; ++ struct dm_config_tree *result = NULL, *prev = NULL, *current = NULL; ++ struct dm_config_node *cn; ++ int r = 0, u = 0, is_lvchange; ++ int use_compression = vtp->use_compression; ++ int use_deduplication = vtp->use_deduplication; ++ int checked_lvchange; ++ ++ if (updated) ++ *updated = 0; ++ ++ // Group all --vdosettings ++ dm_list_iterate_items(group, &cmd->arg_value_groups) { ++ if (!grouped_arg_is_set(group->arg_values, vdosettings_ARG)) ++ continue; ++ ++ if (!(current = dm_config_create())) ++ goto_out; ++ if (prev) ++ current->cascade = prev; ++ prev = current; ++ ++ if (!(str = grouped_arg_str_value(group->arg_values, ++ vdosettings_ARG, ++ NULL))) ++ goto_out; ++ ++ if (!dm_config_parse_without_dup_node_check(current, str, str + strlen(str))) ++ goto_out; ++ } ++ ++ if (current) { ++ if (!(result = dm_config_flatten(current))) ++ goto_out; ++ ++ checked_lvchange = !strcmp(cmd->name, "lvchange"); ++ ++ /* Use all acceptable VDO options */ ++ for (cn = result->root; cn; cn = cn->sib) { ++ is_lvchange = 0; ++ DO_OFFLINE(ack_threads); ++ DO_OFFLINE(bio_rotation); ++ DO_OFFLINE(bio_threads); ++ DO_OFFLINE(block_map_cache_size_mb); ++ DO_OFFLINE(block_map_era_length); ++ DO_OFFLINE(block_map_period); // alias for block_map_era_length ++ DO_OFFLINE(cpu_threads); ++ DO_OFFLINE(hash_zone_threads); ++ DO_OFFLINE(logical_threads); ++ DO_OFFLINE(max_discard); ++ DO_OFFLINE(physical_threads); ++ ++ // Support also these - even when we have regular opts for them ++ DO_ONLINE(use_compression); ++ DO_ONLINE(use_deduplication); ++ ++ // Settings bellow cannot be changed with lvchange command ++ is_lvchange = checked_lvchange; ++ ++ DO_OFFLINE(check_point_frequency); ++ DO_OFFLINE(index_memory_size_mb); ++ DO_OFFLINE(minimum_io_size); ++ DO_OFFLINE(slab_size_mb); ++ DO_OFFLINE(use_metadata_hints); ++ DO_OFFLINE(use_sparse_index); ++ ++ option = "write_policy"; ++ if (_compare_vdo_option(cn->key, option)) { ++ if (is_lvchange || !cn->v || (cn->v->type != DM_CFG_STRING)) ++ goto err; ++ if (!set_vdo_write_policy(&vtp->write_policy, cn->v->v.str)) ++ goto_out; ++ u |= VDO_CHANGE_OFFLINE; ++ continue; ++ } ++ ++ log_error("Unknown VDO setting \"%s\".", cn->key); ++ goto out; ++ } ++ } ++ ++ if (arg_is_set(cmd, compression_ARG)) { ++ vtp->use_compression = arg_int_value(cmd, compression_ARG, 0); ++ if (vtp->use_compression != use_compression) ++ u |= VDO_CHANGE_ONLINE; ++ } ++ ++ if (arg_is_set(cmd, deduplication_ARG)) { ++ vtp->use_deduplication = arg_int_value(cmd, deduplication_ARG, 0); ++ if (vtp->use_deduplication != use_deduplication) ++ u |= VDO_CHANGE_ONLINE; ++ } ++ ++ if (updated) { ++ // validation of updated VDO option ++ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) { ++err: ++ if (is_lvchange) ++ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.", ++ option); ++ else ++ log_error("Invalid argument for VDO setting \"vdo_%s\".", ++ option); ++ goto out; ++ } ++ ++ *updated = u; ++ } ++ ++ r = 1; ++out: ++ if (result) ++ dm_config_destroy(result); ++ ++ while (prev) { ++ current = prev->cascade; ++ dm_config_destroy(prev); ++ prev = current; ++ } ++ ++ return r; ++} ++ + static int _get_one_writecache_setting(struct cmd_context *cmd, struct writecache_settings *settings, + char *key, char *val, uint32_t *block_size_sectors) + { +diff --git a/tools/toollib.h b/tools/toollib.h +index f3a60fbc4..2b38e4e4f 100644 +--- a/tools/toollib.h ++++ b/tools/toollib.h +@@ -217,6 +217,12 @@ int get_cache_params(struct cmd_context *cmd, + const char **name, + struct dm_config_tree **settings); + ++#define VDO_CHANGE_ONLINE 1 ++#define VDO_CHANGE_OFFLINE 2 ++int get_vdo_settings(struct cmd_context *cmd, ++ struct dm_vdo_target_params *vtp, ++ int *updated); ++ + int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings *settings, + uint32_t *block_size_sectors); + +-- +2.34.3 + diff --git a/SOURCES/0048-toollib-fix-segfault-when-handling-selection-with-hi.patch b/SOURCES/0048-toollib-fix-segfault-when-handling-selection-with-hi.patch new file mode 100644 index 0000000..6a0b3e0 --- /dev/null +++ b/SOURCES/0048-toollib-fix-segfault-when-handling-selection-with-hi.patch @@ -0,0 +1,45 @@ +From 45a2ccfa3bdf4c5b3f8b9e0cc5330fca345b0d26 Mon Sep 17 00:00:00 2001 +From: Peter Rajnoha +Date: Thu, 5 May 2022 11:02:32 +0200 +Subject: [PATCH 48/54] toollib: fix segfault when handling selection with + historical LVs + +When processing historical LVs inside process_each_lv_in_vg for +selection, we need to use dummy "_historical_lv" for select_match_lv. + +This is because a historical LV is not an actual LV, but only a tiny +representation with subset of original properties that we recorded +(name, uuid...). + +To use the same processing functions we use for full-fledged non-historical +LVs, we need to use the prefilled "_historical_lv" structure which has all +the other missing properties hard-coded. +--- + tools/toollib.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/toollib.c b/tools/toollib.c +index 697baee82..01ba03658 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -3392,13 +3392,14 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg, + process_lv = 1; + } + +- process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle); ++ _historical_lv.this_glv = glvl->glv; ++ _historical_lv.name = glvl->glv->historical->name; ++ ++ process_lv = process_lv && select_match_lv(cmd, handle, vg, &_historical_lv) && _select_matches(handle); + + if (!process_lv) + continue; + +- _historical_lv.this_glv = glvl->glv; +- _historical_lv.name = glvl->glv->historical->name; + log_very_verbose("Processing historical LV %s in VG %s.", glvl->glv->historical->name, vg->name); + + ret = process_single_lv(cmd, &_historical_lv, handle); +-- +2.34.3 + diff --git a/SOURCES/0049-devices-file-move-clean-up-after-command-is-run.patch b/SOURCES/0049-devices-file-move-clean-up-after-command-is-run.patch new file mode 100644 index 0000000..2fbfdbc --- /dev/null +++ b/SOURCES/0049-devices-file-move-clean-up-after-command-is-run.patch @@ -0,0 +1,39 @@ +From eda98e4b9418568d6793d2c853aaa54db051cc9f Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 27 May 2022 12:38:43 -0500 +Subject: [PATCH 49/54] devices file: move clean up after command is run + +devices_file_exit wasn't being called between lvm_shell +commands, so the file lock wouldn't be released. +--- + lib/commands/toolcontext.c | 1 - + tools/lvmcmdline.c | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index a0c78ddd6..7db5e11a1 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -1912,7 +1912,6 @@ int refresh_toolcontext(struct cmd_context *cmd) + _destroy_segtypes(&cmd->segtypes); + _destroy_formats(cmd, &cmd->formats); + +- devices_file_exit(cmd); + if (!dev_cache_exit()) + stack; + _destroy_dev_types(cmd); +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index 1727ba089..eb63fd9b5 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -3306,6 +3306,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + hints_exit(cmd); + lvmcache_destroy(cmd, 1, 1); + label_scan_destroy(cmd); ++ devices_file_exit(cmd); + + if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING))) + dm_config_destroy(config_string_cft); +-- +2.34.3 + diff --git a/SOURCES/0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch b/SOURCES/0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch new file mode 100644 index 0000000..0adf7b6 --- /dev/null +++ b/SOURCES/0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch @@ -0,0 +1,53 @@ +From bf0b3962088fb18f4a2aba00f38955e1fc6e31fe Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 27 May 2022 14:27:03 -0500 +Subject: [PATCH 50/54] devices file: fail if --devicesfile filename doesn't + exist + +A typo of the filename after --devicesfile should result in a +command error rather than the command falling back to using no +devices file at all. Exception is vgcreate|pvcreate which +create a new devices file if the file name doesn't exist. +--- + lib/device/dev-cache.c | 9 +++++++++ + test/shell/devicesfile-basic.sh | 4 ++++ + 2 files changed, 13 insertions(+) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index b0759b06c..0eb2568b5 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1882,6 +1882,15 @@ static int _setup_devices(struct cmd_context *cmd, int no_file_match) + + file_exists = devices_file_exists(cmd); + ++ /* ++ * Fail if user specifies a file name that doesn't exist and ++ * the command is not creating a new devices file. ++ */ ++ if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) { ++ log_error("Devices file not found: %s", cmd->devices_file_path); ++ return 0; ++ } ++ + /* + * Removing the devices file is another way of disabling the use of + * a devices file, unless the command creates the devices file. +diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh +index 7ba9e2c7f..d1cfb6a35 100644 +--- a/test/shell/devicesfile-basic.sh ++++ b/test/shell/devicesfile-basic.sh +@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices" + vgs --devicesfile test.devices $vg1 + not vgs --devicesfile test.devices $vg2 + ++# misspelled override name fails ++not vgs --devicesfile doesnotexist $vg1 ++not vgs --devicesfile doesnotexist $vg2 ++ + # devicesfile and devices cannot be used together + not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 + +-- +2.34.3 + diff --git a/SOURCES/0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch b/SOURCES/0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch new file mode 100644 index 0000000..820ed88 --- /dev/null +++ b/SOURCES/0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch @@ -0,0 +1,52 @@ +From 25abb5730f4d8f79df69f0817881ffb9eed195a9 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 6 Jun 2022 11:39:02 -0500 +Subject: [PATCH 51/54] filter-mpath: handle other wwid types in blacklist + +Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745 + "filter-mpath: use multipath blacklist" +to handle wwids with initial type digits 1 and 2 used +for t10 and eui ids. Originally recognized type 3 naa. +--- + lib/device/dev-mpath.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index 6eed03c5b..7abbfb289 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path) + int section_black = 0; + int section_exceptions = 0; + int found_quote; +- int found_three; ++ int found_type; + int i, j; + + if (!(fp = fopen(path, "r"))) +@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path) + + memset(wwid, 0, sizeof(wwid)); + found_quote = 0; +- found_three = 0; ++ found_type = 0; + j = 0; + + for (; i < MAX_WWID_LINE; i++) { +@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path) + /* second quote is end of wwid */ + if ((line[i] == '"') && found_quote) + break; +- /* ignore first "3" in wwid */ +- if ((line[i] == '3') && !found_three) { +- found_three = 1; ++ /* exclude initial 3/2/1 for naa/eui/t10 */ ++ if (!j && !found_type && ++ ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) { ++ found_type = 1; + continue; + } + +-- +2.34.3 + diff --git a/SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch b/SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch new file mode 100644 index 0000000..7bb6100 --- /dev/null +++ b/SOURCES/0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch @@ -0,0 +1,56 @@ +From 7cb63b05dad453d015bbe462b799fb031dd6952c Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 31 May 2022 22:48:38 +0200 +Subject: [PATCH 52/54] vdo: fix conversion of vdo_slab_size_mb + +When converting VDO volume, the parameter vdo_slabSize was +incorrectly copied as vdo_blockMapCacheSize, however this parameter +is then no longer used for any table line creation so the wrong +value was only stored in metadata. + +Also use just single get_kb_size_with_unit_ and remove it's duplicate +functionality with get_mb_size_with_unit_. + +Use $VERB for vdo remove call. +--- + scripts/lvm_import_vdo.sh | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index 61a82e41e..beb55dbdb 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -125,15 +125,6 @@ get_kb_size_with_unit_() { + esac + } + +-get_mb_size_with_unit_() { +- case "$1" in +- *[mM]) echo $(( ${1%[mM]} )) ;; +- *[gG]) echo $(( ${1%[gG]} * 1024 )) ;; +- *[tT]) echo $(( ${1%[tT]} * 1024 * 1024 )) ;; +- *[pP]) echo $(( ${1%[pP]} * 1024 * 1024 * 1024 )) ;; +- esac +-} +- + # Figure out largest possible extent size usable for VG + # $1 physical size + # $2 logical size +@@ -328,12 +319,12 @@ allocation { + vdo_use_deduplication = $(get_enabled_value_ "$vdo_deduplication") + vdo_use_metadata_hints=1 + vdo_minimum_io_size = $vdo_logicalBlockSize +- vdo_block_map_cache_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize") ++ vdo_block_map_cache_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 )) + vdo_block_map_period = $vdo_blockMapPeriod + vdo_check_point_frequency = $vdo_indexCfreq + vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse") + vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}") +- vdo_slab_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize") ++ vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 )) + vdo_ack_threads = $vdo_ackThreads + vdo_bio_threads = $vdo_bioThreads + vdo_bio_rotation = $vdo_bioRotationInterval +-- +2.34.3 + diff --git a/SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch b/SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch new file mode 100644 index 0000000..3c98ac4 --- /dev/null +++ b/SOURCES/0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch @@ -0,0 +1,741 @@ +From e36b180a6983c4fa07d6714a0bf81e6935487359 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 6 Jun 2022 14:04:20 -0500 +Subject: [PATCH 53/54] filter-mpath: get wwids from sysfs vpd_pg83 + +to compare with wwids in /etc/multipath/wwids when +excluding multipath components. The wwid printed +from the sysfs wwid file may not be the wwid used +in multipath wwids. Save the wwids found for each +device on dev->wwids to avoid repeating reading +and parsing the sysfs files. +--- + lib/Makefile.in | 1 + + lib/device/dev-cache.c | 18 ++++ + lib/device/dev-cache.h | 1 + + lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++------- + lib/device/device.h | 13 +++ + lib/device/device_id.c | 31 +++++- + lib/device/device_id.h | 2 + + lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++ + 8 files changed, 454 insertions(+), 43 deletions(-) + create mode 100644 lib/device/parse_vpd.c + +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 8b3eac60a..3077825d2 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -40,6 +40,7 @@ SOURCES =\ + device/dev-luks.c \ + device/dev-dasd.c \ + device/dev-lvm1-pool.c \ ++ device/parse_vpd.c \ + display/display.c \ + error/errseg.c \ + unknown/unknown.c \ +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index 0eb2568b5..65e1cb138 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev) + + dm_list_init(&dev->aliases); + dm_list_init(&dev->ids); ++ dm_list_init(&dev->wwids); + } + + void dev_destroy_file(struct device *dev) +@@ -383,6 +384,22 @@ out: + return 1; + } + ++int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen) ++{ ++ int ret; ++ int fd; ++ ++ fd = open(path, O_RDONLY); ++ if (fd < 0) ++ return 0; ++ ret = read(fd, buf, buf_size); ++ close(fd); ++ if (ret <= 0) ++ return 0; ++ *retlen = ret; ++ return 1; ++} ++ + int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value) + { + FILE *fp; +@@ -1336,6 +1353,7 @@ int dev_cache_exit(void) + dm_hash_iterate(n, _cache.names) { + dev = (struct device *) dm_hash_get_data(_cache.names, n); + free_dids(&dev->ids); ++ free_wwids(&dev->wwids); + } + } + +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 321a56d7b..c49e6265d 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path); + bool dev_cache_has_md_with_end_superblock(struct dev_types *dt); + + int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value); ++int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen); + int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor); + + int setup_devices_file(struct cmd_context *cmd); +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index 7abbfb289..3795c992d 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void) + log_debug("multipath config ignored %d wwids", rem_count); + } + +-static void _read_wwid_file(const char *config_wwids_file) ++static void _read_wwid_file(const char *config_wwids_file, int *entries) + { + FILE *fp; + char line[MAX_WWID_LINE]; + char *wwid, *p; ++ char typestr[2] = { 0 }; + int count = 0; + + if (config_wwids_file[0] != '/') { +@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file) + if (line[0] == '/') + wwid++; + +- /* skip the initial '3' */ +- wwid++; ++ ++ /* ++ * the initial character is the id type, ++ * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name. ++ * wwids are stored in the hash table without the type charater. ++ * It seems that sometimes multipath does not include ++ * the type charater (seen with t10 scsi_debug devs). ++ */ ++ typestr[0] = *wwid; ++ if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3') ++ wwid++; + + if ((p = strchr(wwid, '/'))) + *p = '\0'; +@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file) + stack; + + log_debug("multipath wwids read %d from %s", count, config_wwids_file); ++ *entries = count; + } + + int dev_mpath_init(const char *config_wwids_file) +@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file) + struct dm_pool *mem; + struct dm_hash_table *minor_tab; + struct dm_hash_table *wwid_tab; ++ int entries = 0; + + dm_list_init(&_ignored); + dm_list_init(&_ignored_exceptions); +@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file) + _wwid_hash_tab = wwid_tab; + + if (config_wwids_file) { +- _read_wwid_file(config_wwids_file); ++ _read_wwid_file(config_wwids_file, &entries); + _read_wwid_exclusions(); + } + ++ if (!entries) { ++ /* reading dev wwids is skipped with null wwid_hash_tab */ ++ dm_hash_destroy(_wwid_hash_tab); ++ _wwid_hash_tab = NULL; ++ } ++ + return 1; + } + +@@ -432,10 +450,10 @@ static int _dev_is_mpath_component_udev(struct device *dev) + } + #endif + +-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev) ++static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, ++ int primary_result, dev_t primary_dev) + { + struct dev_types *dt = cmd->dev_types; +- const char *part_name; + const char *name; /* e.g. "sda" for "/dev/sda" */ + char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */ + char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */ +@@ -449,25 +467,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device + int dm_dev_major; + int dm_dev_minor; + struct stat info; +- dev_t primary_dev; + int is_mpath_component = 0; + +- /* multipathing is only known to exist for SCSI or NVME devices */ +- if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev)) +- return 0; +- +- switch (dev_get_primary_dev(dt, dev, &primary_dev)) { ++ switch (primary_result) { + + case 2: /* The dev is partition. */ +- part_name = dev_name(dev); /* name of original dev for log_debug msg */ + + /* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */ + if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path)))) + return_0; +- +- log_debug_devs("%s: Device is a partition, using primary " +- "device %s for mpath component detection", +- part_name, name); + break; + + case 1: /* The dev is already a primary dev. Just continue with the dev. */ +@@ -589,47 +597,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device + return is_mpath_component; + } + +-static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev) ++static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev, ++ char *idbuf, int idbufsize) + { +- char sysbuf[PATH_MAX] = { 0 }; +- char *wwid; +- long look; ++ char idtmp[DEV_WWID_SIZE]; + +- if (!_wwid_hash_tab) ++ if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) { ++ /* the wwid file is not under device for nvme devs */ ++ if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize)) ++ return 0; ++ } ++ if (!idbuf[0]) + return 0; + +- if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf))) ++ /* in t10 id, replace series of spaces with one _ like multipath */ ++ if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) { ++ if (idbufsize < DEV_WWID_SIZE) ++ return 0; ++ memcpy(idtmp, idbuf, DEV_WWID_SIZE); ++ memset(idbuf, 0, idbufsize); ++ format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize); ++ } ++ return 1; ++} ++ ++#define VPD_SIZE 4096 ++ ++static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev, ++ struct dm_list *ids) ++{ ++ unsigned char vpd_data[VPD_SIZE] = { 0 }; ++ int vpd_datalen = 0; ++ ++ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen)) ++ return 0; ++ if (!vpd_datalen) + return 0; + +- if (!sysbuf[0]) ++ /* adds dev_wwid entry to dev->wwids for each id in vpd data */ ++ parse_vpd_ids(vpd_data, vpd_datalen, ids); ++ return 1; ++} ++ ++void free_wwids(struct dm_list *ids) ++{ ++ struct dev_wwid *dw, *safe; ++ ++ dm_list_iterate_items_safe(dw, safe, ids) { ++ dm_list_del(&dw->list); ++ free(dw); ++ } ++} ++ ++static int _wwid_type_num(char *id) ++{ ++ if (!strncmp(id, "naa.", 4)) ++ return 3; ++ else if (!strncmp(id, "eui.", 4)) ++ return 2; ++ else if (!strncmp(id, "t10.", 4)) ++ return 1; ++ else ++ return -1; ++} ++ ++/* ++ * TODO: if each of the different wwid types (naa/eui/t10) were ++ * represented by different DEV_ID_TYPE_FOO values, and used ++ * as device_id types, then we could drop struct dev_wwid and ++ * drop dev->wwids, and just use dev->ids for each of the ++ * different wwids found in vpd_pg83. This would also require ++ * the ability to handle both the original method of replacing ++ * every space in the id string with _ and the new/multipath ++ * format_t10_id replacing series of spaces with one _. ++ */ ++struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids) ++{ ++ struct dev_wwid *dw; ++ int len; ++ ++ if (!id_type) { ++ id_type = _wwid_type_num(id); ++ if (id_type == -1) ++ log_debug("unknown wwid type %s", id); ++ } ++ ++ if (!(dw = zalloc(sizeof(struct dev_wwid)))) ++ return NULL; ++ len = strlen(id); ++ if (len >= DEV_WWID_SIZE) ++ len = DEV_WWID_SIZE - 1; ++ memcpy(dw->id, id, len); ++ dw->type = id_type; ++ dm_list_add(ids, &dw->list); ++ return dw; ++} ++ ++/* ++ * we save ids with format: naa., eui., t10.. ++ * multipath wwids file uses format: 3, 2, 1. ++ * The values are saved in wwid_hash_tab without the type prefix. ++ */ ++ ++static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev, ++ int primary_result, dev_t primary_dev) ++{ ++ char idbuf[DEV_WWID_SIZE] = { 0 }; ++ struct dev_wwid *dw; ++ char *wwid; ++ ++ if (!_wwid_hash_tab) + return 0; + + /* +- * sysfs prints wwid as . +- * multipath wwid uses '3' +- * does "." always correspond to "3"? ++ * Check the primary device, not the partition. + */ +- if (!(wwid = strchr(sysbuf, '.'))) +- return 0; ++ if (primary_result == 2) { ++ if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) { ++ log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev)); ++ return 0; ++ } ++ } + +- /* skip the type and dot, just as '3' was skipped from wwids entry */ +- wwid++; +- +- look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid)); ++ /* ++ * This function may be called multiple times for the same device, in ++ * particular if partitioned for each partition. ++ */ ++ if (!dm_list_empty(&dev->wwids)) ++ goto lookup; + +- if (look) { +- log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid); +- return 1; ++ /* ++ * Get all the ids for the device from vpd_pg83 and check if any of ++ * those are in /etc/multipath/wwids. These ids should include the ++ * value printed from the sysfs wwid file. ++ */ ++ _read_sys_vpd_wwids(cmd, dev, &dev->wwids); ++ if (!dm_list_empty(&dev->wwids)) ++ goto lookup; ++ ++ /* ++ * This will read the sysfs wwid file, nvme devices in particular have ++ * a wwid file but not a vpd_pg83 file. ++ */ ++ if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf))) ++ add_wwid(idbuf, 0, &dev->wwids); ++ ++ lookup: ++ dm_list_iterate_items(dw, &dev->wwids) { ++ if (dw->type == 1 || dw->type == 2 || dw->type == 3) ++ wwid = &dw->id[4]; ++ else ++ wwid = dw->id; ++ ++ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) { ++ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id); ++ return 1; ++ } + } ++ + return 0; + } + + int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev) + { +- if (_dev_is_mpath_component_sysfs(cmd, dev) == 1) ++ struct dev_types *dt = cmd->dev_types; ++ int primary_result; ++ dev_t primary_dev; ++ ++ /* ++ * multipath only uses SCSI or NVME devices ++ */ ++ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev)) ++ return 0; ++ ++ /* ++ * primary_result 2: dev is a partition, primary_dev is the whole device ++ * primary_result 1: dev is a whole device ++ */ ++ primary_result = dev_get_primary_dev(dt, dev, &primary_dev); ++ ++ if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev) == 1) + goto found; + +- if (_dev_in_wwid_file(cmd, dev)) ++ if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev)) + goto found; + + if (external_device_info_source() == DEV_EXT_UDEV) { +@@ -637,6 +787,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev) + goto found; + } + ++ /* ++ * TODO: save the result of this function in dev->flags and use those ++ * flags on repeated calls to avoid repeating the work multiple times ++ * for the same device when there are partitions on the device. ++ */ ++ + return 0; + found: + return 1; +diff --git a/lib/device/device.h b/lib/device/device.h +index 572994bb9..1c85f37a9 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -59,6 +59,14 @@ struct dev_ext { + void *handle; + }; + ++#define DEV_WWID_SIZE 128 ++ ++struct dev_wwid { ++ struct dm_list list; ++ int type; ++ char id[DEV_WWID_SIZE]; ++}; ++ + #define DEV_ID_TYPE_SYS_WWID 0x0001 + #define DEV_ID_TYPE_SYS_SERIAL 0x0002 + #define DEV_ID_TYPE_MPATH_UUID 0x0003 +@@ -105,6 +113,7 @@ struct dev_use { + */ + struct device { + struct dm_list aliases; /* struct dm_str_list */ ++ struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */ + struct dm_list ids; /* struct dev_id, different entries for different idtypes */ + struct dev_id *id; /* points to the the ids entry being used for this dev */ + dev_t dev; +@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev); + + int dev_mpath_init(const char *config_wwids_file); + void dev_mpath_exit(void); ++struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids); ++void free_wwids(struct dm_list *ids); ++int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids); ++int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes); + + #endif +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 20901ab90..4d8fa5c9c 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids) + } + } + +-int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize) ++static int _read_sys_block(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, ++ int binary, int *retlen) + { + char path[PATH_MAX]; + dev_t devt = dev->dev; +@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff + return 0; + } + +- get_sysfs_value(path, sysbuf, sysbufsize, 0); ++ if (binary) { ++ ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen); ++ if (ret && !*retlen) ++ ret = 0; ++ } else { ++ ret = get_sysfs_value(path, sysbuf, sysbufsize, 0); ++ if (ret && !sysbuf[0]) ++ ret = 0; ++ } + +- if (sysbuf[0]) { +- if (prim) +- log_debug("Using primary device_id for partition %s.", dev_name(dev)); ++ if (ret) { + sysbuf[sysbufsize - 1] = '\0'; + return 1; + } +@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff + return 0; + } + ++int read_sys_block(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize) ++{ ++ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL); ++} ++ ++int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, ++ int *retlen) ++{ ++ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen); ++} ++ + static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix) + { + if (!strncmp(sysbuf, prefix, strlen(prefix))) +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index 2cd2fd7c6..e049e2333 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -55,6 +55,8 @@ void devices_file_exit(struct cmd_context *cmd); + void unlink_searched_devnames(struct cmd_context *cmd); + + int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize); ++int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, int *retlen); + + int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out); + +diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c +new file mode 100644 +index 000000000..4bafa7b9e +--- /dev/null ++++ b/lib/device/parse_vpd.c +@@ -0,0 +1,199 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * 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 Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "base/memory/zalloc.h" ++#include "lib/misc/lib.h" ++#include "lib/device/device.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Replace series of spaces with a single _. ++ */ ++int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) ++{ ++ int in_space = 0; ++ int retlen = 0; ++ int j = 0; ++ int i; ++ ++ for (i = 0; i < in_bytes; i++) { ++ if (!in[i]) ++ break; ++ if (j >= (out_bytes - 2)) ++ break; ++ /* skip leading spaces */ ++ if (!retlen && (in[i] == ' ')) ++ continue; ++ /* replace one or more spaces with _ */ ++ if (in[i] == ' ') { ++ in_space = 1; ++ continue; ++ } ++ /* spaces are finished so insert _ */ ++ if (in_space) { ++ out[j++] = '_'; ++ in_space = 0; ++ retlen++; ++ } ++ out[j++] = in[i]; ++ retlen++; ++ } ++ return retlen; ++} ++ ++static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) ++{ ++ int off = 0; ++ int num; ++ int i; ++ ++ for (i = 0; i < in_bytes; i++) { ++ num = sprintf((char *)out + off, "%02x", in[i]); ++ if (num < 0) ++ break; ++ off += num; ++ if (off + 2 >= out_bytes) ++ break; ++ } ++ return off; ++} ++ ++#define ID_BUFSIZE 1024 ++ ++/* ++ * based on linux kernel function ++ */ ++int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids) ++{ ++ char id[ID_BUFSIZE]; ++ unsigned char tmp_str[ID_BUFSIZE]; ++ const unsigned char *d, *cur_id_str; ++ size_t id_len = ID_BUFSIZE; ++ int id_size = -1; ++ uint8_t cur_id_size = 0; ++ ++ memset(id, 0, ID_BUFSIZE); ++ for (d = vpd_data + 4; ++ d < vpd_data + vpd_datalen; ++ d += d[3] + 4) { ++ memset(tmp_str, 0, sizeof(tmp_str)); ++ ++ switch (d[1] & 0xf) { ++ case 0x1: ++ /* T10 Vendor ID */ ++ cur_id_size = d[3]; ++ if (cur_id_size + 4 > id_len) ++ cur_id_size = id_len - 4; ++ cur_id_str = d + 4; ++ format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str); ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 1, ids); ++ break; ++ case 0x2: ++ /* EUI-64 */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ switch (cur_id_size) { ++ case 8: ++ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ case 12: ++ _to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ case 16: ++ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ default: ++ break; ++ } ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 2, ids); ++ break; ++ case 0x3: ++ /* NAA */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ switch (cur_id_size) { ++ case 8: ++ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); ++ break; ++ case 16: ++ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); ++ break; ++ default: ++ break; ++ } ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 3, ids); ++ break; ++ case 0x8: ++ /* SCSI name string */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ if (cur_id_size >= id_len) ++ cur_id_size = id_len - 1; ++ memcpy(id, cur_id_str, cur_id_size); ++ id_size = cur_id_size; ++ ++ /* ++ * Not in the kernel version, copying multipath code, ++ * which checks if this string begins with naa or eui ++ * and if so does tolower() on the chars. ++ */ ++ if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) { ++ int i; ++ for (i = 0; i < id_size; i++) ++ id[i] = tolower(id[i]); ++ } ++ add_wwid(id, 8, ids); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return id_size; ++} +-- +2.34.3 + diff --git a/SOURCES/0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch b/SOURCES/0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch new file mode 100644 index 0000000..c1ce567 --- /dev/null +++ b/SOURCES/0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch @@ -0,0 +1,29 @@ +From e60d7ce8e748cb6d51552879c162d01aafa17160 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 15 Jun 2022 11:53:51 +0200 +Subject: [PATCH 54/54] build: Fix make rpm with VERSION_DM without dash + +When building RPM from a branch based on a release tag the expected -git +suffix is missing breaking the script producing error like following one: + + error: line 215: Unterminated rich dependency: (2021-53.ge36b180a6.el9: Requires: device-mapper-devel >= 1.02.181 (2021-53.ge36b180a6.el9 +--- + Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.in b/Makefile.in +index 3b7e0ecaa..f7a46269a 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -110,7 +110,7 @@ rpm: dist + $(LN_S) -f $(abs_top_srcdir)/spec/build.inc $(rpmbuilddir)/SOURCES + $(LN_S) -f $(abs_top_srcdir)/spec/macros.inc $(rpmbuilddir)/SOURCES + $(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES +- DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\ ++ DM_VER=$$(cut -d' ' -f1 $(top_srcdir)/VERSION_DM | cut -d- -f1);\ + GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\ + $(SED) -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \ + -e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \ +-- +2.34.3 + diff --git a/SOURCES/0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch b/SOURCES/0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch new file mode 100644 index 0000000..710790e --- /dev/null +++ b/SOURCES/0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch @@ -0,0 +1,246 @@ +From 73b9a2805ca2f2c70f6f631b405f8fea3f72f23b Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 5 Jul 2022 17:08:00 -0500 +Subject: [PATCH] exit with error when --devicesfile name doesn't exist + +--- + lib/cache/lvmcache.c | 3 ++- + lib/label/label.c | 4 ++-- + test/shell/devicesfile-basic.sh | 1 + + tools/pvcreate.c | 3 ++- + tools/pvremove.c | 3 ++- + tools/pvscan.c | 3 ++- + tools/toollib.c | 27 +++++++++++++++++++++------ + tools/vgcfgrestore.c | 5 ++++- + tools/vgcreate.c | 5 ++++- + tools/vgextend.c | 3 ++- + tools/vgmerge.c | 3 ++- + tools/vgsplit.c | 3 ++- + 12 files changed, 46 insertions(+), 17 deletions(-) + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index 0e62cd267..61a2fee6d 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -1600,7 +1600,8 @@ int lvmcache_label_scan(struct cmd_context *cmd) + * with infos/vginfos based on reading headers from + * each device, and a vg summary from each mda. + */ +- label_scan(cmd); ++ if (!label_scan(cmd)) ++ return_0; + + /* + * When devnames are used as device ids (which is dispreferred), +diff --git a/lib/label/label.c b/lib/label/label.c +index 06958b502..00ede2b76 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -800,7 +800,7 @@ static int _setup_bcache(void) + } + + if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) { +- log_error("Failed to create bcache with %d cache blocks.", cache_blocks); ++ log_error("Failed to set up io layer with %d blocks.", cache_blocks); + return 0; + } + +@@ -1015,7 +1015,7 @@ int label_scan(struct cmd_context *cmd) + * data to invalidate.) + */ + if (!(iter = dev_iter_create(NULL, 0))) { +- log_error("Scanning failed to get devices."); ++ log_error("Failed to get device list."); + return 0; + } + while ((dev = dev_iter_get(cmd, iter))) { +diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh +index d1cfb6a35..2d197a73a 100644 +--- a/test/shell/devicesfile-basic.sh ++++ b/test/shell/devicesfile-basic.sh +@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2 + # misspelled override name fails + not vgs --devicesfile doesnotexist $vg1 + not vgs --devicesfile doesnotexist $vg2 ++not vgs --devicesfile doesnotexist + + # devicesfile and devices cannot be used together + not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 +diff --git a/tools/pvcreate.c b/tools/pvcreate.c +index 71eb060a3..a1ef0e9e1 100644 +--- a/tools/pvcreate.c ++++ b/tools/pvcreate.c +@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) + + cmd->create_edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(handle = init_processing_handle(cmd, NULL))) { + log_error("Failed to initialize processing handle."); +diff --git a/tools/pvremove.c b/tools/pvremove.c +index 2dfdbd016..5c39ee0c7 100644 +--- a/tools/pvremove.c ++++ b/tools/pvremove.c +@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv) + + clear_hint_file(cmd); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + /* When forcibly clearing a PV we don't care about a VG lock. */ + if (pp.force == DONT_PROMPT_OVERRIDE) +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 50d46051a..bce1fbb40 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -1626,7 +1626,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv, + * which we want 'pvscan --cache' to do, and that uses + * info from lvmcache, e.g. duplicate pv info. + */ +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_0; + + cmd->pvscan_recreate_hints = 0; + cmd->use_hints = 0; +diff --git a/tools/toollib.c b/tools/toollib.c +index 01ba03658..210b3dca5 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1601,7 +1601,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv, + + log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } + + if (argc) { + for (; opt < argc; opt++) { +@@ -2381,8 +2384,13 @@ int process_each_vg(struct cmd_context *cmd, + * Scan all devices to populate lvmcache with initial + * list of PVs and VGs. + */ +- if (!(read_flags & PROCESS_SKIP_SCAN)) +- lvmcache_label_scan(cmd); ++ if (!(read_flags & PROCESS_SKIP_SCAN)) { ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } ++ } ++ + + /* + * A list of all VGs on the system is needed when: +@@ -3932,7 +3940,10 @@ int process_each_lv(struct cmd_context *cmd, + * Scan all devices to populate lvmcache with initial + * list of PVs and VGs. + */ +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } + + /* + * A list of all VGs on the system is needed when: +@@ -4568,8 +4579,12 @@ int process_each_pv(struct cmd_context *cmd, + goto_out; + } + +- if (!(read_flags & PROCESS_SKIP_SCAN)) +- lvmcache_label_scan(cmd); ++ if (!(read_flags & PROCESS_SKIP_SCAN)) { ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } ++ } + + if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) { + ret_max = ret; +diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c +index e49313d14..9fcba89d4 100644 +--- a/tools/vgcfgrestore.c ++++ b/tools/vgcfgrestore.c +@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) + + clear_hint_file(cmd); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ unlock_vg(cmd, NULL, vg_name); ++ return_ECMD_FAILED; ++ } + + cmd->handles_unknown_segments = 1; + +diff --git a/tools/vgcreate.c b/tools/vgcreate.c +index dde3f1eac..14608777f 100644 +--- a/tools/vgcreate.c ++++ b/tools/vgcreate.c +@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) + + cmd->create_edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ unlock_vg(cmd, NULL, vp_new.vg_name); ++ return_ECMD_FAILED; ++ } + + if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) { + unlock_vg(cmd, NULL, vp_new.vg_name); +diff --git a/tools/vgextend.c b/tools/vgextend.c +index 0856b4c78..fecd6bdd5 100644 +--- a/tools/vgextend.c ++++ b/tools/vgextend.c +@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) + + cmd->edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(handle = init_processing_handle(cmd, NULL))) { + log_error("Failed to initialize processing handle."); +diff --git a/tools/vgmerge.c b/tools/vgmerge.c +index 08615cd62..4ed4a8f0b 100644 +--- a/tools/vgmerge.c ++++ b/tools/vgmerge.c +@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, + return ECMD_FAILED; + } + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (strcmp(vg_name_to, vg_name_from) > 0) + lock_vg_from_first = 1; +diff --git a/tools/vgsplit.c b/tools/vgsplit.c +index a085ac2ba..9d6534e89 100644 +--- a/tools/vgsplit.c ++++ b/tools/vgsplit.c +@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv) + return ECMD_FAILED; + } + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) { + if (!validate_name(vg_name_to)) { +-- +2.34.3 + diff --git a/SOURCES/0057-apply-multipath_component_detection-0-to-duplicate-P.patch b/SOURCES/0057-apply-multipath_component_detection-0-to-duplicate-P.patch new file mode 100644 index 0000000..7d916fc --- /dev/null +++ b/SOURCES/0057-apply-multipath_component_detection-0-to-duplicate-P.patch @@ -0,0 +1,55 @@ +From 3f297c1b3bebcb8812db882f369fbb4c43f4ceb3 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 25 Jul 2022 13:50:43 -0500 +Subject: [PATCH] apply multipath_component_detection=0 to duplicate PV + handling + +multipath_component_detection=0 has always applied to the filter-based +component detection. Also apply this setting to the duplicate-PV +handling which also eliminates multipath components (based on duplicate +PVs having the same wwid.) + +(cherry picked from commit 99ce09ae778c2cc4aa2611e425bba5287b8b9513) +--- + lib/cache/lvmcache.c | 3 +++ + test/shell/duplicate-pvs-multipath.sh | 10 +++++++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index 61a2fee6d..04e9f0605 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -640,6 +640,9 @@ static int _all_multipath_components(struct cmd_context *cmd, struct lvmcache_in + + *dev_mpath = NULL; + ++ if (!find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL)) ++ return 0; ++ + /* This function only makes sense with more than one dev. */ + if ((info && dm_list_empty(altdevs)) || (!info && (dm_list_size(altdevs) == 1))) { + log_debug("Skip multipath component checks with single device for PVID %s", pvid); +diff --git a/test/shell/duplicate-pvs-multipath.sh b/test/shell/duplicate-pvs-multipath.sh +index 59c15b0d4..bc98d2d5a 100644 +--- a/test/shell/duplicate-pvs-multipath.sh ++++ b/test/shell/duplicate-pvs-multipath.sh +@@ -24,9 +24,13 @@ modprobe --dry-run scsi_debug || skip + multipath -l || skip + multipath -l | grep scsi_debug && skip + +-# Turn off multipath_component_detection so that the duplicate +-# resolution of mpath components is used. +-aux lvmconf 'devices/multipath_component_detection = 0' ++# FIXME: setting multipath_component_detection=0 now also disables ++# the wwid-based mpath component detection, so this test will need ++# to find another way to disable only the filter-mpath code (using ++# sysfs and multipath/wwids) while keeping the code enabled that ++# eliminates duplicates based on their matching wwids which this ++# tries to test. ++ + # Prevent wwids from being used for filtering. + aux lvmconf 'devices/multipath_wwids_file = "/dev/null"' + # Need to use /dev/mapper/mpath +-- +2.37.1 + diff --git a/SOURCES/0058-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch b/SOURCES/0058-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch new file mode 100644 index 0000000..161128e --- /dev/null +++ b/SOURCES/0058-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch @@ -0,0 +1,66 @@ +From 87904fbbb84c10e6f733db1c5ba447537d1cf08c Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 19 Aug 2022 13:31:22 -0500 +Subject: [PATCH 1/6] devices file: fix pvcreate --uuid matching pvid entry + with no device id + +pvcreate with --uuid would segfault if a devices file entry matched +the specified pvid, but the devices file entry had no device_id, which +could happen if the entry has a devname idtype. +--- + lib/device/device_id.c | 7 ++++--- + test/shell/devicesfile-devname.sh | 13 +++++++++++++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 4d8fa5c9c..c3816a66c 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -1142,8 +1142,9 @@ id_done: + du_devname->devname); + + if (du_pvid && (du_pvid->dev != dev)) +- log_warn("WARNING: adding device %s with PVID %s which is already used for %s.", +- dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device"); ++ log_warn("WARNING: adding device %s with PVID %s which is already used for %s device_id %s.", ++ dev_name(dev), pvid, du_pvid->dev ? dev_name(du_pvid->dev) : "missing device", ++ du_pvid->idname ?: "none"); + + if (du_devid && (du_devid->dev != dev)) { + if (!du_devid->dev) { +@@ -1189,7 +1190,7 @@ id_done: + else + check_idname = device_id_system_read(cmd, dev, du_pvid->idtype); + +- if (check_idname && !strcmp(check_idname, du_pvid->idname)) { ++ if (!du_pvid->idname || (check_idname && !strcmp(check_idname, du_pvid->idname))) { + update_du = du_pvid; + dm_list_del(&update_du->list); + update_matching_kind = "PVID"; +diff --git a/test/shell/devicesfile-devname.sh b/test/shell/devicesfile-devname.sh +index 338637275..211f4dbed 100644 +--- a/test/shell/devicesfile-devname.sh ++++ b/test/shell/devicesfile-devname.sh +@@ -550,6 +550,19 @@ vgchange -an $vg2 + vgremove -ff $vg1 + vgremove -ff $vg2 + ++# bz 2119473 ++ ++aux lvmconf "devices/search_for_devnames = \"none\"" ++sed -e "s|DEVNAME=$dev1|DEVNAME=.|" "$ORIG" > tmp1.devices ++sed -e "s|IDNAME=$dev1|IDNAME=.|" tmp1.devices > "$DF" ++pvs ++lvmdevices ++pvcreate -ff --yes --uuid "$PVID1" --norestorefile $dev1 ++grep "$PVID1" "$DF" |tee out ++grep "DEVNAME=$dev1" out ++grep "IDNAME=$dev1" out ++aux lvmconf "devices/search_for_devnames = \"auto\"" ++ + # devnames change so the new devname now refers to a filtered device, + # e.g. an mpath or md component, which is not scanned + +-- +2.38.1 + diff --git a/SOURCES/0059-lvconvert-correct-test-support-for-vdo-pool.patch b/SOURCES/0059-lvconvert-correct-test-support-for-vdo-pool.patch new file mode 100644 index 0000000..cfbe191 --- /dev/null +++ b/SOURCES/0059-lvconvert-correct-test-support-for-vdo-pool.patch @@ -0,0 +1,57 @@ +From 73943825501daede9963bb5d15abbc4d36febb40 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 11 Aug 2022 11:44:58 +0200 +Subject: [PATCH 2/6] lvconvert: correct test support for vdo-pool + +(cherry picked from commit d0697be5004af0e040b1f746e619b8075350bc46) +--- + WHATS_NEW | 4 ++++ + lib/metadata/vdo_manip.c | 4 +++- + tools/lvconvert.c | 4 +++- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 240234e4d..e626802ec 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++Version 2.03.17 - ++=============================== ++ Fix lvconvert --test --type vdo-pool execution. ++ + Version 2.03.14 - 20th October 2021 + =================================== + Device scanning is skipping directories on different filesystems. +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index fa9c893cb..11a119a68 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -392,7 +392,9 @@ struct logical_volume *convert_vdo_pool_lv(struct logical_volume *data_lv, + + /* Format data LV as VDO volume */ + if (format) { +- if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) { ++ if (test_mode()) { ++ log_verbose("Test mode: Skipping formating of VDO pool volume."); ++ } else if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) { + log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv)); + return NULL; + } +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index 3d4b24fe3..c1d373318 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -5482,7 +5482,9 @@ static int _lvconvert_to_vdopool_single(struct cmd_context *cmd, + } + + if (vdo_pool_zero) { +- if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1, .do_wipe_signatures = 1, ++ if (test_mode()) { ++ log_verbose("Test mode: Skipping activation, zeroing and signature wiping."); ++ } else if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1, .do_wipe_signatures = 1, + .yes = arg_count(cmd, yes_ARG), + .force = arg_count(cmd, force_ARG)})) { + log_error("Aborting. Failed to wipe VDO data store."); +-- +2.38.1 + diff --git a/SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch b/SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch new file mode 100644 index 0000000..19ad0b2 --- /dev/null +++ b/SOURCES/0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch @@ -0,0 +1,32 @@ +From 0aa45120e92fe8b0f379d00f3a031e3c53feca43 Mon Sep 17 00:00:00 2001 +From: Tony Asleson +Date: Wed, 24 Aug 2022 15:37:56 -0500 +Subject: [PATCH 3/6] lvmdbusd: Set LVM_COMMAND_PROFILE=lvmdbusd + +We need this to prevent lvm from interleaving the JSON output with errors +written to stderr. + +(cherry picked from commit a5e6947d74f7b88f7f0df4328a923ad82a970634) +--- + daemons/lvmdbusd/main.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py +index b0a82d492..eaea13ef8 100644 +--- a/daemons/lvmdbusd/main.py ++++ b/daemons/lvmdbusd/main.py +@@ -112,8 +112,10 @@ def main(): + + use_session = os.getenv('LVMDBUSD_USE_SESSION', False) + +- # Ensure that we get consistent output for parsing stdout/stderr ++ # Ensure that we get consistent output for parsing stdout/stderr and that we ++ # are using the lvmdbusd profile. + os.environ["LC_ALL"] = "C" ++ os.environ["LVM_COMMAND_PROFILE"] = "lvmdbusd" + + cfg.args = parser.parse_args() + cfg.create_request_entry = RequestEntry +-- +2.38.1 + diff --git a/SOURCES/0061-vgimportdevices-change-result-when-devices-are-not-a.patch b/SOURCES/0061-vgimportdevices-change-result-when-devices-are-not-a.patch new file mode 100644 index 0000000..c15b8fd --- /dev/null +++ b/SOURCES/0061-vgimportdevices-change-result-when-devices-are-not-a.patch @@ -0,0 +1,442 @@ +From f1d8c01dff3f8839355004e5fd77e9cd521e26cb Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 29 Aug 2022 15:17:36 -0500 +Subject: [PATCH 1/4] vgimportdevices: change result when devices are not added + +When using --all, if one VG is skipped, continue adding +other VGs, and do not return an error from the command +if some VGs are added. (A VG is skipped if it's missing PVs.) + +If the command fails during devices file setup or device +scanning, then remove the devices file if it has been +newly created by the command, and exit with an error. + +If devices from a named VG are not imported (e.g. the +VG is missing devices), then remove the devices file if +it has been newly created by the command, and exit with +an error. + +If --all VGs are being imported, and no devices are found +to include in the devices file, then remove the devices +file if it has been newly created by the command, and +exit with an error. +--- + test/shell/vgimportdevices.sh | 308 ++++++++++++++++++++++++++++++++++ + tools/vgimportdevices.c | 41 +++-- + 2 files changed, 336 insertions(+), 13 deletions(-) + create mode 100644 test/shell/vgimportdevices.sh + +diff --git a/test/shell/vgimportdevices.sh b/test/shell/vgimportdevices.sh +new file mode 100644 +index 000000000..47363cec3 +--- /dev/null ++++ b/test/shell/vgimportdevices.sh +@@ -0,0 +1,308 @@ ++ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2020 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++test_description='vgimportdevices' ++ ++. lib/inittest ++ ++aux prepare_devs 5 ++ ++DFDIR="$LVM_SYSTEM_DIR/devices" ++mkdir "$DFDIR" || true ++DF="$DFDIR/system.devices" ++ ++aux lvmconf 'devices/use_devicesfile = 1' ++ ++not ls "$DF" ++pvcreate "$dev1" ++ls "$DF" ++grep "$dev1" "$DF" ++rm -f "$DF" ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++ ++# ++# vgimportdevices -a with no prev df ++# ++ ++# no devs found ++not vgimportdevices -a ++not ls "$DF" ++ ++# one orphan pv, no vgs ++pvcreate "$dev1" ++rm -f "$DF" ++not vgimportdevices -a ++not ls "$DF" ++ ++# one complete vg ++vgcreate $vg1 "$dev1" ++rm -f "$DF" ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++rm -f "$DF" ++ ++# two complete vgs ++vgcreate $vg1 "$dev1" ++vgcreate $vg2 "$dev2" ++rm -f "$DF" ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# one incomplete vg ++vgcreate $vg1 "$dev1" "$dev2" ++lvcreate -l1 -an $vg1 ++rm -f "$DF" ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++not vgimportdevices -a ++not ls "$DF" ++vgs $vg1 ++pvs "$dev2" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# three complete, one incomplete vg ++vgcreate $vg1 "$dev1" ++vgcreate $vg2 "$dev2" ++vgcreate $vg3 "$dev3" ++vgcreate $vg4 "$dev4" "$dev5" ++rm -f "$DF" ++dd if=/dev/zero of="$dev5" bs=1M count=1 ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++grep "$dev3" "$DF" ++not grep "$dev4" "$DF" ++not grep "$dev5" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++dd if=/dev/zero of="$dev3" bs=1M count=1 ++dd if=/dev/zero of="$dev4" bs=1M count=1 ++rm -f "$DF" ++ ++ ++# ++# vgimportdevices -a with existing df ++# ++ ++# no devs found ++vgcreate $vg1 "$dev1" ++grep "$dev1" "$DF" ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++not vgimportdevices -a ++ls "$DF" ++ ++# one complete vg ++vgcreate $vg1 "$dev1" ++vgimportdevices -a ++grep "$dev1" "$DF" ++vgcreate --devicesfile "" $vg2 "$dev2" ++not grep "$dev2" "$DF" ++vgimportdevices -a ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# two complete vgs ++vgcreate --devicesfile "" $vg1 "$dev1" ++vgcreate --devicesfile "" $vg2 "$dev2" ++rm -f "$DF" ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# one incomplete vg ++vgcreate $vg1 "$dev1" ++vgimportdevices -a ++grep "$dev1" "$DF" ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++vgcreate --devicesfile "" $vg2 "$dev2" "$dev3" ++not grep "$dev2" "$DF" ++not grep "$dev3" "$DF" ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++not vgimportdevices -a ++ls "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++dd if=/dev/zero of="$dev3" bs=1M count=1 ++rm -f "$DF" ++ ++# import the same vg again ++vgcreate --devicesfile "" $vg1 "$dev1" ++not ls "$DF" ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++vgimportdevices -a ++ls "$DF" ++grep "$dev1" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++rm -f "$DF" ++ ++# import a series of vgs ++vgcreate --devicesfile "" $vg1 "$dev1" ++vgimportdevices -a ++grep "$dev1" "$DF" ++vgcreate --devicesfile "" $vg2 "$dev2" ++vgimportdevices -a ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++vgcreate --devicesfile "" $vg3 "$dev3" ++vgimportdevices -a ++grep "$dev1" "$DF" ++grep "$dev2" "$DF" ++grep "$dev3" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++dd if=/dev/zero of="$dev3" bs=1M count=1 ++rm -f "$DF" ++ ++# ++# vgimportdevices vg with no prev df ++# ++ ++# no devs found ++not vgimportdevices $vg1 ++not ls "$DF" ++ ++# one complete vg ++vgcreate $vg1 "$dev1" ++rm -f "$DF" ++vgimportdevices $vg1 ++ls "$DF" ++grep "$dev1" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++rm -f "$DF" ++ ++# two complete vgs ++vgcreate $vg1 "$dev1" ++vgcreate $vg2 "$dev2" ++rm -f "$DF" ++vgimportdevices $vg1 ++ls "$DF" ++grep "$dev1" "$DF" ++vgimportdevices $vg2 ++ls "$DF" ++grep "$dev2" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# one incomplete vg ++vgcreate $vg1 "$dev1" "$dev2" ++lvcreate -l1 -an $vg1 ++rm -f "$DF" ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++not vgimportdevices $vg1 ++not ls "$DF" ++vgs $vg1 ++pvs "$dev2" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++rm -f "$DF" ++ ++# three complete, one incomplete vg ++vgcreate $vg1 "$dev1" ++vgcreate $vg2 "$dev2" ++vgcreate $vg3 "$dev3" ++vgcreate $vg4 "$dev4" "$dev5" ++rm -f "$DF" ++dd if=/dev/zero of="$dev5" bs=1M count=1 ++not vgimportdevices $vg4 ++not ls "$DF" ++vgimportdevices $vg3 ++ls "$DF" ++grep "$dev3" "$DF" ++not grep "$dev1" "$DF" ++not grep "$dev2" "$DF" ++not grep "$dev4" "$DF" ++not grep "$dev5" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++dd if=/dev/zero of="$dev3" bs=1M count=1 ++dd if=/dev/zero of="$dev4" bs=1M count=1 ++rm -f "$DF" ++ ++# ++# vgimportdevices vg with existing df ++# ++ ++# vg not found ++vgcreate $vg1 "$dev1" ++vgimportdevices -a ++grep "$dev1" "$DF" ++not vgimportdevices $vg2 ++grep "$dev1" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++rm -f "$DF" ++ ++# vg incomplete ++vgcreate $vg1 "$dev1" ++vgimportdevices -a ++grep "$dev1" "$DF" ++vgcreate --devicesfile "" $vg2 "$dev2" "$dev3" ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++not vgimportdevices $vg2 ++grep "$dev1" "$DF" ++not grep "$dev2" "$DF" ++not grep "$dev3" "$DF" ++ ++# reset ++dd if=/dev/zero of="$dev1" bs=1M count=1 ++dd if=/dev/zero of="$dev2" bs=1M count=1 ++dd if=/dev/zero of="$dev3" bs=1M count=1 ++dd if=/dev/zero of="$dev4" bs=1M count=1 ++rm -f "$DF" ++ +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index ea205d941..9ade1b9e4 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -36,9 +36,9 @@ static int _vgimportdevices_single(struct cmd_context *cmd, + dm_list_iterate_items(pvl, &vg->pvs) { + if (is_missing_pv(pvl->pv) || !pvl->pv->dev) { + memcpy(pvid, &pvl->pv->id.uuid, ID_LEN); +- log_error("Not importing devices for VG %s with missing PV %s.", +- vg->name, pvid); +- goto bad; ++ log_print("Not importing devices for VG %s with missing PV %s.", ++ vg->name, pvid); ++ return ECMD_PROCESSED; + } + } + +@@ -71,14 +71,17 @@ static int _vgimportdevices_single(struct cmd_context *cmd, + updated_pvs++; + } + ++ /* ++ * Writes the device_id of each PV into the vg metadata. ++ * This is not a critial step and should not influence ++ * the result of the command. ++ */ + if (updated_pvs) { + if (!vg_write(vg) || !vg_commit(vg)) +- goto_bad; ++ log_print("Failed to write device ids in VG metadata."); + } + + return ECMD_PROCESSED; +-bad: +- return ECMD_FAILED; + } + + /* +@@ -114,6 +117,7 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + { + struct vgimportdevices_params vp = { 0 }; + struct processing_handle *handle; ++ int created_file = 0; + int ret = ECMD_FAILED; + + if (arg_is_set(cmd, foreign_ARG)) +@@ -139,9 +143,12 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + log_error("Devices file not enabled."); + return ECMD_FAILED; + } +- if (!devices_file_exists(cmd) && !devices_file_touch(cmd)) { +- log_error("Failed to create devices file."); +- return ECMD_FAILED; ++ if (!devices_file_exists(cmd)) { ++ if (!devices_file_touch(cmd)) { ++ log_error("Failed to create devices file."); ++ return ECMD_FAILED; ++ } ++ created_file = 1; + } + + /* +@@ -195,22 +202,30 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + */ + ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, + 0, handle, _vgimportdevices_single); +- if (ret == ECMD_FAILED) +- goto out; ++ if (ret == ECMD_FAILED) { ++ /* ++ * Error from setting up devices file or label_scan, ++ * _vgimportdevices_single does not return an error. ++ */ ++ goto_out; ++ } + + if (!vp.added_devices) { +- log_print("No devices to add."); ++ log_error("No devices to add."); ++ ret = ECMD_FAILED; + goto out; + } + + if (!device_ids_write(cmd)) { +- log_print("Failed to update devices file."); ++ log_error("Failed to write the devices file."); + ret = ECMD_FAILED; + goto out; + } + + log_print("Added %u devices to devices file.", vp.added_devices); + out: ++ if ((ret == ECMD_FAILED) && created_file) ++ unlink(cmd->devices_file_path); + destroy_processing_handle(cmd, handle); + return ret; + } +-- +2.38.1 + diff --git a/SOURCES/0062-vgimportdevices-fix-locking-when-creating-devices-fi.patch b/SOURCES/0062-vgimportdevices-fix-locking-when-creating-devices-fi.patch new file mode 100644 index 0000000..b654250 --- /dev/null +++ b/SOURCES/0062-vgimportdevices-fix-locking-when-creating-devices-fi.patch @@ -0,0 +1,76 @@ +From 0b9d9963b8f15a6f12a0149a62809fa9b846c5c5 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 30 Aug 2022 14:40:48 -0500 +Subject: [PATCH 2/4] vgimportdevices: fix locking when creating devices file + +Take the devices file lock before creating a new devices file. +(Was missed by the change to preemptively create the devices +file prior to setup_devices(), which was done to improve the +error path.) +--- + lib/device/dev-cache.c | 7 +++---- + lib/device/device_id.c | 1 + + tools/vgimportdevices.c | 10 ++++++++-- + 3 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index 65e1cb138..0c9aaf785 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1956,10 +1956,9 @@ static int _setup_devices(struct cmd_context *cmd, int no_file_match) + + if (!file_exists) { + /* +- * pvcreate/vgcreate/vgimportdevices/lvmdevices-add create +- * a new devices file here if it doesn't exist. +- * They have the create_edit_devices_file flag set. +- * First they create/lock-ex the devices file lockfile. ++ * pvcreate/vgcreate create a new devices file here if it ++ * doesn't exist. They have create_edit_devices_file=1. ++ * First create/lock-ex the devices file lockfile. + * Other commands will not use a devices file if none exists. + */ + lock_mode = LOCK_EX; +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index c3816a66c..780e08404 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -2429,6 +2429,7 @@ static int _lock_devices_file(struct cmd_context *cmd, int mode, int nonblock, i + + if (_devices_file_locked == mode) { + /* can happen when a command holds an ex lock and does an update in device_ids_validate */ ++ /* can happen when vgimportdevices calls this directly, followed later by setup_devices */ + if (held) + *held = 1; + return 1; +diff --git a/tools/vgimportdevices.c b/tools/vgimportdevices.c +index 9ade1b9e4..23c2718ff 100644 +--- a/tools/vgimportdevices.c ++++ b/tools/vgimportdevices.c +@@ -132,8 +132,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + return ECMD_FAILED; + + /* +- * Prepare devices file preemptively because the error path for this +- * case from process_each is not as clean. ++ * Prepare/create devices file preemptively because the error path for ++ * this case from process_each/setup_devices is not as clean. ++ * This means that when setup_devices is called, it the devices ++ * file steps will be redundant, and need to handle being repeated. + */ + if (!setup_devices_file(cmd)) { + log_error("Failed to set up devices file."); +@@ -143,6 +145,10 @@ int vgimportdevices(struct cmd_context *cmd, int argc, char **argv) + log_error("Devices file not enabled."); + return ECMD_FAILED; + } ++ if (!lock_devices_file(cmd, LOCK_EX)) { ++ log_error("Failed to lock the devices file."); ++ return ECMD_FAILED; ++ } + if (!devices_file_exists(cmd)) { + if (!devices_file_touch(cmd)) { + log_error("Failed to create devices file."); +-- +2.38.1 + diff --git a/SOURCES/0063-thin-fix-message-processing-on-thin-pool-extension.patch b/SOURCES/0063-thin-fix-message-processing-on-thin-pool-extension.patch new file mode 100644 index 0000000..3c8bcab --- /dev/null +++ b/SOURCES/0063-thin-fix-message-processing-on-thin-pool-extension.patch @@ -0,0 +1,132 @@ +From 7db3a53d8a3aa7401337fb9aaf00f19cf4407e70 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 30 Mar 2022 14:16:11 +0200 +Subject: [PATCH 3/4] thin: fix message processing on thin-pool extension + +When thin-pool had queued some delete message on extension operation +such message has been 'lost' and thin-pool kernel metadata has been +left with a thin volume that no longer existed for lvm2 metadata. + +(cherry picked from commit 09371131469f7398c597a5fb30dc565859253cc2) +--- + WHATS_NEW | 4 ++ + lib/metadata/lv_manip.c | 2 +- + test/shell/lvextend-thin-adddel.sh | 78 ++++++++++++++++++++++++++++++ + 3 files changed, 83 insertions(+), 1 deletion(-) + create mode 100644 test/shell/lvextend-thin-adddel.sh + +diff --git a/WHATS_NEW b/WHATS_NEW +index e626802ec..bffd24648 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -2,6 +2,10 @@ Version 2.03.17 - + =============================== + Fix lvconvert --test --type vdo-pool execution. + ++Version 2.03.16 - ++==================================== ++ Fix lossing of delete message on thin-pool extension. ++ + Version 2.03.14 - 20th October 2021 + =================================== + Device scanning is skipping directories on different filesystems. +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index 003748d6f..9523e3e66 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -6179,7 +6179,7 @@ int lv_resize(struct logical_volume *lv, + + if (lv_is_thin_pool(lock_lv)) { + /* Update lvm pool metadata (drop messages). */ +- if (!update_pool_lv(lock_lv, 0)) ++ if (!update_pool_lv(lock_lv, 1)) + goto_bad; + } + +diff --git a/test/shell/lvextend-thin-adddel.sh b/test/shell/lvextend-thin-adddel.sh +new file mode 100644 +index 000000000..59b1bfa41 +--- /dev/null ++++ b/test/shell/lvextend-thin-adddel.sh +@@ -0,0 +1,78 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2022 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++# ++# Play with thin-pool and thin removal and creation in corner cases ++# ++ ++SKIP_WITH_LVMLOCKD=1 ++SKIP_WITH_LVMPOLLD=1 ++ ++export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false} ++ ++. lib/inittest ++ ++aux have_thin 1 0 0 || skip ++ ++test -n "$LVM_TEST_THIN_RESTORE_CMD" || LVM_TEST_THIN_RESTORE_CMD=$(which thin_restore) || skip ++"$LVM_TEST_THIN_RESTORE_CMD" -V || skip ++ ++aux have_thin 1 10 0 || skip ++ ++aux prepare_vg 2 ++ ++lvcreate -V10 -n $lv1 -L10 -T $vg/pool ++lvcreate -V10 -n $lv2 $vg/pool ++ ++# Forcibly 'error' _tmeta thin-pool metadata device ++not dmsetup remove -f $vg-pool_tmeta ++ ++# Now try to schedule removal of thin volume id 1 ++# that will fail with errored meta device ++not lvremove -y $vg/$lv1 ++ ++# Check we have queued 'message' ++vgcfgbackup -f out0 $vg ++grep "message1" out0 ++ ++vgchange -an $vg || true ++ ++not dmsetup table ${vg}-pool-tpool ++ ++# Reactivate thin-pool ++vgchange -ay $vg ++ ++# Check message is still queued there ++vgcfgbackup -f out1 $vg ++grep "message1" out1 ++ ++lvchange -an $vg ++ ++lvextend -L+10 $vg/pool ++ ++# Messages should be now processed and gone ++vgcfgbackup -f out2 $vg ++not grep "message1" out2 ++ ++lvchange -an $vg ++ ++lvchange -y -ay $vg/pool_tmeta ++ ++# Kernel metadata must not see dev_id 1 either ++thin_dump $DM_DEV_DIR/$vg/pool_tmeta | tee meta ++not grep 'dev_id="1"' meta ++ ++lvremove -ff $vg ++ ++lvs -a $vg ++ ++vgremove -ff $vg +-- +2.38.1 + diff --git a/SOURCES/0064-vdo-fix-vdosettings-parser.patch b/SOURCES/0064-vdo-fix-vdosettings-parser.patch new file mode 100644 index 0000000..45fd669 --- /dev/null +++ b/SOURCES/0064-vdo-fix-vdosettings-parser.patch @@ -0,0 +1,52 @@ +From b56e8fc94d4d2b6d384148e3f74c54f4e1d816e6 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 15 Aug 2022 13:14:03 +0200 +Subject: [PATCH 4/4] vdo: fix --vdosettings parser + +Parser was incorrectly parsing vdo_use_features - move the skip +of 'use_' prefix into internal loop which handles skipping of '_'. + +(cherry picked from commit bba96e8680ef7fa567d6361c269c0bfc05ce3d2c) +--- + tools/toollib.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/tools/toollib.c b/tools/toollib.c +index 210b3dca5..d9a1a92ec 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1198,13 +1198,11 @@ out: + */ + static int _compare_vdo_option(const char *b1, const char *b2) + { ++ int use_skipped = 0; ++ + if (strncasecmp(b1, "vdo", 3) == 0) // skip vdo prefix + b1 += 3; + +- if ((tolower(*b1) != tolower(*b2)) && +- (strncmp(b2, "use_", 4) == 0)) +- b2 += 4; // try again with skipped prefix 'use_' +- + while (*b1 && *b2) { + if (tolower(*b1) == tolower(*b2)) { + ++b1; +@@ -1216,8 +1214,14 @@ static int _compare_vdo_option(const char *b1, const char *b2) + ++b1; // skip to next char + else if (*b2 == '_') + ++b2; // skip to next char +- else ++ else { ++ if (!use_skipped++ && (strncmp(b2, "use_", 4) == 0)) { ++ b2 += 4; // try again with skipped prefix 'use_' ++ continue; ++ } ++ + break; // mismatch ++ } + } + + return (*b1 || *b2) ? 0 : 1; +-- +2.38.1 + diff --git a/SOURCES/0065-make-generate.patch b/SOURCES/0065-make-generate.patch new file mode 100644 index 0000000..886a426 --- /dev/null +++ b/SOURCES/0065-make-generate.patch @@ -0,0 +1,921 @@ +From 71354c39350b482ca8cf0fd9dcaf025b1d55b7d1 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 8 Dec 2022 14:32:23 +0100 +Subject: [PATCH] make: generate + +--- + man/lvchange.8_pregen | 20 ++++++++++++++++++-- + man/lvconvert.8_pregen | 22 ++++++++++++++++++++-- + man/lvcreate.8_pregen | 24 ++++++++++++++++++++++-- + man/lvdisplay.8_pregen | 5 +++-- + man/lvextend.8_pregen | 5 +++-- + man/lvm-fullreport.8_pregen | 5 +++-- + man/lvm-lvpoll.8_pregen | 5 +++-- + man/lvmconfig.8_pregen | 5 +++-- + man/lvmdevices.8_pregen | 8 +++++--- + man/lvmdiskscan.8_pregen | 5 +++-- + man/lvreduce.8_pregen | 5 +++-- + man/lvremove.8_pregen | 5 +++-- + man/lvrename.8_pregen | 5 +++-- + man/lvresize.8_pregen | 5 +++-- + man/lvs.8_pregen | 5 +++-- + man/lvscan.8_pregen | 5 +++-- + man/pvchange.8_pregen | 5 +++-- + man/pvck.8_pregen | 5 +++-- + man/pvcreate.8_pregen | 5 +++-- + man/pvdisplay.8_pregen | 5 +++-- + man/pvmove.8_pregen | 5 +++-- + man/pvremove.8_pregen | 5 +++-- + man/pvresize.8_pregen | 5 +++-- + man/pvs.8_pregen | 5 +++-- + man/pvscan.8_pregen | 5 +++-- + man/vgcfgbackup.8_pregen | 5 +++-- + man/vgcfgrestore.8_pregen | 5 +++-- + man/vgchange.8_pregen | 5 +++-- + man/vgck.8_pregen | 5 +++-- + man/vgconvert.8_pregen | 5 +++-- + man/vgcreate.8_pregen | 5 +++-- + man/vgdisplay.8_pregen | 5 +++-- + man/vgexport.8_pregen | 5 +++-- + man/vgextend.8_pregen | 5 +++-- + man/vgimport.8_pregen | 5 +++-- + man/vgimportclone.8_pregen | 5 +++-- + man/vgimportdevices.8_pregen | 5 +++-- + man/vgmerge.8_pregen | 5 +++-- + man/vgmknodes.8_pregen | 5 +++-- + man/vgreduce.8_pregen | 5 +++-- + man/vgremove.8_pregen | 5 +++-- + man/vgrename.8_pregen | 5 +++-- + man/vgs.8_pregen | 5 +++-- + man/vgscan.8_pregen | 5 +++-- + man/vgsplit.8_pregen | 5 +++-- + 45 files changed, 188 insertions(+), 91 deletions(-) + +diff --git a/man/lvchange.8_pregen b/man/lvchange.8_pregen +index b559c89c9..27bee0f14 100644 +--- a/man/lvchange.8_pregen ++++ b/man/lvchange.8_pregen +@@ -126,6 +126,8 @@ lvchange \(em Change the attributes of logical volume(s) + \fB--sysinit\fP + .br + \fB-t\fP|\fB--test\fP ++.br ++ \fB--vdosettings\fP \fIString\fP + .br + \fB-v\fP|\fB--verbose\fP + .br +@@ -202,6 +204,8 @@ required, after which the others are optional. + \fB--\fP[\fBraid\fP]\fBminrecoveryrate\fP \fISize\fP[k|UNIT] + .br + \fB--\fP[\fBraid\fP]\fBmaxrecoveryrate\fP \fISize\fP[k|UNIT] ++.br ++ \fB--vdosettings\fP \fIString\fP + .br + \fB--\fP[\fBraid\fP]\fBwritebehind\fP \fINumber\fP + .br +@@ -609,8 +613,9 @@ See \fBlvm.conf\fP(5) for more information about profiles. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +@@ -927,6 +932,17 @@ error messages in multi-stage operations if a tool relies on reading + back metadata it believes has changed but hasn't. + . + .HP ++\fB--vdosettings\fP \fIString\fP ++.br ++Specifies tunable VDO options for VDO LVs. ++Use the form 'option=value' or 'option1=value option2=value', or ++repeat --vdosettings for each option being set. ++These settings override the default VDO behaviors. ++To remove vdosettings and revert to the default ++VDO behaviors, use --vdosettings 'default'. ++See \fBlvmvdo\fP(7) for more information. ++. ++.HP + \fB-v\fP|\fB--verbose\fP ... + .br + Set verbose level. Repeat from 1 to 4 times to increase the detail +diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen +index 679519303..fa52da55c 100644 +--- a/man/lvconvert.8_pregen ++++ b/man/lvconvert.8_pregen +@@ -155,6 +155,8 @@ lvconvert \(em Change logical volume layout + \fB--usepolicies\fP + .br + \fB--vdopool\fP \fILV\fP ++.br ++ \fB--vdosettings\fP \fIString\fP + .br + \fB-v\fP|\fB--verbose\fP + .br +@@ -742,6 +744,8 @@ Convert LV to type vdopool. + .br + [ \fB--deduplication\fP \fBy\fP|\fBn\fP ] + .br ++[ \fB--vdosettings\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +@@ -1131,8 +1135,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +@@ -1535,6 +1540,17 @@ The name of a VDO pool LV. + See \fBlvmvdo\fP(7) for more information about VDO usage. + . + .HP ++\fB--vdosettings\fP \fIString\fP ++.br ++Specifies tunable VDO options for VDO LVs. ++Use the form 'option=value' or 'option1=value option2=value', or ++repeat --vdosettings for each option being set. ++These settings override the default VDO behaviors. ++To remove vdosettings and revert to the default ++VDO behaviors, use --vdosettings 'default'. ++See \fBlvmvdo\fP(7) for more information. ++. ++.HP + \fB-v\fP|\fB--verbose\fP ... + .br + Set verbose level. Repeat from 1 to 4 times to increase the detail +@@ -1808,6 +1824,8 @@ Convert LV to type vdopool. + .br + [ \fB--deduplication\fP \fBy\fP|\fBn\fP ] + .br ++[ \fB--vdosettings\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen +index 2cccbbe56..0ffe92a94 100644 +--- a/man/lvcreate.8_pregen ++++ b/man/lvcreate.8_pregen +@@ -157,6 +157,8 @@ lvcreate \(em Create a logical volume + \fB--vdo\fP + .br + \fB--vdopool\fP \fILV\fP ++.br ++ \fB--vdosettings\fP \fIString\fP + .br + \fB-v\fP|\fB--verbose\fP + .br +@@ -537,6 +539,8 @@ Create a LV that returns VDO when used. + .br + [ \fB--deduplication\fP \fBy\fP|\fBn\fP ] + .br ++[ \fB--vdosettings\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +@@ -1003,8 +1007,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +@@ -1438,6 +1443,17 @@ The name of a VDO pool LV. + See \fBlvmvdo\fP(7) for more information about VDO usage. + . + .HP ++\fB--vdosettings\fP \fIString\fP ++.br ++Specifies tunable VDO options for VDO LVs. ++Use the form 'option=value' or 'option1=value option2=value', or ++repeat --vdosettings for each option being set. ++These settings override the default VDO behaviors. ++To remove vdosettings and revert to the default ++VDO behaviors, use --vdosettings 'default'. ++See \fBlvmvdo\fP(7) for more information. ++. ++.HP + \fB-v\fP|\fB--verbose\fP ... + .br + Set verbose level. Repeat from 1 to 4 times to increase the detail +@@ -1966,6 +1982,8 @@ Create a VDO LV with VDO pool. + .br + [ \fB--deduplication\fP \fBy\fP|\fBn\fP ] + .br ++[ \fB--vdosettings\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +@@ -1996,6 +2014,8 @@ Create a VDO LV with VDO pool. + .br + [ \fB--deduplication\fP \fBy\fP|\fBn\fP ] + .br ++[ \fB--vdosettings\fP \fIString\fP ] ++.br + [ COMMON_OPTIONS ] + .ad b + .RE +diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen +index 04aab4c09..387a7d30d 100644 +--- a/man/lvdisplay.8_pregen ++++ b/man/lvdisplay.8_pregen +@@ -186,8 +186,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvextend.8_pregen b/man/lvextend.8_pregen +index be6992e94..8a3e1ea4e 100644 +--- a/man/lvextend.8_pregen ++++ b/man/lvextend.8_pregen +@@ -328,8 +328,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvm-fullreport.8_pregen b/man/lvm-fullreport.8_pregen +index 02b38ef40..edae0efe3 100644 +--- a/man/lvm-fullreport.8_pregen ++++ b/man/lvm-fullreport.8_pregen +@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvm-lvpoll.8_pregen b/man/lvm-lvpoll.8_pregen +index 7f45f6eb3..fa8027f8e 100644 +--- a/man/lvm-lvpoll.8_pregen ++++ b/man/lvm-lvpoll.8_pregen +@@ -115,8 +115,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvmconfig.8_pregen b/man/lvmconfig.8_pregen +index 51946e1ec..e6762f989 100644 +--- a/man/lvmconfig.8_pregen ++++ b/man/lvmconfig.8_pregen +@@ -156,8 +156,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen +index d64c3a31a..a2397e50f 100644 +--- a/man/lvmdevices.8_pregen ++++ b/man/lvmdevices.8_pregen +@@ -322,7 +322,8 @@ Find a device with the PVID and add the device to the devices file. + .HP + \fB--check\fP + .br +-Check the content of the devices file. ++Checks the content of the devices file. ++Reports incorrect device names or PVIDs for entries. + . + .HP + \fB--commandprofile\fP \fIString\fP +@@ -364,8 +365,9 @@ then it will override the default type that lvm would use. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvmdiskscan.8_pregen b/man/lvmdiskscan.8_pregen +index 7fd3d941d..ac0931c88 100644 +--- a/man/lvmdiskscan.8_pregen ++++ b/man/lvmdiskscan.8_pregen +@@ -102,8 +102,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvreduce.8_pregen b/man/lvreduce.8_pregen +index ea960eb53..cd2e38e5b 100644 +--- a/man/lvreduce.8_pregen ++++ b/man/lvreduce.8_pregen +@@ -130,8 +130,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvremove.8_pregen b/man/lvremove.8_pregen +index 2bd7997a3..8a4afbdff 100644 +--- a/man/lvremove.8_pregen ++++ b/man/lvremove.8_pregen +@@ -136,8 +136,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvrename.8_pregen b/man/lvrename.8_pregen +index d41a4c241..27ce2caeb 100644 +--- a/man/lvrename.8_pregen ++++ b/man/lvrename.8_pregen +@@ -120,8 +120,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvresize.8_pregen b/man/lvresize.8_pregen +index f3ea2536c..10e7dda7c 100644 +--- a/man/lvresize.8_pregen ++++ b/man/lvresize.8_pregen +@@ -286,8 +286,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvs.8_pregen b/man/lvs.8_pregen +index 2b2c5f193..94a74f9dd 100644 +--- a/man/lvs.8_pregen ++++ b/man/lvs.8_pregen +@@ -172,8 +172,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/lvscan.8_pregen b/man/lvscan.8_pregen +index f459ab35b..8d79f22dd 100644 +--- a/man/lvscan.8_pregen ++++ b/man/lvscan.8_pregen +@@ -119,8 +119,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvchange.8_pregen b/man/pvchange.8_pregen +index 4add9ca69..010845274 100644 +--- a/man/pvchange.8_pregen ++++ b/man/pvchange.8_pregen +@@ -179,8 +179,9 @@ multiple tags at once. See \fBlvm\fP(8) for information about tags. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvck.8_pregen b/man/pvck.8_pregen +index 88200f21e..7d6652342 100644 +--- a/man/pvck.8_pregen ++++ b/man/pvck.8_pregen +@@ -351,8 +351,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvcreate.8_pregen b/man/pvcreate.8_pregen +index a74a5ec2a..6ffd596fe 100644 +--- a/man/pvcreate.8_pregen ++++ b/man/pvcreate.8_pregen +@@ -229,8 +229,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen +index 2f26a8727..59628bedd 100644 +--- a/man/pvdisplay.8_pregen ++++ b/man/pvdisplay.8_pregen +@@ -183,8 +183,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvmove.8_pregen b/man/pvmove.8_pregen +index 0f70497a2..f633b97d2 100644 +--- a/man/pvmove.8_pregen ++++ b/man/pvmove.8_pregen +@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvremove.8_pregen b/man/pvremove.8_pregen +index 3d4a86c09..51c589fd7 100644 +--- a/man/pvremove.8_pregen ++++ b/man/pvremove.8_pregen +@@ -103,8 +103,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvresize.8_pregen b/man/pvresize.8_pregen +index 87d87c8ce..9ce57e325 100644 +--- a/man/pvresize.8_pregen ++++ b/man/pvresize.8_pregen +@@ -98,8 +98,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvs.8_pregen b/man/pvs.8_pregen +index 32c28e4d1..955b3f887 100644 +--- a/man/pvs.8_pregen ++++ b/man/pvs.8_pregen +@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/pvscan.8_pregen b/man/pvscan.8_pregen +index 1c96d5aab..1e1cc11ab 100644 +--- a/man/pvscan.8_pregen ++++ b/man/pvscan.8_pregen +@@ -369,8 +369,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgcfgbackup.8_pregen b/man/vgcfgbackup.8_pregen +index 5e658093a..cf984b04b 100644 +--- a/man/vgcfgbackup.8_pregen ++++ b/man/vgcfgbackup.8_pregen +@@ -123,8 +123,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgcfgrestore.8_pregen b/man/vgcfgrestore.8_pregen +index 695e05582..6165cd36e 100644 +--- a/man/vgcfgrestore.8_pregen ++++ b/man/vgcfgrestore.8_pregen +@@ -208,8 +208,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen +index 05c67aead..7c7030c0d 100644 +--- a/man/vgchange.8_pregen ++++ b/man/vgchange.8_pregen +@@ -556,8 +556,9 @@ See \fBlvm.conf\fP(5) for more information about profiles. + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgck.8_pregen b/man/vgck.8_pregen +index a8fa33f4b..cfb828ff9 100644 +--- a/man/vgck.8_pregen ++++ b/man/vgck.8_pregen +@@ -114,8 +114,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgconvert.8_pregen b/man/vgconvert.8_pregen +index 4d54c2b27..b99de39b8 100644 +--- a/man/vgconvert.8_pregen ++++ b/man/vgconvert.8_pregen +@@ -124,8 +124,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgcreate.8_pregen b/man/vgcreate.8_pregen +index 9bb8d3868..d5316aa1c 100644 +--- a/man/vgcreate.8_pregen ++++ b/man/vgcreate.8_pregen +@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen +index 0a12b3c39..b6cd294d5 100644 +--- a/man/vgdisplay.8_pregen ++++ b/man/vgdisplay.8_pregen +@@ -180,8 +180,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgexport.8_pregen b/man/vgexport.8_pregen +index a87058946..6af64b82a 100644 +--- a/man/vgexport.8_pregen ++++ b/man/vgexport.8_pregen +@@ -139,8 +139,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgextend.8_pregen b/man/vgextend.8_pregen +index 2b2650527..e55e0a110 100644 +--- a/man/vgextend.8_pregen ++++ b/man/vgextend.8_pregen +@@ -147,8 +147,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgimport.8_pregen b/man/vgimport.8_pregen +index 5cd8fab84..9f8614205 100644 +--- a/man/vgimport.8_pregen ++++ b/man/vgimport.8_pregen +@@ -128,8 +128,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgimportclone.8_pregen b/man/vgimportclone.8_pregen +index bf0af5841..80da5454b 100644 +--- a/man/vgimportclone.8_pregen ++++ b/man/vgimportclone.8_pregen +@@ -113,8 +113,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgimportdevices.8_pregen b/man/vgimportdevices.8_pregen +index 5897e29ad..44e5fc663 100644 +--- a/man/vgimportdevices.8_pregen ++++ b/man/vgimportdevices.8_pregen +@@ -132,8 +132,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgmerge.8_pregen b/man/vgmerge.8_pregen +index a36e0c7bd..dfe8e2f0f 100644 +--- a/man/vgmerge.8_pregen ++++ b/man/vgmerge.8_pregen +@@ -107,8 +107,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgmknodes.8_pregen b/man/vgmknodes.8_pregen +index 0a03e1582..d7cd722a4 100644 +--- a/man/vgmknodes.8_pregen ++++ b/man/vgmknodes.8_pregen +@@ -108,8 +108,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgreduce.8_pregen b/man/vgreduce.8_pregen +index f3178a618..63b0a20f3 100644 +--- a/man/vgreduce.8_pregen ++++ b/man/vgreduce.8_pregen +@@ -199,8 +199,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgremove.8_pregen b/man/vgremove.8_pregen +index 779c0f13e..661ada673 100644 +--- a/man/vgremove.8_pregen ++++ b/man/vgremove.8_pregen +@@ -109,8 +109,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgrename.8_pregen b/man/vgrename.8_pregen +index d3e776ca4..2b849d180 100644 +--- a/man/vgrename.8_pregen ++++ b/man/vgrename.8_pregen +@@ -133,8 +133,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgs.8_pregen b/man/vgs.8_pregen +index ee5083a93..2ca98b0b0 100644 +--- a/man/vgs.8_pregen ++++ b/man/vgs.8_pregen +@@ -166,8 +166,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgscan.8_pregen b/man/vgscan.8_pregen +index 824e7f673..a8da70d99 100644 +--- a/man/vgscan.8_pregen ++++ b/man/vgscan.8_pregen +@@ -101,8 +101,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +diff --git a/man/vgsplit.8_pregen b/man/vgsplit.8_pregen +index 065c8b52a..99938a4e3 100644 +--- a/man/vgsplit.8_pregen ++++ b/man/vgsplit.8_pregen +@@ -175,8 +175,9 @@ messages sent to the log file and/or syslog (if configured). + .HP + \fB--devices\fP \fIPV\fP + .br +-Devices that the command can use. This option can be repeated +-or accepts a comma separated list of devices. This overrides ++Restricts the devices that are visible and accessible to the command. ++Devices not listed will appear to be missing. This option can be ++repeated, or accepts a comma separated list of devices. This overrides + the devices file. + . + .HP +-- +2.38.1 + diff --git a/SOURCES/0066-vdo-use-single-validator.patch b/SOURCES/0066-vdo-use-single-validator.patch new file mode 100644 index 0000000..4d63ae1 --- /dev/null +++ b/SOURCES/0066-vdo-use-single-validator.patch @@ -0,0 +1,90 @@ +From d0b5614d43ac41ee24a480a6272f256b1a242873 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 4 Jul 2022 16:08:30 +0200 +Subject: [PATCH 1/3] vdo: use single validator + +Add era lenght validation into dm_vdo_validate_target_params() +and reuse this validator also for _check_lv_segment(). + +(cherry picked from commit 8ca2b1bc213188037ecedfbf76de53de871c7f5b) +--- + device_mapper/vdo/vdo_target.c | 9 ++++++++- + lib/metadata/merge.c | 37 ++-------------------------------- + 2 files changed, 10 insertions(+), 36 deletions(-) + +diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c +index 2ffd29145..0e5abd162 100644 +--- a/device_mapper/vdo/vdo_target.c ++++ b/device_mapper/vdo/vdo_target.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2018 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved. + * + * This file is part of LVM2. + * +@@ -38,6 +38,13 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + valid = false; + } + ++ if ((vtp->block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) || ++ (vtp->block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)) { ++ log_error("VDO block map era length %u out of range.", ++ vtp->block_map_era_length); ++ valid = false; ++ } ++ + if ((vtp->index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) || + (vtp->index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB)) { + log_error("VDO index memory size %u out of range.", +diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c +index 8eff74297..5209f51b5 100644 +--- a/lib/metadata/merge.c ++++ b/lib/metadata/merge.c +@@ -545,41 +545,8 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg, + seg_error("is missing a VDO pool data LV"); + } else if (!lv_is_vdo_pool_data(seg_lv(seg, 0))) + seg_error("is not VDO pool data LV"); +- if ((seg->vdo_params.minimum_io_size != (512 >> SECTOR_SHIFT)) && +- (seg->vdo_params.minimum_io_size != (4096 >> SECTOR_SHIFT))) +- seg_error("sets unsupported VDO minimum io size"); +- if ((seg->vdo_params.block_map_cache_size_mb < DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB) || +- (seg->vdo_params.block_map_cache_size_mb > DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB)) +- seg_error("sets unsupported VDO block map cache size"); +- if ((seg->vdo_params.block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) || +- (seg->vdo_params.block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)) +- seg_error("sets unsupported VDO block map era length"); +- if ((seg->vdo_params.index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) || +- (seg->vdo_params.index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB)) +- seg_error("sets unsupported VDO index memory size"); +- if ((seg->vdo_params.slab_size_mb < DM_VDO_SLAB_SIZE_MINIMUM_MB) || +- (seg->vdo_params.slab_size_mb > DM_VDO_SLAB_SIZE_MAXIMUM_MB)) +- seg_error("sets unsupported VDO slab size"); +- if ((seg->vdo_params.max_discard < DM_VDO_MAX_DISCARD_MINIMUM) || +- (seg->vdo_params.max_discard > DM_VDO_MAX_DISCARD_MAXIMUM)) +- seg_error("sets unsupported VDO max discard"); +- if (seg->vdo_params.ack_threads > DM_VDO_ACK_THREADS_MAXIMUM) +- seg_error("sets unsupported VDO ack threads"); +- if ((seg->vdo_params.bio_threads < DM_VDO_BIO_THREADS_MINIMUM) || +- (seg->vdo_params.bio_threads > DM_VDO_BIO_THREADS_MAXIMUM)) +- seg_error("sets unsupported VDO bio threads"); +- if ((seg->vdo_params.bio_rotation < DM_VDO_BIO_ROTATION_MINIMUM) || +- (seg->vdo_params.bio_rotation > DM_VDO_BIO_ROTATION_MAXIMUM)) +- seg_error("sets unsupported VDO bio rotation"); +- if ((seg->vdo_params.cpu_threads < DM_VDO_CPU_THREADS_MINIMUM) || +- (seg->vdo_params.cpu_threads > DM_VDO_CPU_THREADS_MAXIMUM)) +- seg_error("sets unsupported VDO cpu threads"); +- if (seg->vdo_params.hash_zone_threads > DM_VDO_HASH_ZONE_THREADS_MAXIMUM) +- seg_error("sets unsupported VDO hash zone threads"); +- if (seg->vdo_params.logical_threads > DM_VDO_LOGICAL_THREADS_MAXIMUM) +- seg_error("sets unsupported VDO logical threads"); +- if (seg->vdo_params.physical_threads > DM_VDO_PHYSICAL_THREADS_MAXIMUM) +- seg_error("sets unsupported VDO physical threads"); ++ if (!dm_vdo_validate_target_params(&seg->vdo_params, 0)) ++ seg_error("sets invalid VDO parameter(s)"); + } else { /* !VDO pool */ + if (seg->vdo_pool_header_size) + seg_error("sets vdo_pool_header_size"); +-- +2.38.1 + diff --git a/SOURCES/0067-vdo-use-defines-also-for-configuration-defines.patch b/SOURCES/0067-vdo-use-defines-also-for-configuration-defines.patch new file mode 100644 index 0000000..2616aa9 --- /dev/null +++ b/SOURCES/0067-vdo-use-defines-also-for-configuration-defines.patch @@ -0,0 +1,295 @@ +From b16082b05639d4321cbf699d3309fe24a8bc71fa Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 24 Jun 2022 15:54:08 +0200 +Subject: [PATCH 2/3] vdo: use defines also for configuration defines + +Keep single source for most of values printed in lvm.conf +(still needs some conversion) + +Correct max for logical threads to 60 +(we may refuse some older configuration which might eventually +user higher numbers - but so far let's assume no user have ever set this +as it's been non-trivial and if would complicate code unnecessarily.) + +Accept maximum of 4PiB for virtual size of VDO LV +(lvm2 will drop 'header borders to 0 for this case'). + +(cherry picked from commit b5c8e591ed9ee30b67e79d60705d3c0bb8509a2a) +--- + conf/example.conf.in | 9 +++--- + device_mapper/vdo/vdo_limits.h | 55 ++++++++++++++++++---------------- + device_mapper/vdo/vdo_target.c | 11 +++---- + lib/config/config_settings.h | 32 +++++++++++++------- + 4 files changed, 60 insertions(+), 47 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index a78ed7333..897622b9d 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -625,13 +625,12 @@ allocation { + # Enables or disables whether VDO volume should tag its latency-critical + # writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5 + # process writes with this flag at a higher priority. +- # Default is enabled. + # This configuration option has an automatic default value. + # vdo_use_metadata_hints = 1 + + # Configuration option allocation/vdo_minimum_io_size. + # The minimum IO size for VDO volume to accept, in bytes. +- # Valid values are 512 or 4096. The recommended and default value is 4096. ++ # Valid values are 512 or 4096. The recommended value is 4096. + # This configuration option has an automatic default value. + # vdo_minimum_io_size = 4096 + +@@ -684,7 +683,7 @@ allocation { + # Configuration option allocation/vdo_bio_threads. + # Specifies the number of threads to use for submitting I/O + # operations to the storage device of VDO volume. +- # The value must be in range [1..100] ++ # The value must be in range [1..100]. + # Each additional thread after the first will use an additional 18MiB of RAM, + # plus 1.12 MiB of RAM per megabyte of configured read cache size. + # This configuration option has an automatic default value. +@@ -698,7 +697,7 @@ allocation { + + # Configuration option allocation/vdo_cpu_threads. + # Specifies the number of threads to use for CPU-intensive work such as +- # hashing or compression for VDO volume. The value must be in range [1..100] ++ # hashing or compression for VDO volume. The value must be in range [1..100]. + # This configuration option has an automatic default value. + # vdo_cpu_threads = 2 + +@@ -716,7 +715,7 @@ allocation { + # processing based on the hash value computed from the block data. + # A logical thread count of 9 or more will require explicitly specifying + # a sufficiently large block map cache size, as well. +- # The value must be in range [0..100]. ++ # The value must be in range [0..60]. + # vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be + # either all zero or all non-zero. + # This configuration option has an automatic default value. +diff --git a/device_mapper/vdo/vdo_limits.h b/device_mapper/vdo/vdo_limits.h +index e145100b1..db365ace2 100644 +--- a/device_mapper/vdo/vdo_limits.h ++++ b/device_mapper/vdo/vdo_limits.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2018 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved. + * + * This file is part of the device-mapper userspace tools. + * +@@ -15,49 +15,52 @@ + #ifndef DEVICE_MAPPER_VDO_LIMITS_H + #define DEVICE_MAPPER_VDO_LIMITS_H + ++#ifndef SECTOR_SHIFT ++#define SECTOR_SHIFT 9L ++#endif ++ + #define DM_VDO_BLOCK_SIZE UINT64_C(8) // 4KiB in sectors ++#define DM_VDO_BLOCK_SIZE_KB (DM_VDO_BLOCK_SIZE << SECTOR_SHIFT) + + #define DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB (128) // 128MiB + #define DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB (16 * 1024 * 1024 - 1) // 16TiB - 1 + #define DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_PER_LOGICAL_THREAD (4096 * DM_VDO_BLOCK_SIZE_KB) + +-#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM (1) +-#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM (16380) ++#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM 1 ++#define DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM 16380 + +-#define DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB (256) // 0.25 GiB ++#define DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB 256 // 0.25 GiB + #define DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB (1024 * 1024 * 1024) // 1TiB + +-//#define DM_VDO_READ_CACHE_SIZE_MINIMUM_MB (0) +-#define DM_VDO_READ_CACHE_SIZE_MAXIMUM_MB (16 * 1024 * 1024 - 1) // 16TiB - 1 +- +-#define DM_VDO_SLAB_SIZE_MINIMUM_MB (128) // 128MiB ++#define DM_VDO_SLAB_SIZE_MINIMUM_MB 128 // 128MiB + #define DM_VDO_SLAB_SIZE_MAXIMUM_MB (32 * 1024) // 32GiB ++#define DM_VDO_SLABS_MAXIMUM 8192 + +-//#define DM_VDO_LOGICAL_SIZE_MINIMUM_MB (0) +-#define DM_VDO_LOGICAL_SIZE_MAXIMUM_MB (UINT64_C(4) * 1024 * 1024 * 1024) // 4PiB ++#define DM_VDO_LOGICAL_SIZE_MAXIMUM (UINT64_C(4) * 1024 * 1024 * 1024 * 1024 * 1024 >> SECTOR_SHIFT) // 4PiB ++#define DM_VDO_PHYSICAL_SIZE_MAXIMUM (UINT64_C(64) * DM_VDO_BLOCK_SIZE_KB * 1024 * 1024 * 1024 >> SECTOR_SHIFT) // 256TiB + +-//#define DM_VDO_ACK_THREADS_MINIMUM (0) +-#define DM_VDO_ACK_THREADS_MAXIMUM (100) ++#define DM_VDO_ACK_THREADS_MINIMUM 0 ++#define DM_VDO_ACK_THREADS_MAXIMUM 100 + +-#define DM_VDO_BIO_THREADS_MINIMUM (1) +-#define DM_VDO_BIO_THREADS_MAXIMUM (100) ++#define DM_VDO_BIO_THREADS_MINIMUM 1 ++#define DM_VDO_BIO_THREADS_MAXIMUM 100 + +-#define DM_VDO_BIO_ROTATION_MINIMUM (1) +-#define DM_VDO_BIO_ROTATION_MAXIMUM (1024) ++#define DM_VDO_BIO_ROTATION_MINIMUM 1 ++#define DM_VDO_BIO_ROTATION_MAXIMUM 1024 + +-#define DM_VDO_CPU_THREADS_MINIMUM (1) +-#define DM_VDO_CPU_THREADS_MAXIMUM (100) ++#define DM_VDO_CPU_THREADS_MINIMUM 1 ++#define DM_VDO_CPU_THREADS_MAXIMUM 100 + +-//#define DM_VDO_HASH_ZONE_THREADS_MINIMUM (0) +-#define DM_VDO_HASH_ZONE_THREADS_MAXIMUM (100) ++#define DM_VDO_HASH_ZONE_THREADS_MINIMUM 0 ++#define DM_VDO_HASH_ZONE_THREADS_MAXIMUM 100 + +-//#define DM_VDO_LOGICAL_THREADS_MINIMUM (0) +-#define DM_VDO_LOGICAL_THREADS_MAXIMUM (100) ++#define DM_VDO_LOGICAL_THREADS_MINIMUM 0 ++#define DM_VDO_LOGICAL_THREADS_MAXIMUM 60 + +-//#define DM_VDO_PHYSICAL_THREADS_MINIMUM (0) +-#define DM_VDO_PHYSICAL_THREADS_MAXIMUM (16) ++#define DM_VDO_PHYSICAL_THREADS_MINIMUM 0 ++#define DM_VDO_PHYSICAL_THREADS_MAXIMUM 16 + +-#define DM_VDO_MAX_DISCARD_MINIMUM (1) +-#define DM_VDO_MAX_DISCARD_MAXIMUM (UINT32_MAX / 4096) ++#define DM_VDO_MAX_DISCARD_MINIMUM 1 ++#define DM_VDO_MAX_DISCARD_MAXIMUM (UINT32_MAX / (uint32_t)(DM_VDO_BLOCK_SIZE_KB)) + + #endif // DEVICE_MAPPER_VDO_LIMITS_H +diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c +index 0e5abd162..3ebe0592e 100644 +--- a/device_mapper/vdo/vdo_target.c ++++ b/device_mapper/vdo/vdo_target.c +@@ -18,14 +18,15 @@ + #include "vdo_limits.h" + #include "target.h" + ++/* validate vdo target parameters and 'vdo_size' in sectors */ + bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + uint64_t vdo_size) + { + bool valid = true; + + /* 512 or 4096 bytes only ATM */ +- if ((vtp->minimum_io_size != 1) && +- (vtp->minimum_io_size != 8)) { ++ if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) && ++ (vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) { + log_error("VDO minimum io size %u is unsupported.", + vtp->minimum_io_size); + valid = false; +@@ -127,10 +128,10 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + valid = false; + } + +- if (vdo_size >= (DM_VDO_LOGICAL_SIZE_MAXIMUM_MB * UINT64_C(1024 * 2))) { ++ if (vdo_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) { + log_error("VDO logical size is by " FMTu64 "KiB bigger then limit " FMTu64 "TiB.", +- (vdo_size - (DM_VDO_LOGICAL_SIZE_MAXIMUM_MB * UINT64_C(1024 * 2))) / 2, +- DM_VDO_LOGICAL_SIZE_MAXIMUM_MB / UINT64_C(1024) / UINT64_C(1024)); ++ (vdo_size - DM_VDO_LOGICAL_SIZE_MAXIMUM) / 2, ++ DM_VDO_LOGICAL_SIZE_MAXIMUM / (UINT64_C(1024) * 1024 * 1024 * 1024 >> SECTOR_SHIFT)); + valid = false; + } + +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index d280e7adb..2c91e8bb6 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -118,6 +118,7 @@ + * the previous default value was set (uncommented) in lvm.conf. + */ + #include "lib/config/defaults.h" ++#include "device_mapper/vdo/vdo_limits.h" + + cfg_section(root_CFG_SECTION, "(root)", root_CFG_SECTION, 0, vsn(0, 0, 0), 0, NULL, NULL) + +@@ -708,12 +709,11 @@ cfg(allocation_vdo_use_deduplication_CFG, "vdo_use_deduplication", allocation_CF + cfg(allocation_vdo_use_metadata_hints_CFG, "vdo_use_metadata_hints", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_USE_METADATA_HINTS, VDO_1ST_VSN, NULL, 0, NULL, + "Enables or disables whether VDO volume should tag its latency-critical\n" + "writes with the REQ_SYNC flag. Some device mapper targets such as dm-raid5\n" +- "process writes with this flag at a higher priority.\n" +- "Default is enabled.\n") ++ "process writes with this flag at a higher priority.\n") + + cfg(allocation_vdo_minimum_io_size_CFG, "vdo_minimum_io_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_MINIMUM_IO_SIZE, VDO_1ST_VSN, NULL, 0, NULL, + "The minimum IO size for VDO volume to accept, in bytes.\n" +- "Valid values are 512 or 4096. The recommended and default value is 4096.\n") ++ "Valid values are 512 or 4096. The recommended value is 4096.\n") + + cfg(allocation_vdo_block_map_cache_size_mb_CFG, "vdo_block_map_cache_size_mb", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BLOCK_MAP_CACHE_SIZE_MB, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the amount of memory in MiB allocated for caching block map\n" +@@ -726,7 +726,8 @@ cfg(allocation_vdo_block_map_era_length_CFG, "vdo_block_map_period", allocation_ + "The speed with which the block map cache writes out modified block map pages.\n" + "A smaller era length is likely to reduce the amount time spent rebuilding,\n" + "at the cost of increased block map writes during normal operation.\n" +- "The maximum and recommended value is 16380; the minimum value is 1.\n") ++ "The maximum and recommended value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM) ++ "; the minimum value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ".\n") + + cfg(allocation_vdo_check_point_frequency_CFG, "vdo_check_point_frequency", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CHECK_POINT_FREQUENCY, VDO_1ST_VSN, NULL, 0, NULL, + "The default check point frequency for VDO volume.\n") +@@ -748,27 +749,34 @@ cfg(allocation_vdo_slab_size_mb_CFG, "vdo_slab_size_mb", allocation_CFG_SECTION, + cfg(allocation_vdo_ack_threads_CFG, "vdo_ack_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_ACK_THREADS, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the number of threads to use for acknowledging\n" + "completion of requested VDO I/O operations.\n" +- "The value must be at in range [0..100].\n") ++ "The value must be at in range [" DM_TO_STRING(DM_VDO_ACK_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_ACK_THREADS_MAXIMUM) "].\n") + + cfg(allocation_vdo_bio_threads_CFG, "vdo_bio_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BIO_THREADS, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the number of threads to use for submitting I/O\n" + "operations to the storage device of VDO volume.\n" +- "The value must be in range [1..100]\n" ++ "The value must be in range [" DM_TO_STRING(DM_VDO_BIO_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_BIO_THREADS_MAXIMUM) "].\n" + "Each additional thread after the first will use an additional 18MiB of RAM,\n" + "plus 1.12 MiB of RAM per megabyte of configured read cache size.\n") + + cfg(allocation_vdo_bio_rotation_CFG, "vdo_bio_rotation", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_BIO_ROTATION, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the number of I/O operations to enqueue for each bio-submission\n" +- "thread before directing work to the next. The value must be in range [1..1024].\n") ++ "thread before directing work to the next. The value must be in range [" ++ DM_TO_STRING(DM_VDO_BIO_ROTATION_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_BIO_ROTATION_MAXIMUM) "].\n") + + cfg(allocation_vdo_cpu_threads_CFG, "vdo_cpu_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CPU_THREADS, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the number of threads to use for CPU-intensive work such as\n" +- "hashing or compression for VDO volume. The value must be in range [1..100]\n") ++ "hashing or compression for VDO volume. The value must be in range [" ++ DM_TO_STRING(DM_VDO_CPU_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_CPU_THREADS_MAXIMUM) "].\n") + + cfg(allocation_vdo_hash_zone_threads_CFG, "vdo_hash_zone_threads", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_HASH_ZONE_THREADS, VDO_1ST_VSN, NULL, 0, NULL, + "Specifies the number of threads across which to subdivide parts of the VDO\n" + "processing based on the hash value computed from the block data.\n" +- "The value must be at in range [0..100].\n" ++ "The value must be at in range [" DM_TO_STRING(DM_VDO_HASH_ZONE_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_HASH_ZONE_THREADS_MAXIMUM) "].\n" + "vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n" + "either all zero or all non-zero.\n") + +@@ -777,7 +785,8 @@ cfg(allocation_vdo_logical_threads_CFG, "vdo_logical_threads", allocation_CFG_SE + "processing based on the hash value computed from the block data.\n" + "A logical thread count of 9 or more will require explicitly specifying\n" + "a sufficiently large block map cache size, as well.\n" +- "The value must be in range [0..100].\n" ++ "The value must be in range [" DM_TO_STRING(DM_VDO_LOGICAL_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_LOGICAL_THREADS_MAXIMUM) "].\n" + "vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n" + "either all zero or all non-zero.\n") + +@@ -785,7 +794,8 @@ cfg(allocation_vdo_physical_threads_CFG, "vdo_physical_threads", allocation_CFG_ + "Specifies the number of threads across which to subdivide parts of the VDO\n" + "processing based on physical block addresses.\n" + "Each additional thread after the first will use an additional 10MiB of RAM.\n" +- "The value must be in range [0..16].\n" ++ "The value must be in range [" DM_TO_STRING(DM_VDO_PHYSICAL_THREADS_MINIMUM) ".." ++ DM_TO_STRING(DM_VDO_PHYSICAL_THREADS_MAXIMUM) "].\n" + "vdo_hash_zone_threads, vdo_logical_threads and vdo_physical_threads must be\n" + "either all zero or all non-zero.\n") + +-- +2.38.1 + diff --git a/SOURCES/0068-vdo-report-supported-range-in-error-path.patch b/SOURCES/0068-vdo-report-supported-range-in-error-path.patch new file mode 100644 index 0000000..4023fc3 --- /dev/null +++ b/SOURCES/0068-vdo-report-supported-range-in-error-path.patch @@ -0,0 +1,144 @@ +From cce56ebaa6b67d53b0430d5b52b957e194c9527d Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sat, 9 Jul 2022 21:28:40 +0200 +Subject: [PATCH 3/3] vdo: report supported range in error path + +(cherry picked from commit 9f3eff002cc229d3c22dfd7db6da69dadc0bd460) +--- + device_mapper/vdo/vdo_target.c | 63 ++++++++++++++++++++++++---------- + 1 file changed, 45 insertions(+), 18 deletions(-) + +diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c +index 3ebe0592e..ab3fff26a 100644 +--- a/device_mapper/vdo/vdo_target.c ++++ b/device_mapper/vdo/vdo_target.c +@@ -27,81 +27,108 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + /* 512 or 4096 bytes only ATM */ + if ((vtp->minimum_io_size != (512 >> SECTOR_SHIFT)) && + (vtp->minimum_io_size != (4096 >> SECTOR_SHIFT))) { +- log_error("VDO minimum io size %u is unsupported.", ++ log_error("VDO minimum io size %u is unsupported [512, 4096].", + vtp->minimum_io_size); + valid = false; + } + + if ((vtp->block_map_cache_size_mb < DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB) || + (vtp->block_map_cache_size_mb > DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB)) { +- log_error("VDO block map cache size %u out of range.", +- vtp->block_map_cache_size_mb); ++ log_error("VDO block map cache size %u MiB is out of range [%u..%u].", ++ vtp->block_map_cache_size_mb, ++ DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB, ++ DM_VDO_BLOCK_MAP_CACHE_SIZE_MAXIMUM_MB); + valid = false; + } + + if ((vtp->block_map_era_length < DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) || + (vtp->block_map_era_length > DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)) { +- log_error("VDO block map era length %u out of range.", +- vtp->block_map_era_length); ++ log_error("VDO block map era length %u is out of range [%u..%u].", ++ vtp->block_map_era_length, ++ DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM, ++ DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM); + valid = false; + } + + if ((vtp->index_memory_size_mb < DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB) || + (vtp->index_memory_size_mb > DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB)) { +- log_error("VDO index memory size %u out of range.", +- vtp->index_memory_size_mb); ++ log_error("VDO index memory size %u MiB is out of range [%u..%u].", ++ vtp->index_memory_size_mb, ++ DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB, ++ DM_VDO_INDEX_MEMORY_SIZE_MAXIMUM_MB); + valid = false; + } + + if ((vtp->slab_size_mb < DM_VDO_SLAB_SIZE_MINIMUM_MB) || + (vtp->slab_size_mb > DM_VDO_SLAB_SIZE_MAXIMUM_MB)) { +- log_error("VDO slab size %u out of range.", +- vtp->slab_size_mb); ++ log_error("VDO slab size %u MiB is out of range [%u..%u].", ++ vtp->slab_size_mb, ++ DM_VDO_SLAB_SIZE_MINIMUM_MB, ++ DM_VDO_SLAB_SIZE_MAXIMUM_MB); + valid = false; + } + + if ((vtp->max_discard < DM_VDO_MAX_DISCARD_MINIMUM) || + (vtp->max_discard > DM_VDO_MAX_DISCARD_MAXIMUM)) { +- log_error("VDO max discard %u out of range.", +- vtp->max_discard); ++ log_error("VDO max discard %u is out of range [%u..%u].", ++ vtp->max_discard, ++ DM_VDO_MAX_DISCARD_MINIMUM, ++ DM_VDO_MAX_DISCARD_MAXIMUM); + valid = false; + } + + if (vtp->ack_threads > DM_VDO_ACK_THREADS_MAXIMUM) { +- log_error("VDO ack threads %u out of range.", vtp->ack_threads); ++ log_error("VDO ack threads %u is out of range [0..%u].", ++ vtp->ack_threads, ++ DM_VDO_ACK_THREADS_MAXIMUM); + valid = false; + } + + if ((vtp->bio_threads < DM_VDO_BIO_THREADS_MINIMUM) || + (vtp->bio_threads > DM_VDO_BIO_THREADS_MAXIMUM)) { +- log_error("VDO bio threads %u out of range.", vtp->bio_threads); ++ log_error("VDO bio threads %u is out of range [%u..%u].", ++ vtp->bio_threads, ++ DM_VDO_BIO_THREADS_MINIMUM, ++ DM_VDO_BIO_THREADS_MAXIMUM); + valid = false; + } + + if ((vtp->bio_rotation < DM_VDO_BIO_ROTATION_MINIMUM) || + (vtp->bio_rotation > DM_VDO_BIO_ROTATION_MAXIMUM)) { +- log_error("VDO bio rotation %u out of range.", vtp->bio_rotation); ++ log_error("VDO bio rotation %u is out of range [%u..%u].", ++ vtp->bio_rotation, ++ DM_VDO_BIO_ROTATION_MINIMUM, ++ DM_VDO_BIO_ROTATION_MAXIMUM); + valid = false; + } + + if ((vtp->cpu_threads < DM_VDO_CPU_THREADS_MINIMUM) || + (vtp->cpu_threads > DM_VDO_CPU_THREADS_MAXIMUM)) { +- log_error("VDO cpu threads %u out of range.", vtp->cpu_threads); ++ log_error("VDO cpu threads %u is out of range [%u..%u].", ++ vtp->cpu_threads, ++ DM_VDO_CPU_THREADS_MINIMUM, ++ DM_VDO_CPU_THREADS_MAXIMUM); + valid = false; + } + + if (vtp->hash_zone_threads > DM_VDO_HASH_ZONE_THREADS_MAXIMUM) { +- log_error("VDO hash zone threads %u out of range.", vtp->hash_zone_threads); ++ log_error("VDO hash zone threads %u is out of range [0..%u].", ++ vtp->hash_zone_threads, ++ DM_VDO_HASH_ZONE_THREADS_MAXIMUM); + valid = false; + } + + if (vtp->logical_threads > DM_VDO_LOGICAL_THREADS_MAXIMUM) { +- log_error("VDO logical threads %u out of range.", vtp->logical_threads); ++ log_error("VDO logical threads %u is out of range [0..%u].", ++ vtp->logical_threads, ++ DM_VDO_LOGICAL_THREADS_MAXIMUM); + valid = false; + } + + if (vtp->physical_threads > DM_VDO_PHYSICAL_THREADS_MAXIMUM) { +- log_error("VDO physical threads %u out of range.", vtp->physical_threads); ++ log_error("VDO physical threads %u is out of range [0..%u].", ++ vtp->physical_threads, ++ DM_VDO_PHYSICAL_THREADS_MAXIMUM); + valid = false; + } + +-- +2.38.1 + diff --git a/SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch b/SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch new file mode 100644 index 0000000..7a7e9b3 --- /dev/null +++ b/SOURCES/0069-vdo-ensure-VDO-config-is-removed.patch @@ -0,0 +1,35 @@ +From c41468a8acff9fd71bf774c821ad7c92623889da Mon Sep 17 00:00:00 2001 +From: Andrew Walsh +Date: Mon, 15 Nov 2021 10:49:06 -0500 +Subject: [PATCH 069/115] vdo: ensure VDO config is removed + +Make sure to remove the VDO config after conversion +of LVM-backed VDO. + +Addresses point 3 in rhbz#1987024#c5 + +(cherry picked from commit 522561e64b5fe73cb9d01c2ee2d4b7624b0ddff4) +--- + scripts/lvm_import_vdo.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index beb55dbdb..cc09187e9 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -405,6 +405,12 @@ EOF + verbose "Converting to VDO pool." + dry "$LVM" lvconvert $YES $VERB $FORCE --config "$PARAMS" -Zn -V "${vdo_logicalSize}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" + ++ # Note: that this is spelled OPPOSITE the other $IS_LV checks. ++ if [ "$IS_LV" = "1" ]; then ++ verbose "Removing now-unused VDO entry from VDO config." ++ dry "$VDO" remove $VDOCONF --force --verbose --name "$VDONAME" ++ fi ++ + rm -fr "$TEMPDIR" + } + +-- +2.41.0 + diff --git a/SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch b/SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch new file mode 100644 index 0000000..ade23f5 --- /dev/null +++ b/SOURCES/0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch @@ -0,0 +1,50 @@ +From a147a14813d576a11ed2f9ff08090fad874e418a Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 31 May 2022 22:48:38 +0200 +Subject: [PATCH 070/115] vdo: fix conversion of vdo_slab_size_mb + +When converting VDO volume, the parameter vdo_slabSize was +incorrectly copied as vdo_blockMapCacheSize, however this parameter +is then no longer used for any table line creation so the wrong +value was only stored in metadata. + +Also use just single get_kb_size_with_unit_ and remove it's duplicate +functionality with get_mb_size_with_unit_. + +Use $VERB for vdo remove call. + +(cherry picked from commit 1b070f366ba57a6eb24df03241284732db5047e9) +--- + WHATS_NEW | 3 ++- + scripts/lvm_import_vdo.sh | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index bffd24648..705fbde74 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,6 +1,7 @@ + Version 2.03.17 - + =============================== +- Fix lvconvert --test --type vdo-pool execution. ++ Fix lvconvert --test --type vdo-pool execution. ++ Fix vdo_slab_size_mb value for converted VDO volume. + + Version 2.03.16 - + ==================================== +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index cc09187e9..c10b3b050 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -408,7 +408,7 @@ EOF + # Note: that this is spelled OPPOSITE the other $IS_LV checks. + if [ "$IS_LV" = "1" ]; then + verbose "Removing now-unused VDO entry from VDO config." +- dry "$VDO" remove $VDOCONF --force --verbose --name "$VDONAME" ++ dry "$VDO" remove $VDOCONF $VERB --force --name "$VDONAME" + fi + + rm -fr "$TEMPDIR" +-- +2.41.0 + diff --git a/SOURCES/0071-tests-add-lvm_vdo_wrapper.patch b/SOURCES/0071-tests-add-lvm_vdo_wrapper.patch new file mode 100644 index 0000000..9ec24fb --- /dev/null +++ b/SOURCES/0071-tests-add-lvm_vdo_wrapper.patch @@ -0,0 +1,396 @@ +From 2456b39b345a589949528bd439052a776d274d63 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 31 May 2022 22:45:29 +0200 +Subject: [PATCH 071/115] tests: add lvm_vdo_wrapper + +Introduce a replacement vdo manager wrapper for testing. +When using test suite on a system without vdo manager (which has got +deprecated) - we still need its functionality to prepare 'vdo volume' +for testing lvm_import_vdo. + +Wrapper currently need 2 binaries from older 'vdo 6.2' package - +to be named: +oldvdoformat - format VDO metadata with older format +oldvdoprepareforlvm - shift vdo metadata by 1MiB + +(cherry picked from commit 2ecfd503edadaf5d46115826c629754bf9fd573f) +--- + test/Makefile.in | 1 + + test/lib/lvm_vdo_wrapper.sh | 353 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 354 insertions(+) + create mode 100755 test/lib/lvm_vdo_wrapper.sh + +diff --git a/test/Makefile.in b/test/Makefile.in +index ecb9e4264..f69dc97b6 100644 +--- a/test/Makefile.in ++++ b/test/Makefile.in +@@ -369,6 +369,7 @@ LIB = $(addprefix lib/, $(LIB_SECURETEST) $(LIB_DMSECURETEST) $(LIB_SHARED) $(LI + $(Q) $(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/ + $(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm + $(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/lvm_import_vdo.sh lib/lvm_import_vdo ++ $(Q) which vdo || $(LN_S) -f $(abs_top_srcdir)/test/lib/lvm_vdo_wrapper.sh lib/vdo + @test "$(srcdir)" = . || \ + for i in $(LIB_LVMLOCKD_CONF) $(LIB_MKE2FS_CONF); do \ + test -n "$(Q)" || echo "$(LN_S) -f $(abs_top_srcdir)/test/lib/$$i lib/"; \ +diff --git a/test/lib/lvm_vdo_wrapper.sh b/test/lib/lvm_vdo_wrapper.sh +new file mode 100755 +index 000000000..d622d6456 +--- /dev/null ++++ b/test/lib/lvm_vdo_wrapper.sh +@@ -0,0 +1,353 @@ ++#!/bin/bash ++# ++# Wrapper script for 'naive' emulation of vdo manager tool for systems ++# that no longer have this tool present ++# ++ ++set -euE -o pipefail ++ ++# tool for formating 'old' VDO metadata format ++LVM_VDO_FORMAT=${LVM_VDO_FORMAT-"oldvdoformat"} ++# tool for shifting VDO metadata header by 2MiB ++LVM_VDO_PREPARE=${LVM_VDO_PREPARE-"oldvdoprepareforlvm"} ++# default vdo conf file ++LVM_VDO_DEFAULT_CONF=${LVM_VDO_DEFAULT_CONF-"/tmp/vdoconf.yml"} ++ ++vdo_die_() { ++ echo -e "$@" >&2 ++ return 1 ++} ++ ++vdo_verbose_() { ++ test -z "$vdo_verbose" || echo "$0:" "$@" ++} ++ ++vdo_dry_() { ++ if test -n "$vdo_dry"; then ++ vdo_verbose_ "Dry execution" "$@" ++ return 0 ++ fi ++ vdo_verbose_ "Executing" "$@" ++ "$@" ++} ++ ++vdo_get_kb_size_with_unit_() { ++ local sz=${2-1} # 2nd. arg as unit - default 'k' ++ ++ case "$sz" in ++ [mM]) sz=1024 ;; ++ esac ++ ++ case "$1" in ++ *[mM]) sz=1024 ;; ++ *[gG]) sz=$(( 1024 * 1024 )) ;; ++ *[tT]) sz=$(( 1024 * 1024 * 1024 )) ;; ++ *[pP]) sz=$(( 1024 * 1024 * 1024 * 1024 )) ;; ++ esac ++ ++ echo $(( sz * ${1%[kKmMgGtTpP]} )) ++} ++ ++# ++# Emulate functionality of deprecated 'vdo create' ++# ++vdo_create_() { ++local cachesize= ++local devsize= ++local emulate512=disabled ++local logicalsize= ++local maxdiscardsize= ++local slabbits=0 # 4k ++local slabsize= ++local sparse= ++local table= ++local vdo_compression_msg= ++local vdo_dry= ++local vdo_index_msg= ++local vdo_logicalBlockSize= ++local vdo_verbose= ++ ++local vdo_ackThreads=${vdo_ackThreads-1} ++local vdo_bioRotationInterval=${vdo_bioRotationInterval-64} ++local vdo_bioThreads=${vdo_bioThreads-4} ++local vdo_blockMapCacheSize=${vdo_blockMapCacheSize-128M} ++local vdo_blockMapPeriod=${vdo_blockMapPeriod-16380} ++local vdo_compression=${vdo_compression-enabled} ++local vdo_confFile=$LVM_VDO_DEFAULT_CONF # place some file in /tmp ++local vdo_cpuThreads=${vdo_cpuThreads-2} ++local vdo_deduplication=${vdo_deduplication-enabled} ++local vdo_hashZoneThreads=${vdo_hashZoneThreads-1} ++local vdo_indexCfreq=${vdo_indexCfreq-0} ++local vdo_indexMemory=${vdo_indexMemory-0.25} ++local vdo_indexSparse=${vdo_indexSparse-disabled} ++local vdo_indexThreads=${vdo_indexThreads-0} ++local vdo_logicalSize=${vdo_logicalSize-0} ++local vdo_logicalThreads=${vdo_logicalThreads-1} ++local vdo_maxDiscardSize=${vdo_maxDiscardSize-4K} ++local vdo_name=${vdo_name-VDONAME} ++local vdo_physicalThreads=${vdo_physicalThreads-1} ++local vdo_slabSize=${vdo_slabSize-2G} ++local vdo_uuid="VDO-$(uuidgen || echo \"f7a3ecdc-40a0-4e43-814c-4a7039a75de4\")" ++local vdo_writePolicy=${vdo_writePolicy-auto} ++ ++while [ "$#" -ne 0 ] ++do ++ case "$1" in ++ "--blockMapCacheSize") shift; vdo_blockMapCacheSize=$1 ;; ++ "--blockMapPeriod") shift; vdo_blockMapPeriod=$1 ;; ++ "--compression") shift; vdo_compression=$1 ;; ++ "--confFile"|"-f") shift; vdo_confFile=$1 ;; ++ "--deduplication") shift; vdo_deduplication=$1 ;; ++ "--device") shift; vdo_device=$1 ;; ++ "--emulate512") shift; emulate512=$1 ;; ++ "--indexMem") shift; vdo_indexMemory=$1 ;; ++ "--maxDiscardSize") shift; vdo_maxDiscardSize=$1 ;; ++ "--name"|"-n") shift; vdo_name=$1 ;; ++ "--sparseIndex") shift; vdo_indexSparse=$1 ;; ++ "--uuid") shift ;; # ignored ++ "--vdoAckThreads") shift; vdo_ackThreads=$1 ;; ++ "--vdoBioRotationInterval") shift; vdo_bioRotationInterval=$1 ;; ++ "--vdoBioThreads") shift; vdo_bioThreads=$1 ;; ++ "--vdoCpuThreads") shift; vdo_cpuThreads=$1 ;; ++ "--vdoHashZoneThreads") shift; vdo_hashZoneThreads=$1 ;; ++ "--vdoLogicalSize") shift; vdo_logicalSize=$1 ;; ++ "--vdoLogicalThreads") shift; vdo_logicalThreads=$1 ;; ++ "--vdoLogLevel") shift ;; # ignored ++ "--vdoPhysicalThreads") shift; vdo_physicalSize=$1 ;; ++ "--vdoSlabSize") shift; vdo_slabSize=$1 ;; ++ "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;; ++ "--writePolicy") shift; vdo_writePolicy=$1 ;; ++ esac ++ shift ++done ++ ++# Convert when set ++case "$emulate512" in ++ "enabled") vdo_logicalBlockSize=512 ;; ++ "disabled") vdo_logicalBlockSize=4096 ;; ++ *) vdo_die_ "Invalid emulate512 setting." ++esac ++ ++case "$vdo_deduplication" in ++ "enabled") vdo_index_msg="index-enable" ;; ++ "disabled") vdo_index_msg="index-disable";; ++ *) vdo_die_ "Invalid deduplication setting." ++esac ++ ++case "$vdo_compression" in ++ "enabled") vdo_compression_msg="compression on" ;; ++ "disabled") vdo_compression_msg="compression off";; ++ *) vdo_die_ "Invalid compression setting." ++esac ++ ++test -n "${vdo_device-}" || vdo_die_ "VDO device is missing" ++ ++blkid -s UUID -o value "${vdo_device}" || true ++ ++devsize=$(blockdev --getsize64 "$vdo_device") ++devsize=$(( devsize / 4096 )) # convert to 4KiB units ++ ++logicalsize=$(vdo_get_kb_size_with_unit_ "$vdo_logicalSize" M) ++logicalsize=$(( logicalsize * 2 )) # 512B units ++ ++cachesize=$(vdo_get_kb_size_with_unit_ "$vdo_blockMapCacheSize" M) ++cachesize=$(( cachesize / 4 )) # 4KiB units ++ ++maxdiscardsize=$(vdo_get_kb_size_with_unit_ "$vdo_maxDiscardSize" M) ++maxdiscardsize=$(( maxdiscardsize / 4 )) # 4KiB units ++ ++test -e "$vdo_confFile" || { ++ cat > "$vdo_confFile" <> "$vdo_confFile" </dev/null || return 0 ++vdo_dry_ dmsetup remove $vdo_force "$vdo_name" || true ++} ++ ++# ++# vdo remove ++# ++vdo_remove_() { ++local vdo_confFile=$LVM_VDO_DEFAULT_CONF ++local vdo_name= ++ ++vdo_stop_ "$@" ++while [ "$#" -ne 0 ] ++do ++ case "$1" in ++ "--confFile"|"-f") shift; vdo_confFile=$1 ;; ++ "--name"|"-n") shift; vdo_name=$1 ;; ++ esac ++ shift ++done ++ ++# remove entry from conf file ++awk -v vdovolname="$vdo_name" 'BEGIN { have=0 } ++ $0 ~ "!VDOService" { have=0 } ++ $0 ~ vdovolname":" { have=1 } ++ { if (have==0) { print } ;} ++ ' "$vdo_confFile" >"${vdo_confFile}.new" ++ ++mv "${vdo_confFile}.new" "$vdo_confFile" ++grep "!VDOService" "$vdo_confFile" || rm -f "$vdo_confFile" ++} ++ ++ ++# ++# print_config_file ++# ++vdo_print_config_file_() { ++local vdo_confFile=$LVM_VDO_DEFAULT_CONF ++ ++while [ "$#" -ne 0 ] ++do ++ case "$1" in ++ "--confFile"|"-f") shift; vdo_confFile=$1 ;; ++ "--verbose"|"-d"|"--debug") ;; ++ "--logfile") shift ;; # ignore ++ esac ++ shift ++done ++ ++cat "$vdo_confFile" ++} ++ ++# ++# vdo convert ++# ++vdo_convert_() { ++local vdo_confFile=$LVM_VDO_DEFAULT_CONF ++local vdo_dry= ++local vdo_force= ++local vdo_name= ++local vdo_verbose= ++local vdo_device= ++ ++while [ "$#" -ne 0 ] ++do ++ case "$1" in ++ "--confFile"|"-f") shift; vdo_confFile=$1 ;; ++ "--name"|"-n") shift; vdo_name=$1 ;; ++ "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;; ++ "--force") vdo_force="--force" ;; ++ esac ++ shift ++done ++ ++vdo_device=$(awk -v vdovolname="$vdo_name" 'BEGIN { have=0 } ++ $0 ~ "!VDOService" { have=0 } ++ $0 ~ vdovolname":" { have=1 } ++ { if (have==1 && $0 ~ "device:" ) { print $2 } ;}'\ ++ "$vdo_confFile") ++ ++#dmsetup status --target vdo "$vdo_name" || true ++vdo_dry_ "$LVM_VDO_PREPARE" "$vdo_device" ++vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true ++} ++ ++# ++# MAIN ++# ++case "$1" in ++ "create") shift; vdo_create_ "$@" ;; ++ "remove") shift; vdo_remove_ "$@" ;; ++ "stop") shift; vdo_stop_ "$@" ;; ++ "convert") shift; vdo_convert_ "$@" ;; ++ "printConfigFile") shift; vdo_print_config_file_ "$@" ;; ++esac +-- +2.41.0 + diff --git a/SOURCES/0072-tests-update-for-wrapper.patch b/SOURCES/0072-tests-update-for-wrapper.patch new file mode 100644 index 0000000..21631ee --- /dev/null +++ b/SOURCES/0072-tests-update-for-wrapper.patch @@ -0,0 +1,84 @@ +From 64a78a2904c0481de8c1f9894cedcbd5f6525287 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 7 Jun 2022 16:52:30 +0200 +Subject: [PATCH 072/115] tests: update for wrapper + +Update calling vdo manager since our vdo wrapper has a simple shell +arg parser so it needs args without '=' + +Also correct using DM_DEV_DIR for 'pvcreate' + +(cherry picked from commit 4a498512077b4fe5cf6b806a91228bd23e513123) +--- + test/shell/vdo-convert.sh | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh +index 2a2026c2e..8b03344a7 100644 +--- a/test/shell/vdo-convert.sh ++++ b/test/shell/vdo-convert.sh +@@ -54,7 +54,7 @@ vgcreate $vg "$dev1" + + lvcreate -L5G -n $lv1 $vg + +-vdo create $VDOCONF --name "$VDONAME" --device="$DM_DEV_DIR/$vg/$lv1" --vdoLogicalSize=10G ++vdo create $VDOCONF --name "$VDONAME" --device "$DM_DEV_DIR/$vg/$lv1" --vdoSlabSize 128M --vdoLogicalSize 10G + + mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME" + +@@ -75,7 +75,7 @@ lvremove -f $vg + # Test user can specify different VDO LV name (so the original LV is renamed) + lvcreate -y -L5G -n $lv1 $vg + +-vdo create $VDOCONF --name "$VDONAME" --device="$DM_DEV_DIR/$vg/$lv1" --vdoLogicalSize=10G ++vdo create $VDOCONF --name "$VDONAME" --device "$DM_DEV_DIR/$vg/$lv1" --vdoSlabSize 128M --vdoLogicalSize 10G + + lvm_import_vdo -y --name $vg/$lv2 "$DM_DEV_DIR/$vg/$lv1" + +@@ -95,7 +95,7 @@ vgcreate $vg2 "$dev2" + # + # Check conversion of VDO volume on non-LV device and with >2T size + # +-vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=3T ++vdo create $VDOCONF --name "$VDONAME" --device "$dev1" --vdoSlabSize 128M --vdoLogicalSize 3T + + # Fail with an already existing volume group $vg2 + not lvm_import_vdo --dry-run -y -v --name $vg2/$lv1 "$dev1" |& tee err +@@ -117,7 +117,7 @@ vgremove -f $vg + aux teardown_devs + aux prepare_devs 1 23456 + +-vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=23G ++vdo create $VDOCONF --name "$VDONAME" --device "$dev1" --vdoSlabSize 128M --vdoLogicalSize 23G + + mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME" + +@@ -137,6 +137,7 @@ aux prepare_loop 60000 || skip + + test -f LOOP + LOOP=$(< LOOP) ++LOOP="${DM_DEV_DIR}/${LOOP##/dev/}" + + aux extend_filter "a|$LOOP|" + aux extend_devices "$LOOP" +@@ -155,7 +156,7 @@ aux extend_devices "$LOOP" + # + # automate... + # +-vdo create $VDOCONF --name "$VDONAME" --device="$LOOP" --vdoLogicalSize=23G \ ++vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoLogicalSize 23G\ + --blockMapCacheSize 192 \ + --blockMapPeriod 2048 \ + --emulate512 disabled \ +@@ -173,7 +174,7 @@ vdo create $VDOCONF --name "$VDONAME" --device="$LOOP" --vdoLogicalSize=23G \ + # Get VDO table line + dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig + +-DM_DEV_DIR="" lvm_import_vdo -y --name $vg/$lv "$LOOP" ++lvm_import_vdo -y --name $vg/$lv "$LOOP" + lvs -a $vg + + dmsetup table "$vg-${lv}_vpool-vpool" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee new-vdo-lv +-- +2.41.0 + diff --git a/SOURCES/0073-lvmdbusd-Change-unit-test-vdo-minimum-size.patch b/SOURCES/0073-lvmdbusd-Change-unit-test-vdo-minimum-size.patch new file mode 100644 index 0000000..a75ce58 --- /dev/null +++ b/SOURCES/0073-lvmdbusd-Change-unit-test-vdo-minimum-size.patch @@ -0,0 +1,73 @@ +From 8702e97022753c9f21c85af6deecea76b179911d Mon Sep 17 00:00:00 2001 +From: Tony Asleson +Date: Wed, 25 May 2022 16:03:27 -0500 +Subject: [PATCH 073/115] lvmdbusd: Change unit test vdo minimum size + +(cherry picked from commit 47c61907b4adbdead50f5bb5ac95c0f5d0fe263e) +--- + test/dbus/lvmdbustest.py | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py +index 6d692223f..3eef77fd7 100755 +--- a/test/dbus/lvmdbustest.py ++++ b/test/dbus/lvmdbustest.py +@@ -23,6 +23,9 @@ import os + + g_tmo = 0 + ++# Approx. min size ++VDO_MIN_SIZE = mib(8192) ++ + # Prefix on created objects to enable easier clean-up + g_prefix = os.getenv('PREFIX', '') + +@@ -1155,7 +1158,7 @@ class TestDbusService(unittest.TestCase): + return + + # This may not pass +- for i in [48, 64, 128]: ++ for i in [64, 128]: + yes = self._test_expired_timer(i) + if yes: + break +@@ -1907,8 +1910,8 @@ class TestDbusService(unittest.TestCase): + vdo_pool_object_path = self.handle_return( + vg_proxy.VgVdo.CreateVdoPoolandLv( + pool_name, lv_name, +- dbus.UInt64(mib(4096)), # Appears to be minimum size +- dbus.UInt64(mib(8192)), ++ dbus.UInt64(VDO_MIN_SIZE), ++ dbus.UInt64(VDO_MIN_SIZE * 2), + dbus.Int32(g_tmo), + EOD)) + +@@ -1950,7 +1953,7 @@ class TestDbusService(unittest.TestCase): + vg_proxy = self._vg_create(vg_prefix="vdo_conv_") + lv = self._test_lv_create( + vg_proxy.Vg.LvCreate, +- (dbus.String(pool_name), dbus.UInt64(mib(4096)), ++ (dbus.String(pool_name), dbus.UInt64(VDO_MIN_SIZE), + dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo), + EOD), vg_proxy.Vg, LV_BASE_INT) + lv_obj_path = self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name)) +@@ -1959,7 +1962,7 @@ class TestDbusService(unittest.TestCase): + vdo_pool_path = self.handle_return( + vg_proxy.VgVdo.CreateVdoPool( + dbus.ObjectPath(lv.object_path), lv_name, +- dbus.UInt64(mib(8192)), ++ dbus.UInt64(VDO_MIN_SIZE), + dbus.Int32(g_tmo), + EOD)) + +@@ -2083,6 +2086,7 @@ if __name__ == '__main__': + std_err_print('\n*** Testing only lvm shell mode ***\n') + + for g_tmo in [0, 15]: ++ std_err_print('Testing TMO=%d\n' % g_tmo) + if mode == 0: + if set_execution(False, r): + r.register_result(unittest.main(exit=False)) +-- +2.41.0 + diff --git a/SOURCES/0074-vdo-fix-conversion-of-vdo_slab_size_mb-2nd.patch b/SOURCES/0074-vdo-fix-conversion-of-vdo_slab_size_mb-2nd.patch new file mode 100644 index 0000000..812d17a --- /dev/null +++ b/SOURCES/0074-vdo-fix-conversion-of-vdo_slab_size_mb-2nd.patch @@ -0,0 +1,31 @@ +From e82e23447f830bd6c38bbefa600212e84cdb0f27 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 11 Jul 2022 01:07:24 +0200 +Subject: [PATCH 074/115] vdo: fix conversion of vdo_slab_size_mb 2nd + +Patch 1b070f366ba57a6eb24df03241284732db5047e9 should have +been already fixing this issue but since it the incorrect +patch rebasing the change to vdo_slabSize got lost. +So again now with explicit one-line patch. + +(cherry picked from commit d2667bc25bccaf0f70cc2ded0fd3f25a79cb4f6c) +--- + scripts/lvm_import_vdo.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index c10b3b050..c4c1d152e 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -324,7 +324,7 @@ allocation { + vdo_check_point_frequency = $vdo_indexCfreq + vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse") + vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}") +- vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 )) ++ vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_slabSize") / 1024 )) + vdo_ack_threads = $vdo_ackThreads + vdo_bio_threads = $vdo_bioThreads + vdo_bio_rotation = $vdo_bioRotationInterval +-- +2.41.0 + diff --git a/SOURCES/0075-vdo-update-info-about-memory.patch b/SOURCES/0075-vdo-update-info-about-memory.patch new file mode 100644 index 0000000..84d0325 --- /dev/null +++ b/SOURCES/0075-vdo-update-info-about-memory.patch @@ -0,0 +1,49 @@ +From 1a39e0c2c24c7c505753658f9a74bf962fdf013b Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 4 Jul 2022 15:00:26 +0200 +Subject: [PATCH 075/115] vdo: update info about memory + +Add more info about kernel target memory allocation associated with +VDO pool usage. + +(cherry picked from commit f445624c339a5c1436a47d2b51046869f183eb03) +--- + man/lvmvdo.7_main | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main +index 14bd640b5..8c3e3eeaa 100644 +--- a/man/lvmvdo.7_main ++++ b/man/lvmvdo.7_main +@@ -12,7 +12,7 @@ for primary storage. + .P + Deduplication is a technique for reducing the consumption of storage + resources by eliminating multiple copies of duplicate blocks. Compression +-takes the individual unique blocks and shrinks them. ++takes the individual unique blocks and shrinks them. + These reduced blocks are then efficiently packed together into + physical blocks. Thin provisioning manages the mapping from logical blocks + presented by VDO to where the data has actually been physically stored, +@@ -358,8 +358,17 @@ take otherwise as device is already expected to be empty. + . + .SS \n+[step]. Memory usage + . +-The VDO target requires 370 MiB of RAM plus an additional 268 MiB +-per each 1 TiB of physical storage managed by the volume. ++The VDO target requires 38 MiB of RAM and several variable amounts: ++.IP \(bu 2 ++1.15 MiB of RAM for each 1 MiB of configured block map cache size. ++The block map cache requires a minimum of 150 MiB RAM. ++.br ++.IP \(bu ++1.6 MiB of RAM for each 1 TiB of logical space. ++.br ++.IP \(bu ++268 MiB of RAM for each 1 TiB of physical storage managed by the volume. ++.br + .P + UDS requires a minimum of 250 MiB of RAM, + which is also the default amount that deduplication uses. +-- +2.41.0 + diff --git a/SOURCES/0076-vdo-check-vdo-memory-constrains.patch b/SOURCES/0076-vdo-check-vdo-memory-constrains.patch new file mode 100644 index 0000000..430ef61 --- /dev/null +++ b/SOURCES/0076-vdo-check-vdo-memory-constrains.patch @@ -0,0 +1,246 @@ +From 783213e4da16a70f5e3d5efae2d409b92d899fc9 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 8 Jul 2022 23:33:29 +0200 +Subject: [PATCH 076/115] vdo: check vdo memory constrains + +Add function to check for avaialble memory for particular VDO +configuration - to avoid unnecessary machine swapping for configs +that will not fit into memory (possibly in locked section). + +Formula tries to estimate RAM size machine can use also with +swapping for kernel target - but still leaving some amount of +usable RAM. + +Estimation is based on documented RAM usage of VDO target. + +If the /proc/meminfo would be theoretically unavailable, try to use +'sysinfo()' function, however this is giving only free RAM without +the knowledge about how much RAM could be eventually swapped. + +TODO: move _get_memory_info() into generic lvm2 API function used +by other targets with non-trivial memory requirements. + +(cherry picked from commit ebad057579aeff0980a1b8af7eaacd56e62ed0c9) +--- + lib/metadata/metadata-exported.h | 2 + + lib/metadata/vdo_manip.c | 144 +++++++++++++++++++++++++++++++ + lib/vdo/vdo.c | 8 +- + tools/lvcreate.c | 4 + + 4 files changed, 156 insertions(+), 2 deletions(-) + +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index 7bac5b900..449c8d014 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -1377,6 +1377,8 @@ int fill_vdo_target_params(struct cmd_context *cmd, + struct dm_vdo_target_params *vtp, + uint64_t *vdo_pool_header_size, + struct profile *profile); ++int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, ++ uint64_t virtual_size, struct dm_vdo_target_params *vtp); + /* -- metadata/vdo_manip.c */ + + struct logical_volume *find_pvmove_lv(struct volume_group *vg, +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 11a119a68..9f449ef8b 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -23,6 +23,8 @@ + #include "lib/config/defaults.h" + #include "lib/misc/lvm-exec.h" + ++#include // sysinfo ++ + const char *get_vdo_compression_state_name(enum dm_vdo_compression_state state) + { + switch (state) { +@@ -516,3 +518,145 @@ int fill_vdo_target_params(struct cmd_context *cmd, + + return 1; + } ++ ++static int _get_sysinfo_memory(uint64_t *total_mb, uint64_t *available_mb) ++{ ++ struct sysinfo si = { 0 }; ++ ++ *total_mb = *available_mb = UINT64_MAX; ++ ++ if (sysinfo(&si) != 0) ++ return 0; ++ ++ log_debug("Sysinfo free:%lu bufferram:%lu sharedram:%lu freehigh:%lu unit:%u.", ++ si.freeram >> 20, si.bufferram >> 20, si.sharedram >> 20, ++ si.freehigh >> 20, si.mem_unit); ++ ++ *available_mb = ((uint64_t)(si.freeram + si.bufferram) * si.mem_unit) >> 30; ++ *total_mb = si.totalram >> 30; ++ ++ return 1; ++} ++ ++typedef struct mem_table_s { ++ const char *name; ++ uint64_t *value; ++} mem_table_t; ++ ++static int _compare_mem_table_s(const void *a, const void *b){ ++ return strcmp(((const mem_table_t*)a)->name, ((const mem_table_t*)b)->name); ++} ++ ++static int _get_memory_info(uint64_t *total_mb, uint64_t *available_mb) ++{ ++ uint64_t anon_pages, mem_available, mem_free, mem_total, shmem, swap_free; ++ uint64_t can_swap; ++ mem_table_t mt[] = { ++ { "AnonPages", &anon_pages }, ++ { "MemAvailable", &mem_available }, ++ { "MemFree", &mem_free }, ++ { "MemTotal", &mem_total }, ++ { "Shmem", &shmem }, ++ { "SwapFree", &swap_free }, ++ }; ++ ++ char line[128], namebuf[32], *e, *tail; ++ FILE *fp; ++ mem_table_t findme = { namebuf, NULL }; ++ mem_table_t *found; ++ ++ if (!(fp = fopen("/proc/meminfo", "r"))) ++ return _get_sysinfo_memory(total_mb, available_mb); ++ ++ while (fgets(line, sizeof(line), fp)) { ++ if (!(e = strchr(line, ':'))) ++ break; ++ ++ if ((++e - line) > sizeof(namebuf)) ++ continue; // something too long ++ ++ (void)dm_strncpy((char*)findme.name, line, e - line); ++ ++ found = bsearch(&findme, mt, DM_ARRAY_SIZE(mt), sizeof(mem_table_t), ++ _compare_mem_table_s); ++ if (!found) ++ continue; // not interesting ++ ++ *(found->value) = (uint64_t) strtoull(e, &tail, 10); ++ ++ if ((e == tail) || errno) ++ log_debug("Failing to parse value from %s.", line); ++ else ++ log_debug("Parsed %s = " FMTu64 " KiB.", found->name, *(found->value)); ++ } ++ (void)fclose(fp); ++ ++ // use at most 2/3 of swap space to keep machine usable ++ can_swap = (anon_pages + shmem) * 2 / 3; ++ swap_free = swap_free * 2 / 3; ++ ++ if (can_swap > swap_free) ++ can_swap = swap_free; ++ ++ // TODO: add more constrains, i.e. 3/4 of physical RAM... ++ ++ *total_mb = mem_total >> 10; ++ *available_mb = (mem_available + can_swap) >> 10; ++ ++ return 1; ++} ++ ++static uint64_t _round_1024(uint64_t s) ++{ ++ return (s + ((1 << 10) - 1)) >> 10; ++} ++ ++static uint64_t _round_sectors_to_tib(uint64_t s) ++{ ++ return (s + ((UINT64_C(1) << (40 - SECTOR_SHIFT)) - 1)) >> (40 - SECTOR_SHIFT); ++} ++ ++int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, ++ uint64_t virtual_size, struct dm_vdo_target_params *vtp) ++{ ++ uint64_t req_mb, total_mb, available_mb; ++ uint64_t phy_mb = _round_sectors_to_tib(UINT64_C(268) * physical_size); // 268 MiB per 1 TiB of physical size ++ uint64_t virt_mb = _round_1024(UINT64_C(1638) * _round_sectors_to_tib(virtual_size)); // 1.6 MiB per 1 TiB ++ uint64_t cache_mb = _round_1024(UINT64_C(1177) * vtp->block_map_cache_size_mb); // 1.15 MiB per 1 MiB cache size ++ char msg[512]; ++ ++ if (cache_mb < 150) ++ cache_mb = 150; // always at least 150 MiB for block map ++ ++ // total required memory for VDO target ++ req_mb = 38 + vtp->index_memory_size_mb + virt_mb + phy_mb + cache_mb; ++ ++ _get_memory_info(&total_mb, &available_mb); ++ ++ (void)snprintf(msg, sizeof(msg), "VDO configuration needs %s RAM for physical volume size %s, " ++ "%s RAM for virtual volume size %s, %s RAM for block map cache size %s and " ++ "%s RAM for index memory.", ++ display_size(cmd, phy_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, physical_size), ++ display_size(cmd, virt_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, virtual_size), ++ display_size(cmd, cache_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, ((uint64_t)vtp->block_map_cache_size_mb) << (20 - SECTOR_SHIFT)), ++ display_size(cmd, ((uint64_t)vtp->index_memory_size_mb) << (20 - SECTOR_SHIFT))); ++ ++ if (req_mb > available_mb) { ++ log_error("Not enough free memory for VDO target. %s RAM is required, but only %s RAM is available.", ++ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, available_mb << (20 - SECTOR_SHIFT))); ++ log_print_unless_silent("%s", msg); ++ return 0; ++ } ++ ++ log_debug("VDO requires %s RAM, currently available %s RAM.", ++ display_size(cmd, req_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, available_mb << (20 - SECTOR_SHIFT))); ++ ++ log_verbose("%s", msg); ++ ++ return 1; ++} +diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c +index 52e9443ea..b9bcc044f 100644 +--- a/lib/vdo/vdo.c ++++ b/lib/vdo/vdo.c +@@ -355,8 +355,8 @@ static int _vdo_pool_target_status_compatible(const char *type) + } + + static int _vdo_pool_add_target_line(struct dev_manager *dm, +- struct dm_pool *mem __attribute__((unused)), +- struct cmd_context *cmd __attribute__((unused)), ++ struct dm_pool *mem, ++ struct cmd_context *cmd, + void **target_state __attribute__((unused)), + struct lv_segment *seg, + const struct lv_activate_opts *laopts __attribute__((unused)), +@@ -369,6 +369,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + log_error(INTERNAL_ERROR "Passed segment is not VDO pool."); + return 0; + } ++ ++ if (!check_vdo_constrains(cmd, seg->lv->size, seg_lv(seg, 0)->size, &seg->vdo_params)) ++ return_0; ++ + if (!(vdo_pool_name = dm_build_dm_name(mem, seg->lv->vg->name, seg->lv->name, lv_layer(seg->lv)))) + return_0; + +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index 8de6f3408..fb57d84bd 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -1729,6 +1729,10 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name, + if (!_update_extents_params(vg, lp, lcp)) + goto_out; + ++ if (seg_is_vdo(lp) && !check_vdo_constrains(cmd, (uint64_t)lp->extents * vg->extent_size, ++ lcp->virtual_size, &lp->vdo_params)) ++ return_0; ++ + if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp)) + goto_out; + +-- +2.41.0 + diff --git a/SOURCES/0077-vdo-add-reformating-to-extent-size-aligned-virtual-s.patch b/SOURCES/0077-vdo-add-reformating-to-extent-size-aligned-virtual-s.patch new file mode 100644 index 0000000..95f738d --- /dev/null +++ b/SOURCES/0077-vdo-add-reformating-to-extent-size-aligned-virtual-s.patch @@ -0,0 +1,79 @@ +From d2a2720ccb88d99c76423ebd5c3bb1f13dc60ab1 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sat, 9 Jul 2022 00:42:01 +0200 +Subject: [PATCH 077/115] vdo: add reformating to extent size aligned virtual + size + +Newer VDO kernel target require to have matching virtual size - this +however cause incompatiblity when lvcreate is let to format VDO data +device and read the usable size from vdoformat. +Altough this is a kernel regression and will likely get fixed, +lvm2 can actually reformat VDO device to use properly aligned VDO LV +size to make this problem disappear. + +(cherry picked from commit a477490e812639fed3be495f215fcf1a7b65b7ee) +--- + lib/metadata/vdo_manip.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 9f449ef8b..f3a4a9534 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -227,10 +227,11 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + const struct dm_vdo_target_params *vtp, + uint64_t *logical_size) + { +- char *dpath; ++ char *dpath, *c; + const struct dm_config_node *cn; + const struct dm_config_value *cv; + struct pipe_data pdata; ++ uint64_t logical_size_aligned = 1; + FILE *f; + uint64_t lb; + unsigned slabbits; +@@ -247,7 +248,9 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + return 0; + } + ++reformat: + if (*logical_size) { ++ logical_size_aligned = 0; + if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K", + (*logical_size / 2)) < 0) + return_0; +@@ -332,8 +335,8 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + log_verbose("Available VDO logical blocks " FMTu64 " (%s).", + lb, display_size(data_lv->vg->cmd, *logical_size)); + } +- if ((dpath = strchr(buf, '\n'))) +- *dpath = 0; /* cut last '\n' away */ ++ if ((c = strchr(buf, '\n'))) ++ *c = 0; /* cut last '\n' away */ + if (buf[0]) + log_print(" %s", buf); /* Print vdo_format messages */ + } +@@ -348,6 +351,19 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + return 0; + } + ++ if (logical_size_aligned) { ++ // align obtained size to extent size ++ logical_size_aligned = *logical_size / data_lv->vg->extent_size * data_lv->vg->extent_size; ++ if (*logical_size != logical_size_aligned) { ++ *logical_size = logical_size_aligned; ++ argv[1] = (char*) "--force"; ++ args = 2; ++ log_verbose("Reformating VDO to align virtual size %s by extent size.", ++ display_size(data_lv->vg->cmd, *logical_size)); ++ goto reformat; ++ } ++ } ++ + return 1; + } + +-- +2.41.0 + diff --git a/SOURCES/0078-vdo-support-v4-kernel-target-line.patch b/SOURCES/0078-vdo-support-v4-kernel-target-line.patch new file mode 100644 index 0000000..71543a5 --- /dev/null +++ b/SOURCES/0078-vdo-support-v4-kernel-target-line.patch @@ -0,0 +1,172 @@ +From c160f54ec5cc26b78db38058f1a8bd63da9e225d Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 8 Jul 2022 23:35:06 +0200 +Subject: [PATCH 078/115] vdo: support v4 kernel target line + +Check and use new available table line v4, if kernel supports it. + +(cherry picked from commit 1c18ed3b4ab2f2d5a15995b8f0a18d7d1c4d60ca) +--- + device_mapper/all.h | 1 + + device_mapper/libdm-deptree.c | 37 +++++++++++++++++++++++------------ + lib/metadata/segtype.h | 1 + + lib/vdo/vdo.c | 10 ++++++++-- + test/shell/vdo-convert.sh | 2 ++ + 5 files changed, 37 insertions(+), 14 deletions(-) + +diff --git a/device_mapper/all.h b/device_mapper/all.h +index 17f78d989..e45f5923a 100644 +--- a/device_mapper/all.h ++++ b/device_mapper/all.h +@@ -1020,6 +1020,7 @@ int dm_tree_node_add_integrity_target(struct dm_tree_node *node, + */ + int dm_tree_node_add_vdo_target(struct dm_tree_node *node, + uint64_t size, ++ uint32_t vdo_version, + const char *vdo_pool_name, + const char *data_uuid, + uint64_t data_size, +diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c +index e4bf4c814..2d382037c 100644 +--- a/device_mapper/libdm-deptree.c ++++ b/device_mapper/libdm-deptree.c +@@ -214,6 +214,7 @@ struct load_segment { + uint32_t device_id; /* Thin */ + + // VDO params ++ uint32_t vdo_version; /* VDO - version of target table line */ + struct dm_tree_node *vdo_data; /* VDO */ + struct dm_vdo_target_params vdo_params; /* VDO */ + const char *vdo_name; /* VDO - device name is ALSO passed as table arg */ +@@ -2865,18 +2866,28 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + return 0; + } + +- EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s " +- "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u", +- data_dev, +- seg->vdo_data_size / 8, // this parameter is in 4K units +- seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units +- seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units +- seg->vdo_params.block_map_era_length, +- seg->vdo_params.use_metadata_hints ? "on" : "off" , +- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" : +- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" : +- (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy +- seg->vdo_name, ++ if (seg->vdo_version < 4) { ++ EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s ", ++ data_dev, ++ seg->vdo_data_size / 8, // this parameter is in 4K units ++ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units ++ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units ++ seg->vdo_params.block_map_era_length, ++ seg->vdo_params.use_metadata_hints ? "on" : "off" , ++ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_SYNC) ? "sync" : ++ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC) ? "async" : ++ (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy ++ seg->vdo_name); ++ } else { ++ EMIT_PARAMS(pos, "V4 %s " FMTu64 " %u " FMTu64 " %u ", ++ data_dev, ++ seg->vdo_data_size / 8, // this parameter is in 4K units ++ seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units ++ seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units ++ seg->vdo_params.block_map_era_length); ++ } ++ ++ EMIT_PARAMS(pos, "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u", + seg->vdo_params.max_discard, + seg->vdo_params.ack_threads, + seg->vdo_params.bio_threads, +@@ -4323,6 +4334,7 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode, + + int dm_tree_node_add_vdo_target(struct dm_tree_node *node, + uint64_t size, ++ uint32_t vdo_version, + const char *vdo_pool_name, + const char *data_uuid, + uint64_t data_size, +@@ -4344,6 +4356,7 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node, + if (!_link_tree_nodes(node, seg->vdo_data)) + return_0; + ++ seg->vdo_version = vdo_version; + seg->vdo_params = *vtp; + seg->vdo_name = vdo_pool_name; + seg->vdo_data_size = data_size; +diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h +index 2f4949267..3e52f04a1 100644 +--- a/lib/metadata/segtype.h ++++ b/lib/metadata/segtype.h +@@ -353,6 +353,7 @@ int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); + #endif + + #define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */ ++#define VDO_FEATURE_VERSION4 (1U << 1) /* version 8.2.0 */ + + int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); + +diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c +index b9bcc044f..9efb424f0 100644 +--- a/lib/vdo/vdo.c ++++ b/lib/vdo/vdo.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2018-2022 Red Hat, Inc. All rights reserved. + * + * This file is part of LVM2. + * +@@ -364,6 +364,10 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + uint32_t *pvmove_mirror_count __attribute__((unused))) + { + char *vdo_pool_name, *data_uuid; ++ unsigned attrs = 0; ++ ++ if (seg->segtype->ops->target_present) ++ seg->segtype->ops->target_present(cmd, NULL, &attrs); + + if (!seg_is_vdo_pool(seg)) { + log_error(INTERNAL_ERROR "Passed segment is not VDO pool."); +@@ -381,6 +385,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + + /* VDO uses virtual size instead of its physical size */ + if (!dm_tree_node_add_vdo_target(node, get_vdo_pool_virtual_size(seg), ++ !(attrs & VDO_FEATURE_VERSION4) ? 2 : 4, + vdo_pool_name, data_uuid, seg_lv(seg, 0)->size, + &seg->vdo_params)) + return_0; +@@ -390,7 +395,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + + static int _vdo_target_present(struct cmd_context *cmd, + const struct lv_segment *seg __attribute__((unused)), +- unsigned *attributes __attribute__((unused))) ++ unsigned *attributes) + { + /* List of features with their kernel target version */ + static const struct feature { +@@ -401,6 +406,7 @@ static int _vdo_target_present(struct cmd_context *cmd, + const char *feature; + } _features[] = { + { 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" }, ++ { 8, 2, 0, VDO_FEATURE_VERSION4, "version4" }, + }; + static const char _lvmconf[] = "global/vdo_disabled_features"; + static int _vdo_checked = 0; +diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh +index 8b03344a7..f1d04d596 100644 +--- a/test/shell/vdo-convert.sh ++++ b/test/shell/vdo-convert.sh +@@ -174,6 +174,8 @@ vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoL + # Get VDO table line + dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig + ++aux lvmconf 'global/vdo_disabled_features = [ "version4" ]' ++ + lvm_import_vdo -y --name $vg/$lv "$LOOP" + lvs -a $vg + +-- +2.41.0 + diff --git a/SOURCES/0079-vdo-enhance-lvcreate-validation.patch b/SOURCES/0079-vdo-enhance-lvcreate-validation.patch new file mode 100644 index 0000000..9d8ae9f --- /dev/null +++ b/SOURCES/0079-vdo-enhance-lvcreate-validation.patch @@ -0,0 +1,171 @@ +From aa75359c7c1baae43349416f3761754507cd5c1a Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 8 Jul 2022 23:38:34 +0200 +Subject: [PATCH 079/115] vdo: enhance lvcreate validation + +When creating VDO pool based of % values, lvm2 is now more clever +and avoids to create 'unsupportable' sizes of physical backend +volumes as 16TiB is maximum size supported by VDO target +(and also limited by maximum supportable slabs (8192) based on slab +size. + +If the requested virtual size is approaching max supported size 4PiB, +switch header size to 0. + +(cherry picked from commit e2e31d9acf1b96ab741c22dc0a2fefd672996d3a) +--- + lib/metadata/metadata-exported.h | 2 ++ + lib/metadata/vdo_manip.c | 14 ++++++++++ + tools/lvcreate.c | 48 ++++++++++++++++++++++++++------ + 3 files changed, 56 insertions(+), 8 deletions(-) + +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index 449c8d014..f735baa55 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -1364,6 +1364,8 @@ const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode); + const char *get_vdo_write_policy_name(enum dm_vdo_write_policy policy); + uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg); + int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg); ++uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp, ++ uint32_t extent_size); + int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv, + const char *params, const struct dm_info *dminfo, + struct lv_status_vdo *status); +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index f3a4a9534..4ccde40b1 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -127,6 +127,20 @@ int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg) + return 1; + } + ++uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp, ++ uint32_t extent_size) ++{ ++ uint64_t max_extents = (DM_VDO_PHYSICAL_SIZE_MAXIMUM + extent_size - 1) / extent_size; ++ uint64_t max_slab_extents = ((extent_size - 1 + DM_VDO_SLABS_MAXIMUM * ++ ((uint64_t)vtp->slab_size_mb << (20 - SECTOR_SHIFT))) / ++ extent_size); ++ ++ max_extents = (max_slab_extents < max_extents) ? max_slab_extents : max_extents; ++ ++ return (max_extents > UINT32_MAX) ? UINT32_MAX : (uint32_t)max_extents; ++} ++ ++ + static int _sysfs_get_kvdo_value(const char *dm_name, const struct dm_info *dminfo, + const char *vdo_param, uint64_t *value) + { +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index fb57d84bd..3eee5de90 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -253,6 +253,7 @@ static int _update_extents_params(struct volume_group *vg, + uint32_t stripesize_extents; + uint32_t extents; + uint32_t base_calc_extents; ++ uint32_t vdo_pool_max_extents; + + if (lcp->size && + !(lp->extents = extents_from_size(vg->cmd, lcp->size, +@@ -322,6 +323,23 @@ static int _update_extents_params(struct volume_group *vg, + return 0; + } + ++ if (seg_is_vdo(lp)) { ++ vdo_pool_max_extents = get_vdo_pool_max_extents(&lp->vdo_params, vg->extent_size); ++ if (extents > vdo_pool_max_extents) { ++ if (lcp->percent == PERCENT_NONE) { ++ log_error("Can't use %s size. Maximal supported VDO POOL volume size with slab size %s is %s.", ++ display_size(vg->cmd, (uint64_t)vg->extent_size * extents), ++ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT)), ++ display_size(vg->cmd, (uint64_t)vg->extent_size * vdo_pool_max_extents)); ++ return 0; ++ } ++ extents = vdo_pool_max_extents; ++ log_verbose("Using maximal supported VDO POOL volume size %s (with slab size %s).", ++ display_size(vg->cmd, (uint64_t)vg->extent_size * extents), ++ display_size(vg->cmd, (uint64_t)lp->vdo_params.slab_size_mb << (20 - SECTOR_SHIFT))); ++ } ++ } ++ + if (lcp->percent != PERCENT_NONE) { + /* FIXME Don't do the adjustment for parallel allocation with PERCENT_ORIGIN! */ + lp->approx_alloc = 1; +@@ -699,15 +717,23 @@ static int _read_cache_params(struct cmd_context *cmd, + } + + static int _read_vdo_params(struct cmd_context *cmd, +- struct lvcreate_params *lp) ++ struct lvcreate_params *lp, ++ struct lvcreate_cmdline_params *lcp) + { + if (!seg_is_vdo(lp)) + return 1; + + // prefiling settings here +- if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL)) ++ if (!fill_vdo_target_params(cmd, &lp->vdo_params, &lp->vdo_pool_header_size, NULL)) + return_0; + ++ if ((lcp->virtual_size <= DM_VDO_LOGICAL_SIZE_MAXIMUM) && ++ ((lcp->virtual_size + lp->vdo_pool_header_size) > DM_VDO_LOGICAL_SIZE_MAXIMUM)) { ++ log_verbose("Dropping VDO pool header size to 0 to support maximal size %s.", ++ display_size(cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM)); ++ lp->vdo_pool_header_size = 0; ++ } ++ + // override with optional vdo settings + if (!get_vdo_settings(cmd, &lp->vdo_params, NULL)) + return_0; +@@ -1203,7 +1229,7 @@ static int _lvcreate_params(struct cmd_context *cmd, + &lp->pool_metadata_size, &lp->pool_metadata_spare, + &lp->chunk_size, &lp->discards, &lp->zero_new_blocks)) || + !_read_cache_params(cmd, lp) || +- !_read_vdo_params(cmd, lp) || ++ !_read_vdo_params(cmd, lp, lcp) || + !_read_mirror_and_raid_params(cmd, lp)) + return_0; + +@@ -1589,13 +1615,19 @@ static int _check_pool_parameters(struct cmd_context *cmd, + } + + static int _check_vdo_parameters(struct volume_group *vg, struct lvcreate_params *lp, +- struct lvcreate_cmdline_params *lcp) ++ struct lvcreate_cmdline_params *lcp) + { +- if (seg_is_vdo(lp) && lp->snapshot) { ++ if (lp->snapshot) { + log_error("Please either create VDO or snapshot."); + return 0; + } + ++ if (lcp->virtual_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) { ++ log_error("Maximal supported VDO virtual size is %s.", ++ display_size(vg->cmd, DM_VDO_LOGICAL_SIZE_MAXIMUM)); ++ return 0; ++ } ++ + return 1; + } + +@@ -1716,12 +1748,12 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name, + if (seg_is_thin(lp) && !_check_thin_parameters(vg, lp, lcp)) + goto_out; + +- if (!_check_pool_parameters(cmd, vg, lp, lcp)) +- goto_out; +- + if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp)) + return_0; + ++ if (!_check_pool_parameters(cmd, vg, lp, lcp)) ++ goto_out; ++ + /* All types are checked */ + if (!_check_zero_parameters(cmd, lp)) + return_0; +-- +2.41.0 + diff --git a/SOURCES/0080-vdo-suffle-code-for-better-error-path-handling.patch b/SOURCES/0080-vdo-suffle-code-for-better-error-path-handling.patch new file mode 100644 index 0000000..128b317 --- /dev/null +++ b/SOURCES/0080-vdo-suffle-code-for-better-error-path-handling.patch @@ -0,0 +1,58 @@ +From f5c194afc5d904e3a936dc167ac14b204c049969 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sat, 9 Jul 2022 21:33:57 +0200 +Subject: [PATCH 080/115] vdo: suffle code for better error path handling + +For failing dm_ no need to report 2nd. error, +but we missed to report error with 'updated==NULL'. + +(cherry picked from commit 493acb9195cef185b38ae4e4ffb84b984e5cc08c) +--- + tools/toollib.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/tools/toollib.c b/tools/toollib.c +index d9a1a92ec..71bf26d39 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1343,23 +1343,23 @@ int get_vdo_settings(struct cmd_context *cmd, + u |= VDO_CHANGE_ONLINE; + } + +- if (updated) { +- // validation of updated VDO option +- if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) { +-err: +- if (is_lvchange) +- log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.", +- option); +- else +- log_error("Invalid argument for VDO setting \"vdo_%s\".", +- option); +- goto out; +- } ++ // validation of updated VDO option ++ if (!dm_vdo_validate_target_params(vtp, 0 /* vdo_size */)) ++ goto_out; + ++ if (updated) + *updated = u; +- } + +- r = 1; ++ r = 1; // success ++ goto out; ++err: ++ if (is_lvchange) ++ log_error("Cannot change VDO setting \"vdo_%s\" in existing VDO pool.", ++ option); ++ else ++ log_error("Invalid argument for VDO setting \"vdo_%s\".", ++ option); ++ + out: + if (result) + dm_config_destroy(result); +-- +2.41.0 + diff --git a/SOURCES/0081-vdo-use-only-verbose-log-level-for-reformating.patch b/SOURCES/0081-vdo-use-only-verbose-log-level-for-reformating.patch new file mode 100644 index 0000000..05f7ca2 --- /dev/null +++ b/SOURCES/0081-vdo-use-only-verbose-log-level-for-reformating.patch @@ -0,0 +1,55 @@ +From fee817aff4bbd4a8dad7ceae7da179997dc7d359 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 15 Aug 2022 13:08:59 +0200 +Subject: [PATCH 081/115] vdo: use only verbose log level for reformating + +When lvcreate is makeing VDO pool and user has not specified -V size, +ATM we actually run 'vdoformat' twice to get properly 'extent' aligned +size matching lvm2 properties - so the 2nd. run of vdoformat actually +can stay with 'log_verbose()' so the standard printed result +is not showing confusing info (which is now also correctly using +print_unless_silent) + +(cherry picked from commit fc5bc5985d03aef5846cb98882d17815fc00ca15) +--- + lib/metadata/vdo_manip.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 4ccde40b1..637fd1e5d 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -249,6 +249,7 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + FILE *f; + uint64_t lb; + unsigned slabbits; ++ unsigned reformating = 0; + int args = 1; + char buf_args[5][128]; + char buf[256]; /* buffer for short disk header (64B) */ +@@ -351,8 +352,12 @@ reformat: + } + if ((c = strchr(buf, '\n'))) + *c = 0; /* cut last '\n' away */ +- if (buf[0]) +- log_print(" %s", buf); /* Print vdo_format messages */ ++ if (buf[0]) { ++ if (reformating) ++ log_verbose(" %s", buf); /* Print vdo_format messages */ ++ else ++ log_print_unless_silent(" %s", buf); /* Print vdo_format messages */ ++ } + } + + if (!pipe_close(&pdata)) { +@@ -372,6 +377,7 @@ reformat: + *logical_size = logical_size_aligned; + argv[1] = (char*) "--force"; + args = 2; ++ reformating = 1; + log_verbose("Reformating VDO to align virtual size %s by extent size.", + display_size(data_lv->vg->cmd, *logical_size)); + goto reformat; +-- +2.41.0 + diff --git a/SOURCES/0082-vdo-reset-errno-before-strtoull.patch b/SOURCES/0082-vdo-reset-errno-before-strtoull.patch new file mode 100644 index 0000000..308e7fd --- /dev/null +++ b/SOURCES/0082-vdo-reset-errno-before-strtoull.patch @@ -0,0 +1,27 @@ +From a4f39c5bbff286cc1323f799d269e35bf8e615b6 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 18 Aug 2022 13:55:29 +0200 +Subject: [PATCH 082/115] vdo: reset errno before strtoull + +Missed errno reset in commit ebad057579aeff0980a1b8af7eaacd56e62ed0c9. + +(cherry picked from commit 309df239e3ee474f3a5337f8fa3c0a1f7b0a89e5) +--- + lib/metadata/vdo_manip.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 637fd1e5d..0db401537 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -618,6 +618,7 @@ static int _get_memory_info(uint64_t *total_mb, uint64_t *available_mb) + if (!found) + continue; // not interesting + ++ errno = 0; + *(found->value) = (uint64_t) strtoull(e, &tail, 10); + + if ((e == tail) || errno) +-- +2.41.0 + diff --git a/SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch b/SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch new file mode 100644 index 0000000..08f4363 --- /dev/null +++ b/SOURCES/0083-vdo-extend-volume-and-pool-without-flush.patch @@ -0,0 +1,66 @@ +From c3d533a0ea20aa26868c55959365a52f3eaf34d1 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 19 Aug 2022 14:48:01 +0200 +Subject: [PATCH 083/115] vdo: extend volume and pool without flush + +When the volume size is extended, there is no need to flush +IO operations (nothing can be targeting new space yet). +VDO target is supported as target that can safely work with +this condition. + +Such support is also needed, when extending VDOPOOL size +while the pool is reaching its capacity - since this allows +to continue working without reaching 'out-of-space' condition +due to flushing of all in flight IO. + +(cherry picked from commit e26c21cb8d5841141dcfdfc77f46da1108a81255) +--- + WHATS_NEW | 1 + + lib/activate/activate.c | 6 +++++- + lib/activate/dev_manager.c | 2 ++ + 3 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 705fbde74..48b1d7d86 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,6 @@ + Version 2.03.17 - + =============================== ++ Extend VDO and VDOPOOL without flushing and locking fs. + Fix lvconvert --test --type vdo-pool execution. + Fix vdo_slab_size_mb value for converted VDO volume. + +diff --git a/lib/activate/activate.c b/lib/activate/activate.c +index 727bd2386..76740bb2b 100644 +--- a/lib/activate/activate.c ++++ b/lib/activate/activate.c +@@ -2124,7 +2124,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s, + * TODO: Relax this limiting condition further */ + if (!flush_required && + (lv_is_pvmove(lv) || pvmove_lv || +- (!lv_is_mirror(lv) && !lv_is_thin_pool(lv) && !lv_is_thin_volume(lv)))) { ++ (!lv_is_mirror(lv) && ++ !lv_is_thin_volume(lv) && ++ !lv_is_thin_pool(lv) && ++ !lv_is_vdo(lv) && ++ !lv_is_vdo_pool(lv)))) { + log_debug("Requiring flush for LV %s.", display_lvname(lv)); + flush_required = 1; + } +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index 284254d68..9058510e4 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -3826,6 +3826,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv, + * non 'thin pool/volume' and size increase */ + else if (!lv_is_thin_volume(lv) && + !lv_is_thin_pool(lv) && ++ !lv_is_vdo(lv) && ++ !lv_is_vdo_pool(lv) && + dm_tree_node_size_changed(root)) + dm->flush_required = 1; + +-- +2.41.0 + diff --git a/SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch b/SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch new file mode 100644 index 0000000..1f4036a --- /dev/null +++ b/SOURCES/0084-tests-vdo-emulation-without-vdo-binary.patch @@ -0,0 +1,52 @@ +From fc1c105c75b81b4cecf24e7924605abcceb91d67 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 6 Sep 2022 16:44:24 +0200 +Subject: [PATCH 084/115] tests: vdo emulation without vdo binary + +Avoid inserting 'vdo' binary into path - and use +alias and VDO_BINARY shell vars for emulation. + +(cherry picked from commit 15ad2b8e5585b89bc3f09a53567f17eb70f45714) +--- + test/lib/lvm_vdo_wrapper.sh | 2 +- + test/shell/vdo-convert.sh | 11 ++++++++++- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/test/lib/lvm_vdo_wrapper.sh b/test/lib/lvm_vdo_wrapper.sh +index d622d6456..90d0b2ce8 100755 +--- a/test/lib/lvm_vdo_wrapper.sh ++++ b/test/lib/lvm_vdo_wrapper.sh +@@ -344,7 +344,7 @@ vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true + # + # MAIN + # +-case "$1" in ++case "${1-}" in + "create") shift; vdo_create_ "$@" ;; + "remove") shift; vdo_remove_ "$@" ;; + "stop") shift; vdo_stop_ "$@" ;; +diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh +index f1d04d596..5bf53d081 100644 +--- a/test/shell/vdo-convert.sh ++++ b/test/shell/vdo-convert.sh +@@ -29,7 +29,16 @@ aux prepare_dmeventd + # + # Main + # +-which vdo || skip ++if not which vdo ; then ++ which lvm_vdo_wrapper || skip "Missing 'lvm_vdo_wrapper'." ++ which oldvdoformat || skip "Emulation of vdo manager 'oldvdoformat' missing." ++ which oldvdoprepareforlvm || skip "Emulation of vdo manager 'oldvdoprepareforlvm' missing." ++ # enable expansion of aliasis within script itself ++ shopt -s expand_aliases ++ alias vdo='lvm_vdo_wrapper' ++ export VDO_BINARY=lvm_vdo_wrapper ++ echo "Using 'lvm_vdo_wrapper' emulation of 'vdo' manager." ++fi + which mkfs.ext4 || skip + export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf" + +-- +2.41.0 + diff --git a/SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch b/SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch new file mode 100644 index 0000000..2642d5e --- /dev/null +++ b/SOURCES/0085-device_mapper-add-parser-for-vdo-metadata.patch @@ -0,0 +1,373 @@ +From fd16a667a985ef116f3deed1910b99aa0859f244 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 26 Oct 2022 14:33:09 +0200 +Subject: [PATCH 085/115] device_mapper: add parser for vdo metadata + +Add very simplistic parser of vdo metadata to be able to obtain +logical_blocks stored within vdo metadata - as lvm2 may +submit smaller value due to internal aligment rules. + +To avoid creation of mismatching table line - use this number +instead the one provided by lvm2. + +(cherry picked from commit 829ab017082eaad253ebd28ad7d7ae7f3936dbcb) +--- + device_mapper/Makefile | 3 +- + device_mapper/libdm-deptree.c | 15 ++ + device_mapper/vdo/target.h | 2 + + device_mapper/vdo/vdo_reader.c | 279 +++++++++++++++++++++++++++++++++ + 4 files changed, 298 insertions(+), 1 deletion(-) + create mode 100644 device_mapper/vdo/vdo_reader.c + +diff --git a/device_mapper/Makefile b/device_mapper/Makefile +index d3b791eb5..a322235cb 100644 +--- a/device_mapper/Makefile ++++ b/device_mapper/Makefile +@@ -1,4 +1,4 @@ +-# Copyright (C) 2018 Red Hat, Inc. All rights reserved. ++# Copyright (C) 2018 - 2022 Red Hat, Inc. All rights reserved. + # + # This file is part of the device-mapper userspace tools. + # +@@ -29,6 +29,7 @@ DEVICE_MAPPER_SOURCE=\ + device_mapper/regex/parse_rx.c \ + device_mapper/regex/ttree.c \ + device_mapper/vdo/status.c \ ++ device_mapper/vdo/vdo_reader.c \ + device_mapper/vdo/vdo_target.c + + DEVICE_MAPPER_TARGET = device_mapper/libdevice-mapper.a +diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c +index 2d382037c..0445e1b4b 100644 +--- a/device_mapper/libdm-deptree.c ++++ b/device_mapper/libdm-deptree.c +@@ -2857,6 +2857,7 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + int pos = 0; + char data[DM_FORMAT_DEV_BUFSIZE]; + char data_dev[128]; // for /dev/dm-XXXX ++ uint64_t logical_blocks; + + if (!_build_dev_string(data, sizeof(data), seg->vdo_data)) + return_0; +@@ -2866,6 +2867,20 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + return 0; + } + ++ if (dm_vdo_parse_logical_size(data_dev, &logical_blocks)) { ++ logical_blocks *= 8; ++ if (seg->size != logical_blocks) { ++ if (seg->size > logical_blocks) { ++ log_error("Virtual size of VDO volume is smaller then expected (" FMTu64 " > " FMTu64 ").", ++ seg->size, logical_blocks); ++ return 1; ++ } ++ log_debug_activation("Increasing VDO virtual volume size from " FMTu64 " to " FMTu64 ".", ++ seg->size, logical_blocks); ++ seg->size = logical_blocks; ++ } ++ } ++ + if (seg->vdo_version < 4) { + EMIT_PARAMS(pos, "V2 %s " FMTu64 " %u " FMTu64 " %u %s %s %s ", + data_dev, +diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h +index 60c5bff56..bd21bb5d7 100644 +--- a/device_mapper/vdo/target.h ++++ b/device_mapper/vdo/target.h +@@ -108,6 +108,8 @@ struct dm_vdo_target_params { + bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + uint64_t vdo_size); + ++bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks); ++ + //---------------------------------------------------------------- + + #endif +diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c +new file mode 100644 +index 000000000..b765af042 +--- /dev/null ++++ b/device_mapper/vdo/vdo_reader.c +@@ -0,0 +1,279 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of the device-mapper userspace tools. ++ * ++ * 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 Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * Based on VDO sources: https://github.com/dm-vdo/vdo ++ * ++ * Simplified parser of VDO superblock to obtain basic VDO parameteers ++ * ++ * TODO: maybe switch to some library in the future ++ */ ++ ++//#define _GNU_SOURCE 1 ++//#define _LARGEFILE64_SOURCE 1 ++ ++#include "device_mapper/misc/dmlib.h" ++ ++#include "target.h" ++ ++#include "lib/mm/xlate.h" ++//#include "linux/byteorder/big_endian.h" ++//#include "linux/byteorder/little_endian.h" ++//#define le32_to_cpu __le32_to_cpu ++//#define le64_to_cpu __le64_to_cpu ++ ++ ++#include ++#include ++#include /* For block ioctl definitions */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef unsigned char uuid_t[16]; ++ ++#define __packed __attribute__((packed)) ++ ++static const char _MAGIC_NUMBER[] = "dmvdo001"; ++#define MAGIC_NUMBER_SIZE (sizeof(_MAGIC_NUMBER) - 1) ++ ++struct vdo_version_number { ++ uint32_t major_version; ++ uint32_t minor_version; ++} __packed; ++ ++/* ++ * The registry of component ids for use in headers ++ */ ++enum { ++ SUPER_BLOCK = 0, ++ FIXED_LAYOUT = 1, ++ RECOVERY_JOURNAL = 2, ++ SLAB_DEPOT = 3, ++ BLOCK_MAP = 4, ++ GEOMETRY_BLOCK = 5, ++}; /* ComponentID */ ++ ++struct vdo_header { ++ uint32_t id; /* The component this is a header for */ ++ struct vdo_version_number version; /* The version of the data format */ ++ size_t size; /* The size of the data following this header */ ++} __packed; ++ ++struct vdo_geometry_block { ++ char magic_number[MAGIC_NUMBER_SIZE]; ++ struct vdo_header header; ++ uint32_t checksum; ++} __packed; ++ ++struct vdo_config { ++ uint64_t logical_blocks; /* number of logical blocks */ ++ uint64_t physical_blocks; /* number of physical blocks */ ++ uint64_t slab_size; /* number of blocks in a slab */ ++ uint64_t recovery_journal_size; /* number of recovery journal blocks */ ++ uint64_t slab_journal_blocks; /* number of slab journal blocks */ ++} __packed; ++ ++struct vdo_component_41_0 { ++ uint32_t state; ++ uint64_t complete_recoveries; ++ uint64_t read_only_recoveries; ++ struct vdo_config config; /* packed */ ++ uint64_t nonce; ++} __packed; ++ ++enum vdo_volume_region_id { ++ VDO_INDEX_REGION = 0, ++ VDO_DATA_REGION = 1, ++ VDO_VOLUME_REGION_COUNT, ++}; ++ ++struct vdo_volume_region { ++ /* The ID of the region */ ++ enum vdo_volume_region_id id; ++ /* ++ * The absolute starting offset on the device. The region continues ++ * until the next region begins. ++ */ ++ uint64_t start_block; ++} __packed; ++ ++struct vdo_index_config { ++ uint32_t mem; ++ uint32_t unused; ++ uint8_t sparse; ++} __packed; ++ ++struct vdo_volume_geometry { ++ uint32_t release_version; ++ uint64_t nonce; ++ uuid_t uuid; ++ uint64_t bio_offset; ++ struct vdo_volume_region regions[VDO_VOLUME_REGION_COUNT]; ++ struct vdo_index_config index_config; ++} __packed; ++ ++/* Decoding mostly only some used stucture members */ ++ ++static void _vdo_decode_version(struct vdo_version_number *v) ++{ ++ v->major_version = le32_to_cpu(v->major_version); ++ v->minor_version = le32_to_cpu(v->minor_version); ++} ++ ++static void _vdo_decode_header(struct vdo_header *h) ++{ ++ h->id = le32_to_cpu(h->id); ++ _vdo_decode_version(&h->version); ++ h->size = le64_to_cpu(h->size); ++} ++ ++static void _vdo_decode_geometry_region(struct vdo_volume_region *vr) ++{ ++ vr->id = le32_to_cpu(vr->id); ++ vr->start_block = le32_to_cpu(vr->start_block); ++} ++ ++static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg) ++{ ++ vg->release_version = le64_to_cpu(vg->release_version); ++ vg->nonce = le64_to_cpu(vg->nonce); ++ _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); ++} ++ ++static void _vdo_decode_config(struct vdo_config *vc) ++{ ++ vc->logical_blocks = le64_to_cpu(vc->logical_blocks); ++ vc->physical_blocks = le64_to_cpu(vc->physical_blocks); ++ vc->slab_size = le64_to_cpu(vc->slab_size); ++ vc->recovery_journal_size = le64_to_cpu(vc->recovery_journal_size); ++ vc->slab_journal_blocks = le64_to_cpu(vc->slab_journal_blocks); ++} ++ ++static void _vdo_decode_pvc(struct vdo_component_41_0 *pvc) ++{ ++ _vdo_decode_config(&pvc->config); ++ pvc->nonce = le64_to_cpu(pvc->nonce); ++} ++ ++bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) ++{ ++ char buffer[4096]; ++ int fh, n; ++ bool r = false; ++ off_t l; ++ struct stat st; ++ uint64_t size; ++ uint64_t regpos; ++ ++ struct vdo_header h; ++ struct vdo_version_number vn; ++ struct vdo_volume_geometry vg; ++ struct vdo_component_41_0 pvc; ++ ++ *logical_blocks = 0; ++ if ((fh = open(vdo_path, O_RDONLY)) == -1) { ++ log_sys_error("Failed to open VDO backend %s", vdo_path); ++ goto err; ++ } ++ ++ if (ioctl(fh, BLKGETSIZE64, &size) == -1) { ++ if (errno != ENOTTY) { ++ log_sys_error("ioctl", vdo_path); ++ goto err; ++ } ++ ++ /* lets retry for file sizes */ ++ if (fstat(fh, &st) < 0) { ++ log_sys_error("fstat", vdo_path); ++ goto err; ++ } ++ ++ size = st.st_size; ++ } ++ ++ if ((n = read(fh, buffer, sizeof(buffer))) < 0) { ++ log_sys_error("read", vdo_path); ++ goto err; ++ } ++ ++ if (strncmp(buffer, _MAGIC_NUMBER, MAGIC_NUMBER_SIZE)) { ++ log_sys_error("mismatch header", vdo_path); ++ goto err; ++ } ++ ++ memcpy(&h, buffer + MAGIC_NUMBER_SIZE, sizeof(h)); ++ _vdo_decode_header(&h); ++ ++ if (h.version.major_version != 5) { ++ log_error("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); ++ goto err; ++ } ++ ++ memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); ++ _vdo_decode_volume_geometry(&vg); ++ ++ regpos = vg.regions[VDO_DATA_REGION].start_block * 4096; ++ ++ if ((regpos + sizeof(buffer)) > size) { ++ log_error("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size); ++ goto err; ++ } ++ ++ if ((l = lseek(fh, regpos, SEEK_SET)) < 0) { ++ log_sys_error("lseek", vdo_path); ++ goto err; ++ } ++ ++ if ((n = read(fh, buffer, sizeof(buffer))) < 0) { ++ log_sys_error("read error", vdo_path); ++ goto err; ++ } ++ ++ ++ memcpy(&vn, buffer + sizeof(struct vdo_geometry_block), sizeof(vn)); ++ _vdo_decode_version(&vn); ++ ++ if (vn.major_version > 41) { ++ log_error("Unknown VDO component version %u.", vn.major_version); // should be 41! ++ goto err; ++ } ++ ++ memcpy(&pvc, buffer + sizeof(struct vdo_geometry_block) + sizeof(vn), sizeof(pvc)); ++ _vdo_decode_pvc(&pvc); ++ ++ if (pvc.nonce != vg.nonce) { ++ log_error("Mismatching VDO nonce " FMTu64 " != " FMTu64 ".", pvc.nonce, vg.nonce); ++ goto err; ++ } ++ ++#if 0 ++ log_debug("LogBlocks " FMTu64 ".", pvc.config.logical_blocks); ++ log_debug("PhyBlocks " FMTu64 ".", pvc.config.physical_blocks); ++ log_debug("SlabSize " FMTu64 ".", pvc.config.slab_size); ++ log_debug("RecJourSize " FMTu64 ".", pvc.config.recovery_journal_size); ++ log_debug("SlabJouSize " FMTu64 ".", pvc.config.slab_journal_blocks); ++#endif ++ ++ *logical_blocks = pvc.config.logical_blocks; ++ r = true; ++err: ++ (void) close(fh); ++ ++ return r; ++} +-- +2.41.0 + diff --git a/SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch b/SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch new file mode 100644 index 0000000..229cd80 --- /dev/null +++ b/SOURCES/0086-dev_manager-accept-misalined-vdo-pools.patch @@ -0,0 +1,78 @@ +From 13ce88a2b204e9b05206b624bbcca00446312ebb Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 26 Oct 2022 14:38:29 +0200 +Subject: [PATCH 086/115] dev_manager: accept misalined vdo pools. + +Since lvm2 may create VDO pool virtual size aligned only on extent size +while VDO itself is just 4K aligned - we need to support such misalign. + +(cherry picked from commit 2e79b005c2013fb03d8a48a3cfd8e70a982dd65b) +--- + lib/activate/dev_manager.c | 8 +++++--- + lib/metadata/vdo_manip.c | 10 ++-------- + 2 files changed, 7 insertions(+), 11 deletions(-) + +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index 9058510e4..5b72bf772 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -263,7 +263,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, + int dmtask; + int with_flush; /* TODO: arg for _info_run */ + void *target = NULL; +- uint64_t target_start, target_length, start, length, length_crop = 0; ++ uint64_t target_start, target_length, start, extent_size, length, length_crop = 0; + char *target_name, *target_params; + const char *devname; + +@@ -292,8 +292,8 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, + + /* Query status only for active device */ + if (seg_status && dminfo->exists) { +- start = length = seg_status->seg->lv->vg->extent_size; +- start *= seg_status->seg->le; ++ extent_size = length = seg_status->seg->lv->vg->extent_size; ++ start = extent_size * seg_status->seg->le; + length *= _seg_len(seg_status->seg); + + /* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */ +@@ -314,6 +314,8 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, + + if ((start == target_start) && + ((length == target_length) || ++ ((lv_is_vdo_pool(seg_status->seg->lv)) && /* should fit within extent size */ ++ (length < target_length) && ((length + extent_size) > target_length)) || + (length_crop && (length_crop == target_length)))) + break; /* Keep target_params when matching segment is found */ + +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 0db401537..1cd2130a7 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -263,7 +263,6 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + return 0; + } + +-reformat: + if (*logical_size) { + logical_size_aligned = 0; + if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K", +@@ -374,13 +373,8 @@ reformat: + // align obtained size to extent size + logical_size_aligned = *logical_size / data_lv->vg->extent_size * data_lv->vg->extent_size; + if (*logical_size != logical_size_aligned) { +- *logical_size = logical_size_aligned; +- argv[1] = (char*) "--force"; +- args = 2; +- reformating = 1; +- log_verbose("Reformating VDO to align virtual size %s by extent size.", +- display_size(data_lv->vg->cmd, *logical_size)); +- goto reformat; ++ log_debug("Using bigger VDO virtual size unaligned on extent size by %s.", ++ display_size(data_lv->vg->cmd, *logical_size - logical_size_aligned)); + } + } + +-- +2.41.0 + diff --git a/SOURCES/0087-device_mapper-vdo-V4-avoid-messaging.patch b/SOURCES/0087-device_mapper-vdo-V4-avoid-messaging.patch new file mode 100644 index 0000000..772dba9 --- /dev/null +++ b/SOURCES/0087-device_mapper-vdo-V4-avoid-messaging.patch @@ -0,0 +1,49 @@ +From 9399376608f5a81164c7bf9c8f3d724991a152b9 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 27 Oct 2022 23:58:42 +0200 +Subject: [PATCH 087/115] device_mapper: vdo V4 avoid messaging + +With V4 format build table line with compression and +deduplication and skip sending any messages to set up +these parameters. + +(cherry picked from commit 36a923926c2c27c1a8a5ac262387d2a4d3e620f8) +--- + device_mapper/libdm-deptree.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c +index 0445e1b4b..02a56c8e3 100644 +--- a/device_mapper/libdm-deptree.c ++++ b/device_mapper/libdm-deptree.c +@@ -2894,12 +2894,15 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + (seg->vdo_params.write_policy == DM_VDO_WRITE_POLICY_ASYNC_UNSAFE) ? "async-unsafe" : "auto", // policy + seg->vdo_name); + } else { +- EMIT_PARAMS(pos, "V4 %s " FMTu64 " %u " FMTu64 " %u ", ++ EMIT_PARAMS(pos, "V4 %s " FMTu64 " %u " FMTu64 " %u " ++ "deduplication %s compression %s ", + data_dev, + seg->vdo_data_size / 8, // this parameter is in 4K units + seg->vdo_params.minimum_io_size * UINT32_C(512), // sector to byte units + seg->vdo_params.block_map_cache_size_mb * UINT64_C(256), // 1MiB -> 4KiB units +- seg->vdo_params.block_map_era_length); ++ seg->vdo_params.block_map_era_length, ++ seg->vdo_params.use_deduplication ? "on" : "off", ++ seg->vdo_params.use_compression ? "on" : "off"); + } + + EMIT_PARAMS(pos, "maxDiscard %u ack %u bio %u bioRotationInterval %u cpu %u hash %u logical %u physical %u", +@@ -4376,7 +4379,8 @@ int dm_tree_node_add_vdo_target(struct dm_tree_node *node, + seg->vdo_name = vdo_pool_name; + seg->vdo_data_size = data_size; + +- node->props.send_messages = 2; ++ if (seg->vdo_version < 4) ++ node->props.send_messages = 2; + + return 1; + } +-- +2.41.0 + diff --git a/SOURCES/0088-vdo-replace-errors-with-debug.patch b/SOURCES/0088-vdo-replace-errors-with-debug.patch new file mode 100644 index 0000000..776704c --- /dev/null +++ b/SOURCES/0088-vdo-replace-errors-with-debug.patch @@ -0,0 +1,121 @@ +From f67de990a60777410e2029deb7322243716e9b5d Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 4 Nov 2022 16:27:56 +0100 +Subject: [PATCH 088/115] vdo: replace errors with debug + +As we actully use reading of VDO metadata only as extra 'information' source, +and not error command - switch to 'log_debug()' severity with messages +out of parser code. + +(cherry picked from commit 218c7d44b5ac64b6c38dfd40885a22008b5cec81) +--- + device_mapper/vdo/vdo_reader.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c +index b765af042..4f91f8011 100644 +--- a/device_mapper/vdo/vdo_reader.c ++++ b/device_mapper/vdo/vdo_reader.c +@@ -188,19 +188,19 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + + *logical_blocks = 0; + if ((fh = open(vdo_path, O_RDONLY)) == -1) { +- log_sys_error("Failed to open VDO backend %s", vdo_path); ++ log_sys_debug("Failed to open VDO backend %s.", vdo_path); + goto err; + } + + if (ioctl(fh, BLKGETSIZE64, &size) == -1) { + if (errno != ENOTTY) { +- log_sys_error("ioctl", vdo_path); ++ log_sys_debug("ioctl", vdo_path); + goto err; + } + + /* lets retry for file sizes */ + if (fstat(fh, &st) < 0) { +- log_sys_error("fstat", vdo_path); ++ log_sys_debug("fstat", vdo_path); + goto err; + } + +@@ -208,12 +208,12 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + } + + if ((n = read(fh, buffer, sizeof(buffer))) < 0) { +- log_sys_error("read", vdo_path); ++ log_sys_debug("read", vdo_path); + goto err; + } + + if (strncmp(buffer, _MAGIC_NUMBER, MAGIC_NUMBER_SIZE)) { +- log_sys_error("mismatch header", vdo_path); ++ log_debug_activation("Found mismatching VDO magic header in %s.", vdo_path); + goto err; + } + +@@ -221,7 +221,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + _vdo_decode_header(&h); + + if (h.version.major_version != 5) { +- log_error("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); ++ log_debug_activation("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); + goto err; + } + +@@ -231,17 +231,17 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + regpos = vg.regions[VDO_DATA_REGION].start_block * 4096; + + if ((regpos + sizeof(buffer)) > size) { +- log_error("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size); ++ log_debug_activation("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size); + goto err; + } + + if ((l = lseek(fh, regpos, SEEK_SET)) < 0) { +- log_sys_error("lseek", vdo_path); ++ log_sys_debug("lseek", vdo_path); + goto err; + } + + if ((n = read(fh, buffer, sizeof(buffer))) < 0) { +- log_sys_error("read error", vdo_path); ++ log_sys_debug("read", vdo_path); + goto err; + } + +@@ -250,7 +250,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + _vdo_decode_version(&vn); + + if (vn.major_version > 41) { +- log_error("Unknown VDO component version %u.", vn.major_version); // should be 41! ++ log_debug_activation("Unknown VDO component version %u.", vn.major_version); // should be 41! + goto err; + } + +@@ -258,16 +258,16 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + _vdo_decode_pvc(&pvc); + + if (pvc.nonce != vg.nonce) { +- log_error("Mismatching VDO nonce " FMTu64 " != " FMTu64 ".", pvc.nonce, vg.nonce); ++ log_debug_activation("VDO metadata has mismatching VDO nonces " FMTu64 " != " FMTu64 ".", pvc.nonce, vg.nonce); + goto err; + } + + #if 0 +- log_debug("LogBlocks " FMTu64 ".", pvc.config.logical_blocks); +- log_debug("PhyBlocks " FMTu64 ".", pvc.config.physical_blocks); +- log_debug("SlabSize " FMTu64 ".", pvc.config.slab_size); +- log_debug("RecJourSize " FMTu64 ".", pvc.config.recovery_journal_size); +- log_debug("SlabJouSize " FMTu64 ".", pvc.config.slab_journal_blocks); ++ log_debug_activation("LogBlocks " FMTu64 ".", pvc.config.logical_blocks); ++ log_debug_activation("PhyBlocks " FMTu64 ".", pvc.config.physical_blocks); ++ log_debug_activation("SlabSize " FMTu64 ".", pvc.config.slab_size); ++ log_debug_activation("RecJourSize " FMTu64 ".", pvc.config.recovery_journal_size); ++ log_debug_activation("SlabJouSize " FMTu64 ".", pvc.config.slab_journal_blocks); + #endif + + *logical_blocks = pvc.config.logical_blocks; +-- +2.41.0 + diff --git a/SOURCES/0089-vdo-enhance-detection-of-virtual-size.patch b/SOURCES/0089-vdo-enhance-detection-of-virtual-size.patch new file mode 100644 index 0000000..fcae02a --- /dev/null +++ b/SOURCES/0089-vdo-enhance-detection-of-virtual-size.patch @@ -0,0 +1,98 @@ +From c66a3010e0b90a5eb2a17717ecc73f62859d1eea Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sat, 5 Nov 2022 23:10:36 +0100 +Subject: [PATCH 089/115] vdo: enhance detection of virtual size + +Improve detection of VDO virtual size - so it's not reading VDO +metadata when VDO device is already active and instead we reuse +existing table line for knowing existing metadata size. + +NOTE: if there is ever going to be added support for reduction +of VDO virtual size - this method will need to be reworked to +allow size difference only within 'extent_size' alignment. + +(cherry picked from commit 8e9410594b3113386a667df400b2c229c745cb6a) +--- + device_mapper/libdm-deptree.c | 44 ++++++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 13 deletions(-) + +diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c +index 02a56c8e3..39af7b1d4 100644 +--- a/device_mapper/libdm-deptree.c ++++ b/device_mapper/libdm-deptree.c +@@ -2850,7 +2850,7 @@ static int _thin_pool_emit_segment_line(struct dm_task *dmt, + return 1; + } + +-static int _vdo_emit_segment_line(struct dm_task *dmt, ++static int _vdo_emit_segment_line(struct dm_task *dmt, uint32_t major, uint32_t minor, + struct load_segment *seg, + char *params, size_t paramsize) + { +@@ -2858,6 +2858,10 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + char data[DM_FORMAT_DEV_BUFSIZE]; + char data_dev[128]; // for /dev/dm-XXXX + uint64_t logical_blocks; ++ struct dm_task *vdo_dmt; ++ uint64_t start, length = 0; ++ char *type = NULL; ++ char *vdo_params = NULL; + + if (!_build_dev_string(data, sizeof(data), seg->vdo_data)) + return_0; +@@ -2867,18 +2871,32 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, + return 0; + } + +- if (dm_vdo_parse_logical_size(data_dev, &logical_blocks)) { +- logical_blocks *= 8; +- if (seg->size != logical_blocks) { +- if (seg->size > logical_blocks) { +- log_error("Virtual size of VDO volume is smaller then expected (" FMTu64 " > " FMTu64 ").", +- seg->size, logical_blocks); +- return 1; +- } +- log_debug_activation("Increasing VDO virtual volume size from " FMTu64 " to " FMTu64 ".", +- seg->size, logical_blocks); +- seg->size = logical_blocks; ++ /* ++ * If there is already running VDO target, read 'existing' virtual size out of table line ++ * and avoid reading it them from VDO metadata device ++ * ++ * NOTE: ATM VDO virtual size can be ONLY extended thus it's simple to recongnize 'right' size. ++ * However if there would be supported also reduction, this check would need to check range. ++ */ ++ if ((vdo_dmt = dm_task_create(DM_DEVICE_TABLE))) { ++ if (dm_task_set_major(vdo_dmt, major) && ++ dm_task_set_minor(vdo_dmt, minor) && ++ dm_task_run(vdo_dmt)) { ++ (void) dm_get_next_target(vdo_dmt, NULL, &start, &length, &type, &vdo_params); ++ if (!type || strcmp(type, "vdo")) ++ length = 0; + } ++ ++ dm_task_destroy(vdo_dmt); ++ } ++ ++ if (!length && dm_vdo_parse_logical_size(data_dev, &logical_blocks)) ++ length = logical_blocks * 8; ++ ++ if (seg->size < length) { ++ log_debug_activation("Correcting VDO virtual volume size from " FMTu64 " to " FMTu64 ".", ++ seg->size, length); ++ seg->size = length; + } + + if (seg->vdo_version < 4) { +@@ -2980,7 +2998,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major, + EMIT_PARAMS(pos, "%u %u ", seg->area_count, seg->stripe_size); + break; + case SEG_VDO: +- if (!_vdo_emit_segment_line(dmt, seg, params, paramsize)) ++ if (!_vdo_emit_segment_line(dmt, major, minor, seg, params, paramsize)) + return_0; + break; + case SEG_CRYPT: +-- +2.41.0 + diff --git a/SOURCES/0090-vdo-improve-validation-message.patch b/SOURCES/0090-vdo-improve-validation-message.patch new file mode 100644 index 0000000..0eb45d7 --- /dev/null +++ b/SOURCES/0090-vdo-improve-validation-message.patch @@ -0,0 +1,32 @@ +From 57eb6c1b9c3122a33da38c561e5177183577a958 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 8 Nov 2022 12:40:21 +0100 +Subject: [PATCH 090/115] vdo: improve validation message + +Rephrase. + +(cherry picked from commit 403779333be419352d6062da592ea78e6096e12b) +--- + device_mapper/vdo/vdo_target.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/device_mapper/vdo/vdo_target.c b/device_mapper/vdo/vdo_target.c +index ab3fff26a..a8a753e39 100644 +--- a/device_mapper/vdo/vdo_target.c ++++ b/device_mapper/vdo/vdo_target.c +@@ -156,9 +156,9 @@ bool dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp, + } + + if (vdo_size > DM_VDO_LOGICAL_SIZE_MAXIMUM) { +- log_error("VDO logical size is by " FMTu64 "KiB bigger then limit " FMTu64 "TiB.", +- (vdo_size - DM_VDO_LOGICAL_SIZE_MAXIMUM) / 2, +- DM_VDO_LOGICAL_SIZE_MAXIMUM / (UINT64_C(1024) * 1024 * 1024 * 1024 >> SECTOR_SHIFT)); ++ log_error("VDO logical size is larger than limit " FMTu64 " TiB by " FMTu64 " KiB.", ++ DM_VDO_LOGICAL_SIZE_MAXIMUM / (UINT64_C(1024) * 1024 * 1024 * 1024 >> SECTOR_SHIFT), ++ (vdo_size - DM_VDO_LOGICAL_SIZE_MAXIMUM) / 2); + valid = false; + } + +-- +2.41.0 + diff --git a/SOURCES/0091-vdo-fix-reader-error-path.patch b/SOURCES/0091-vdo-fix-reader-error-path.patch new file mode 100644 index 0000000..e653746 --- /dev/null +++ b/SOURCES/0091-vdo-fix-reader-error-path.patch @@ -0,0 +1,28 @@ +From 05b4d98a51f09e8fdb555cdf1678de8645d5e9c4 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 20 Dec 2022 13:52:31 +0100 +Subject: [PATCH 091/115] vdo: fix reader error path + +Nothing to be closed on this error path. + +(cherry picked from commit b6b1c19365d20d926d8aa39bf591731a7f9bb75a) +--- + device_mapper/vdo/vdo_reader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c +index 4f91f8011..3596afbd3 100644 +--- a/device_mapper/vdo/vdo_reader.c ++++ b/device_mapper/vdo/vdo_reader.c +@@ -189,7 +189,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + *logical_blocks = 0; + if ((fh = open(vdo_path, O_RDONLY)) == -1) { + log_sys_debug("Failed to open VDO backend %s.", vdo_path); +- goto err; ++ return false; + } + + if (ioctl(fh, BLKGETSIZE64, &size) == -1) { +-- +2.41.0 + diff --git a/SOURCES/0092-vdo-check-memory-only-in-non-critical-section.patch b/SOURCES/0092-vdo-check-memory-only-in-non-critical-section.patch new file mode 100644 index 0000000..e475c90 --- /dev/null +++ b/SOURCES/0092-vdo-check-memory-only-in-non-critical-section.patch @@ -0,0 +1,38 @@ +From 71c8df45c7d7efddad66e379d492b6f92cdfb4b9 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 10 Jan 2023 21:12:22 +0100 +Subject: [PATCH 092/115] vdo: check memory only in non critical section + +When we are actually resizing VDO device - we need to check size only in +non-critical section - otherwise we are checking + +(cherry picked from commit 773b88e028ab2965a8c185f5f2147334f8f2bbfd) +--- + lib/vdo/vdo.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c +index 9efb424f0..d2d14d146 100644 +--- a/lib/vdo/vdo.c ++++ b/lib/vdo/vdo.c +@@ -23,6 +23,7 @@ + #include "lib/metadata/metadata.h" + #include "lib/metadata/lv_alloc.h" + #include "lib/metadata/segtype.h" ++#include "lib/mm/memlock.h" + #include "base/memory/zalloc.h" + + static const char _vdo_module[] = MODULE_NAME_VDO; +@@ -374,7 +375,8 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + return 0; + } + +- if (!check_vdo_constrains(cmd, seg->lv->size, seg_lv(seg, 0)->size, &seg->vdo_params)) ++ if (!critical_section() && ++ !check_vdo_constrains(cmd, seg->lv->size, get_vdo_pool_virtual_size(seg), &seg->vdo_params)) + return_0; + + if (!(vdo_pool_name = dm_build_dm_name(mem, seg->lv->vg->name, seg->lv->name, lv_layer(seg->lv)))) +-- +2.41.0 + diff --git a/SOURCES/0093-vdo-read-live-vdo-size-configuration.patch b/SOURCES/0093-vdo-read-live-vdo-size-configuration.patch new file mode 100644 index 0000000..3704200 --- /dev/null +++ b/SOURCES/0093-vdo-read-live-vdo-size-configuration.patch @@ -0,0 +1,192 @@ +From 696036c20f8b452f0eb8482a9aa13878ce398452 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sun, 15 Jan 2023 21:24:28 +0100 +Subject: [PATCH 093/115] vdo: read live vdo size configuration + +Introduce struct vdo_pool_size_config usable to calculate necessary +memory size for active VDO volume. + +Function lv_vdo_pool_size_config() is able to read out this +configuration out of runtime DM table line. + +(cherry picked from commit 1bed2cafe83096cf01cfff5cd2cd64ecb32b7d78) +--- + lib/activate/activate.c | 31 +++++++++++++++ + lib/activate/activate.h | 2 + + lib/activate/dev_manager.c | 65 ++++++++++++++++++++++++++++++++ + lib/activate/dev_manager.h | 3 ++ + lib/metadata/metadata-exported.h | 6 +++ + 5 files changed, 107 insertions(+) + +diff --git a/lib/activate/activate.c b/lib/activate/activate.c +index 76740bb2b..c951523c5 100644 +--- a/lib/activate/activate.c ++++ b/lib/activate/activate.c +@@ -322,6 +322,11 @@ int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent) + { + return 0; + } ++int lv_vdo_pool_size_config(const struct logical_volume *lv, ++ struct vdo_pool_size_config *cfg) ++{ ++ return 0; ++} + int lvs_in_vg_activated(const struct volume_group *vg) + { + return 0; +@@ -1346,6 +1351,32 @@ int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent) + return 1; + } + ++/* ++ * lv_vdo_pool_size_config obtains size configuration from active VDO table line ++ * ++ * If the 'params' string has been already retrieved, use it. ++ * If the mempool already exists, use it. ++ * ++ */ ++int lv_vdo_pool_size_config(const struct logical_volume *lv, ++ struct vdo_pool_size_config *cfg) ++{ ++ struct dev_manager *dm; ++ int r; ++ ++ if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0)) ++ return 1; /* Inactive VDO pool -> no runtime config */ ++ ++ if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, !lv_is_pvmove(lv)))) ++ return_0; ++ ++ r = dev_manager_vdo_pool_size_config(dm, lv, cfg); ++ ++ dev_manager_destroy(dm); ++ ++ return r; ++} ++ + static int _lv_active(struct cmd_context *cmd, const struct logical_volume *lv) + { + struct lvinfo info; +diff --git a/lib/activate/activate.h b/lib/activate/activate.h +index edd385aef..ca2b7f559 100644 +--- a/lib/activate/activate.h ++++ b/lib/activate/activate.h +@@ -200,6 +200,8 @@ int lv_thin_pool_status(const struct logical_volume *lv, int flush, + int lv_vdo_pool_status(const struct logical_volume *lv, int flush, + struct lv_status_vdo **status); + int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent); ++int lv_vdo_pool_size_config(const struct logical_volume *lv, ++ struct vdo_pool_size_config *cfg); + + /* + * Return number of LVs in the VG that are active. +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index 5b72bf772..4924d8c56 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -1901,6 +1901,71 @@ out: + return r; + } + ++int dev_manager_vdo_pool_size_config(struct dev_manager *dm, ++ const struct logical_volume *lv, ++ struct vdo_pool_size_config *cfg) ++{ ++ const char *dlid; ++ struct dm_info info; ++ uint64_t start, length; ++ struct dm_task *dmt = NULL; ++ char *type = NULL; ++ char *params = NULL; ++ int r = 0; ++ unsigned version = 0; ++ ++ memset(cfg, 0, sizeof(*cfg)); ++ ++ if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv)))) ++ return_0; ++ ++ if (!(dmt = _setup_task_run(DM_DEVICE_TABLE, &info, NULL, dlid, 0, 0, 0, 0, 0, 0))) ++ return_0; ++ ++ if (!info.exists) ++ goto inactive; /* VDO device is not active, should not happen here... */ ++ ++ log_debug_activation("Checking VDO pool table line for LV %s.", ++ display_lvname(lv)); ++ ++ if (dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms)) { ++ log_error("More then one table line found for %s.", ++ display_lvname(lv)); ++ goto out; ++ } ++ ++ if (!type || strcmp(type, TARGET_NAME_VDO)) { ++ log_error("Expected %s segment type but got %s instead.", ++ TARGET_NAME_VDO, type ? type : "NULL"); ++ goto out; ++ } ++ ++ if (sscanf(params, "V%u %*s " FMTu64 " %*u " FMTu32, ++ &version, &cfg->physical_size, &cfg->block_map_cache_size_mb) != 3) { ++ log_error("Failed to parse VDO parameters %s for LV %s.", ++ params, display_lvname(lv)); ++ goto out; ++ } ++ ++ switch (version) { ++ case 2: break; ++ case 4: break; ++ default: log_warn("WARNING: Unknown VDO table line version %u.", version); ++ } ++ ++ cfg->virtual_size = length; ++ cfg->physical_size *= 8; // From 4K unit to 512B ++ cfg->block_map_cache_size_mb /= 256; // From 4K unit to MiB ++ cfg->index_memory_size_mb = first_seg(lv)->vdo_params.index_memory_size_mb; // Preserved ++ ++inactive: ++ r = 1; ++out: ++ dm_task_destroy(dmt); ++ ++ return r; ++} ++ + + /*************************/ + /* NEW CODE STARTS HERE */ +diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h +index 27092f2b9..2f7ce6099 100644 +--- a/lib/activate/dev_manager.h ++++ b/lib/activate/dev_manager.h +@@ -81,6 +81,9 @@ int dev_manager_thin_pool_status(struct dev_manager *dm, + int dev_manager_vdo_pool_status(struct dev_manager *dm, + const struct logical_volume *lv, int flush, + struct lv_status_vdo **status, int *exists); ++int dev_manager_vdo_pool_size_config(struct dev_manager *dm, ++ const struct logical_volume *lv, ++ struct vdo_pool_size_config *cfg); + int dev_manager_suspend(struct dev_manager *dm, const struct logical_volume *lv, + struct lv_activate_opts *laopts, int lockfs, int flush_required); + int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv, +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index f735baa55..de21f48f2 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -1379,6 +1379,12 @@ int fill_vdo_target_params(struct cmd_context *cmd, + struct dm_vdo_target_params *vtp, + uint64_t *vdo_pool_header_size, + struct profile *profile); ++struct vdo_pool_size_config { ++ uint64_t physical_size; ++ uint64_t virtual_size; ++ uint32_t block_map_cache_size_mb; ++ uint32_t index_memory_size_mb; ++}; + int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, + uint64_t virtual_size, struct dm_vdo_target_params *vtp); + /* -- metadata/vdo_manip.c */ +-- +2.41.0 + diff --git a/SOURCES/0094-lvcreate-fix-error-path-return-values.patch b/SOURCES/0094-lvcreate-fix-error-path-return-values.patch new file mode 100644 index 0000000..86df0e8 --- /dev/null +++ b/SOURCES/0094-lvcreate-fix-error-path-return-values.patch @@ -0,0 +1,45 @@ +From 52e019c6133fbd68676bc6fecb40da9cb7e1986e Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Tue, 8 Nov 2022 12:39:25 +0100 +Subject: [PATCH 094/115] lvcreate: fix error path return values + +Return failing error code for return path, as 'return 0' in this +case was returning success. + +(cherry picked from commit b9f35e07db41f3dd6bea2c91a8bc1bff93a4d406) +--- + tools/lvcreate.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index 3eee5de90..d3fa5281f 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -1749,21 +1749,21 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name, + goto_out; + + if (seg_is_vdo(lp) && !_check_vdo_parameters(vg, lp, lcp)) +- return_0; ++ goto_out; + + if (!_check_pool_parameters(cmd, vg, lp, lcp)) + goto_out; + + /* All types are checked */ + if (!_check_zero_parameters(cmd, lp)) +- return_0; ++ goto_out; + + if (!_update_extents_params(vg, lp, lcp)) + goto_out; + + if (seg_is_vdo(lp) && !check_vdo_constrains(cmd, (uint64_t)lp->extents * vg->extent_size, + lcp->virtual_size, &lp->vdo_params)) +- return_0; ++ goto_out; + + if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp)) + goto_out; +-- +2.41.0 + diff --git a/SOURCES/0095-vdo-fix-and-enhance-vdo-constain-checking.patch b/SOURCES/0095-vdo-fix-and-enhance-vdo-constain-checking.patch new file mode 100644 index 0000000..10d37f8 --- /dev/null +++ b/SOURCES/0095-vdo-fix-and-enhance-vdo-constain-checking.patch @@ -0,0 +1,228 @@ +From a22a9aa39b7521cc04b5ac3ae4629cd022a4bd6d Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sun, 15 Jan 2023 21:27:37 +0100 +Subject: [PATCH 095/115] vdo: fix and enhance vdo constain checking + +Enhance checking vdo constains so it also handles changes of active VDO LVs +where only added difference is considered now. + +For this also the reported informational message about used memory +was improved to only list consuming RAM blocks. + +(cherry picked from commit 2451bc568feb9b3d0cb4d7c15e3c723f4d0c8cc9) +--- + WHATS_NEW | 4 ++ + lib/metadata/metadata-exported.h | 4 +- + lib/metadata/vdo_manip.c | 77 ++++++++++++++++++++++++-------- + lib/vdo/vdo.c | 24 +++++++++- + tools/lvcreate.c | 8 +++- + 5 files changed, 92 insertions(+), 25 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 48b1d7d86..7f8a16e24 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++version 2.03.19 - ++==================================== ++ Fix and improve runtime memory size detection for VDO volumes. ++ + Version 2.03.17 - + =============================== + Extend VDO and VDOPOOL without flushing and locking fs. +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index de21f48f2..6ad89a9a4 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -1385,8 +1385,8 @@ struct vdo_pool_size_config { + uint32_t block_map_cache_size_mb; + uint32_t index_memory_size_mb; + }; +-int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, +- uint64_t virtual_size, struct dm_vdo_target_params *vtp); ++ ++int check_vdo_constrains(struct cmd_context *cmd, const struct vdo_pool_size_config *cfg); + /* -- metadata/vdo_manip.c */ + + struct logical_volume *find_pvmove_lv(struct volume_group *vg, +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 1cd2130a7..787101094 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -24,6 +24,7 @@ + #include "lib/misc/lvm-exec.h" + + #include // sysinfo ++#include + + const char *get_vdo_compression_state_name(enum dm_vdo_compression_state state) + { +@@ -647,39 +648,76 @@ static uint64_t _round_sectors_to_tib(uint64_t s) + return (s + ((UINT64_C(1) << (40 - SECTOR_SHIFT)) - 1)) >> (40 - SECTOR_SHIFT); + } + +-int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, +- uint64_t virtual_size, struct dm_vdo_target_params *vtp) ++__attribute__ ((format(printf, 3, 4))) ++static int _vdo_snprintf(char **buf, size_t *bufsize, const char *format, ...) + { ++ int n; ++ va_list ap; ++ ++ va_start(ap, format); ++ n = vsnprintf(*buf, *bufsize, format, ap); ++ va_end(ap); ++ ++ if (n < 0 || ((unsigned) n >= *bufsize)) ++ return -1; ++ ++ *buf += n; ++ *bufsize -= n; ++ ++ return n; ++} ++ ++int check_vdo_constrains(struct cmd_context *cmd, const struct vdo_pool_size_config *cfg) ++{ ++ static const char *_split[] = { "", " and", ",", "," }; + uint64_t req_mb, total_mb, available_mb; +- uint64_t phy_mb = _round_sectors_to_tib(UINT64_C(268) * physical_size); // 268 MiB per 1 TiB of physical size +- uint64_t virt_mb = _round_1024(UINT64_C(1638) * _round_sectors_to_tib(virtual_size)); // 1.6 MiB per 1 TiB +- uint64_t cache_mb = _round_1024(UINT64_C(1177) * vtp->block_map_cache_size_mb); // 1.15 MiB per 1 MiB cache size ++ uint64_t phy_mb = _round_sectors_to_tib(UINT64_C(268) * cfg->physical_size); // 268 MiB per 1 TiB of physical size ++ uint64_t virt_mb = _round_1024(UINT64_C(1638) * _round_sectors_to_tib(cfg->virtual_size)); // 1.6 MiB per 1 TiB ++ uint64_t cache_mb = _round_1024(UINT64_C(1177) * cfg->block_map_cache_size_mb); // 1.15 MiB per 1 MiB cache size + char msg[512]; ++ size_t mlen = sizeof(msg); ++ char *pmsg = msg; ++ int cnt, has_cnt; + +- if (cache_mb < 150) ++ if (cfg->block_map_cache_size_mb && (cache_mb < 150)) + cache_mb = 150; // always at least 150 MiB for block map + + // total required memory for VDO target +- req_mb = 38 + vtp->index_memory_size_mb + virt_mb + phy_mb + cache_mb; ++ req_mb = 38 + cfg->index_memory_size_mb + virt_mb + phy_mb + cache_mb; + + _get_memory_info(&total_mb, &available_mb); + +- (void)snprintf(msg, sizeof(msg), "VDO configuration needs %s RAM for physical volume size %s, " +- "%s RAM for virtual volume size %s, %s RAM for block map cache size %s and " +- "%s RAM for index memory.", +- display_size(cmd, phy_mb << (20 - SECTOR_SHIFT)), +- display_size(cmd, physical_size), +- display_size(cmd, virt_mb << (20 - SECTOR_SHIFT)), +- display_size(cmd, virtual_size), +- display_size(cmd, cache_mb << (20 - SECTOR_SHIFT)), +- display_size(cmd, ((uint64_t)vtp->block_map_cache_size_mb) << (20 - SECTOR_SHIFT)), +- display_size(cmd, ((uint64_t)vtp->index_memory_size_mb) << (20 - SECTOR_SHIFT))); ++ has_cnt = cnt = (phy_mb ? 1 : 0) + ++ (virt_mb ? 1 : 0) + ++ (cfg->block_map_cache_size_mb ? 1 : 0) + ++ (cfg->index_memory_size_mb ? 1 : 0); ++ ++ if (phy_mb) ++ (void)_vdo_snprintf(&pmsg, &mlen, " %s RAM for physical volume size %s%s", ++ display_size(cmd, phy_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, cfg->physical_size), _split[--cnt]); ++ ++ if (virt_mb) ++ (void)_vdo_snprintf(&pmsg, &mlen, " %s RAM for virtual volume size %s%s", ++ display_size(cmd, virt_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, cfg->virtual_size), _split[--cnt]); ++ ++ if (cfg->block_map_cache_size_mb) ++ (void)_vdo_snprintf(&pmsg, &mlen, " %s RAM for block map cache size %s%s", ++ display_size(cmd, cache_mb << (20 - SECTOR_SHIFT)), ++ display_size(cmd, ((uint64_t)cfg->block_map_cache_size_mb) << (20 - SECTOR_SHIFT)), ++ _split[--cnt]); ++ ++ if (cfg->index_memory_size_mb) ++ (void)_vdo_snprintf(&pmsg, &mlen, " %s RAM for index memory", ++ display_size(cmd, ((uint64_t)cfg->index_memory_size_mb) << (20 - SECTOR_SHIFT))); + + if (req_mb > available_mb) { + log_error("Not enough free memory for VDO target. %s RAM is required, but only %s RAM is available.", + display_size(cmd, req_mb << (20 - SECTOR_SHIFT)), + display_size(cmd, available_mb << (20 - SECTOR_SHIFT))); +- log_print_unless_silent("%s", msg); ++ if (has_cnt) ++ log_print_unless_silent("VDO configuration needs%s.", msg); + return 0; + } + +@@ -687,7 +725,8 @@ int check_vdo_constrains(struct cmd_context *cmd, uint64_t physical_size, + display_size(cmd, req_mb << (20 - SECTOR_SHIFT)), + display_size(cmd, available_mb << (20 - SECTOR_SHIFT))); + +- log_verbose("%s", msg); ++ if (has_cnt) ++ log_verbose("VDO configuration needs%s.", msg); + + return 1; + } +diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c +index d2d14d146..133678ae7 100644 +--- a/lib/vdo/vdo.c ++++ b/lib/vdo/vdo.c +@@ -355,6 +355,27 @@ static int _vdo_pool_target_status_compatible(const char *type) + return (strcmp(type, TARGET_NAME_VDO) == 0); + } + ++static int _vdo_check(struct cmd_context *cmd, const struct lv_segment *seg) ++{ ++ ++ struct vdo_pool_size_config cfg = { 0 }; ++ ++ if (!lv_vdo_pool_size_config(seg->lv, &cfg)) ++ return_0; ++ ++ /* Check if we are just adding more size to the already running vdo pool */ ++ if (seg->lv->size >= cfg.physical_size) ++ cfg.physical_size = seg->lv->size - cfg.physical_size; ++ if (get_vdo_pool_virtual_size(seg) >= cfg.virtual_size) ++ cfg.virtual_size = get_vdo_pool_virtual_size(seg) - cfg.virtual_size; ++ if (seg->vdo_params.block_map_cache_size_mb >= cfg.block_map_cache_size_mb) ++ cfg.block_map_cache_size_mb = seg->vdo_params.block_map_cache_size_mb - cfg.block_map_cache_size_mb; ++ if (seg->vdo_params.index_memory_size_mb >= cfg.index_memory_size_mb) ++ cfg.index_memory_size_mb = seg->vdo_params.index_memory_size_mb - cfg.index_memory_size_mb; ++ ++ return check_vdo_constrains(cmd, &cfg); ++} ++ + static int _vdo_pool_add_target_line(struct dev_manager *dm, + struct dm_pool *mem, + struct cmd_context *cmd, +@@ -375,8 +396,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm, + return 0; + } + +- if (!critical_section() && +- !check_vdo_constrains(cmd, seg->lv->size, get_vdo_pool_virtual_size(seg), &seg->vdo_params)) ++ if (!critical_section() && !_vdo_check(cmd, seg)) + return_0; + + if (!(vdo_pool_name = dm_build_dm_name(mem, seg->lv->vg->name, seg->lv->name, lv_layer(seg->lv)))) +diff --git a/tools/lvcreate.c b/tools/lvcreate.c +index d3fa5281f..a2e260c5d 100644 +--- a/tools/lvcreate.c ++++ b/tools/lvcreate.c +@@ -1761,8 +1761,12 @@ static int _lvcreate_single(struct cmd_context *cmd, const char *vg_name, + if (!_update_extents_params(vg, lp, lcp)) + goto_out; + +- if (seg_is_vdo(lp) && !check_vdo_constrains(cmd, (uint64_t)lp->extents * vg->extent_size, +- lcp->virtual_size, &lp->vdo_params)) ++ if (seg_is_vdo(lp) && ++ !check_vdo_constrains(cmd, &(struct vdo_pool_size_config) { ++ .physical_size = (uint64_t)lp->extents * vg->extent_size, ++ .virtual_size = lcp->virtual_size, ++ .block_map_cache_size_mb = lp->vdo_params.block_map_cache_size_mb, ++ .index_memory_size_mb = lp->vdo_params.index_memory_size_mb })) + goto_out; + + if (seg_is_thin(lp) && !_validate_internal_thin_processing(lp)) +-- +2.41.0 + diff --git a/SOURCES/0096-vdo-resize-requires-active-vdopool-volume.patch b/SOURCES/0096-vdo-resize-requires-active-vdopool-volume.patch new file mode 100644 index 0000000..20f2bce --- /dev/null +++ b/SOURCES/0096-vdo-resize-requires-active-vdopool-volume.patch @@ -0,0 +1,37 @@ +From 72749491665de8f090292af86a62fc4405e7e8fe Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 22 Jun 2023 16:55:47 +0200 +Subject: [PATCH 096/115] vdo: resize requires active vdopool volume + +ATM kernel VDO target does not handle resize of inactive VDO LVs +so prevent users corrupting such LVs and require active such LVs. + +(manually backported from commit c20f01a0cbb24e8276734a00f26a510cf6daaf21) +--- + lib/metadata/lv_manip.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index 9523e3e66..0a51e0315 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -5190,6 +5190,16 @@ static int _lvresize_check(struct logical_volume *lv, + struct volume_group *vg = lv->vg; + struct lv_segment *seg = first_seg(lv); + ++ if (lv_is_vdo(lv) && !lv_is_active(lv)) { ++ log_error("Cannot resize inactive VDO logical volume %s.", display_lvname(lv)); ++ return 0; ++ } ++ ++ if (lv_is_vdo_pool(lv) && !lv_is_active(lv_lock_holder(lv))) { ++ log_error("Cannot resize inactive VDO POOL volume %s.", display_lvname(lv)); ++ return 0; ++ } ++ + if (lv_is_external_origin(lv)) { + /* + * Since external-origin can be activated read-only, +-- +2.41.0 + diff --git a/SOURCES/0097-tests-vdo-resizing.patch b/SOURCES/0097-tests-vdo-resizing.patch new file mode 100644 index 0000000..625c7df --- /dev/null +++ b/SOURCES/0097-tests-vdo-resizing.patch @@ -0,0 +1,37 @@ +From 686d6ecdccf0a72f149c42c6cfe2d630bfe03ded Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 16 Jan 2023 01:11:37 +0100 +Subject: [PATCH 097/115] tests: vdo resizing + +(cherry picked from commit aa09232dc4fb825f4e643bbe87a95e2318dd5a93) +--- + test/shell/lvresize-vdo.sh | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/test/shell/lvresize-vdo.sh b/test/shell/lvresize-vdo.sh +index 6fe0e9c26..cbe8ce967 100644 +--- a/test/shell/lvresize-vdo.sh ++++ b/test/shell/lvresize-vdo.sh +@@ -32,4 +32,19 @@ check lv_field $vg/${lv2}_vdata size "6.00g" + lvresize -L6G $vg/$lv1 + check lv_field $vg/$lv1 size "6.00g" + ++# Check too large size ++not lvresize -L4P $vg/$lv1 2>err ++grep "Volume too large" err ++ ++# Can't resize inactive VDO ++lvchange -an $vg ++not lvresize -L10G $vg/$lv1 2>err ++grep "Cannot resize inactive" err ++ ++not lvresize -L10G $vg/$lv2 2>err ++grep "Cannot resize inactive" err ++ ++not lvresize -L10G $vg/${lv2}_vdata 2>err ++grep "Cannot resize inactive" err ++ + vgremove -ff $vg +-- +2.41.0 + diff --git a/SOURCES/0098-tests-check-failing-vdo-conversion.patch b/SOURCES/0098-tests-check-failing-vdo-conversion.patch new file mode 100644 index 0000000..302afe4 --- /dev/null +++ b/SOURCES/0098-tests-check-failing-vdo-conversion.patch @@ -0,0 +1,40 @@ +From 31e71842d4be795a8f675d0cd50f8a7b8d737cd9 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 17 Feb 2023 00:06:56 +0100 +Subject: [PATCH 098/115] tests: check failing vdo conversion + +When we detect not usable vdo on a machine, check lvconvert fails. + +(cherry picked from commit 06c5c29443fdd48730a282a5db16e46c793db27b) +--- + test/shell/lvconvert-vdo.sh | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/test/shell/lvconvert-vdo.sh b/test/shell/lvconvert-vdo.sh +index c42d8f25a..7c0bce56b 100644 +--- a/test/shell/lvconvert-vdo.sh ++++ b/test/shell/lvconvert-vdo.sh +@@ -18,12 +18,18 @@ SKIP_WITH_LVMPOLLD=1 + # + # Main + # +-aux have_vdo 6 2 0 || skip +- + aux prepare_vg 2 6400 + + # Conversion to vdo-pool + lvcreate -L5G -n $lv1 $vg ++ ++if not aux have_vdo 6 2 0 ; then ++# For unsupported VDO let's check lvconvert fails ++ not lvconvert --yes --type vdo-pool $vg/$lv1 |& tee out ++ vgremove -ff $vg ++ exit ++fi ++ + # Check there is big prompting warning + not lvconvert --type vdo-pool $vg/$lv1 |& tee out + grep "WARNING" out +-- +2.41.0 + diff --git a/SOURCES/0099-vdo-use-fixed-size-vdopool-wrapper.patch b/SOURCES/0099-vdo-use-fixed-size-vdopool-wrapper.patch new file mode 100644 index 0000000..3eb7f18 --- /dev/null +++ b/SOURCES/0099-vdo-use-fixed-size-vdopool-wrapper.patch @@ -0,0 +1,38 @@ +From 51e90d49bae0a1d92687876f161c8463529fb702 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 6 Mar 2023 14:52:59 +0100 +Subject: [PATCH 099/115] vdo: use fixed size vdopool wrapper + +Instead of using size of 'empty header' in vdopool use fixed size 4K +for a 'wrappeing' vdo-pool device. + +This fixes the issue when user tried to activate vdo-pool after +a conversion from vdo managed device with 'vgchange -ay' - where +this command activated all LVs with 'vdo-pool' wrapping device as well, +but this converted pool uses 0-length header. + +This 4k size should usually prevent other tools like 'blkid' recognize +such device as anything - so it shouldn't cause any problems with +duplicate indentification of devices. + +(cherry picked from commit e8e6347ba3f59cbd2f7e92aa707543b90fa607a3) +--- + lib/activate/dev_manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index 4924d8c56..0c029917f 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -3043,7 +3043,7 @@ static int _add_layer_target_to_dtree(struct dev_manager *dm, + + /* Add linear mapping over layered LV */ + /* From VDO layer expose ONLY vdo pool header, we would need to use virtual size otherwise */ +- if (!add_linear_area_to_dtree(dnode, lv_is_vdo_pool(lv) ? first_seg(lv)->vdo_pool_header_size : lv->size, ++ if (!add_linear_area_to_dtree(dnode, lv_is_vdo_pool(lv) ? 8 : lv->size, + lv->vg->extent_size, + lv->vg->cmd->use_linear_target, + lv->vg->name, lv->name) || +-- +2.41.0 + diff --git a/SOURCES/0100-vdo-document-feature-option.patch b/SOURCES/0100-vdo-document-feature-option.patch new file mode 100644 index 0000000..0ca67fd --- /dev/null +++ b/SOURCES/0100-vdo-document-feature-option.patch @@ -0,0 +1,48 @@ +From 5e6aa69ec03848942153c7b65b270a0503363e58 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 27 Apr 2023 23:17:40 +0200 +Subject: [PATCH 100/115] vdo: document feature option + +(cherry picked from commit 534269d0fb834fb9a3b115bf859319fc1acb2275) +--- + conf/example.conf.in | 4 ++-- + lib/config/config_settings.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index 897622b9d..c74800676 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -1318,10 +1318,10 @@ global { + # Configuration option global/vdo_disabled_features. + # Features to not use in the vdo driver. + # This can be helpful for testing, or to avoid using a feature that is +- # causing problems. Features include: online_rename ++ # causing problems. Features include: online_rename, version4 + # + # Example +- # vdo_disabled_features = [ "online_rename" ] ++ # vdo_disabled_features = [ "online_rename", "version4" ] + # + # This configuration option does not have a default value defined. + +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index 2c91e8bb6..a4beda654 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -1265,10 +1265,10 @@ cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTIO + cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL, + "Features to not use in the vdo driver.\n" + "This can be helpful for testing, or to avoid using a feature that is\n" +- "causing problems. Features include: online_rename\n" ++ "causing problems. Features include: online_rename, version4\n" + "#\n" + "Example\n" +- "vdo_disabled_features = [ \"online_rename\" ]\n" ++ "vdo_disabled_features = [ \"online_rename\", \"version4\" ]\n" + "#\n") + + cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL, +-- +2.41.0 + diff --git a/SOURCES/0101-vdo-fix-and-enhance-vdo-metadata-reader.patch b/SOURCES/0101-vdo-fix-and-enhance-vdo-metadata-reader.patch new file mode 100644 index 0000000..74feb72 --- /dev/null +++ b/SOURCES/0101-vdo-fix-and-enhance-vdo-metadata-reader.patch @@ -0,0 +1,65 @@ +From 3b7c0786cce47b0f8b260605d25365145aefbda6 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 9 Jun 2023 13:21:35 +0200 +Subject: [PATCH 101/115] vdo: fix and enhance vdo metadata reader + +Improve metadata parser to handle volume_geometry bio_offset, +which needs to be substracted from 'region' start_block when present. + +This bio_offset block is non-zero i.e. with converted VDO volumes. + +Also fix some converted structure value (but they are not in use). + +(cherry picked from commit 00633f8b668d94a58756d96f5927fd690b8f41d3) +--- + device_mapper/vdo/vdo_reader.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c +index 3596afbd3..2451947cd 100644 +--- a/device_mapper/vdo/vdo_reader.c ++++ b/device_mapper/vdo/vdo_reader.c +@@ -146,13 +146,14 @@ static void _vdo_decode_header(struct vdo_header *h) + static void _vdo_decode_geometry_region(struct vdo_volume_region *vr) + { + vr->id = le32_to_cpu(vr->id); +- vr->start_block = le32_to_cpu(vr->start_block); ++ vr->start_block = le64_to_cpu(vr->start_block); + } + + static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg) + { +- vg->release_version = le64_to_cpu(vg->release_version); ++ vg->release_version = le32_to_cpu(vg->release_version); + vg->nonce = le64_to_cpu(vg->nonce); ++ vg->bio_offset = le64_to_cpu(vg->bio_offset); + _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); + } + +@@ -225,10 +226,14 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + goto err; + } + ++ if (h.id != 5) { ++ log_debug_activation("Expected geometry VDO block instead of block %u.", h.id); ++ goto err; ++ } + memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); + _vdo_decode_volume_geometry(&vg); + +- regpos = vg.regions[VDO_DATA_REGION].start_block * 4096; ++ regpos = (vg.regions[VDO_DATA_REGION].start_block - vg.bio_offset) * 4096; + + if ((regpos + sizeof(buffer)) > size) { + log_debug_activation("File/Device is shorter and can't provide requested VDO volume region at " FMTu64 " > " FMTu64 ".", regpos, size); +@@ -245,7 +250,6 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + goto err; + } + +- + memcpy(&vn, buffer + sizeof(struct vdo_geometry_block), sizeof(vn)); + _vdo_decode_version(&vn); + +-- +2.41.0 + diff --git a/SOURCES/0102-tests-cleanup-some-shellcheck-warns.patch b/SOURCES/0102-tests-cleanup-some-shellcheck-warns.patch new file mode 100644 index 0000000..f3252c9 --- /dev/null +++ b/SOURCES/0102-tests-cleanup-some-shellcheck-warns.patch @@ -0,0 +1,31 @@ +From 062b014c04d15ad5a5c0b8aaeb30166c33e0d763 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 22 Jun 2023 18:01:27 +0200 +Subject: [PATCH 102/115] tests: cleanup some shellcheck warns + +(manually backported some changes from commit 773bc013778df631f9ee14e7a79d5f02211b1e67) +--- + scripts/lvm_import_vdo.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index c4c1d152e..134c96513 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -255,11 +255,11 @@ convert2lvm_() { + # Find largest matching VG name to our 'default' vgname + LASTVGNAME=$(LC_ALL=C "$LVM" vgs -oname -O-name --noheadings -S name=~${VGNAME} | grep -E "${VGNAME}[0-9]? ?" | head -1 || true) + if test -n "$LASTVGNAME" ; then +- LASTVGNAME=${LASTVGNAME#*${VGNAME}} ++ LASTVGNAME=${LASTVGNAME#*"${VGNAME}"} + # If the number is becoming too high, try some random number + test "$LASTVGNAME" -gt 99999999 2>/dev/null && LASTVGNAME=$RANDOM + # Generate new unused VG name +- VGNAME="${VGNAME}$(( ${LASTVGNAME} + 1 ))" ++ VGNAME="${VGNAME}$(( LASTVGNAME + 1 ))" + verbose "Selected unused volume group name $VGNAME." + fi + fi +-- +2.41.0 + diff --git a/SOURCES/0103-vdo-enhance-lvm_vdo_import.patch b/SOURCES/0103-vdo-enhance-lvm_vdo_import.patch new file mode 100644 index 0000000..8917468 --- /dev/null +++ b/SOURCES/0103-vdo-enhance-lvm_vdo_import.patch @@ -0,0 +1,564 @@ +From 80a59e88c995b9935042e2d3f803b411353bf6d5 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 11 May 2023 20:07:37 +0200 +Subject: [PATCH 103/115] vdo: enhance lvm_vdo_import + +Add support for usage of 'dm-snapshot' for doing whole device conversion +in a snapshot which could be merged once the whole conversion has been +made. +This helps with cases where there would be any unexpected failure in the +middle of conversion process and user can continue using original +device until problem in conversion is fixed. + +Import tool now uses 'truncate' tool to create a small backend file (20M) for loop device +to hold COW exception store. + +Option --vdo-config has been added to allow specifing location of vdo +configuration file. + +Option --no-snapshot allows to use import tool without creation of +snapshot, however recovery after finished VDO conversion and unfinished +lvm2 conversion is then very difficult. + +Option --uuid-prefix allow to specify DM UUID prefix for snapshot +device. + +Use read with -r. + +(cherry picked from commit be6c34212b05d8c59c0ba68e26c56cddf61c9f04) +--- + scripts/lvm_import_vdo.sh | 375 ++++++++++++++++++++++++++++---------- + 1 file changed, 282 insertions(+), 93 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index 134c96513..bae4b52d1 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -1,6 +1,6 @@ + #!/bin/bash + # +-# Copyright (C) 2021 Red Hat, Inc. All rights reserved. ++# Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved. + # + # This file is part of LVM2. + # +@@ -19,7 +19,7 @@ + # Needed utilities: + # lvm, dmsetup, + # vdo, +-# grep, awk, sed, blockdev, readlink, stat, mkdir ++# grep, awk, sed, blockdev, readlink, stat, mkdir, truncate + # + # Conversion is using 'vdo convert' support from VDO manager to move + # existing VDO header by 2M which makes space to place in PV header +@@ -29,6 +29,9 @@ + set -euE -o pipefail + + TOOL=lvm_import_vdo ++IMPORT_NAME="VDO_${TOOL}_${RANDOM}$$" ++test ${#IMPORT_NAME} -lt 100 || error "Random name \"$IMPORT_NAME\" is too long!" ++TEMPDIR="${TMPDIR:-/tmp}/$IMPORT_NAME" + + _SAVEPATH=$PATH + PATH="/sbin:/usr/sbin:/bin:/usr/sbin:$PATH" +@@ -36,26 +39,40 @@ PATH="/sbin:/usr/sbin:/bin:/usr/sbin:$PATH" + # user may override lvm location by setting LVM_BINARY + LVM=${LVM_BINARY:-lvm} + VDO=${VDO_BINARY:-vdo} +-VDOCONF=${VDOCONF:-} + BLOCKDEV="blockdev" ++LOSETUP="losetup" + READLINK="readlink" + READLINK_E="-e" + STAT="stat" + MKDIR="mkdir" ++TRUNCATE="truncate" + DMSETUP="dmsetup" + +-TEMPDIR="${TMPDIR:-/tmp}/${TOOL}_${RANDOM}$$" + DM_DEV_DIR="${DM_DEV_DIR:-/dev}" +- +-DEVICENAME="" ++DM_UUID_PREFIX="${DM_UUID_PREFIX:-}" ++DM_VG_NAME= ++DM_LV_NAME= ++VDO_CONFIG=${VDO_CONFIG:-} # can be overriden with --vdo-config ++VDOCONF= ++test -n "$VDO_CONFIG" && VDOCONF="-f $VDO_CONFIG" ++ ++DEVICE= ++VGNAME= ++LVNAME= + DEVMAJOR=0 + DEVMINOR=0 + PROMPTING="" ++USE_VDO_DM_SNAPSHOT=1 ++VDO_DM_SNAPSHOT_NAME= ++VDO_DM_SNAPSHOT_DEVICE= ++VDO_SNAPSHOT_LOOP= + + DRY=0 + VERB="" + FORCE="" + YES="" ++ABORT_AFTER_VDO_CONVERT=0 ++VDO_ALLOCATION_PARAMS= + + # default name for converted VG and its VDO LV + DEFAULT_NAME="vdovg/vdolvol" +@@ -74,6 +91,9 @@ tool_usage() { + echo " -v | --verbose Be verbose" + echo " -y | --yes Answer \"yes\" at any prompts" + echo " --dry-run Print verbosely commands without running them" ++ echo " --no-snapshot Do not use snapshot for converted VDO device" ++ echo " --uuid-prefix Prefix for DM snapshot uuid" ++ echo " --vdo-config Configuration file for VDO manager" + + exit + } +@@ -102,12 +122,79 @@ dry() { + cleanup() { + trap '' 2 + ++ test -n "$VDO_DM_SNAPSHOT_NAME" && { "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || true ; } ++ test -n "$VDO_SNAPSHOT_LOOP" && { "$LOSETUP" -d "$VDO_SNAPSHOT_LOOP" || true ; } ++ + test -z "$PROMPTING" || echo "No" +- rm -rf "$TEMPDIR" ++ rm -rf "$TEMPDIR" || true + # error exit status for break + exit "${1:-1}" + } + ++# Create snapshot target like for persistent snapshot with 16KiB chunksize ++snapshot_target_line_() { ++ echo "0 $("$BLOCKDEV" --getsize "$1") snapshot${3:-} $1 $2 P 32" ++} ++ ++snapshot_create_() { ++ VDO_DM_SNAPSHOT_NAME="${IMPORT_NAME}_snap" ++ local file="$TEMPDIR/$VDO_DM_SNAPSHOT_NAME" ++ ++ # TODO: maybe use ramdisk via 'brd' device ?) ++ "$TRUNCATE" -s 20M "$file" ++ VDO_SNAPSHOT_LOOP=$("$LOSETUP" -f --show "$file") ++ "$DMSETUP" create "$VDO_DM_SNAPSHOT_NAME" -u "${DM_UUID_PREFIX}-${VDO_DM_SNAPSHOT_NAME}-priv" --table "$(snapshot_target_line_ "$1" "$VDO_SNAPSHOT_LOOP")" ++ VDO_DM_SNAPSHOT_DEVICE="$DM_DEV_DIR/mapper/$VDO_DM_SNAPSHOT_NAME" ++ verbose "Snapshot of VDO device $1 created: $VDO_DM_SNAPSHOT_DEVICE." ++} ++ ++snapshot_merge_() { ++ local status ++ local inital_status ++ ++ initial_status=( $("$DMSETUP" status "$VDO_DM_SNAPSHOT_NAME") ) ++ "$DMSETUP" reload "$VDO_DM_SNAPSHOT_NAME" --table "$(snapshot_target_line_ "$1" "$VDO_SNAPSHOT_LOOP" -merge)" ++ "$DMSETUP" suspend "$VDO_DM_SNAPSHOT_NAME" || { ++ error "ABORTING: Failed to initialize snapshot merge! Origin volume is unchanged." ++ } ++ ++ verbose "Merging converted VDO volume..." ++ # Running merging ++ "$DMSETUP" resume "$VDO_DM_SNAPSHOT_NAME" ++ ++ #du -h "$TEMPDIR/$VDO_DM_SNAPSHOT_NAME" ++ ++ # Loop for a while, till the snapshot is merged. ++ # Should be nearly instantenious. ++ # FIXME: Recovery when something prevents merging is hard ++ for i in $(seq 1 20) ; do ++ status=( $("$DMSETUP" status "$VDO_DM_SNAPSHOT_NAME") ) ++ # Check if merging is finished ++ test "${status[3]%/*}" = "${status[4]}" && break ++ # Wait a bit and retry ++ sleep .2 ++ done ++ test "${status[3]%/*}" = "${status[4]}" || { ++ # FIXME: Now what shall we do ??? Help.... ++ # Keep snapshot in table for possible analysis... ++ VDO_DM_SNAPSHOT_NAME= ++ VDO_SNAPSHOT_LOOP= ++ echo "Initial snapshot status ${initial_status[*]}" ++ echo "Failing merge snapshot status ${status[*]}" ++ error "ABORTING: Snapshot failed to merge! (Administrator required...)" ++ } ++ sync ++ "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || { ++ sleep 1 # sleep and retry once more ++ "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || { ++ error "ABORTING: Cannot remove snapshot $VDO_DM_SNAPSHOT_NAME! (check volume autoactivation...)" ++ } ++ } ++ VDO_DM_SNAPSHOT_NAME= ++ "$LOSETUP" -d "$VDO_SNAPSHOT_LOOP" ++ VDO_SNAPSHOT_LOOP= ++} ++ + get_enabled_value_() { + case "$1" in + enabled) echo "1" ;; +@@ -221,46 +308,191 @@ parse_yaml_() { + ) < "$yaml_file" + } + +-# convert existing VDO volume into lvm2 volume ++# ++# Convert VDO volume on LV to VDOPool within this VG ++# ++# This conversion requires the size of VDO virtual volume has to be expressed in the VG's extent size. ++# Currently this enforces a user to reduce the VG extent size to the smaller size (up to 4KiB). ++# ++# TODO: We may eventually relax this condition just like we are doing rounding for convert_non_lv_() ++# Let's if there would be any singly user requiring this feauture. ++# It may allow to better use larger VDO volume size (in TiB ranges). ++# ++convert_lv_() { ++ local vdo_logicalSize=$1 ++ local extent_size ++ local pvfree ++ ++ pvfree=$("$LVM" lvs -o size --units b --nosuffix --noheadings "$DM_VG_NAME/$DM_LV_NAME") ++ pvfree=$(( pvfree / 1024 )) # to KiB ++ # select largest possible extent size that can exactly express both sizes ++ extent_size=$(get_largest_extent_size_ "$pvfree" "$vdo_logicalSize") ++ ++ # validate existing VG extent_size can express virtual VDO size ++ vg_extent_size=$("$LVM" vgs -o vg_extent_size --units b --nosuffix --noheadings "$VGNAME") ++ vg_extent_size=$(( vg_extent_size / 1024 )) ++ ++ test "$vg_extent_size" -le "$extent_size" || { ++ error "Please vgchange extent_size to at most $extent_size KiB or extend and align virtual size of VDO device on $vg_extent_size KiB before retrying conversion." ++ } ++ verbose "Renaming existing LV to be used as _vdata volume for VDO pool LV." ++ dry "$LVM" lvrename $YES $VERB "$VGNAME/$DM_LV_NAME" "$VGNAME/${LVNAME}_vpool" || { ++ error "Rename of LV \"$VGNAME/$DM_LV_NAME\" failed, while VDO header has been already moved!" ++ } ++ ++ verbose "Converting to VDO pool." ++ dry "$LVM" lvconvert $YES $VERB $FORCE --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSize}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" ++ ++ verbose "Removing now unused VDO entry from VDO configuration." ++ dry "$VDO" remove $VDOCONF $VERB --force --name "$VDONAME" ++} ++ ++# ++# Convert VDO volume on a device to VG with VDOPool LV ++# ++# Convert device with the use of snapshot on top of original VDO volume (can be optionally disabled) ++# Once the whole conversion is finished, snapshot is merged (During the short periof time of merging ++# user must ensure there will be no power-off!) ++# ++# For best use the latest version of vdoprepareforlvm tool is required. ++convert_non_lv_() { ++ local vdo_logicalSize=$1 ++ local extent_size ++ local output ++ local pvfree ++ ++ if [ "$USE_VDO_DM_SNAPSHOT" = "1" ]; then ++ dry snapshot_create_ "$DEVICE" ++ sed "s:$DEVICE:$VDO_DM_SNAPSHOT_DEVICE:" "$TEMPDIR/vdoconf.yml" > "$TEMPDIR/vdo_snap.yml" ++ # Let VDO manager operate on snapshot volume ++ VDOCONF="-f $TEMPDIR/vdo_snap.yml" ++ fi ++ ++ verbose "Moving VDO header." ++ output=$(dry "$VDO" convert $VDOCONF --force --name "$VDONAME") ++ ++ if [ "$ABORT_AFTER_VDO_CONVERT" != "0" ] ; then ++ verbose "Aborting VDO coversion after moving VDO, volume is useless!" ++ cleanup 0 ++ fi ++ ++ # Parse result from VDO preparation/conversion tool ++ # New version of the tool provides output with alingment and offset ++ local vdo_length=0 ++ local vdo_aligned=0 ++ local vdo_offset=0 ++ local vdo_non_converted=0 ++ while IFS= read -r line ; do ++ case "$line" in ++ "Non converted"*) vdo_non_converted=1 ;; ++ "Length"*) vdo_length=${line##* = } ;; ++ "Conversion completed"*) ++ vdo_aligned=${line##*aligned on } ++ vdo_aligned=${vdo_aligned%%[!0-9]*} ++ vdo_offset=${line##*offset } ++ # backward compatibility with report from older version ++ vdo_offset=${vdo_offset##*by } ++ vdo_offset=${vdo_offset%%[!0-9]*} ++ ;; ++ esac ++ done <<< "$output" ++ ++ # In case we operation with snapshot, all lvm2 operation will also run on top of snapshot ++ local devices=${VDO_DM_SNAPSHOT_DEVICE:-$DEVICE} ++ ++ dry "$LVM" pvcreate $YES --devices "$devices" --dataalignment "$vdo_offset"b "$devices" || { ++ error "Creation of PV on \"$DEVICE\" failed, while VDO header has been already moved!" ++ } ++ ++ # Obtain free space in this new PV ++ # after 'vdo convert' call there is ~(1-2)M free space at the front of the device ++ pvfree=$("$BLOCKDEV" --getsize64 "$DEVICE") ++ pvfree=$(( ( pvfree - vdo_offset ) / 1024 )) # to KiB ++ if [ -n "$vdo_aligned" ] && [ "$vdo_aligned" != "0" ]; then ++ extent_size=$(( vdo_aligned / 1024 )) ++ else ++ extent_size=$(get_largest_extent_size_ "$pvfree" "$vdo_logicalSize") ++ fi ++ ++ # Round virtual size to the LOWER size expressed in extent units. ++ # lvm is parsing VDO metadata and can read real full size and use it instead of this smaller value. ++ # To precisely byte-synchronize the size of VDO LV, user can lvresize such VDO LV later. ++ vdo_logicalSize=$(( ( vdo_logicalSize / extent_size ) * extent_size )) ++ ++ verbose "Creating VG \"${NAME%/*}\" with extent size $extent_size KiB." ++ dry "$LVM" vgcreate $YES $VERB --devices "$devices" -s "${extent_size}k" "$VGNAME" "$devices" || { ++ error "Creation of VG \"$VGNAME\" failed, while VDO header has been already moved!" ++ } ++ ++ verbose "Creating VDO pool data LV from all extents in volume group $VGNAME." ++ dry "$LVM" lvcreate -Zn -Wn -an $YES $VERB --devices "$devices" -l100%VG -n "${LVNAME}_vpool" "$VGNAME" "$devices" ++ ++ verbose "Converting to VDO pool." ++ dry "$LVM" lvconvert $YES $VERB $FORCE --devices "$devices" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSize}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" ++ ++ dry "$LVM" vgchange -an $VERB $FORCE --devices "$devices" "$VGNAME" ++ ++ if [ "$USE_VDO_DM_SNAPSHOT" = "1" ]; then ++ if [ -z "$YES" ]; then ++ PROMPTING=yes ++ echo "Warning: Do not interrupt merging process once it starts (VDO data may become irrecoverable)!" ++ echo -n "Do you want to merge converted VDO device \"$DEVICE\" to VDO LV \"$VGNAME/$LVNAME\"? [y|N]: " ++ read -r -n 1 -s ANSWER ++ case "${ANSWER:0:1}" in ++ y|Y ) echo "Yes" ;; ++ * ) echo "No" ; PROMPTING=""; cleanup 1 ;; ++ esac ++ PROMPTING="" ++ YES="-y" # From now, now prompting ++ fi ++ ++ dry snapshot_merge_ "$DEVICE" ++ if [ -e "$TEMPDIR/vdo_snap.yml" ]; then ++ dry cp "$TEMPDIR/vdo_snap.yml" "$VDO_CONFIG" ++ else ++ dry rm -f "$VDO_CONFIG" ++ fi ++ verbose "Merging of VDO device finished." ++ fi ++ ++ dry "$LVM" lvchange -ay $VERB $FORCE "$VGNAME/$LVNAME" ++} ++ ++# Convert existing VDO volume into lvm2 volume + convert2lvm_() { +- local DEVICE=$1 +- local VGNAME=${NAME%/*} +- local LVNAME=${NAME#*/} + local VDONAME + local TRVDONAME +- local EXTENTSZ +- local IS_LV=1 + local FOUND="" + local MAJOR=0 + local MINOR=0 +- local DM_VG_NAME +- local DM_LV_NAME + ++ VGNAME=${NAME%/*} ++ LVNAME=${NAME#*/} + DM_UUID="" + detect_lv_ "$DEVICE" + case "$DM_UUID" in + LVM-*) eval "$("$DMSETUP" splitname --nameprefixes --noheadings --separator ' ' "$DM_NAME")" + if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then + VGNAME=$DM_VG_NAME +- verbose "Using existing volume group name $VGNAME." ++ verbose "Using existing volume group name \"$VGNAME\"." + test -n "$LVNAME" || LVNAME=$DM_LV_NAME +- elif test "$VGNAME" != "$DM_VG_NAME" ; then ++ elif [ "$VGNAME" != "$DM_VG_NAME" ]; then + error "Volume group name \"$VGNAME\" does not match name \"$DM_VG_NAME\" for VDO device \"$DEVICE\"." + fi + ;; +- *) IS_LV=0 ++ *) + # Check if we need to generate unused $VGNANE + if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then + VGNAME=${DEFAULT_NAME%/*} + # Find largest matching VG name to our 'default' vgname +- LASTVGNAME=$(LC_ALL=C "$LVM" vgs -oname -O-name --noheadings -S name=~${VGNAME} | grep -E "${VGNAME}[0-9]? ?" | head -1 || true) +- if test -n "$LASTVGNAME" ; then ++ LASTVGNAME=$(LC_ALL=C "$LVM" vgs -oname -O-name --noheadings -S name=~"${VGNAME}" | grep -E "${VGNAME}[0-9]? ?" | head -1 || true) ++ if [ -n "$LASTVGNAME" ]; then + LASTVGNAME=${LASTVGNAME#*"${VGNAME}"} + # If the number is becoming too high, try some random number + test "$LASTVGNAME" -gt 99999999 2>/dev/null && LASTVGNAME=$RANDOM + # Generate new unused VG name + VGNAME="${VGNAME}$(( LASTVGNAME + 1 ))" +- verbose "Selected unused volume group name $VGNAME." ++ verbose "Selected unused volume group name \"$VGNAME\"." + fi + fi + # New VG is created, LV name should be always unused. +@@ -269,13 +501,14 @@ convert2lvm_() { + ;; + esac + +- verbose "Checked whether device $1 is already LV ($IS_LV)." ++ verbose "Checked whether device \"$DEVICE\" is already logical volume." + + "$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR." + + # TODO: might use directly /etc/vdoconf.yml (avoding need of 'vdo' manager) + verbose "Getting YAML VDO configuration." + "$VDO" printConfigFile $VDOCONF >"$TEMPDIR/vdoconf.yml" ++ test -s "$TEMPDIR/vdoconf.yml" || error "Cannot work without VDO configuration" + + # Check list of devices in VDO configure file for their major:minor + # and match with given $DEVICE devmajor:devminor +@@ -290,8 +523,8 @@ convert2lvm_() { + } + done + +- test -n "$FOUND" || error "Can't find matching device in vdo configuration file." +- verbose "Found matching device $FOUND $MAJOR:$MINOR" ++ test -n "$FOUND" || error "Can't find matching device in VDO configuration file." ++ verbose "Found matching device $FOUND $MAJOR:$MINOR." + + VDONAME=$(awk -v DNAME="$FOUND" '/.*VDOService$/ {VNAME=substr($1, 0, length($1) - 1)} /[[:space:]]*device:/ { if ($2 ~ DNAME) {print VNAME}}' "$TEMPDIR/vdoconf.yml") + TRVDONAME=$(echo "$VDONAME" | tr '-' '_') +@@ -313,7 +546,7 @@ convert2lvm_() { + + verbose "Converted VDO device has logical/physical size $vdo_logicalSize/$vdo_physicalSize KiB." + +- PARAMS=$(cat < +Date: Fri, 9 Jun 2023 13:24:19 +0200 +Subject: [PATCH 104/115] vdo: man updates for lvm_import_vdo + +(cherry picked from commit 17ee5df8576acf628d88fd6840ce55aa1388d6d1) +--- + man/lvm_import_vdo.8_main | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/man/lvm_import_vdo.8_main b/man/lvm_import_vdo.8_main +index 23755a3aa..20be6847d 100644 +--- a/man/lvm_import_vdo.8_main ++++ b/man/lvm_import_vdo.8_main +@@ -61,6 +61,20 @@ Answer "yes" at any prompts. + .BR --dry-run + Print verbosely commands without running them. + . ++.TP ++.BR --no-snapshot ++With this option conversion tool will not use snapshot (COW storage) for conversion ++in your $TMPDIR filesystem and it will directly manipulate with VDO device in-place. ++Warning: the snapshot usage makes the whole conversion transactional and ++the snapshot can be just simply merged once the whole conversion ++has successfully proceeded. In the case of error the snapshot is just removed. ++Without the use of snapshot there is higher risk of problems with recoverability in ++case some unexpected error occurs. ++. ++.TP ++.BR --vdo-config ++Configuration file for VDO manager. Can be used to specify configuration for vdo manager. ++. + . + .SH DIAGNOSTICS + . +@@ -83,6 +97,15 @@ The temporary directory name for mount points. Defaults to "\fI/tmp\fP". + .B DM_DEV_DIR + The device directory name. + Defaults to "\fI/dev\fP" and must be an absolute path. ++.TP ++.B DM_UUID_PREFIX ++Specify uuid prefix for snapshot volume used during vdo conversion. ++.TP ++.B LVM_BINARY ++Allow to overide command called from lvm. Defaults to "\fIlvm\fP". ++.TP ++.B VDO_BINARY ++Allow to overide command called from vdo. Defaults to "\fIvdo\fP". + . + .SH SEE ALSO + . +-- +2.41.0 + diff --git a/SOURCES/0105-tests-vdo-manager-wrapper-tool-updates.patch b/SOURCES/0105-tests-vdo-manager-wrapper-tool-updates.patch new file mode 100644 index 0000000..1bbbb47 --- /dev/null +++ b/SOURCES/0105-tests-vdo-manager-wrapper-tool-updates.patch @@ -0,0 +1,68 @@ +From f38f89313938906cee1ef945847c26f37d7bb7fe Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 9 Jun 2023 13:24:56 +0200 +Subject: [PATCH 105/115] tests: vdo manager wrapper tool updates + +Support size specification in KiB units. +Add some theoretical support for some new options from vdoprepareforlvm. + +(cherry picked from commit 7f661a24c4f7fa8f161f17da093e456f0d60e106) +--- + test/lib/lvm_vdo_wrapper.sh | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/test/lib/lvm_vdo_wrapper.sh b/test/lib/lvm_vdo_wrapper.sh +index 90d0b2ce8..131f3e872 100755 +--- a/test/lib/lvm_vdo_wrapper.sh ++++ b/test/lib/lvm_vdo_wrapper.sh +@@ -11,7 +11,7 @@ LVM_VDO_FORMAT=${LVM_VDO_FORMAT-"oldvdoformat"} + # tool for shifting VDO metadata header by 2MiB + LVM_VDO_PREPARE=${LVM_VDO_PREPARE-"oldvdoprepareforlvm"} + # default vdo conf file +-LVM_VDO_DEFAULT_CONF=${LVM_VDO_DEFAULT_CONF-"/tmp/vdoconf.yml"} ++LVM_VDO_DEFAULT_CONF=${LVM_VDO_DEFAULT_CONF-"${TMPDIR:-/tmp}/vdoconf.yml"} + + vdo_die_() { + echo -e "$@" >&2 +@@ -39,6 +39,7 @@ vdo_get_kb_size_with_unit_() { + esac + + case "$1" in ++ *[kK]) sz=1 ;; + *[mM]) sz=1024 ;; + *[gG]) sz=$(( 1024 * 1024 )) ;; + *[tT]) sz=$(( 1024 * 1024 * 1024 )) ;; +@@ -318,6 +319,10 @@ local vdo_force= + local vdo_name= + local vdo_verbose= + local vdo_device= ++local vdo_dry_run= ++local vdo_check= ++local vdo_version= ++local vdo_help= + + while [ "$#" -ne 0 ] + do +@@ -326,6 +331,10 @@ do + "--name"|"-n") shift; vdo_name=$1 ;; + "--verbose"|"-d"|"--debug") vdo_verbose="-v" ;; + "--force") vdo_force="--force" ;; ++ "--dry-run") vdo_dry_run="--dry-run" ;; ++ "--check") vdo_check="--check" ;; ++ "--version") vdo_version="--version" ;; ++ "--help") vdo_help="--help" ;; + esac + shift + done +@@ -337,7 +346,7 @@ vdo_device=$(awk -v vdovolname="$vdo_name" 'BEGIN { have=0 } + "$vdo_confFile") + + #dmsetup status --target vdo "$vdo_name" || true +-vdo_dry_ "$LVM_VDO_PREPARE" "$vdo_device" ++vdo_dry_ "$LVM_VDO_PREPARE" $vdo_dry_run $vdo_check $vdo_version $vdo_help "$vdo_device" + vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true + } + +-- +2.41.0 + diff --git a/SOURCES/0106-tests-update-test-to-handle-different-status.patch b/SOURCES/0106-tests-update-test-to-handle-different-status.patch new file mode 100644 index 0000000..91fee23 --- /dev/null +++ b/SOURCES/0106-tests-update-test-to-handle-different-status.patch @@ -0,0 +1,40 @@ +From 0fe0f35cda550aa3876126171c119904902ad2b4 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 4 Nov 2022 17:00:48 +0100 +Subject: [PATCH 106/115] tests: update test to handle different status + +Since now we change deduplication with V4 table line change, +the modification tends to be faster and we can capture for a few ms +also 'status' about opening or closing deduplication index. +Use 'grep -E' to handle both words. + +(cherry picked from commit 0fed9b097120648301faa586970a47b8b4d629ff) +--- + test/shell/lvchange-vdo.sh | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/test/shell/lvchange-vdo.sh b/test/shell/lvchange-vdo.sh +index 7cc44d6bc..b11edf35c 100644 +--- a/test/shell/lvchange-vdo.sh ++++ b/test/shell/lvchange-vdo.sh +@@ -40,13 +40,14 @@ check grep_dmsetup status $vg-vdopool-vpool " online online " + + # dedulication_ARG + lvchange --deduplication n $vg/vdopool +-check grep_dmsetup status $vg-vdopool-vpool " offline online " ++check grep_dmsetup status $vg-vdopool-vpool -E " offline|closed online " ++ + lvchange --deduplication y $vg/vdopool +-check grep_dmsetup status $vg-vdopool-vpool " online online " ++check grep_dmsetup status $vg-vdopool-vpool -E " online|opening online " + + + lvchange --compression n --deduplication n $vg/vdopool +-check grep_dmsetup status $vg-vdopool-vpool " offline offline " ++check grep_dmsetup status $vg-vdopool-vpool -E " offline|closed offline " + + # --vdosettings needs inactive LV + not lvchange --vdosettings 'ack_threads=8' $vg/vdopool +-- +2.41.0 + diff --git a/SOURCES/0107-tests-updates.patch b/SOURCES/0107-tests-updates.patch new file mode 100644 index 0000000..ba39993 --- /dev/null +++ b/SOURCES/0107-tests-updates.patch @@ -0,0 +1,158 @@ +From a621c3a6dcd8e08315579f725b6565a583a2be45 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 9 Jun 2023 13:28:23 +0200 +Subject: [PATCH 107/115] tests: updates + +Add some more complicated conversion tests. + +(cherry picked from commit 9105890d43bd1b6fe514114f671af2e946e13083) +--- + test/shell/vdo-convert.sh | 67 +++++++++++++++++++++++++++------------ + 1 file changed, 46 insertions(+), 21 deletions(-) + +diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh +index 5bf53d081..cb3dd7100 100644 +--- a/test/shell/vdo-convert.sh ++++ b/test/shell/vdo-convert.sh +@@ -18,10 +18,12 @@ SKIP_WITH_LVMPOLLD=1 + . lib/inittest + + # Use local for this test vdo configuratoin +-VDOCONF="-f vdotestconf.yml" ++VDO_CONFIG="vdotestconf.yml" ++VDOCONF="-f $VDO_CONFIG" + #VDOCONF="" +-export VDOCONF ++export VDOCONF VDO_CONFIG + VDONAME="${PREFIX}-TESTVDO" ++export DM_UUID_PREFIX=$PREFIX + + # VDO automatically starts dmeventd + aux prepare_dmeventd +@@ -44,11 +46,11 @@ export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf" + + aux have_vdo 6 2 0 || skip + +-aux prepare_devs 2 10000 ++aux prepare_devs 2 20000 + + aux extend_filter_LVMTEST + +- ++export TMPDIR=$PWD + + + # Conversion can be made with this version of vdo driver +@@ -59,14 +61,16 @@ aux have_vdo 6 2 5 || skip + # + # In this case we do not need to move any VDO headers. + # ++if [ 1 -eq 0 ]; then + vgcreate $vg "$dev1" + + lvcreate -L5G -n $lv1 $vg + ++# use some not so 'well' aligned virtual|logical size + vdo create $VDOCONF --name "$VDONAME" --device "$DM_DEV_DIR/$vg/$lv1" --vdoSlabSize 128M --vdoLogicalSize 10G + + mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME" +- ++##XXXXX + # Different VG name fails + not lvm_import_vdo -y -v --name $vg1/$lv1 "$DM_DEV_DIR/$vg/$lv1" + +@@ -130,26 +134,25 @@ vdo create $VDOCONF --name "$VDONAME" --device "$dev1" --vdoSlabSize 128M --vdoL + + mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME" + +-lvm_import_vdo -y -v --name $vg1/$lv2 "$dev1" ++lvm_import_vdo --vdo-config "$VDO_CONFIG" -y -v --name $vg1/$lv2 "$dev1" + + fsck -n "$DM_DEV_DIR/$vg1/$lv2" + + vgremove -f $vg1 ++fi + +-aux teardown_devs +- +- +-# Check with some real non-DM device from system +-# this needs to dropping DM_DEV_DIR ++aux wipefs_a "$dev1" + +-aux prepare_loop 60000 || skip ++# let's assume users with VDO target have 'new' enough version of stat too ++# otherwise use more universal code from lvm_vdo_import ++read major minor < <(stat -c '%Hr %Lr' $(readlink -e "$dev1")) ++dmsetup create "$PREFIX-vdotest" --table "0 30280004 linear $major:$minor 32" + +-test -f LOOP +-LOOP=$(< LOOP) +-LOOP="${DM_DEV_DIR}/${LOOP##/dev/}" ++TEST="$DM_DEV_DIR/mapper/$PREFIX-vdotest" + +-aux extend_filter "a|$LOOP|" +-aux extend_devices "$LOOP" ++aux wipefs_a "$TEST" ++aux extend_filter "a|$TEST|" ++aux extend_devices "$TEST" + + # + # Unfortunatelly generates this in syslog: +@@ -165,7 +168,9 @@ aux extend_devices "$LOOP" + # + # automate... + # +-vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoLogicalSize 23G\ ++ ++# use slightly smaller size then 'rounded' 23G - to enforce vdo_logicalSize rounding ++vdo create $VDOCONF --name "$VDONAME" --device "$TEST" --vdoSlabSize 128M --vdoLogicalSize 24117240K\ + --blockMapCacheSize 192 \ + --blockMapPeriod 2048 \ + --emulate512 disabled \ +@@ -179,19 +184,39 @@ vdo create $VDOCONF --name "$VDONAME" --device "$LOOP" --vdoSlabSize 128M --vdoL + --vdoHashZoneThreads 3 \ + --vdoLogicalThreads 3 \ + --writePolicy async-unsafe ++dmsetup table + + # Get VDO table line + dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig + ++# For conversion we + aux lvmconf 'global/vdo_disabled_features = [ "version4" ]' + +-lvm_import_vdo -y --name $vg/$lv "$LOOP" +-lvs -a $vg ++# ++# Try to prepare 'broken' case where header was moved by older tool to 2M position ++# ++export LVM_VDO_PREPARE=oldvdoprepareforlvm2M ++if which "$LVM_VDO_PREPARE" ; then ++# Use old vdoprepareforlvm tool, that always moves header to 2M offset ++cp "$VDO_CONFIG" "$VDO_CONFIG.backup" ++lvm_import_vdo --abort-after-vdo-convert --vdo-config "$VDO_CONFIG" -v -y --name $vg/$lv "$TEST" ++# Restore VDO configuration (as it's been removed with succeful vdo conversion ++cp "$VDO_CONFIG.backup" "$VDO_CONFIG" ++# Check VDO header is seen at 2M offset ++blkid -c /dev/null --probe --offset 2M "$TEST" ++fi ++unset LVM_VDO_PREPARE ++ ++#lvm_import_vdo --no-snapshot --vdo-config "$VDO_CONFIG" -v -y --name $vg/$lv "$TEST" ++lvm_import_vdo --vdo-config "$VDO_CONFIG" --uuid-prefix "$PREFIX" -v -y --name $vg/$lv "$TEST" + ++# Compare converted LV uses same VDO table line + dmsetup table "$vg-${lv}_vpool-vpool" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee new-vdo-lv + + # Check there is a match between VDO and LV managed volume + # (when differentiating parameters are deleted first) + diff -u vdo-orig new-vdo-lv || die "Found mismatching VDO table lines!" + +-check lv_field $vg/$lv size "23.00g" ++check lv_field $vg/$lv size "<23.00g" ++unset LVM_VDO_PREPARE ++ +-- +2.41.0 + diff --git a/SOURCES/0108-WHATS_NEW-update.patch b/SOURCES/0108-WHATS_NEW-update.patch new file mode 100644 index 0000000..627bf6c --- /dev/null +++ b/SOURCES/0108-WHATS_NEW-update.patch @@ -0,0 +1,28 @@ +From d698509aa858b9da78e9c3719ba80dfcb15fd4cb Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 9 Jun 2023 17:52:00 +0200 +Subject: [PATCH 108/115] WHATS_NEW: update + +(cherry picked from commit 7ac5dbfd09e771f087a9467aca8a0d5905084459) +--- + WHATS_NEW | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 7f8a16e24..a2bec7e11 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,5 +1,9 @@ ++version 2.03.22 - ++================================= ++ Enhance lvm_import_vdo and use snapshot when converting VDO volume. ++ Fix parsing of VDO metadata. ++ + version 2.03.19 - +-==================================== + Fix and improve runtime memory size detection for VDO volumes. + + Version 2.03.17 - +-- +2.41.0 + diff --git a/SOURCES/0109-lvm_import_vdo-correct-the-converted-virtual-size.patch b/SOURCES/0109-lvm_import_vdo-correct-the-converted-virtual-size.patch new file mode 100644 index 0000000..b6fb637 --- /dev/null +++ b/SOURCES/0109-lvm_import_vdo-correct-the-converted-virtual-size.patch @@ -0,0 +1,55 @@ +From 3603348e5035d58aa6c458cdf273760be9af7462 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 23 Jun 2023 18:01:32 +0200 +Subject: [PATCH 109/115] lvm_import_vdo: correct the converted virtual size + +Ensure the volume after conversion has the properly aligned size to the +volume group extent size. This would be visible when using virtual size, +that cannot be divided by extent size. + +Before the user had to manually adjust the size after conversion to get +access to all data stored on VDO volume. + +(cherry picked from commit 657dde6208ddc8172b7d0e1466751046c8ddaeaa) +--- + scripts/lvm_import_vdo.sh | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index bae4b52d1..13197c6fb 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -357,6 +357,7 @@ convert_lv_() { + # For best use the latest version of vdoprepareforlvm tool is required. + convert_non_lv_() { + local vdo_logicalSize=$1 ++ local vdo_logicalSizeRounded + local extent_size + local output + local pvfree +@@ -417,7 +418,7 @@ convert_non_lv_() { + # Round virtual size to the LOWER size expressed in extent units. + # lvm is parsing VDO metadata and can read real full size and use it instead of this smaller value. + # To precisely byte-synchronize the size of VDO LV, user can lvresize such VDO LV later. +- vdo_logicalSize=$(( ( vdo_logicalSize / extent_size ) * extent_size )) ++ vdo_logicalSizeRounded=$(( ( vdo_logicalSize / extent_size ) * extent_size )) + + verbose "Creating VG \"${NAME%/*}\" with extent size $extent_size KiB." + dry "$LVM" vgcreate $YES $VERB --devices "$devices" -s "${extent_size}k" "$VGNAME" "$devices" || { +@@ -428,7 +429,12 @@ convert_non_lv_() { + dry "$LVM" lvcreate -Zn -Wn -an $YES $VERB --devices "$devices" -l100%VG -n "${LVNAME}_vpool" "$VGNAME" "$devices" + + verbose "Converting to VDO pool." +- dry "$LVM" lvconvert $YES $VERB $FORCE --devices "$devices" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSize}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" ++ dry "$LVM" lvconvert $YES $VERB $FORCE --devices "$devices" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSizeRounded}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" ++ if [ "$vdo_logicalSizeRounded" -lt "$vdo_logicalSize" ] ; then ++ # need to extend virtal size to be covering all the converted area ++ # let lvm2 to round to the proper virtual size of VDO LV ++ dry "$LVM" lvextend $YES $VERB --fs ignore --devices "$devices" -L "$vdo_logicalSize"k "$VGNAME/$LVNAME" ++ fi + + dry "$LVM" vgchange -an $VERB $FORCE --devices "$devices" "$VGNAME" + +-- +2.41.0 + diff --git a/SOURCES/0110-tests-update-test-for-automatic-virtual-size-correct.patch b/SOURCES/0110-tests-update-test-for-automatic-virtual-size-correct.patch new file mode 100644 index 0000000..e623219 --- /dev/null +++ b/SOURCES/0110-tests-update-test-for-automatic-virtual-size-correct.patch @@ -0,0 +1,71 @@ +From 36ef0612d9bc8866dc72c6c9896db0014fe68cd1 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 23 Jun 2023 18:03:25 +0200 +Subject: [PATCH 110/115] tests: update test for automatic virtual size + correction + +lvm_import_vdo will adjust the virtual size within conversion +so the volume can be use without any futher tweaking. + +(cherry picked from commit 8d09124c6204d49f6bda833229c96e8a76665127) +--- + test/shell/vdo-convert.sh | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/test/shell/vdo-convert.sh b/test/shell/vdo-convert.sh +index cb3dd7100..231939cf4 100644 +--- a/test/shell/vdo-convert.sh ++++ b/test/shell/vdo-convert.sh +@@ -61,7 +61,6 @@ aux have_vdo 6 2 5 || skip + # + # In this case we do not need to move any VDO headers. + # +-if [ 1 -eq 0 ]; then + vgcreate $vg "$dev1" + + lvcreate -L5G -n $lv1 $vg +@@ -139,7 +138,6 @@ lvm_import_vdo --vdo-config "$VDO_CONFIG" -y -v --name $vg1/$lv2 "$dev1" + fsck -n "$DM_DEV_DIR/$vg1/$lv2" + + vgremove -f $vg1 +-fi + + aux wipefs_a "$dev1" + +@@ -189,6 +187,8 @@ dmsetup table + # Get VDO table line + dmsetup table "$VDONAME" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee vdo-orig + ++mkfs.ext4 -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME" ++ + # For conversion we + aux lvmconf 'global/vdo_disabled_features = [ "version4" ]' + +@@ -209,14 +209,22 @@ unset LVM_VDO_PREPARE + + #lvm_import_vdo --no-snapshot --vdo-config "$VDO_CONFIG" -v -y --name $vg/$lv "$TEST" + lvm_import_vdo --vdo-config "$VDO_CONFIG" --uuid-prefix "$PREFIX" -v -y --name $vg/$lv "$TEST" ++dmsetup table ++ ++# check our filesystem is OK ++fsck -n "$DM_DEV_DIR/$vg/$lv" + + # Compare converted LV uses same VDO table line + dmsetup table "$vg-${lv}_vpool-vpool" | tr " " "\n" | sed -e '5,6d' -e '12d' | tee new-vdo-lv + ++tail -n+3 vdo-orig >vdo-orig-3 ++tail -n+3 new-vdo-lv >new-vdo-lv-3 ++ + # Check there is a match between VDO and LV managed volume + # (when differentiating parameters are deleted first) +-diff -u vdo-orig new-vdo-lv || die "Found mismatching VDO table lines!" ++# we need to skip first 2 lines as the device size gets rounded to match VG extent size ++diff -u vdo-orig-3 new-vdo-lv-3 || die "Found mismatching VDO table lines!" + +-check lv_field $vg/$lv size "<23.00g" ++check lv_field $vg/$lv size "23.00g" + unset LVM_VDO_PREPARE + +-- +2.41.0 + diff --git a/SOURCES/0111-vdo-check_point_frequence-is-unused-option.patch b/SOURCES/0111-vdo-check_point_frequence-is-unused-option.patch new file mode 100644 index 0000000..29d3136 --- /dev/null +++ b/SOURCES/0111-vdo-check_point_frequence-is-unused-option.patch @@ -0,0 +1,174 @@ +From e001f919e8cc8f4f0cf9cad304fdf4ff4556e326 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 28 Jun 2023 11:55:20 +0200 +Subject: [PATCH 111/115] vdo: check_point_frequence is unused option + +This vdo parameter existed in the early stage of integration of vdo into lvm2, +but later it's been removed from vdoformat tool - so actually if +there would be any non-zero value it would cause error on lvcreate. +Option was not stored on disk in lvm2 metadata. + +Remove this vdo parameter from lvm2 sources. + +(Although this vdo parameter will be still accepted on cmdline through + --vdosettings option, but it will be ignored.) + +(cherry picked from commit 6ff65e675582265a673136f1edd5358b26c9e481) +--- + conf/example.conf.in | 5 ----- + conf/vdo-small.profile | 1 - + device_mapper/vdo/target.h | 1 - + lib/config/config_settings.h | 4 ++-- + lib/metadata/merge.c | 1 - + lib/metadata/vdo_manip.c | 10 ---------- + man/lvmvdo.7_main | 1 - + scripts/lvm_import_vdo.sh | 1 - + tools/toollib.c | 6 +++++- + 9 files changed, 7 insertions(+), 23 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index c74800676..d5af25061 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -650,11 +650,6 @@ allocation { + # This configuration option has an automatic default value. + # vdo_block_map_period = 16380 + +- # Configuration option allocation/vdo_check_point_frequency. +- # The default check point frequency for VDO volume. +- # This configuration option has an automatic default value. +- # vdo_check_point_frequency = 0 +- + # Configuration option allocation/vdo_use_sparse_index. + # Enables sparse indexing for VDO volume. + # This configuration option has an automatic default value. +diff --git a/conf/vdo-small.profile b/conf/vdo-small.profile +index 2044fc27f..97b5b37dd 100644 +--- a/conf/vdo-small.profile ++++ b/conf/vdo-small.profile +@@ -8,7 +8,6 @@ allocation { + vdo_minimum_io_size=4096 + vdo_block_map_cache_size_mb=128 + vdo_block_map_period=16380 +- vdo_check_point_frequency=0 + vdo_use_sparse_index=0 + vdo_index_memory_size_mb=256 + vdo_slab_size_mb=2048 +diff --git a/device_mapper/vdo/target.h b/device_mapper/vdo/target.h +index bd21bb5d7..353320f9e 100644 +--- a/device_mapper/vdo/target.h ++++ b/device_mapper/vdo/target.h +@@ -81,7 +81,6 @@ struct dm_vdo_target_params { + uint32_t block_map_era_length; // format period + uint32_t block_map_period; // supported alias + }; +- uint32_t check_point_frequency; + uint32_t index_memory_size_mb; // format + + uint32_t slab_size_mb; // format +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index a4beda654..3a99ea582 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -729,8 +729,8 @@ cfg(allocation_vdo_block_map_era_length_CFG, "vdo_block_map_period", allocation_ + "The maximum and recommended value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM) + "; the minimum value is " DM_TO_STRING(DM_VDO_BLOCK_MAP_ERA_LENGTH_MINIMUM) ".\n") + +-cfg(allocation_vdo_check_point_frequency_CFG, "vdo_check_point_frequency", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CHECK_POINT_FREQUENCY, VDO_1ST_VSN, NULL, 0, NULL, +- "The default check point frequency for VDO volume.\n") ++cfg(allocation_vdo_check_point_frequency_CFG, "vdo_check_point_frequency", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_CHECK_POINT_FREQUENCY, VDO_1ST_VSN, NULL, vsn(2, 3, 22), NULL, ++ "Deprecated option to set default check point frequency for VDO volume.\n") + + // vdo format + cfg(allocation_vdo_use_sparse_index_CFG, "vdo_use_sparse_index", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_USE_SPARSE_INDEX, VDO_1ST_VSN, NULL, 0, NULL, +diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c +index 5209f51b5..25b2bc33a 100644 +--- a/lib/metadata/merge.c ++++ b/lib/metadata/merge.c +@@ -555,7 +555,6 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg, + if (seg->vdo_params.minimum_io_size | + seg->vdo_params.block_map_cache_size_mb | + seg->vdo_params.block_map_era_length | +- seg->vdo_params.check_point_frequency | + seg->vdo_params.index_memory_size_mb | + seg->vdo_params.slab_size_mb | + seg->vdo_params.max_discard | +diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c +index 787101094..952b1e71d 100644 +--- a/lib/metadata/vdo_manip.c ++++ b/lib/metadata/vdo_manip.c +@@ -283,14 +283,6 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv, + argv[args] = buf_args[args]; + args++; + +- if (vtp->check_point_frequency) { +- if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-checkpoint-frequency=%u", +- vtp->check_point_frequency) < 0) +- return_0; +- argv[args] = buf_args[args]; +- args++; +- } +- + /* Convert size to GiB units or one of these strings: 0.25, 0.50, 0.75 */ + if (vtp->index_memory_size_mb >= 1024) { + if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-memory-size=%u", +@@ -516,8 +508,6 @@ int fill_vdo_target_params(struct cmd_context *cmd, + find_config_tree_int64(cmd, allocation_vdo_block_map_cache_size_mb_CFG, profile); + vtp->block_map_era_length = + find_config_tree_int(cmd, allocation_vdo_block_map_era_length_CFG, profile); +- vtp->check_point_frequency = +- find_config_tree_int(cmd, allocation_vdo_check_point_frequency_CFG, profile); + vtp->use_sparse_index = + find_config_tree_int(cmd, allocation_vdo_use_sparse_index_CFG, profile); + vtp->index_memory_size_mb = +diff --git a/man/lvmvdo.7_main b/man/lvmvdo.7_main +index 8c3e3eeaa..a31e5dd4d 100644 +--- a/man/lvmvdo.7_main ++++ b/man/lvmvdo.7_main +@@ -165,7 +165,6 @@ vdo_use_metadata_hints=1 + vdo_minimum_io_size=4096 + vdo_block_map_cache_size_mb=128 + vdo_block_map_period=16380 +-vdo_check_point_frequency=0 + vdo_use_sparse_index=0 + vdo_index_memory_size_mb=256 + vdo_slab_size_mb=2048 +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index 13197c6fb..307233429 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -560,7 +560,6 @@ allocation { + vdo_minimum_io_size = $vdo_logicalBlockSize + vdo_block_map_cache_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 )) + vdo_block_map_period = $vdo_blockMapPeriod +- vdo_check_point_frequency = $vdo_indexCfreq + vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse") + vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}") + vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_slabSize") / 1024 )) +diff --git a/tools/toollib.c b/tools/toollib.c +index 71bf26d39..87207f86f 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1309,7 +1309,6 @@ int get_vdo_settings(struct cmd_context *cmd, + // Settings bellow cannot be changed with lvchange command + is_lvchange = checked_lvchange; + +- DO_OFFLINE(check_point_frequency); + DO_OFFLINE(index_memory_size_mb); + DO_OFFLINE(minimum_io_size); + DO_OFFLINE(slab_size_mb); +@@ -1326,6 +1325,11 @@ int get_vdo_settings(struct cmd_context *cmd, + continue; + } + ++ if (_compare_vdo_option(cn->key, "check_point_frequency")) { ++ log_verbose("Ignoring deprecated --vdosettings option \"%s\" and its value.", cn->key); ++ continue; /* Accept & ignore deprecated option */ ++ } ++ + log_error("Unknown VDO setting \"%s\".", cn->key); + goto out; + } +-- +2.41.0 + diff --git a/SOURCES/0112-vdo-indent-for-lvdisplay.patch b/SOURCES/0112-vdo-indent-for-lvdisplay.patch new file mode 100644 index 0000000..3548108 --- /dev/null +++ b/SOURCES/0112-vdo-indent-for-lvdisplay.patch @@ -0,0 +1,35 @@ +From eb32a7ca3eac92a1975863a641e40bf30df86df1 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 28 Jun 2023 11:53:29 +0200 +Subject: [PATCH 112/115] vdo: indent for lvdisplay + +(cherry picked from commit e48c9826e3069b06a5aa31e1e59200dce4915983) +--- + lib/vdo/vdo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c +index 133678ae7..6d3b67421 100644 +--- a/lib/vdo/vdo.c ++++ b/lib/vdo/vdo.c +@@ -173,7 +173,7 @@ static void _vdo_pool_display(const struct lv_segment *seg) + display_size(cmd, vtp->minimum_io_size)); + log_print(" Block map cache sz\t%s", + display_size(cmd, vtp->block_map_cache_size_mb * UINT64_C(2 * 1024))); +- log_print(" Block map era length\t%u", vtp->block_map_era_length); ++ log_print(" Block map era length %u", vtp->block_map_era_length); + + _print_yes_no("Sparse index", vtp->use_sparse_index); + +@@ -190,7 +190,7 @@ static void _vdo_pool_display(const struct lv_segment *seg) + log_print(" # Hash zone threads\t%u", (unsigned) vtp->hash_zone_threads); + log_print(" # Logical threads\t%u", (unsigned) vtp->logical_threads); + log_print(" # Physical threads\t%u", (unsigned) vtp->physical_threads); +- log_print(" Max discard\t%u", (unsigned) vtp->max_discard); ++ log_print(" Max discard\t\t%u", (unsigned) vtp->max_discard); + log_print(" Write policy\t%s", get_vdo_write_policy_name(vtp->write_policy)); + } + +-- +2.41.0 + diff --git a/SOURCES/0113-vdo-lvm_import_vdo-correct-parsing-output.patch b/SOURCES/0113-vdo-lvm_import_vdo-correct-parsing-output.patch new file mode 100644 index 0000000..edabcf1 --- /dev/null +++ b/SOURCES/0113-vdo-lvm_import_vdo-correct-parsing-output.patch @@ -0,0 +1,50 @@ +From d50c0cdcda52494823ee28cc6f88911bf3153ef7 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 29 Jun 2023 13:06:18 +0200 +Subject: [PATCH 113/115] vdo: lvm_import_vdo correct parsing output + +Output from vdo manager may actually indent output with spaces, +so trim leading and ending space. + +Also add support for verbosity flag for vdo conversion tool. + +(cherry picked from commit 8b75bbe47d2a2961b0fb029ad7a01dc37ee6a8e5) +--- + scripts/lvm_import_vdo.sh | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index 307233429..319bcb33d 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -370,7 +370,7 @@ convert_non_lv_() { + fi + + verbose "Moving VDO header." +- output=$(dry "$VDO" convert $VDOCONF --force --name "$VDONAME") ++ output=$(dry "$VDO" convert $VDOCONF $VERB --force --name "$VDONAME") + + if [ "$ABORT_AFTER_VDO_CONVERT" != "0" ] ; then + verbose "Aborting VDO coversion after moving VDO, volume is useless!" +@@ -384,7 +384,8 @@ convert_non_lv_() { + local vdo_offset=0 + local vdo_non_converted=0 + while IFS= read -r line ; do +- case "$line" in ++ # trim leading spaces ++ case "$(echo $line)" in + "Non converted"*) vdo_non_converted=1 ;; + "Length"*) vdo_length=${line##* = } ;; + "Conversion completed"*) +@@ -579,7 +580,7 @@ EOF + verbose "VDO conversion parameters: $VDO_ALLOCATION_PARAMS" + + verbose "Stopping VDO volume." +- dry "$VDO" stop $VDOCONF --name "$VDONAME" ++ dry "$VDO" stop $VDOCONF --name "$VDONAME" $VERB + + # If user has not provided '--yes', prompt before conversion + if [ -z "$YES" ] && [ "$USE_VDO_DM_SNAPSHOT" != "1" ]; then +-- +2.41.0 + diff --git a/SOURCES/0114-lvm_import_vdo-spelling-fixes.patch b/SOURCES/0114-lvm_import_vdo-spelling-fixes.patch new file mode 100644 index 0000000..704d487 --- /dev/null +++ b/SOURCES/0114-lvm_import_vdo-spelling-fixes.patch @@ -0,0 +1,104 @@ +From e6fc4b2d369d41d004b930f5c8642f63d64b8a22 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Thu, 29 Jun 2023 13:05:55 +0200 +Subject: [PATCH 114/115] lvm_import_vdo: spelling fixes + +(cherry picked from commit 8a07f57ba478c16ca5d5eacf778ee2708109aa65) +--- + scripts/lvm_import_vdo.sh | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index 319bcb33d..b5e1a9e16 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -52,7 +52,7 @@ DM_DEV_DIR="${DM_DEV_DIR:-/dev}" + DM_UUID_PREFIX="${DM_UUID_PREFIX:-}" + DM_VG_NAME= + DM_LV_NAME= +-VDO_CONFIG=${VDO_CONFIG:-} # can be overriden with --vdo-config ++VDO_CONFIG=${VDO_CONFIG:-} # can be overridden with --vdo-config + VDOCONF= + test -n "$VDO_CONFIG" && VDOCONF="-f $VDO_CONFIG" + +@@ -150,7 +150,7 @@ snapshot_create_() { + + snapshot_merge_() { + local status +- local inital_status ++ local initial_status + + initial_status=( $("$DMSETUP" status "$VDO_DM_SNAPSHOT_NAME") ) + "$DMSETUP" reload "$VDO_DM_SNAPSHOT_NAME" --table "$(snapshot_target_line_ "$1" "$VDO_SNAPSHOT_LOOP" -merge)" +@@ -165,7 +165,7 @@ snapshot_merge_() { + #du -h "$TEMPDIR/$VDO_DM_SNAPSHOT_NAME" + + # Loop for a while, till the snapshot is merged. +- # Should be nearly instantenious. ++ # Should be nearly instantaneous. + # FIXME: Recovery when something prevents merging is hard + for i in $(seq 1 20) ; do + status=( $("$DMSETUP" status "$VDO_DM_SNAPSHOT_NAME") ) +@@ -231,7 +231,7 @@ get_largest_extent_size_() { + } + + # detect LV on the given device +-# dereference device name if it is symbolic link ++# deference device name if it is symbolic link + detect_lv_() { + local DEVICE=$1 + local SYSVOLUME +@@ -315,7 +315,7 @@ parse_yaml_() { + # Currently this enforces a user to reduce the VG extent size to the smaller size (up to 4KiB). + # + # TODO: We may eventually relax this condition just like we are doing rounding for convert_non_lv_() +-# Let's if there would be any singly user requiring this feauture. ++# Let's if there would be any singly user requiring this feature. + # It may allow to better use larger VDO volume size (in TiB ranges). + # + convert_lv_() { +@@ -351,7 +351,7 @@ convert_lv_() { + # Convert VDO volume on a device to VG with VDOPool LV + # + # Convert device with the use of snapshot on top of original VDO volume (can be optionally disabled) +-# Once the whole conversion is finished, snapshot is merged (During the short periof time of merging ++# Once the whole conversion is finished, snapshot is merged (During the short period time of merging + # user must ensure there will be no power-off!) + # + # For best use the latest version of vdoprepareforlvm tool is required. +@@ -373,12 +373,12 @@ convert_non_lv_() { + output=$(dry "$VDO" convert $VDOCONF $VERB --force --name "$VDONAME") + + if [ "$ABORT_AFTER_VDO_CONVERT" != "0" ] ; then +- verbose "Aborting VDO coversion after moving VDO, volume is useless!" ++ verbose "Aborting VDO conversion after moving VDO header, volume is useless!" + cleanup 0 + fi + + # Parse result from VDO preparation/conversion tool +- # New version of the tool provides output with alingment and offset ++ # New version of the tool provides output with alignment and offset + local vdo_length=0 + local vdo_aligned=0 + local vdo_offset=0 +@@ -432,7 +432,7 @@ convert_non_lv_() { + verbose "Converting to VDO pool." + dry "$LVM" lvconvert $YES $VERB $FORCE --devices "$devices" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSizeRounded}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" + if [ "$vdo_logicalSizeRounded" -lt "$vdo_logicalSize" ] ; then +- # need to extend virtal size to be covering all the converted area ++ # need to extend virtual size to be covering all the converted area + # let lvm2 to round to the proper virtual size of VDO LV + dry "$LVM" lvextend $YES $VERB --fs ignore --devices "$devices" -L "$vdo_logicalSize"k "$VGNAME/$LVNAME" + fi +@@ -512,7 +512,7 @@ convert2lvm_() { + + "$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR." + +- # TODO: might use directly /etc/vdoconf.yml (avoding need of 'vdo' manager) ++ # TODO: might use directly /etc/vdoconf.yml (avoiding need of 'vdo' manager) + verbose "Getting YAML VDO configuration." + "$VDO" printConfigFile $VDOCONF >"$TEMPDIR/vdoconf.yml" + test -s "$TEMPDIR/vdoconf.yml" || error "Cannot work without VDO configuration" +-- +2.41.0 + diff --git a/SOURCES/0115-vdo-support-version-4.patch b/SOURCES/0115-vdo-support-version-4.patch new file mode 100644 index 0000000..b30060d --- /dev/null +++ b/SOURCES/0115-vdo-support-version-4.patch @@ -0,0 +1,90 @@ +From 50b89ccac3d145d0173eed1a72ad15b21e7a26c2 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sun, 2 Jul 2023 22:02:18 +0200 +Subject: [PATCH 115/115] vdo: support version 4 + +Properly parse VDO volumes formatted with geometry block version 4.0. + +(cherry picked from commit b90c5d60156c59c33ac440dd5ea7681457684f64) +--- + device_mapper/vdo/vdo_reader.c | 38 ++++++++++++++++++++++++++++------ + 1 file changed, 32 insertions(+), 6 deletions(-) + +diff --git a/device_mapper/vdo/vdo_reader.c b/device_mapper/vdo/vdo_reader.c +index 2451947cd..15d8b7abb 100644 +--- a/device_mapper/vdo/vdo_reader.c ++++ b/device_mapper/vdo/vdo_reader.c +@@ -128,6 +128,14 @@ struct vdo_volume_geometry { + struct vdo_index_config index_config; + } __packed; + ++struct vdo_volume_geometry_4 { ++ uint32_t release_version; ++ uint64_t nonce; ++ uuid_t uuid; ++ struct vdo_volume_region regions[VDO_VOLUME_REGION_COUNT]; ++ struct vdo_index_config index_config; ++} __packed; ++ + /* Decoding mostly only some used stucture members */ + + static void _vdo_decode_version(struct vdo_version_number *v) +@@ -157,6 +165,16 @@ static void _vdo_decode_volume_geometry(struct vdo_volume_geometry *vg) + _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); + } + ++static void _vdo_decode_volume_geometry_4(struct vdo_volume_geometry *vg, ++ struct vdo_volume_geometry_4 *vg_4) ++{ ++ vg->release_version = le32_to_cpu(vg_4->release_version); ++ vg->nonce = le64_to_cpu(vg_4->nonce); ++ vg->bio_offset = 0; ++ vg->regions[VDO_DATA_REGION] = vg_4->regions[VDO_DATA_REGION]; ++ _vdo_decode_geometry_region(&vg->regions[VDO_DATA_REGION]); ++} ++ + static void _vdo_decode_config(struct vdo_config *vc) + { + vc->logical_blocks = le64_to_cpu(vc->logical_blocks); +@@ -185,6 +203,7 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + struct vdo_header h; + struct vdo_version_number vn; + struct vdo_volume_geometry vg; ++ struct vdo_volume_geometry_4 vg_4; + struct vdo_component_41_0 pvc; + + *logical_blocks = 0; +@@ -221,17 +240,24 @@ bool dm_vdo_parse_logical_size(const char *vdo_path, uint64_t *logical_blocks) + memcpy(&h, buffer + MAGIC_NUMBER_SIZE, sizeof(h)); + _vdo_decode_header(&h); + +- if (h.version.major_version != 5) { +- log_debug_activation("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); ++ if (h.id != 5) { ++ log_debug_activation("Expected geometry VDO block instead of block %u.", h.id); + goto err; + } + +- if (h.id != 5) { +- log_debug_activation("Expected geometry VDO block instead of block %u.", h.id); ++ switch (h.version.major_version) { ++ case 4: ++ memcpy(&vg_4, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg_4)); ++ _vdo_decode_volume_geometry_4(&vg, &vg_4); ++ break; ++ case 5: ++ memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); ++ _vdo_decode_volume_geometry(&vg); ++ break; ++ default: ++ log_debug_activation("Unsupported VDO version %u.%u.", h.version.major_version, h.version.minor_version); + goto err; + } +- memcpy(&vg, buffer + MAGIC_NUMBER_SIZE + sizeof(h), sizeof(vg)); +- _vdo_decode_volume_geometry(&vg); + + regpos = (vg.regions[VDO_DATA_REGION].start_block - vg.bio_offset) * 4096; + +-- +2.41.0 + diff --git a/SOURCES/0116-vdo-use-long-verbose.patch b/SOURCES/0116-vdo-use-long-verbose.patch new file mode 100644 index 0000000..f916b5c --- /dev/null +++ b/SOURCES/0116-vdo-use-long-verbose.patch @@ -0,0 +1,28 @@ +From adaa7034883c7f237fa35a80e93563ea56ea9362 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 17 Jul 2023 16:22:29 +0200 +Subject: [PATCH 1/2] vdo: use long --verbose + +vdo tools needs long option. + +(cherry picked from commit 1c2782354c9ad49f1e2c9af58d7f5085f0632cb5) +--- + scripts/lvm_import_vdo.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index b5e1a9e16..f0e93075a 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -619,7 +619,7 @@ do + "-f"|"--force" ) FORCE="-f" ;; + "-h"|"--help" ) tool_usage ;; + "-n"|"--name" ) shift; NAME=$1 ;; +- "-v"|"--verbose") VERB="-v" ;; ++ "-v"|"--verbose") VERB="--verbose" ;; + "-y"|"--yes" ) YES="-y" ;; + "--abort-after-vdo-convert" ) ABORT_AFTER_VDO_CONVERT=1; USE_VDO_DM_SNAPSHOT=0 ;; # For testing only + "--dry-run" ) DRY="1" ; VERB="-v" ;; +-- +2.41.0 + diff --git a/SOURCES/0117-vdo-Sync-lvm_import_vdo.sh-with-main-as-of-970e4d295.patch b/SOURCES/0117-vdo-Sync-lvm_import_vdo.sh-with-main-as-of-970e4d295.patch new file mode 100644 index 0000000..ba5e072 --- /dev/null +++ b/SOURCES/0117-vdo-Sync-lvm_import_vdo.sh-with-main-as-of-970e4d295.patch @@ -0,0 +1,542 @@ +From 34255cb85ad476fd5b4ba3f30a53ea3dc084fcbb Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Thu, 7 Sep 2023 15:06:33 +0200 +Subject: [PATCH] vdo: Sync lvm_import_vdo.sh with main as of 970e4d295edd. + +--- + scripts/lvm_import_vdo.sh | 277 ++++++++++++++++++++++++-------------- + 1 file changed, 176 insertions(+), 101 deletions(-) + +diff --git a/scripts/lvm_import_vdo.sh b/scripts/lvm_import_vdo.sh +index f0e93075a..7f3f413e9 100755 +--- a/scripts/lvm_import_vdo.sh ++++ b/scripts/lvm_import_vdo.sh +@@ -36,6 +36,9 @@ TEMPDIR="${TMPDIR:-/tmp}/$IMPORT_NAME" + _SAVEPATH=$PATH + PATH="/sbin:/usr/sbin:/bin:/usr/sbin:$PATH" + ++# Set of trapped signals ++declare -a SIGNALS=("HUP" "INT" "QUIT" "ABRT" "TERM" "EXIT") ++ + # user may override lvm location by setting LVM_BINARY + LVM=${LVM_BINARY:-lvm} + VDO=${VDO_BINARY:-vdo} +@@ -52,7 +55,9 @@ DM_DEV_DIR="${DM_DEV_DIR:-/dev}" + DM_UUID_PREFIX="${DM_UUID_PREFIX:-}" + DM_VG_NAME= + DM_LV_NAME= ++DEFAULT_VDO_CONFIG="/etc/vdoconf.yml" # Default location of vdo's manager config file + VDO_CONFIG=${VDO_CONFIG:-} # can be overridden with --vdo-config ++VDO_CONFIG_RESTORE= + VDOCONF= + test -n "$VDO_CONFIG" && VDOCONF="-f $VDO_CONFIG" + +@@ -61,16 +66,17 @@ VGNAME= + LVNAME= + DEVMAJOR=0 + DEVMINOR=0 +-PROMPTING="" +-USE_VDO_DM_SNAPSHOT=1 ++PROMPTING= ++USE_VDO_DM_SNAPSHOT="--yes" + VDO_DM_SNAPSHOT_NAME= + VDO_DM_SNAPSHOT_DEVICE= + VDO_SNAPSHOT_LOOP= ++VDO_INCONSISTENT= + + DRY=0 +-VERB="" +-FORCE="" +-YES="" ++VERB= ++FORCE= ++YES= + ABORT_AFTER_VDO_CONVERT=0 + VDO_ALLOCATION_PARAMS= + +@@ -78,6 +84,25 @@ VDO_ALLOCATION_PARAMS= + DEFAULT_NAME="vdovg/vdolvol" + NAME="" + ++# predefine empty ++vdo_ackThreads= ++vdo_bioRotationInterval= ++vdo_bioThreads= ++vdo_blockMapCacheSize= ++vdo_blockMapPeriod= ++vdo_compression= ++vdo_cpuThreads= ++vdo_deduplication= ++vdo_hashZoneThreads= ++vdo_indexMemory= ++vdo_indexSparse= ++vdo_logicalBlockSize= ++vdo_logicalThreads= ++vdo_maxDiscardSize= ++vdo_physicalThreads= ++vdo_slabSize= ++vdo_writePolicy= ++ + # help message + tool_usage() { + echo "${TOOL}: Utility to convert VDO volume to VDO LV." +@@ -107,7 +132,11 @@ error() { + for i in "$@" ; do + echo "$TOOL: $i" >&2 + done +- cleanup 1 ++ return 1 ++} ++ ++warn() { ++ echo "$TOOL: WARNING: $i" >&2 + } + + dry() { +@@ -120,15 +149,31 @@ dry() { + } + + cleanup() { +- trap '' 2 ++ RC=$? # Return code + 128 of the last command eg INT=2 + 128 -> 130 + +- test -n "$VDO_DM_SNAPSHOT_NAME" && { "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || true ; } +- test -n "$VDO_SNAPSHOT_LOOP" && { "$LOSETUP" -d "$VDO_SNAPSHOT_LOOP" || true ; } ++ trap '' "${SIGNALS[@]}" # mute trap for all signals to not interrupt cleanup() on any next signal ++ ++ [ -z "$PROMPTING" ] || echo "No" ++ ++ [ -e "$VDO_CONFIG_RESTORE" ] && { dry cp -a "$VDO_CONFIG_RESTORE" "${VDO_CONFIG:-"$DEFAULT_VDO_CONFIG"}" || true ; } ++ ++ if [ -n "$VDO_DM_SNAPSHOT_NAME" ]; then ++ dry "$LVM" vgchange -an --devices "$VDO_DM_SNAPSHOT_DEVICE" "$VGNAME" &>/dev/null || true ++ for i in {1..20} ; do ++ [ "$(dry "$DMSETUP" info --noheading -co open "$VDO_DM_SNAPSHOT_NAME")" = "0" ] && break ++ sleep .1 ++ done ++ dry "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" &>/dev/null || true ++ fi ++ ++ ++ [ -n "$VDO_SNAPSHOT_LOOP" ] && { dry "$LOSETUP" -d "$VDO_SNAPSHOT_LOOP" || true ; } ++ ++ [ -z "$VDO_INCONSISTENT" ] || echo "$TOOL: VDO volume import process exited unexpectedly!" >&2 + +- test -z "$PROMPTING" || echo "No" + rm -rf "$TEMPDIR" || true +- # error exit status for break +- exit "${1:-1}" ++ ++ exit "$RC" + } + + # Create snapshot target like for persistent snapshot with 16KiB chunksize +@@ -143,7 +188,7 @@ snapshot_create_() { + # TODO: maybe use ramdisk via 'brd' device ?) + "$TRUNCATE" -s 20M "$file" + VDO_SNAPSHOT_LOOP=$("$LOSETUP" -f --show "$file") +- "$DMSETUP" create "$VDO_DM_SNAPSHOT_NAME" -u "${DM_UUID_PREFIX}-${VDO_DM_SNAPSHOT_NAME}-priv" --table "$(snapshot_target_line_ "$1" "$VDO_SNAPSHOT_LOOP")" ++ "$DMSETUP" create "$VDO_DM_SNAPSHOT_NAME" -u "${DM_UUID_PREFIX}${VDO_DM_SNAPSHOT_NAME}-priv" --table "$(snapshot_target_line_ "$1" "$VDO_SNAPSHOT_LOOP")" + VDO_DM_SNAPSHOT_DEVICE="$DM_DEV_DIR/mapper/$VDO_DM_SNAPSHOT_NAME" + verbose "Snapshot of VDO device $1 created: $VDO_DM_SNAPSHOT_DEVICE." + } +@@ -158,7 +203,9 @@ snapshot_merge_() { + error "ABORTING: Failed to initialize snapshot merge! Origin volume is unchanged." + } + +- verbose "Merging converted VDO volume..." ++ verbose "Merging converted VDO volume \"$VDO_DM_SNAPSHOT_NAME\"." ++ VDO_INCONSISTENT=1 ++ + # Running merging + "$DMSETUP" resume "$VDO_DM_SNAPSHOT_NAME" + +@@ -166,30 +213,37 @@ snapshot_merge_() { + + # Loop for a while, till the snapshot is merged. + # Should be nearly instantaneous. +- # FIXME: Recovery when something prevents merging is hard ++ # FIXME: Recovery when something prevents merging is hard + for i in $(seq 1 20) ; do + status=( $("$DMSETUP" status "$VDO_DM_SNAPSHOT_NAME") ) + # Check if merging is finished +- test "${status[3]%/*}" = "${status[4]}" && break ++ [ "${status[3]%/*}" = "${status[4]}" ] && break + # Wait a bit and retry + sleep .2 + done +- test "${status[3]%/*}" = "${status[4]}" || { ++ ++ if [ "${status[3]%/*}" != "${status[4]}" ]; then + # FIXME: Now what shall we do ??? Help.... +- # Keep snapshot in table for possible analysis... ++ # Keep snapshot in DM table for possible analysis... + VDO_DM_SNAPSHOT_NAME= + VDO_SNAPSHOT_LOOP= +- echo "Initial snapshot status ${initial_status[*]}" +- echo "Failing merge snapshot status ${status[*]}" ++ echo "$TOOL: Initial snapshot status ${initial_status[*]}" ++ echo "$TOOL: Failing merge snapshot status ${status[*]}" + error "ABORTING: Snapshot failed to merge! (Administrator required...)" +- } +- sync ++ fi ++ ++ VDO_INCONSISTENT= ++ VDO_CONFIG_RESTORE= ++ ++ verbose "Converted VDO volume is merged to \"$1\"." ++ + "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || { + sleep 1 # sleep and retry once more + "$DMSETUP" remove "$VDO_DM_SNAPSHOT_NAME" || { + error "ABORTING: Cannot remove snapshot $VDO_DM_SNAPSHOT_NAME! (check volume autoactivation...)" + } + } ++ + VDO_DM_SNAPSHOT_NAME= + "$LOSETUP" -d "$VDO_SNAPSHOT_LOOP" + VDO_SNAPSHOT_LOOP= +@@ -222,9 +276,9 @@ get_largest_extent_size_() { + + for i in 8 16 32 64 128 256 512 1024 2048 4096 ; do + d=$(( $1 / i )) +- test $(( d * i )) -eq "$1" || break ++ [ $(( d * i )) -eq "$1" ] || break + d=$(( $2 / i )) +- test $(( d * i )) -eq "$2" || break ++ [ $(( d * i )) -eq "$2" ] || break + max=$i + done + echo "$max" +@@ -239,7 +293,7 @@ detect_lv_() { + + DEVICE=${1/#"${DM_DEV_DIR}/"/} + DEVICE=$("$READLINK" $READLINK_E "$DM_DEV_DIR/$DEVICE" || true) +- test -n "$DEVICE" || error "Readlink cannot access device \"$1\"." ++ [ -n "$DEVICE" ] || error "Readlink cannot access device \"$1\"." + RDEVICE=$DEVICE + case "$RDEVICE" in + # hardcoded /dev since udev does not create these entries elsewhere +@@ -251,12 +305,12 @@ detect_lv_() { + ;; + *) + RSTAT=$("$STAT" --format "DEVMAJOR=\$((0x%t)) DEVMINOR=\$((0x%T))" "$RDEVICE" || true) +- test -n "$RSTAT" || error "Cannot get major:minor for \"$DEVICE\"." ++ [ -n "$RSTAT" ] || error "Cannot get major:minor for \"$DEVICE\"." + eval "$RSTAT" + ;; + esac + +- test "$DEVMAJOR" != "$(grep device-mapper /proc/devices | cut -f1 -d' ')" && return ++ [ "$DEVMAJOR" != "$(grep device-mapper /proc/devices | cut -f1 -d' ')" ] && return + + DEV="$("$DMSETUP" info -c -j "$DEVMAJOR" -m "$DEVMINOR" -o uuid,name --noheadings --nameprefixes --separator ' ')" + case "$DEV" in +@@ -332,9 +386,10 @@ convert_lv_() { + vg_extent_size=$("$LVM" vgs -o vg_extent_size --units b --nosuffix --noheadings "$VGNAME") + vg_extent_size=$(( vg_extent_size / 1024 )) + +- test "$vg_extent_size" -le "$extent_size" || { ++ [ "$vg_extent_size" -le "$extent_size" ] || { + error "Please vgchange extent_size to at most $extent_size KiB or extend and align virtual size of VDO device on $vg_extent_size KiB before retrying conversion." + } ++ + verbose "Renaming existing LV to be used as _vdata volume for VDO pool LV." + dry "$LVM" lvrename $YES $VERB "$VGNAME/$DM_LV_NAME" "$VGNAME/${LVNAME}_vpool" || { + error "Rename of LV \"$VGNAME/$DM_LV_NAME\" failed, while VDO header has been already moved!" +@@ -362,19 +417,39 @@ convert_non_lv_() { + local output + local pvfree + +- if [ "$USE_VDO_DM_SNAPSHOT" = "1" ]; then ++ if [ -n "$USE_VDO_DM_SNAPSHOT" ]; then + dry snapshot_create_ "$DEVICE" +- sed "s:$DEVICE:$VDO_DM_SNAPSHOT_DEVICE:" "$TEMPDIR/vdoconf.yml" > "$TEMPDIR/vdo_snap.yml" ++ sed "s|$DEVICE|$VDO_DM_SNAPSHOT_DEVICE|" "$TEMPDIR/vdoconf.yml" > "$TEMPDIR/vdo_snap.yml" ++ # In case of error in the middle of conversion restore original config file ++ VDO_CONFIG_RESTORE="$TEMPDIR/vdoconf.yml" + # Let VDO manager operate on snapshot volume +- VDOCONF="-f $TEMPDIR/vdo_snap.yml" ++ dry cp -a "$TEMPDIR/vdo_snap.yml" "${VDO_CONFIG:-"$DEFAULT_VDO_CONFIG"}" ++ else ++ # If error in the following section, report possible problems ahead ++ VDO_INCONSISTENT=1 + fi + +- verbose "Moving VDO header." +- output=$(dry "$VDO" convert $VDOCONF $VERB --force --name "$VDONAME") ++ # In case we operate with snapshot, all lvm2 operation will also run on top of snapshot ++ local device=${VDO_DM_SNAPSHOT_DEVICE:-$DEVICE} ++ ++ # Check if there is not already an existing PV header, this would have fail on pvcreate after conversion ++ "$LVM" pvs --devices "$device" "$device" 2>/dev/null && { ++ error "Cannot convert volume \"$DEVICE\" with existing PV header." ++ } ++ ++ verbose "Moving VDO header on \"$device\"." + +- if [ "$ABORT_AFTER_VDO_CONVERT" != "0" ] ; then +- verbose "Aborting VDO conversion after moving VDO header, volume is useless!" +- cleanup 0 ++ output=$(dry "$VDO" convert $VDOCONF $VERB --force --name "$VDONAME" 2>&1) || { ++ local rc=$? ++ echo "$output" ++ error "Failed to convert VDO volume \"$DEVICE\" (exit code $rc)." ++ } ++ ++ echo "$output" ++ ++ if [ "$ABORT_AFTER_VDO_CONVERT" != "0" ]; then ++ warn "Aborting VDO conversion after moving VDO header, volume is useless!" ++ return 0 + fi + + # Parse result from VDO preparation/conversion tool +@@ -399,12 +474,7 @@ convert_non_lv_() { + esac + done <<< "$output" + +- # In case we operation with snapshot, all lvm2 operation will also run on top of snapshot +- local devices=${VDO_DM_SNAPSHOT_DEVICE:-$DEVICE} +- +- dry "$LVM" pvcreate $YES --devices "$devices" --dataalignment "$vdo_offset"b "$devices" || { +- error "Creation of PV on \"$DEVICE\" failed, while VDO header has been already moved!" +- } ++ dry "$LVM" pvcreate $YES $VERB $FORCE --devices "$device" --dataalignment "$vdo_offset"b "$device" + + # Obtain free space in this new PV + # after 'vdo convert' call there is ~(1-2)M free space at the front of the device +@@ -421,47 +491,53 @@ convert_non_lv_() { + # To precisely byte-synchronize the size of VDO LV, user can lvresize such VDO LV later. + vdo_logicalSizeRounded=$(( ( vdo_logicalSize / extent_size ) * extent_size )) + +- verbose "Creating VG \"${NAME%/*}\" with extent size $extent_size KiB." +- dry "$LVM" vgcreate $YES $VERB --devices "$devices" -s "${extent_size}k" "$VGNAME" "$devices" || { +- error "Creation of VG \"$VGNAME\" failed, while VDO header has been already moved!" +- } ++ verbose "Creating volume group \"$VGNAME\" with the extent size $extent_size KiB." ++ dry "$LVM" vgcreate $YES $VERB --devices "$device" -s "${extent_size}k" "$VGNAME" "$device" + +- verbose "Creating VDO pool data LV from all extents in volume group $VGNAME." +- dry "$LVM" lvcreate -Zn -Wn -an $YES $VERB --devices "$devices" -l100%VG -n "${LVNAME}_vpool" "$VGNAME" "$devices" ++ verbose "Creating VDO pool data LV from all extents in the volume group \"$VGNAME\"." ++ dry "$LVM" lvcreate -Zn -Wn -an $YES $VERB --devices "$device" -l100%VG -n "${LVNAME}_vpool" "$VGNAME" "$device" + + verbose "Converting to VDO pool." +- dry "$LVM" lvconvert $YES $VERB $FORCE --devices "$devices" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSizeRounded}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" +- if [ "$vdo_logicalSizeRounded" -lt "$vdo_logicalSize" ] ; then ++ dry "$LVM" lvconvert ${USE_VDO_DM_SNAPSHOT:-"$YES"} $VERB $FORCE --devices "$device" --config "$VDO_ALLOCATION_PARAMS" -Zn -V "${vdo_logicalSizeRounded}k" -n "$LVNAME" --type vdo-pool "$VGNAME/${LVNAME}_vpool" ++ ++ if [ "$vdo_logicalSizeRounded" -lt "$vdo_logicalSize" ]; then + # need to extend virtual size to be covering all the converted area + # let lvm2 to round to the proper virtual size of VDO LV +- dry "$LVM" lvextend $YES $VERB --fs ignore --devices "$devices" -L "$vdo_logicalSize"k "$VGNAME/$LVNAME" ++ dry "$LVM" lvextend $YES $VERB --devices "$device" -L "$vdo_logicalSize"k "$VGNAME/$LVNAME" + fi + +- dry "$LVM" vgchange -an $VERB $FORCE --devices "$devices" "$VGNAME" +- +- if [ "$USE_VDO_DM_SNAPSHOT" = "1" ]; then +- if [ -z "$YES" ]; then +- PROMPTING=yes +- echo "Warning: Do not interrupt merging process once it starts (VDO data may become irrecoverable)!" +- echo -n "Do you want to merge converted VDO device \"$DEVICE\" to VDO LV \"$VGNAME/$LVNAME\"? [y|N]: " +- read -r -n 1 -s ANSWER +- case "${ANSWER:0:1}" in +- y|Y ) echo "Yes" ;; +- * ) echo "No" ; PROMPTING=""; cleanup 1 ;; +- esac +- PROMPTING="" +- YES="-y" # From now, now prompting +- fi ++ VDO_INCONSISTENT= + +- dry snapshot_merge_ "$DEVICE" +- if [ -e "$TEMPDIR/vdo_snap.yml" ]; then +- dry cp "$TEMPDIR/vdo_snap.yml" "$VDO_CONFIG" +- else +- dry rm -f "$VDO_CONFIG" +- fi +- verbose "Merging of VDO device finished." ++ [ -z "$USE_VDO_DM_SNAPSHOT" ] && return # no-snapshot case finished ++ ++ dry "$LVM" vgchange -an $VERB $FORCE --devices "$device" "$VGNAME" ++ ++ # Prevent unwanted auto activation when VG is merged ++ dry "$LVM" vgchange --setautoactivation n $VERB $FORCE --devices "$device" "$VGNAME" ++ ++ if [ -z "$YES" ]; then ++ PROMPTING=yes ++ warn "Do not interrupt merging process once it starts (VDO data may become irrecoverable)!" ++ echo -n "$TOOL: Do you want to merge converted VDO device \"$DEVICE\" to VDO LV \"$VGNAME/$LVNAME\"? [y|N]: " ++ read -r -n 1 -s ANSWER ++ case "${ANSWER:0:1}" in ++ y|Y ) echo "Yes" ;; ++ * ) echo "No" ; PROMPTING=""; return 1 ;; ++ esac ++ PROMPTING="" ++ YES="-y" # From now, now prompting + fi + ++ dry snapshot_merge_ "$DEVICE" ++ ++ # For systems using devicesfile add 'merged' PV into system.devices. ++ # Bypassing use of --valuesonly to keep compatibility with older lvm. ++ local usedev=$("$LVM" lvmconfig --typeconfig full devices/use_devicesfile || true) ++ [ "${usedev#*=}" = "1" ] && dry "$LVM" lvmdevices --adddev "$DEVICE" ++ ++ # Restore auto activation for a VG ++ dry "$LVM" vgchange --setautoactivation y $VERB $FORCE "$VGNAME" ++ + dry "$LVM" lvchange -ay $VERB $FORCE "$VGNAME/$LVNAME" + } + +@@ -479,43 +555,43 @@ convert2lvm_() { + detect_lv_ "$DEVICE" + case "$DM_UUID" in + LVM-*) eval "$("$DMSETUP" splitname --nameprefixes --noheadings --separator ' ' "$DM_NAME")" +- if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then ++ if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ]; then + VGNAME=$DM_VG_NAME + verbose "Using existing volume group name \"$VGNAME\"." +- test -n "$LVNAME" || LVNAME=$DM_LV_NAME ++ [ -n "$LVNAME" ] || LVNAME=$DM_LV_NAME + elif [ "$VGNAME" != "$DM_VG_NAME" ]; then + error "Volume group name \"$VGNAME\" does not match name \"$DM_VG_NAME\" for VDO device \"$DEVICE\"." + fi + ;; + *) + # Check if we need to generate unused $VGNANE +- if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then ++ if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ]; then + VGNAME=${DEFAULT_NAME%/*} + # Find largest matching VG name to our 'default' vgname +- LASTVGNAME=$(LC_ALL=C "$LVM" vgs -oname -O-name --noheadings -S name=~"${VGNAME}" | grep -E "${VGNAME}[0-9]? ?" | head -1 || true) ++ LASTVGNAME=$(LC_ALL=C "$LVM" vgs -oname -O-name --noheadings -S name=~"${VGNAME}" | grep -m 1 -E "${VGNAME}[0-9]? ?" || true) + if [ -n "$LASTVGNAME" ]; then + LASTVGNAME=${LASTVGNAME#*"${VGNAME}"} + # If the number is becoming too high, try some random number +- test "$LASTVGNAME" -gt 99999999 2>/dev/null && LASTVGNAME=$RANDOM ++ [ -n "$LASTVGNAME" ] && [ "$LASTVGNAME" -gt 99999999 ] && LASTVGNAME=$RANDOM + # Generate new unused VG name + VGNAME="${VGNAME}$(( LASTVGNAME + 1 ))" + verbose "Selected unused volume group name \"$VGNAME\"." + fi + fi + # New VG is created, LV name should be always unused. +- test -n "$LVNAME" || LVNAME=${DEFAULT_NAME#*/} ++ [ -n "$LVNAME" ] || LVNAME=${DEFAULT_NAME#*/} + "$LVM" vgs "$VGNAME" >/dev/null 2>&1 && error "Cannot use already existing volume group name \"$VGNAME\"." + ;; + esac + + verbose "Checked whether device \"$DEVICE\" is already logical volume." + +- "$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR." ++ "$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create \"$TEMPDIR\"." + + # TODO: might use directly /etc/vdoconf.yml (avoiding need of 'vdo' manager) + verbose "Getting YAML VDO configuration." + "$VDO" printConfigFile $VDOCONF >"$TEMPDIR/vdoconf.yml" +- test -s "$TEMPDIR/vdoconf.yml" || error "Cannot work without VDO configuration" ++ [ -s "$TEMPDIR/vdoconf.yml" ] || error "Cannot work without VDO configuration." + + # Check list of devices in VDO configure file for their major:minor + # and match with given $DEVICE devmajor:devminor +@@ -524,13 +600,13 @@ convert2lvm_() { + DEV=$("$READLINK" $READLINK_E "$i") || continue + RSTAT=$("$STAT" --format "MAJOR=\$((0x%t)) MINOR=\$((0x%T))" "$DEV" 2>/dev/null) || continue + eval "$RSTAT" +- test "$MAJOR" = "$DEVMAJOR" && test "$MINOR" = "$DEVMINOR" && { +- test -z "$FOUND" || error "VDO configuration contains duplicate entries $FOUND and $i" ++ if [ "$MAJOR" = "$DEVMAJOR" ] && [ "$MINOR" = "$DEVMINOR" ]; then ++ [ -z "$FOUND" ] || error "VDO configuration contains duplicate entries $FOUND and $i." + FOUND=$i +- } ++ fi + done + +- test -n "$FOUND" || error "Can't find matching device in VDO configuration file." ++ [ -n "$FOUND" ] || error "Can't find matching device in VDO configuration file." + verbose "Found matching device $FOUND $MAJOR:$MINOR." + + VDONAME=$(awk -v DNAME="$FOUND" '/.*VDOService$/ {VNAME=substr($1, 0, length($1) - 1)} /[[:space:]]*device:/ { if ($2 ~ DNAME) {print VNAME}}' "$TEMPDIR/vdoconf.yml") +@@ -541,7 +617,7 @@ convert2lvm_() { + case "$DM_OPEN" in + Device*) ;; # no devices + *) eval "$DM_OPEN" +- test "${DM_OPEN:-0}" -eq 0 || error "Cannot convert in use VDO volume \"$VDONAME\"!" ++ [ "${DM_OPEN:-0}" -eq 0 ] || error "Cannot convert in use VDO volume \"$VDONAME\"!" + ;; + esac + +@@ -583,21 +659,22 @@ EOF + dry "$VDO" stop $VDOCONF --name "$VDONAME" $VERB + + # If user has not provided '--yes', prompt before conversion +- if [ -z "$YES" ] && [ "$USE_VDO_DM_SNAPSHOT" != "1" ]; then ++ if [ -z "$YES" ] && [ -z "$USE_VDO_DM_SNAPSHOT" ]; then + PROMPTING=yes +- echo -n "Convert VDO device \"$DEVICE\" to VDO LV \"$VGNAME/$LVNAME\"? [y|N]: " ++ echo -n "$TOOL: Convert VDO device \"$DEVICE\" to VDO LV \"$VGNAME/$LVNAME\"? [y|N]: " + read -r -n 1 -s ANSWER + case "${ANSWER:0:1}" in + y|Y ) echo "Yes" ;; +- * ) echo "No" ; PROMPTING=""; cleanup 1 ;; ++ * ) echo "No" ; PROMPTING=""; return 1 ;; + esac + PROMPTING="" + YES="-y" # From now, no prompting + fi + + # Make a backup of the existing VDO yaml configuration file +- test -e "$VDO_CONFIG" && dry cp -a "$VDO_CONFIG" "${VDO_CONFIG}.backup" ++ [ -e "$VDO_CONFIG" ] && dry cp -a "$VDO_CONFIG" "${VDO_CONFIG}.backup" + ++ DEVICE=$FOUND + case "$DM_UUID" in + LVM-*) convert_lv_ "$vdo_logicalSize" ;; + *) convert_non_lv_ "$vdo_logicalSize" ;; +@@ -608,9 +685,9 @@ EOF + # start point of this script + # - parsing parameters + ############################# +-trap "cleanup 2" 2 ++trap "cleanup" "${SIGNALS[@]}" + +-test "$#" -eq 0 && tool_usage ++[ "$#" -eq 0 ] && tool_usage + + while [ "$#" -ne 0 ] + do +@@ -621,19 +698,17 @@ do + "-n"|"--name" ) shift; NAME=$1 ;; + "-v"|"--verbose") VERB="--verbose" ;; + "-y"|"--yes" ) YES="-y" ;; +- "--abort-after-vdo-convert" ) ABORT_AFTER_VDO_CONVERT=1; USE_VDO_DM_SNAPSHOT=0 ;; # For testing only +- "--dry-run" ) DRY="1" ; VERB="-v" ;; +- "--no-snapshot" ) USE_VDO_DM_SNAPSHOT=0 ;; +- "--uuid-prefix" ) shift; DM_UUID_PREFIX=$1 ;; # For testing only +- "--vdo-config" ) shift; VDO_CONFIG=$1 ; VDOCONF="-f $VDO_CONFIG" ;; +- "-*") error "Wrong argument \"$1\". (see: $TOOL --help)" ;; ++ "--abort-after-vdo-convert"|"--abortaftervdoconvert" ) ABORT_AFTER_VDO_CONVERT=1; USE_VDO_DM_SNAPSHOT= ;; # For testing only ++ "--dry-run"|"--dryrun" ) DRY="1" ; VERB="-v" ;; ++ "--no-snapshot"|"--nosnapshot" ) USE_VDO_DM_SNAPSHOT= ;; ++ "--uuid-prefix"|"--uuidprefix" ) shift; DM_UUID_PREFIX=$1 ;; # For testing only ++ "--vdo-config"|"--vdoconfig" ) shift; VDO_CONFIG=$1 ; VDOCONF="-f $VDO_CONFIG" ;; ++ -* ) error "Wrong argument \"$1\". (see: $TOOL --help)" ;; + *) DEVICE=$1 ;; # device name does not start with '-' + esac + shift + done + +-test -n "$DEVICE" || error "Device name is not specified. (see: $TOOL --help)" ++[ -n "$DEVICE" ] || error "Device name is not specified. (see: $TOOL --help)" + + convert2lvm_ +- +-cleanup 0 +-- +2.41.0 + diff --git a/SOURCES/0118-man-Fix-typo.patch b/SOURCES/0118-man-Fix-typo.patch new file mode 100644 index 0000000..d95f82c --- /dev/null +++ b/SOURCES/0118-man-Fix-typo.patch @@ -0,0 +1,25 @@ +From cf7e7e0041b1f92ad3e9e8f1d7fb24c4ba5949e9 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 31 Jan 2024 18:48:24 +0100 +Subject: [PATCH 01/12] man: Fix typo + +--- + man/lvmcache.7_main | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main +index 519e352cb..824f24e91 100644 +--- a/man/lvmcache.7_main ++++ b/man/lvmcache.7_main +@@ -252,7 +252,7 @@ when selecting the writecache cachevol size and the writecache block size. + .P + .IP \[bu] 2 + writecache block size 4096: each 100 GiB of writecache cachevol uses +-slighly over 2 GiB of system memory. ++slightly over 2 GiB of system memory. + .IP \[bu] 2 + writecache block size 512: each 100 GiB of writecache cachevol uses + a little over 16 GiB of system memory. +-- +2.43.0 + diff --git a/SOURCES/0119-doc-fix-typos-in-documentation.patch b/SOURCES/0119-doc-fix-typos-in-documentation.patch new file mode 100644 index 0000000..3bfe9a8 --- /dev/null +++ b/SOURCES/0119-doc-fix-typos-in-documentation.patch @@ -0,0 +1,649 @@ +From 3d6f6b58f6426dfcbfa59de90b47f0bbd46759e7 Mon Sep 17 00:00:00 2001 +From: Samanta Navarro +Date: Fri, 30 Dec 2022 11:52:49 +0000 +Subject: [PATCH 02/12] doc: fix typos in documentation + +Typos found with codespell. + +(cherry picked from commit aec5e573afe610070eb2c6bed675d2a7c0efc7e8) +--- + TESTING | 2 +- + conf/example.conf.in | 12 ++++++------ + doc/kernel/cache-policies.txt | 2 +- + doc/kernel/crypt.txt | 4 ++-- + doc/kernel/integrity.txt | 2 +- + doc/kernel/verity.txt | 2 +- + doc/lvm2-raid.txt | 10 +++++----- + doc/lvm_fault_handling.txt | 10 +++++----- + doc/lvmpolld_overview.txt | 2 +- + doc/tagging.txt | 2 +- + doc/udev_assembly.txt | 2 +- + libdm/make.tmpl.in | 2 +- + make.tmpl.in | 2 +- + man/dmeventd.8_main | 6 +++--- + man/dmsetup.8_main | 2 +- + man/dmstats.8_main | 24 ++++++++++++------------ + man/lvchange.8_pregen | 2 +- + man/lvconvert.8_des | 2 +- + man/lvconvert.8_pregen | 2 +- + man/lvcreate.8_pregen | 2 +- + man/lvmcache.7_main | 8 ++++---- + man/lvmdevices.8_des | 2 +- + man/lvmdevices.8_pregen | 2 +- + man/lvmreport.7_main | 6 +++--- + man/vgcfgrestore.8_des | 2 +- + man/vgcfgrestore.8_pregen | 2 +- + man/vgchange.8_pregen | 2 +- + udev/69-dm-lvm-metad.rules.in | 2 +- + 28 files changed, 60 insertions(+), 60 deletions(-) + +diff --git a/TESTING b/TESTING +index 57932f56a..3c1e3afc6 100644 +--- a/TESTING ++++ b/TESTING +@@ -24,7 +24,7 @@ You MUST disable (or mask) any LVM daemons: + For running cluster tests, we are using singlenode locking. Pass + `--with-clvmd=singlenode` to configure. + +-NOTE: This is useful only for testing, and should not be used in produciton ++NOTE: This is useful only for testing, and should not be used in production + code. + + To run D-Bus daemon tests, existing D-Bus session is required. +diff --git a/conf/example.conf.in b/conf/example.conf.in +index d5af25061..bb2e60ace 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -752,7 +752,7 @@ allocation { + # vdo_max_discard = 1 + + # Configuration option allocation/vdo_pool_header_size. +- # Specified the emptry header size in KiB at the front and end of vdo pool device. ++ # Specified the empty header size in KiB at the front and end of vdo pool device. + # This configuration option has an automatic default value. + # vdo_pool_header_size = 512 + } +@@ -931,7 +931,7 @@ backup { + # archive = 1 + + # Configuration option backup/archive_dir. +- # Location of the metdata archive files. ++ # Location of the metadata archive files. + # Remember to back up this directory regularly! + # This configuration option has an automatic default value. + # archive_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_ARCHIVE_SUBDIR@" +@@ -1463,13 +1463,13 @@ activation { + + # Configuration option activation/reserved_stack. + # Stack size in KiB to reserve for use while devices are suspended. +- # Insufficent reserve risks I/O deadlock during device suspension. ++ # Insufficient reserve risks I/O deadlock during device suspension. + # This configuration option has an automatic default value. + # reserved_stack = 64 + + # Configuration option activation/reserved_memory. + # Memory size in KiB to reserve for use while devices are suspended. +- # Insufficent reserve risks I/O deadlock during device suspension. ++ # Insufficient reserve risks I/O deadlock during device suspension. + # This configuration option has an automatic default value. + # reserved_memory = 8192 + +@@ -1604,7 +1604,7 @@ activation { + # This includes LVs that have the following segment types: + # raid1, raid4, raid5*, and raid6*. + # If a device in the LV fails, the policy determines the steps +- # performed by dmeventd automatically, and the steps perfomed by the ++ # performed by dmeventd automatically, and the steps performed by the + # manual command lvconvert --repair --use-policies. + # Automatic handling requires dmeventd to be monitoring the LV. + # +@@ -1628,7 +1628,7 @@ activation { + # (copies) and a mirror log. A disk log ensures that a mirror LV does + # not need to be re-synced (all copies made the same) every time a + # machine reboots or crashes. If a device in the LV fails, this policy +- # determines the steps perfomed by dmeventd automatically, and the steps ++ # determines the steps performed by dmeventd automatically, and the steps + # performed by the manual command lvconvert --repair --use-policies. + # Automatic handling requires dmeventd to be monitoring the LV. + # +diff --git a/doc/kernel/cache-policies.txt b/doc/kernel/cache-policies.txt +index d3ca8af21..1436dbc6e 100644 +--- a/doc/kernel/cache-policies.txt ++++ b/doc/kernel/cache-policies.txt +@@ -67,7 +67,7 @@ the entries (each hotspot block covers a larger area than a single + cache block). + + All this means smq uses ~25bytes per cache block. Still a lot of +-memory, but a substantial improvement nontheless. ++memory, but a substantial improvement nonetheless. + + Level balancing: + mq placed entries in different levels of the multiqueue structures +diff --git a/doc/kernel/crypt.txt b/doc/kernel/crypt.txt +index 3b3e1de21..df18572f9 100644 +--- a/doc/kernel/crypt.txt ++++ b/doc/kernel/crypt.txt +@@ -35,7 +35,7 @@ Parameters: \ + capi:authenc(hmac(sha256),xts(aes))-random + capi:rfc7539(chacha20,poly1305)-random + +- The /proc/crypto contains a list of curently loaded crypto modes. ++ The /proc/crypto contains a list of currently loaded crypto modes. + + + Key used for encryption. It is encoded either as a hexadecimal number +@@ -81,7 +81,7 @@ Parameters: \ + + <#opt_params> + Number of optional parameters. If there are no optional parameters, +- the optional paramaters section can be skipped or #opt_params can be zero. ++ the optional parameters section can be skipped or #opt_params can be zero. + Otherwise #opt_params is the number of following arguments. + + Example of optional parameters section: +diff --git a/doc/kernel/integrity.txt b/doc/kernel/integrity.txt +index 03a3b956a..0822de802 100644 +--- a/doc/kernel/integrity.txt ++++ b/doc/kernel/integrity.txt +@@ -120,7 +120,7 @@ journal_crypt:algorithm(:key) (the key is optional) + "salsa20", "ctr(aes)" or "ecb(arc4)"). + + The journal contains history of last writes to the block device, +- an attacker reading the journal could see the last sector nubmers ++ an attacker reading the journal could see the last sector numbers + that were written. From the sector numbers, the attacker can infer + the size of files that were written. To protect against this + situation, you can encrypt the journal. +diff --git a/doc/kernel/verity.txt b/doc/kernel/verity.txt +index 89fd8f9a2..9822f1d61 100644 +--- a/doc/kernel/verity.txt ++++ b/doc/kernel/verity.txt +@@ -65,7 +65,7 @@ Construction Parameters + + <#opt_params> + Number of optional parameters. If there are no optional parameters, +- the optional paramaters section can be skipped or #opt_params can be zero. ++ the optional parameters section can be skipped or #opt_params can be zero. + Otherwise #opt_params is the number of following arguments. + + Example of optional parameters section: +diff --git a/doc/lvm2-raid.txt b/doc/lvm2-raid.txt +index a6f091543..a3226f230 100644 +--- a/doc/lvm2-raid.txt ++++ b/doc/lvm2-raid.txt +@@ -37,7 +37,7 @@ segment type. The available RAID types are: + "raid6_nr" - RAID6 Rotating parity N with data restart + "raid6_nc" - RAID6 Rotating parity N with data continuation + The exception to 'no shorthand options' will be where the RAID implementations +-can displace traditional tagets. This is the case with 'mirror' and 'raid1'. ++can displace traditional targets. This is the case with 'mirror' and 'raid1'. + In this case, "mirror_segtype_default" - found under the "global" section in + lvm.conf - can be set to "mirror" or "raid1". The segment type inferred when + the '-m' option is used will be taken from this setting. The default segment +@@ -104,7 +104,7 @@ and 4 devices for RAID 6/10. + + lvconvert should work exactly as it does now when dealing with mirrors - + even if(when) we switch to MD RAID1. Of course, there are no plans to +-allow the presense of the metadata area to be configurable (e.g. --corelog). ++allow the presence of the metadata area to be configurable (e.g. --corelog). + It will be simple enough to detect if the LV being up/down-converted is + new or old-style mirroring. + +@@ -120,7 +120,7 @@ RAID4 to RAID5 or RAID5 to RAID6. + Line 02/03/04: + These are familiar options - all of which would now be available as options + for change. (However, it'd be nice if we didn't have regionsize in there. +-It's simple on the kernel side, but is just an extra - often unecessary - ++It's simple on the kernel side, but is just an extra - often unnecessary - + parameter to many functions in the LVM codebase.) + + Line 05: +@@ -375,8 +375,8 @@ the slot. Even the names of the images will be renamed to properly reflect + their index in the array. Unlike the "mirror" segment type, you will never have + an image named "*_rimage_1" occupying the index position 0. + +-As with adding images, removing images holds off on commiting LVM metadata +-until all possible changes have been made. This reduces the likelyhood of bad ++As with adding images, removing images holds off on committing LVM metadata ++until all possible changes have been made. This reduces the likelihood of bad + intermediate stages being left due to a failure of operation or machine crash. + + RAID1 '--splitmirrors', '--trackchanges', and '--merge' operations +diff --git a/doc/lvm_fault_handling.txt b/doc/lvm_fault_handling.txt +index 53b447eac..196b782db 100644 +--- a/doc/lvm_fault_handling.txt ++++ b/doc/lvm_fault_handling.txt +@@ -87,7 +87,7 @@ are as follows: + /etc/lvm/lvm.conf. Once this operation is complete, the logical volumes + will be consistent. However, the volume group will still be inconsistent - + due to the refernced-but-missing device/PV - and operations will still be +- restricted to the aformentioned actions until either the device is ++ restricted to the aforementioned actions until either the device is + restored or 'vgreduce --removemissing' is run. + + Device Revival (transient failures): +@@ -135,9 +135,9 @@ If a mirror is not 'in-sync', a read failure will produce an I/O error. + This error will propagate all the way up to the applications above the + logical volume (e.g. the file system). No automatic intervention will + take place in this case either. It is up to the user to decide what +-can be done/salvaged in this senario. If the user is confident that the ++can be done/salvaged in this scenario. If the user is confident that the + images of the mirror are the same (or they are willing to simply attempt +-to retreive whatever data they can), 'lvconvert' can be used to eliminate ++to retrieve whatever data they can), 'lvconvert' can be used to eliminate + the failed image and proceed. + + Mirror resynchronization errors: +@@ -191,11 +191,11 @@ command are set in the LVM configuration file. They are: + 3-way mirror fails, the mirror will be converted to a 2-way mirror. + The "allocate" policy takes the further action of trying to replace + the failed image using space that is available in the volume group. +- Replacing a failed mirror image will incure the cost of ++ Replacing a failed mirror image will incur the cost of + resynchronizing - degrading the performance of the mirror. The + default policy for handling an image failure is "remove". This + allows the mirror to still function, but gives the administrator the +- choice of when to incure the extra performance costs of replacing ++ choice of when to incur the extra performance costs of replacing + the failed image. + + RAID logical volume device failures are handled differently from the "mirror" +diff --git a/doc/lvmpolld_overview.txt b/doc/lvmpolld_overview.txt +index 8c66e5e1a..ecff2eb81 100644 +--- a/doc/lvmpolld_overview.txt ++++ b/doc/lvmpolld_overview.txt +@@ -63,7 +63,7 @@ classical snapshot merge, thin snapshot merge. + + The second store is suited only for pvmove --abort operations in-progress. Both + stores are independent and identical LVs (pvmove /dev/sda3 and pvmove --abort /dev/sda3) +-can be run concurently from lvmpolld point of view (on lvm2 side the consistency is ++can be run concurrently from lvmpolld point of view (on lvm2 side the consistency is + guaranteed by lvm2 locking mechanism). + + Locking order +diff --git a/doc/tagging.txt b/doc/tagging.txt +index b66e0ecd3..95ee02d83 100644 +--- a/doc/tagging.txt ++++ b/doc/tagging.txt +@@ -126,7 +126,7 @@ Usage Examples + followed by 'vgchange -ay vg2' + + +- Option (ii) - localised admin & configuation ++ Option (ii) - localised admin & configuration + (i.e. each host holds *locally* which classes of volumes to activate) + # Add @database tag to vg1's metadata + vgchange --addtag @database vg1 +diff --git a/doc/udev_assembly.txt b/doc/udev_assembly.txt +index 618640273..45af41209 100644 +--- a/doc/udev_assembly.txt ++++ b/doc/udev_assembly.txt +@@ -35,7 +35,7 @@ VGs from PVs as they appear, and at the same time collect information on what is + already available. A command, pvscan --cache is expected to be used to + implement udev rules. It is relatively easy to make this command print out a + list of VGs (and possibly LVs) that have been made available by adding any +-particular device to the set of visible devices. In othe words, udev says "hey, ++particular device to the set of visible devices. In other words, udev says "hey, + /dev/sdb just appeared", calls pvscan --cache, which talks to lvmetad, which + says "cool, that makes vg0 complete". Pvscan takes this info and prints it out, + and the udev rule can then somehow decide whether anything needs to be done +diff --git a/libdm/make.tmpl.in b/libdm/make.tmpl.in +index a306101d5..1816bff55 100644 +--- a/libdm/make.tmpl.in ++++ b/libdm/make.tmpl.in +@@ -248,7 +248,7 @@ endif + # end of fPIC protection + endif + +-# Combination of DEBUG_POOL and DEBUG_ENFORCE_POOL_LOCKING is not suppored. ++# Combination of DEBUG_POOL and DEBUG_ENFORCE_POOL_LOCKING is not supported. + #DEFS += -DDEBUG_POOL + # Default pool locking is using the crc checksum. With mprotect memory + # enforcing compilation faulty memory write could be easily found. +diff --git a/make.tmpl.in b/make.tmpl.in +index cccda10d6..7799a8adb 100644 +--- a/make.tmpl.in ++++ b/make.tmpl.in +@@ -281,7 +281,7 @@ ifeq ("@BUILD_DMEVENTD@", "yes") + CLDFLAGS += -L$(top_builddir)/daemons/dmeventd + endif + +-# Combination of DEBUG_POOL and DEBUG_ENFORCE_POOL_LOCKING is not suppored. ++# Combination of DEBUG_POOL and DEBUG_ENFORCE_POOL_LOCKING is not supported. + #DEFS += -DDEBUG_POOL + # Default pool locking is using the crc checksum. With mprotect memory + # enforcing compilation faulty memory write could be easily found. +diff --git a/man/dmeventd.8_main b/man/dmeventd.8_main +index c03605d9c..77b07e4d8 100644 +--- a/man/dmeventd.8_main ++++ b/man/dmeventd.8_main +@@ -103,7 +103,7 @@ when it's been filled above configured threshold + \fBactivation/thin_pool_autoextend_threshold\fP. + If the command fails, dmeventd thin plugin will keep + retrying execution with increasing time delay between +-retries upto 42 minutes. ++retries up to 42 minutes. + User may also configure external command to support more advanced + maintenance operations of a thin pool. + Such external command can e.g. remove some unneeded snapshots, +@@ -133,7 +133,7 @@ when it's been filled above the configured threshold + \fBactivation/vdo_pool_autoextend_threshold\fP. + If the command fails, dmeventd vdo plugin will keep + retrying execution with increasing time delay between +-retries upto 42 minutes. ++retries up to 42 minutes. + User may also configure external command to support more advanced + maintenance operations of a VDO pool. + Such external command can e.g. remove some unneeded space +@@ -166,7 +166,7 @@ actual usage of VDO pool data volume. Variable is not set when error event + is processed. + .TP + .B LVM_RUN_BY_DMEVENTD +-Variable is set by thin and vdo plugin to prohibit recursive interation ++Variable is set by thin and vdo plugin to prohibit recursive interaction + with dmeventd by any executed lvm2 command from + a thin_command, vdo_command environment. + . +diff --git a/man/dmsetup.8_main b/man/dmsetup.8_main +index 7576b54bc..1cafae017 100644 +--- a/man/dmsetup.8_main ++++ b/man/dmsetup.8_main +@@ -572,7 +572,7 @@ See below for more information on the table format. + .B --udevcookie \fIcookie + Use cookie for udev synchronisation. + Note: Same cookie should be used for same type of operations i.e. creation of +-multiple different devices. It's not adviced to combine different ++multiple different devices. It's not advised to combine different + operations on the single device. + . + .TP +diff --git a/man/dmstats.8_main b/man/dmstats.8_main +index bf492c554..6991071bb 100644 +--- a/man/dmstats.8_main ++++ b/man/dmstats.8_main +@@ -292,7 +292,7 @@ region identifier. + . + .TP + .B --area +-When peforming a list or report, include objects of type area in the ++When performing a list or report, include objects of type area in the + results. + . + .TP +@@ -317,7 +317,7 @@ argument is zero reports will continue to repeat until interrupted. + . + .TP + .B --group +-When peforming a list or report, include objects of type group in the ++When performing a list or report, include objects of type group in the + results. + . + .TP +@@ -389,7 +389,7 @@ region as a comma separated list of latency values. Latency values are + given in nanoseconds. An optional unit suffix of + .BR ns , us , ms , + or \fBs\fP may be given after each value to specify units of +-nanoseconds, microseconds, miliseconds or seconds respectively. ++nanoseconds, microseconds, milliseconds or seconds respectively. + . + .TP + .B --histogram +@@ -456,7 +456,7 @@ default program ID for dmstats-managed regions is "dmstats". + . + .TP + .B --region +-When peforming a list or report, include objects of type region in the ++When performing a list or report, include objects of type region in the + results. + . + .TP +@@ -530,7 +530,7 @@ Produce additional output. + .HP + .CMD_CLEAR + .br +-Instructs the kernel to clear statistics counters for the speficied ++Instructs the kernel to clear statistics counters for the specified + regions (with the exception of in-flight IO counters). + . + .HP +@@ -556,10 +556,10 @@ configured interval duration) on the final bin. + .sp + Latencies are given in nanoseconds. An optional unit suffix of ns, us, + ms, or s may be given after each value to specify units of nanoseconds, +-microseconds, miliseconds or seconds respectively, so for example, 10ms ++microseconds, milliseconds or seconds respectively, so for example, 10ms + is equivalent to 10000000. Latency values with a precision of less than +-one milisecond can only be used when precise timestamps are enabled: if +-\fB--precise\fP is not given and values less than one milisecond are ++one millisecond can only be used when precise timestamps are enabled: if ++\fB--precise\fP is not given and values less than one millisecond are + used it will be enabled automatically. + .sp + An optional \fBprogram_id\fP or \fBuser_data\fP string may be associated +@@ -627,7 +627,7 @@ group. + The list of regions to be grouped is specified with \fB--regions\fP + and an optional alias may be assigned with \fB--alias\fP. The set of + regions is given as a comma-separated list of region identifiers. A +-continuous range of identifers spanning from \fBR1\fP to \fBR2\fP may ++continuous range of identifiers spanning from \fBR1\fP to \fBR2\fP may + be expressed as '\fBR1\fP-\fBR2\fP'. + .sp + Regions that have a histogram configured can be grouped: in this case +@@ -711,7 +711,7 @@ that were previously created with \fB--filemap\fP, either directly, + or by starting the monitoring daemon, \fBdmfilemapd\fP. + .sp + This will add and remove regions to reflect changes in the allocated +-extents of the file on-disk, since the time that it was crated or last ++extents of the file on-disk, since the time that it was created or last + updated. + .sp + Use of this command is not normally needed since the \fBdmfilemapd\fP +@@ -1090,13 +1090,13 @@ bounds. + .B hist_bounds + A list of the histogram boundary values for the current statistics area + in order of ascending latency value. The values are expressed in whole +-units of seconds, miliseconds, microseconds or nanoseconds with a suffix ++units of seconds, milliseconds, microseconds or nanoseconds with a suffix + indicating the unit. + .TP + .B hist_ranges + A list of the histogram bin ranges for the current statistics area in + order of ascending latency value. The values are expressed as +-"LOWER-UPPER" in whole units of seconds, miliseconds, microseconds or ++"LOWER-UPPER" in whole units of seconds, milliseconds, microseconds or + nanoseconds with a suffix indicating the unit. + .TP + .B hist_bins +diff --git a/man/lvchange.8_pregen b/man/lvchange.8_pregen +index 27bee0f14..4e0a8bf70 100644 +--- a/man/lvchange.8_pregen ++++ b/man/lvchange.8_pregen +@@ -744,7 +744,7 @@ See \fBlvmraid\fP(7) for more information. + .br + Start (yes) or stop (no) monitoring an LV with dmeventd. + dmeventd monitors kernel events for an LV, and performs +-automated maintenance for the LV in reponse to specific events. ++automated maintenance for the LV in response to specific events. + See \fBdmeventd\fP(8) for more information. + . + .HP +diff --git a/man/lvconvert.8_des b/man/lvconvert.8_des +index f36135f21..1bc3dfa11 100644 +--- a/man/lvconvert.8_des ++++ b/man/lvconvert.8_des +@@ -23,7 +23,7 @@ The + type is equivalent to the + .B striped + type when one stripe exists. +-In that case, the types can sometimes be used interchangably. ++In that case, the types can sometimes be used interchangeably. + .P + In most cases, the + .B mirror +diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen +index fa52da55c..f1d0d0256 100644 +--- a/man/lvconvert.8_pregen ++++ b/man/lvconvert.8_pregen +@@ -196,7 +196,7 @@ The + type is equivalent to the + .B striped + type when one stripe exists. +-In that case, the types can sometimes be used interchangably. ++In that case, the types can sometimes be used interchangeably. + .P + In most cases, the + .B mirror +diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen +index 0ffe92a94..5416b9c2f 100644 +--- a/man/lvcreate.8_pregen ++++ b/man/lvcreate.8_pregen +@@ -1175,7 +1175,7 @@ See \fBlvmraid\fP(7) for more information. + .br + Start (yes) or stop (no) monitoring an LV with dmeventd. + dmeventd monitors kernel events for an LV, and performs +-automated maintenance for the LV in reponse to specific events. ++automated maintenance for the LV in response to specific events. + See \fBdmeventd\fP(8) for more information. + . + .HP +diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main +index 824f24e91..a139062d1 100644 +--- a/man/lvmcache.7_main ++++ b/man/lvmcache.7_main +@@ -73,7 +73,7 @@ using dm-writecache (with cachevol): + .P + # lvconvert --type writecache --cachevol fast vg/main + .P +-For more alteratives see: ++For more alternatives see: + .br + dm-cache command shortcut + .br +@@ -286,11 +286,11 @@ read requests. + .TP + autocommit_blocks = + When the application writes this amount of blocks without issuing the +-FLUSH request, the blocks are automatically commited. ++FLUSH request, the blocks are automatically committed. + . + .TP + autocommit_time = +-The data is automatically commited if this time passes and no FLUSH ++The data is automatically committed if this time passes and no FLUSH + request is received. + . + .TP +@@ -403,7 +403,7 @@ cache, in which small reads and writes cause large sections of an LV to be + stored in the cache. It can also require increasing migration threshold + which defaults to 2048 sectors (1 MiB). Lvm2 ensures migration threshold is + at least 8 chunks in size. This may in some cases result in very +-high bandwidth load of transfering data between the cache LV and its ++high bandwidth load of transferring data between the cache LV and its + cache origin LV. However, choosing a chunk size that is too small + can result in more overhead trying to manage the numerous chunks that + become mapped into the cache. Overhead can include both excessive CPU +diff --git a/man/lvmdevices.8_des b/man/lvmdevices.8_des +index 2335456ad..ed24d4cd4 100644 +--- a/man/lvmdevices.8_des ++++ b/man/lvmdevices.8_des +@@ -95,7 +95,7 @@ is used for loop devices, the backing file name repored by sysfs. + the device name is used if no other type applies. + .P + +-The default choice for device ID type can be overriden using lvmdevices ++The default choice for device ID type can be overridden using lvmdevices + --addev --deviceidtype . If the specified type is available for the + device it will be used, otherwise the device will be added using the type + that would otherwise be chosen. +diff --git a/man/lvmdevices.8_pregen b/man/lvmdevices.8_pregen +index a2397e50f..e782596d0 100644 +--- a/man/lvmdevices.8_pregen ++++ b/man/lvmdevices.8_pregen +@@ -162,7 +162,7 @@ is used for loop devices, the backing file name repored by sysfs. + the device name is used if no other type applies. + .P + +-The default choice for device ID type can be overriden using lvmdevices ++The default choice for device ID type can be overridden using lvmdevices + --addev --deviceidtype . If the specified type is available for the + device it will be used, otherwise the device will be added using the type + that would otherwise be chosen. +diff --git a/man/lvmreport.7_main b/man/lvmreport.7_main +index f0f04ad1c..021089951 100644 +--- a/man/lvmreport.7_main ++++ b/man/lvmreport.7_main +@@ -1197,7 +1197,7 @@ But let's still use the original "," character for list_item_separator + for subsequent examples. + .P + Format for any of time values displayed in reports can be configured with +-\fBreport/time_format\fP configuretion setting. By default complete date ++\fBreport/time_format\fP configuration setting. By default complete date + and time is displayed, including timezone. + .P + .nf +@@ -1302,9 +1302,9 @@ binary_values_as_numeric=1 + .SS Changing output format + . + LVM can output reports in different formats - use \fBreport/output_format\fP +-configuration setting (or \fB--reportformat\fP command line option) to swith ++configuration setting (or \fB--reportformat\fP command line option) to switch + the report output format. Currently, LVM supports \fB"basic"\fP (all the examples +-we used above used this format) and \fB"JSON"\fP output format. ++we used above used this format) and \fB"json"\fP output format. + .P + .nf + # lvs -o lv_name,lv_size --reportformat json +diff --git a/man/vgcfgrestore.8_des b/man/vgcfgrestore.8_des +index dbc9aee16..10aa460c6 100644 +--- a/man/vgcfgrestore.8_des ++++ b/man/vgcfgrestore.8_des +@@ -1,6 +1,6 @@ + vgcfgrestore restores the metadata of a VG from a text back up file + produced by \fBvgcfgbackup\fP. This writes VG metadata onto the devices +-specifed in back up file. ++specified in back up file. + .P + A back up file can be specified with \fB--file\fP. If no backup file is + specified, the most recent one is used. Use \fB--list\fP for a list of +diff --git a/man/vgcfgrestore.8_pregen b/man/vgcfgrestore.8_pregen +index 6165cd36e..86e62c870 100644 +--- a/man/vgcfgrestore.8_pregen ++++ b/man/vgcfgrestore.8_pregen +@@ -63,7 +63,7 @@ vgcfgrestore \(em Restore volume group configuration + . + vgcfgrestore restores the metadata of a VG from a text back up file + produced by \fBvgcfgbackup\fP. This writes VG metadata onto the devices +-specifed in back up file. ++specified in back up file. + .P + A back up file can be specified with \fB--file\fP. If no backup file is + specified, the most recent one is used. Use \fB--list\fP for a list of +diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen +index 7c7030c0d..0e6bd7b24 100644 +--- a/man/vgchange.8_pregen ++++ b/man/vgchange.8_pregen +@@ -670,7 +670,7 @@ See \fBlvm.conf\fP(5) for more information about profiles. + .br + Start (yes) or stop (no) monitoring an LV with dmeventd. + dmeventd monitors kernel events for an LV, and performs +-automated maintenance for the LV in reponse to specific events. ++automated maintenance for the LV in response to specific events. + See \fBdmeventd\fP(8) for more information. + . + .HP +diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in +index 78f506520..7e2af981f 100644 +--- a/udev/69-dm-lvm-metad.rules.in ++++ b/udev/69-dm-lvm-metad.rules.in +@@ -87,7 +87,7 @@ LABEL="systemd_background" + # + # In this case, we simply set up the dependency between the device and the pvscan + # job using SYSTEMD_ALIAS (which sets up a simplified device identifier that +-# allows using "BindsTo" in the sytemd unit file) and SYSTEMD_WANTS (which tells ++# allows using "BindsTo" in the systemd unit file) and SYSTEMD_WANTS (which tells + # systemd to start the pvscan job once the device is ready). + # We need to set these variables for both "add" and "change" events, otherwise + # systemd may loose information about the device/unit dependencies. +-- +2.43.0 + diff --git a/SOURCES/0120-archiving-Fix-doubled-filename-in-vgcfgrestore.patch b/SOURCES/0120-archiving-Fix-doubled-filename-in-vgcfgrestore.patch new file mode 100644 index 0000000..53003ff --- /dev/null +++ b/SOURCES/0120-archiving-Fix-doubled-filename-in-vgcfgrestore.patch @@ -0,0 +1,26 @@ +From 4d602fc32a2c7f7575dae4b37f6a0b12f4c09cb4 Mon Sep 17 00:00:00 2001 +From: Ranjith ML +Date: Wed, 24 Jan 2024 14:05:24 +0100 +Subject: [PATCH 03/12] archiving: Fix doubled filename in vgcfgrestore + +(cherry picked from commit 1c3ae2b678ddae0c1916caca4dbe65049dcea3d7) +--- + lib/format_text/archive.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c +index 2e8792a93..388789c0d 100644 +--- a/lib/format_text/archive.c ++++ b/lib/format_text/archive.c +@@ -313,7 +313,7 @@ static void _display_archive(struct cmd_context *cmd, const char *dir, struct ar + } + + log_print(" "); +- log_print("File:\t\t%s/%s", path, af->name); ++ log_print("File:\t\t%s", path); + tc.path_live = path; + + fic.type = FMT_INSTANCE_PRIVATE_MDAS; +-- +2.43.0 + diff --git a/SOURCES/0121-man-add-inte-g-rity-to-man-lvs.patch b/SOURCES/0121-man-add-inte-g-rity-to-man-lvs.patch new file mode 100644 index 0000000..b6322b7 --- /dev/null +++ b/SOURCES/0121-man-add-inte-g-rity-to-man-lvs.patch @@ -0,0 +1,26 @@ +From 4db199be5c7ac6da9741e188f7ad1a076659b8c0 Mon Sep 17 00:00:00 2001 +From: Lukas Herbolt +Date: Tue, 5 Dec 2023 09:08:24 -0600 +Subject: [PATCH 04/12] man: add inte(g)rity to man lvs + +(cherry picked from commit 7b64d9946d6a3be84338ad976383b6ab53e97484) +--- + man/lvs.8_end | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/lvs.8_end b/man/lvs.8_end +index dc3a27446..e9897b4fc 100644 +--- a/man/lvs.8_end ++++ b/man/lvs.8_end +@@ -4,7 +4,7 @@ + The lv_attr bits are: + .IP 1 3 + Volume type: (\fBC\fP)ache, (\fBm\fP)irrored, (\fBM\fP)irrored without initial sync, (\fBo\fP)rigin, +-(\fBO\fP)rigin with merging snapshot, (\fBr\fP)aid, (\fBR\fP)aid without initial sync, ++(\fBO\fP)rigin with merging snapshot, inte(\fBg\fP)rity, (\fBr\fP)aid, (\fBR\fP)aid without initial sync, + (\fBs\fP)napshot, merging (\fBS\fP)napshot, (\fBp\fP)vmove, (\fBv\fP)irtual, + mirror or raid (\fBi\fP)mage, mirror or raid (\fBI\fP)mage out-of-sync, mirror (\fBl\fP)og device, + under (\fBc\fP)onversion, thin (\fBV\fP)olume, (\fBt\fP)hin pool, (\fBT\fP)hin pool data, +-- +2.43.0 + diff --git a/SOURCES/0122-Fix-lvconvert-m-0-will-always-take-rimage_0-even-if-.patch b/SOURCES/0122-Fix-lvconvert-m-0-will-always-take-rimage_0-even-if-.patch new file mode 100644 index 0000000..d68766d --- /dev/null +++ b/SOURCES/0122-Fix-lvconvert-m-0-will-always-take-rimage_0-even-if-.patch @@ -0,0 +1,48 @@ +From 3b5e2537ae1ce6ee633b92f8df30602b9167044e Mon Sep 17 00:00:00 2001 +From: heinzm +Date: Fri, 5 May 2023 15:00:49 +0200 +Subject: [PATCH 05/12] Fix "lvconvert -m 0 will always take rimage_0 even if + it is out-of-sync" + +Bail out in case first rimage is out-of-sync. +Refresh first, i.e. "lvchange --resync $RaidLV", +then retry downgrade to linear after resynchronization. + +(cherry picked from commit d7e922480e04ecfb7c4d8b2d42533699ddef5c34) +--- + lib/metadata/raid_manip.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c +index 0e6a77bac..5112989ab 100644 +--- a/lib/metadata/raid_manip.c ++++ b/lib/metadata/raid_manip.c +@@ -3112,14 +3112,23 @@ static int _raid_remove_images(struct logical_volume *lv, int yes, + { + struct dm_list removed_lvs; + +- if (!archive(lv->vg)) +- return_0; ++ if (new_count == 1) { ++ struct lv_segment *seg = first_seg(lv); ++ ++ if (seg_is_raid1(seg) && !lv_raid_image_in_sync(seg_lv(seg, 0))) { ++ log_error("%s is out-of-sync! Please try refreshing first.", display_lvname(lv)); ++ return 0; ++ } ++ } + + if (!removal_lvs) { + dm_list_init(&removed_lvs); + removal_lvs = &removed_lvs; + } + ++ if (!archive(lv->vg)) ++ return_0; ++ + if (!_raid_extract_images(lv, 0, new_count, allocate_pvs, 1, + removal_lvs, removal_lvs)) { + log_error("Failed to extract images from %s.", +-- +2.43.0 + diff --git a/SOURCES/0123-lvconvert-fix-lvconvert-m-0-for-in-sync-legs.patch b/SOURCES/0123-lvconvert-fix-lvconvert-m-0-for-in-sync-legs.patch new file mode 100644 index 0000000..3158636 --- /dev/null +++ b/SOURCES/0123-lvconvert-fix-lvconvert-m-0-for-in-sync-legs.patch @@ -0,0 +1,52 @@ +From 54576eb1e4217353072933d5c2b3274c08c67e82 Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Thu, 19 Oct 2023 16:50:01 +0200 +Subject: [PATCH 06/12] lvconvert: fix "lvconvert -m 0" for in-sync legs + +With commit d7e922480e04ecfb7c4d8b2d42533699ddef5c34 +lvconvert -m may fail if we try to remove 1st. leg that +is out-of-sync while other leg is in-sync. + +Hot fix allows to proceed with such down conversion. + +Signed-off-by: Heinz Mauelshagen +(cherry picked from commit e41da923a3bec2df603b54f0f466e9574b6544db) +--- + lib/metadata/raid_manip.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c +index 5112989ab..7ce2c177d 100644 +--- a/lib/metadata/raid_manip.c ++++ b/lib/metadata/raid_manip.c +@@ -3113,9 +3113,26 @@ static int _raid_remove_images(struct logical_volume *lv, int yes, + struct dm_list removed_lvs; + + if (new_count == 1) { ++ uint32_t s; + struct lv_segment *seg = first_seg(lv); + +- if (seg_is_raid1(seg) && !lv_raid_image_in_sync(seg_lv(seg, 0))) { ++ if (!seg_is_raid1(seg)) { ++ log_error("%s called on non-raid1 LV.", display_lvname(lv)); ++ return 0; ++ } ++ ++ for (s = 0; s < seg->area_count; s++) { ++ if (seg_type(seg, s) == AREA_UNASSIGNED) ++ continue; ++ ++ if (lv_raid_image_in_sync(seg_lv(seg, s))) { ++ _swap_areas(seg->areas + 0, seg->areas + s); ++ break; ++ } ++ ++ } ++ ++ if (s >= seg->area_count) { + log_error("%s is out-of-sync! Please try refreshing first.", display_lvname(lv)); + return 0; + } +-- +2.43.0 + diff --git a/SOURCES/0124-Fix-multisegment-RAID1-allocator-uses-one-disk-for-b.patch b/SOURCES/0124-Fix-multisegment-RAID1-allocator-uses-one-disk-for-b.patch new file mode 100644 index 0000000..5da988b --- /dev/null +++ b/SOURCES/0124-Fix-multisegment-RAID1-allocator-uses-one-disk-for-b.patch @@ -0,0 +1,79 @@ +From b9b28ee11adc8aba0fe11dda56a88b3cfc8d6b41 Mon Sep 17 00:00:00 2001 +From: heinzm +Date: Wed, 10 May 2023 18:22:11 +0200 +Subject: [PATCH 07/12] Fix "multisegment RAID1, allocator uses one disk for + both legs" + +In case of e.g. 3 PVs, creating or extending a RaidLV causes SubLV +collocation thus putting segments of diffent rimage (and potentially +larger rmeta) SubLVs onto the same PV. For redundant RaidLVs this'll +compromise redundancy. Fix by detecting such bogus allocation on +lvcreate/lvextend and reject the request. + +(cherry picked from commit 05c2b10c5d0a99993430ffbcef684a099ba810ad) +--- + lib/metadata/lv_manip.c | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index 0a51e0315..24d8adc18 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -4454,6 +4454,38 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah, + return 1; + } + ++/* Check either RAID images and metas are being allocated redundantly. */ ++static int _lv_raid_redundant(struct logical_volume *lv, ++ struct dm_list *allocatable_pvs, int meta) ++{ ++ uint32_t nlvs, s; ++ struct lv_segment *seg = first_seg(lv); ++ struct pv_list *pvl; ++ ++ if (meta && !seg->meta_areas) ++ return 1; ++ ++ dm_list_iterate_items(pvl, allocatable_pvs) { ++ nlvs = 0; ++ ++ for (s = 0; s < seg->area_count; s++) { ++ struct logical_volume *slv = meta ? seg_metalv(seg, s) : seg_lv(seg, s); ++ ++ if (slv && lv_is_on_pv(slv, pvl->pv) && nlvs++) ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++/* Check both RAID images and metas are being allocated redundantly. */ ++static int _lv_raid_redundant_allocation(struct logical_volume *lv, struct dm_list *allocatable_pvs) ++{ ++ return _lv_raid_redundant(lv, allocatable_pvs, 0) && ++ _lv_raid_redundant(lv, allocatable_pvs, 1); ++} ++ + /* + * Entry point for single-step LV allocation + extension. + * Extents is the number of logical extents to append to the LV unless +@@ -4556,6 +4588,15 @@ int lv_extend(struct logical_volume *lv, + mirrors, stripes, stripe_size))) + goto_out; + ++ if (segtype_is_raid(segtype) && ++ alloc != ALLOC_ANYWHERE && ++ !(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) { ++ log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv)); ++ if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)) ++ return_0; ++ goto out; ++ } ++ + if (lv_raid_has_integrity(lv)) { + if (!lv_extend_integrity_in_raid(lv, allocatable_pvs)) { + r = 0; +-- +2.43.0 + diff --git a/SOURCES/0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch b/SOURCES/0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch new file mode 100644 index 0000000..91dcdaa --- /dev/null +++ b/SOURCES/0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch @@ -0,0 +1,58 @@ +From 1c773b76965efe1fd7c4b3c8211296ede5b4c1e5 Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Wed, 6 Dec 2023 12:58:14 +0100 +Subject: [PATCH 08/12] raid: add messages to lvs command output in case + RaidLVs require a refresh + +If a RaidLV mapping is required to be refreshed as a result of temporarily failed +and recurred RAID leg device (pairs) caused by writes to the LV during failure, +the requirement is reported by volume health character r' in position 9 of the +LV's attribute field (see 'man lvs' about additional volume health characters). + +As this character can be overlooked, this patch adds messages to the top +of the lvs command output informing the user explicitely about the fact. + +(cherry picked from commit b69f73b13ee55ef3feb7427c6dc099dc3472d9fc) +--- + tools/reporter.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/tools/reporter.c b/tools/reporter.c +index eafba4fec..ff30a31a9 100644 +--- a/tools/reporter.c ++++ b/tools/reporter.c +@@ -150,6 +150,13 @@ static int _check_merging_origin(const struct logical_volume *lv, + return 1; + } + ++static void _cond_warn_raid_volume_health(struct cmd_context *cmd, const struct logical_volume *lv) ++{ ++ if (lv_is_raid(lv) && !lv_raid_healthy(lv) && !lv_is_partial(lv)) ++ log_warn("WARNING: RaidLV %s needs to be refreshed! See character 'r' at position 9 in the RaidLV's attributes%s.", display_lvname(lv), ++ arg_is_set(cmd, all_ARG) ? " and its SubLV(s)" : " and also its SubLV(s) with option '-a'"); ++} ++ + static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd, + const struct logical_volume *lv, + int do_info, int do_status, +@@ -176,6 +183,8 @@ static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd, + lv = lv->snapshot->lv; + } + ++ _cond_warn_raid_volume_health(cmd, lv); ++ + if (!report_object(sh ? : handle->custom_handle, sh != NULL, + lv->vg, lv, NULL, NULL, NULL, &status, NULL)) + goto out; +@@ -238,6 +247,8 @@ static int _do_segs_with_info_and_status_single(struct cmd_context *cmd, + seg = seg->lv->snapshot; + } + ++ _cond_warn_raid_volume_health(cmd, seg->lv); ++ + if (!report_object(sh ? : handle->custom_handle, sh != NULL, + seg->lv->vg, seg->lv, NULL, seg, NULL, &status, NULL)) + goto_out; +-- +2.43.0 + diff --git a/SOURCES/0130-spec-Install-and-package-etc-lvm-devices.patch b/SOURCES/0130-spec-Install-and-package-etc-lvm-devices.patch new file mode 100644 index 0000000..41c9834 --- /dev/null +++ b/SOURCES/0130-spec-Install-and-package-etc-lvm-devices.patch @@ -0,0 +1,25 @@ +From e85d3a5487893cd2b8464d0b9a69f0050f686d7e Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 29 Nov 2023 15:09:36 +0100 +Subject: [PATCH] spec: Install and package /etc/lvm/devices + +(cherry picked from commit ee31ba5023e6e1430c0d808f54015ccd3eb3931a) +--- + Makefile.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile.in b/Makefile.in +index f7a46269a..afbb0d1bd 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -127,6 +127,7 @@ all_man: + + install_system_dirs: + $(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR) ++ $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)/devices + $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR) + $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR) + $(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR) +-- +2.43.0 + diff --git a/SOURCES/lvm2-rhel8.patch b/SOURCES/lvm2-rhel8.patch new file mode 100644 index 0000000..596b317 --- /dev/null +++ b/SOURCES/lvm2-rhel8.patch @@ -0,0 +1,18 @@ + VERSION | 2 +- + VERSION_DM | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/VERSION b/VERSION +index 0a36180..57ed15e 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-2.03.14(2) (2021-10-20) ++2.03.14(2)-RHEL8 (2021-10-20) +diff --git a/VERSION_DM b/VERSION_DM +index 52cb622..bf97bda 100644 +--- a/VERSION_DM ++++ b/VERSION_DM +@@ -1 +1 @@ +-1.02.181 (2021-10-20) ++1.02.181-RHEL8 (2021-10-20) diff --git a/SOURCES/lvm2-test-skip-problematic-tests.patch b/SOURCES/lvm2-test-skip-problematic-tests.patch new file mode 100644 index 0000000..0f107ad --- /dev/null +++ b/SOURCES/lvm2-test-skip-problematic-tests.patch @@ -0,0 +1,39 @@ + test/dbus/lvmdbustest.py | 1 + + test/shell/lvcreate-usage.sh | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py +index 6d69222..64faf84 100755 +--- a/test/dbus/lvmdbustest.py ++++ b/test/dbus/lvmdbustest.py +@@ -1856,6 +1856,7 @@ class TestDbusService(unittest.TestCase): + # path to it. Additionally, we will take the symlink and do a lookup + # (Manager.LookUpByLvmId) using it and the original device path to + # ensure that we can find the PV. ++ raise unittest.SkipTest('Test need fixing') + symlink = None + + pv = self.objs[PV_INT][0] +diff --git a/test/shell/lvcreate-usage.sh b/test/shell/lvcreate-usage.sh +index 6d46939..9e00f1c 100644 +--- a/test/shell/lvcreate-usage.sh ++++ b/test/shell/lvcreate-usage.sh +@@ -181,15 +181,15 @@ check lv_field $vg/$lv4 lv_read_ahead "auto" + DEVICE=$(dmsetup deps -o blkdevname "$dev1" | sed -e "s,.*:\ (\(.*\)),/dev/\1,") + RASZ=$(( $(blockdev --getra "$DEVICE" ) / 2 )) + test "$RASZ" -ge 128 || RASZ="128" +-check lv_field $vg/$lv4 lv_kernel_read_ahead "${RASZ}.00k" --units k ++should check lv_field $vg/$lv4 lv_kernel_read_ahead "${RASZ}.00k" --units k + lvcreate -vvvvv -L 8 -n $lv5 -i2 --stripesize 16k --readahead auto $vg + check lv_field $vg/$lv5 lv_read_ahead "auto" + # For 16k stripe we set '128k' as the is the minimum size we get when creating DM device +-check lv_field $vg/$lv5 lv_kernel_read_ahead "128.00k" --units k ++should check lv_field $vg/$lv5 lv_kernel_read_ahead "128.00k" --units k + lvcreate -L 8 -n $lv6 -i2 --stripesize 128k --readahead auto $vg + check lv_field $vg/$lv6 lv_read_ahead "auto" + # For striped device we set double of strip size unrelated to underlaying dev RA size +-check lv_field $vg/$lv6 lv_kernel_read_ahead "512.00k" --units k ++should check lv_field $vg/$lv6 lv_kernel_read_ahead "512.00k" --units k + lvremove -ff $vg + + # diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec new file mode 100644 index 0000000..41013c9 --- /dev/null +++ b/SPECS/lvm2.spec @@ -0,0 +1,5335 @@ +%global device_mapper_version 1.02.181 + +%global enable_cache 1 +%global enable_cluster 1 +%global enable_cmirror 1 +%global enable_lvmdbusd 1 +%global enable_lvmlockd 1 +%global enable_lvmpolld 1 +%global enable_thin 1 +%global enable_dmfilemapd 1 +%global enable_testsuite 1 +%global enable_vdo 1 +%global enable_writecache 1 +%global enable_integrity 1 + +%global system_release_version 23 +%global systemd_version 189-3 +%global dracut_version 002-18 +%global util_linux_version 2.24 +%global bash_version 4.0 +%global corosync_version 1.99.9-1 +%global resource_agents_version 3.9.5-12 +# TODO: This needs newer dlm - do I need a side tag??? :-/ +%global dlm_version 4.0.9-1 +%global libselinux_version 1.30.19-4 +%global persistent_data_version 0.7.0-0.1.rc6 +%global sanlock_version 3.3.0-2 + +%global enable_lockd_sanlock %{enable_lvmlockd} +%global enable_lockd_dlm %{enable_lvmlockd} + +%if 0%{?rhel} && 0%{?rhel} <= 8 + %ifnarch i686 x86_64 ppc64le s390x + %global enable_cluster 0 + %global enable_cmirror 0 + %global enable_lockd_dlm 0 + %endif + + %ifnarch x86_64 ppc64 aarch64 + %global enable_lockd_sanlock 0 + %endif +%endif + +%if %{enable_cluster} + %global configure_cluster --with-cluster=internal + %if %{enable_cmirror} + %global configure_cmirror --enable-cmirrord + %endif +%else + %global configure_cluster --with-cluster=internal +%endif + +%global from_snapshot 0 +%if 0%{?from_snapshot} +%global commit 4dc5d4ac7e7a9457ccc46ff04796b347e58bf4da +%global shortcommit %(c=%{commit}; echo ${c:0:7}) +%endif +#%%global rel_suffix .bz2233901_1 + +# Do not reset Release to 1 unless both lvm2 and device-mapper +# versions are increased together. +Summary: Userland logical volume management tools +Name: lvm2 +%if 0%{?rhel} +Epoch: %{rhel} +%endif +Version: 2.03.14 +%if 0%{?from_snapshot} +Release: 0.1.20210426git%{shortcommit}%{?dist}%{?rel_suffix} +%else +Release: 14%{?dist}%{?rel_suffix} +%endif +License: GPLv2 +URL: http://sourceware.org/lvm2 +%if 0%{?from_snapshot} +Source0: lvm2-%{shortcommit}.tgz +%else +Source0: ftp://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz +Patch0: lvm2-rhel8.patch +%endif +Patch1: lvm2-test-skip-problematic-tests.patch +Patch2: 0001-Revert-new-udev-autoactivation.patch +Patch3: 0002-Revert-pvscan-only-add-device-args-to-dev-cache.patch +Patch4: 0003-pvscan-fix-messages-from-coverity-changes.patch +Patch5: 0004-vgimportdevices-skip-lvmlockd-locking.patch +Patch6: 0005-hints-remove-the-cmd-hints-list.patch +Patch7: 0006-filter-sysfs-skip-when-device-id-is-set.patch +Patch8: 0007-lvmdevices-increase-open-file-limit.patch +Patch9: 0008-filter-sysfs-support-old-kernels-without-sys-dev-blo.patch +Patch10: 0009-device_id-match-different-dm-device-names.patch +Patch11: 0010-device_id-fix-search-on-filtered-device.patch +Patch12: 0011-device_id-searched_devnames-improvements.patch +Patch13: 0012-tests-pv-ext-flags-work-with-devices-file.patch +Patch14: 0013-display-ignore-reportformat.patch +Patch15: 0014-fix-spelling-of-pruning.patch +Patch16: 0015-man-lvmautoactivation.patch +#Patch17: 0016-spec-Add-lvmautoactivation-man-page.patch +Patch18: 0017-tests-devicesfile-devname.sh-drop-mdadm-chunk.patch +Patch19: 0018-devices-file-don-t-write-in-test-mode.patch +Patch20: 0019-print-warning-about-unrecognized-journal-option-valu.patch +Patch21: 0020-device_id-handle-wwid-with-spaces-or-control-charact.patch +Patch22: 0021-man-add-section-about-static-autoactivation.patch +Patch23: 0022-lvcreate-include-recent-options.patch +Patch24: 0023-man-lvmautoactivation-replace-systemctl-with-journal.patch +Patch25: 0024-make-generate.patch +Patch26: 0025-pvcreate-overwrite-partition-header-with-f.patch +Patch27: 0026-lvmdevices-check-error-exit-if-update-is-needed.patch +Patch28: 0027-Revert-pvcreate-overwrite-partition-header-with-f.patch +Patch29: 0028-devices-exclude-multipath-components-based-on-matchi.patch +Patch30: 0029-devices-exclude-md-components-when-duplicate-pvs-are.patch +Patch31: 0030-lvmdevices-fix-checks-when-adding-entries.patch +Patch32: 0031-lvmdevices-make-deldev-work-for-missing-device.patch +Patch33: 0032-devices-file-do-not-clear-PVID-of-unread-devices.patch +Patch34: 0033-man-lvmcache-mention-writecache-memory-usage.patch +Patch35: 0034-writecache-display-block-size-from-lvs.patch +Patch36: 0035-devices-simplify-dev_cache_get_by_devt.patch +Patch37: 0036-devices-drop-incorrect-paths-from-aliases-list.patch +Patch38: 0037-devices-initial-use-of-existing-option.patch +Patch39: 0038-devices-fix-dev_name-assumptions.patch +Patch40: 0039-devices-use-dev-cache-aliases-handling-from-label-sc.patch +Patch41: 0040-writecache-check-memory-usage.patch +Patch42: 0041-change-messages-about-filtered-devices.patch +Patch43: 0042-vgimportdevices-fix-incorrect-deviceidtype-usage.patch +Patch44: 0043-lvmlockd-return-error-from-vgcreate-init_vg_sanlock.patch +Patch45: 0044-devices-file-remove-extraneous-unlock-in-vgchange-u.patch +Patch46: 0045-filter-mpath-use-multipath-blacklist.patch +Patch47: 0046-improve-description-of-devices-option.patch +Patch48: 0047-vdo-support-vdosettings.patch +Patch49: 0048-toollib-fix-segfault-when-handling-selection-with-hi.patch +Patch50: 0049-devices-file-move-clean-up-after-command-is-run.patch +Patch51: 0050-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch +Patch52: 0051-filter-mpath-handle-other-wwid-types-in-blacklist.patch +Patch53: 0052-vdo-fix-conversion-of-vdo_slab_size_mb.patch +Patch54: 0053-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch +Patch55: 0054-build-Fix-make-rpm-with-VERSION_DM-without-dash.patch +# BZ 2090949: +Patch57: 0056-exit-with-error-when-devicesfile-name-doesn-t-exist.patch +# BZ 2111137: +Patch58: 0057-apply-multipath_component_detection-0-to-duplicate-P.patch +# BZ 2121237: +Patch59: 0058-devices-file-fix-pvcreate-uuid-matching-pvid-entry-w.patch +# BZ 2061800: +Patch60: 0059-lvconvert-correct-test-support-for-vdo-pool.patch +# BZ 2022135: +Patch61: 0060-lvmdbusd-Set-LVM_COMMAND_PROFILE-lvmdbusd.patch +# BZ 2139512: +Patch62: 0061-vgimportdevices-change-result-when-devices-are-not-a.patch +Patch63: 0062-vgimportdevices-fix-locking-when-creating-devices-fi.patch +# BZ 2054032: +Patch64: 0063-thin-fix-message-processing-on-thin-pool-extension.patch +# BZ 2108254: +Patch65: 0064-vdo-fix-vdosettings-parser.patch +Patch66: 0065-make-generate.patch +# BZ 2108239: +Patch67: 0066-vdo-use-single-validator.patch +Patch68: 0067-vdo-use-defines-also-for-configuration-defines.patch +Patch69: 0068-vdo-report-supported-range-in-error-path.patch +# BZ 2173312: +Patch70: 0069-vdo-ensure-VDO-config-is-removed.patch +Patch71: 0070-vdo-fix-conversion-of-vdo_slab_size_mb.patch +Patch72: 0071-tests-add-lvm_vdo_wrapper.patch +Patch73: 0072-tests-update-for-wrapper.patch +Patch74: 0073-lvmdbusd-Change-unit-test-vdo-minimum-size.patch +Patch75: 0074-vdo-fix-conversion-of-vdo_slab_size_mb-2nd.patch +Patch76: 0075-vdo-update-info-about-memory.patch +Patch77: 0076-vdo-check-vdo-memory-constrains.patch +Patch78: 0077-vdo-add-reformating-to-extent-size-aligned-virtual-s.patch +Patch79: 0078-vdo-support-v4-kernel-target-line.patch +Patch80: 0079-vdo-enhance-lvcreate-validation.patch +Patch81: 0080-vdo-suffle-code-for-better-error-path-handling.patch +Patch82: 0081-vdo-use-only-verbose-log-level-for-reformating.patch +Patch83: 0082-vdo-reset-errno-before-strtoull.patch +Patch84: 0083-vdo-extend-volume-and-pool-without-flush.patch +Patch85: 0084-tests-vdo-emulation-without-vdo-binary.patch +Patch86: 0085-device_mapper-add-parser-for-vdo-metadata.patch +Patch87: 0086-dev_manager-accept-misalined-vdo-pools.patch +Patch88: 0087-device_mapper-vdo-V4-avoid-messaging.patch +Patch89: 0088-vdo-replace-errors-with-debug.patch +Patch90: 0089-vdo-enhance-detection-of-virtual-size.patch +Patch91: 0090-vdo-improve-validation-message.patch +Patch92: 0091-vdo-fix-reader-error-path.patch +Patch93: 0092-vdo-check-memory-only-in-non-critical-section.patch +Patch94: 0093-vdo-read-live-vdo-size-configuration.patch +Patch95: 0094-lvcreate-fix-error-path-return-values.patch +Patch96: 0095-vdo-fix-and-enhance-vdo-constain-checking.patch +Patch97: 0096-vdo-resize-requires-active-vdopool-volume.patch +Patch98: 0097-tests-vdo-resizing.patch +Patch99: 0098-tests-check-failing-vdo-conversion.patch +Patch100: 0099-vdo-use-fixed-size-vdopool-wrapper.patch +Patch101: 0100-vdo-document-feature-option.patch +Patch102: 0101-vdo-fix-and-enhance-vdo-metadata-reader.patch +Patch103: 0102-tests-cleanup-some-shellcheck-warns.patch +Patch104: 0103-vdo-enhance-lvm_vdo_import.patch +Patch105: 0104-vdo-man-updates-for-lvm_import_vdo.patch +Patch106: 0105-tests-vdo-manager-wrapper-tool-updates.patch +Patch107: 0106-tests-update-test-to-handle-different-status.patch +Patch108: 0107-tests-updates.patch +Patch109: 0108-WHATS_NEW-update.patch +Patch110: 0109-lvm_import_vdo-correct-the-converted-virtual-size.patch +Patch111: 0110-tests-update-test-for-automatic-virtual-size-correct.patch +Patch112: 0111-vdo-check_point_frequence-is-unused-option.patch +Patch113: 0112-vdo-indent-for-lvdisplay.patch +Patch114: 0113-vdo-lvm_import_vdo-correct-parsing-output.patch +Patch115: 0114-lvm_import_vdo-spelling-fixes.patch +Patch116: 0115-vdo-support-version-4.patch +Patch117: 0116-vdo-use-long-verbose.patch +# BZ 2233901: +Patch118: 0117-vdo-Sync-lvm_import_vdo.sh-with-main-as-of-970e4d295.patch +# RHEL-8289: +Patch119: 0118-man-Fix-typo.patch +Patch120: 0119-doc-fix-typos-in-documentation.patch +# RHEL-20192: +Patch121: 0120-archiving-Fix-doubled-filename-in-vgcfgrestore.patch +# RHEL-14216: +Patch122: 0121-man-add-inte-g-rity-to-man-lvs.patch +# RHEL-8298: +Patch123: 0122-Fix-lvconvert-m-0-will-always-take-rimage_0-even-if-.patch +Patch124: 0123-lvconvert-fix-lvconvert-m-0-for-in-sync-legs.patch +# RHEL-8334: +Patch125: 0124-Fix-multisegment-RAID1-allocator-uses-one-disk-for-b.patch +# RHEL-8270: +Patch126: 0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch +## RHEL-8295: +#Patch127: 0126-vgsplit-don-t-reread-vg_to.patch +#Patch128: 0127-lvmcache-remove-lvmcache_update_vg_from_write.patch +#Patch129: 0128-handle-duplicate-vgids.patch +#Patch130: 0129-remove-unused-variable.patch +# +Patch131: 0130-spec-Install-and-package-etc-lvm-devices.patch + +BuildRequires: gcc +%if %{enable_testsuite} +BuildRequires: gcc-c++ +%endif +BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel +BuildRequires: libblkid-devel >= %{util_linux_version} +BuildRequires: ncurses-devel +BuildRequires: readline-devel +BuildRequires: libaio-devel +%if %{enable_cluster} +BuildRequires: corosynclib-devel >= %{corosync_version} +%endif +%if %{enable_cluster} || %{enable_lockd_dlm} +BuildRequires: dlm-devel >= %{dlm_version} +%endif +BuildRequires: module-init-tools +BuildRequires: pkgconfig +BuildRequires: systemd-devel +BuildRequires: systemd-units +%if %{enable_lvmdbusd} +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-dbus +BuildRequires: python3-pyudev +%endif +%if %{enable_thin} || %{enable_cache} +BuildRequires: device-mapper-persistent-data >= %{persistent_data_version} +%endif +%if %{enable_lockd_sanlock} +BuildRequires: sanlock-devel >= %{sanlock_version} +%endif +Requires: %{name}-libs = %{?epoch}:%{version}-%{release} +%if 0%{?fedora} +Requires: system-release >= %{system_release_version} +%endif +Requires: bash >= %{bash_version} +Requires(post): systemd-units >= %{systemd_version}, systemd-sysv +Requires(preun): systemd-units >= %{systemd_version} +Requires(postun): systemd-units >= %{systemd_version} +Requires: module-init-tools +%if %{enable_thin} || %{enable_cache} +Requires: device-mapper-persistent-data >= %{persistent_data_version} +%endif + +%description +LVM2 includes all of the support for handling read/write operations on +physical volumes (hard disks, RAID-Systems, magneto optical, etc., +multiple devices (MD), see mdadm(8) or even loop devices, see +losetup(8)), creating volume groups (kind of virtual disks) from one +or more physical volumes and creating one or more logical volumes +(kind of logical partitions) in volume groups. + +%prep +%if 0%{?from_snapshot} +%autosetup -n lvm2-%{commit} +%else +%autosetup -p1 -n LVM2.%{version} +%endif + +%build +%global _default_pid_dir /run +%global _default_dm_run_dir /run +%global _default_run_dir /run/lvm +%global _default_locking_dir /run/lock/lvm + +%global _udevdir %{_prefix}/lib/udev/rules.d + +%configure \ + --with-default-dm-run-dir=%{_default_dm_run_dir} \ + --with-default-run-dir=%{_default_run_dir} \ + --with-default-pid-dir=%{_default_pid_dir} \ + --with-default-locking-dir=%{_default_locking_dir} \ + --with-usrlibdir=%{_libdir} \ + --enable-fsadm \ + --enable-write_install \ + --with-user= \ + --with-group= \ + --with-device-uid=0 \ + --with-device-gid=6 \ + --with-device-mode=0660 \ + --enable-pkgconfig \ + --enable-cmdlib \ + --enable-dmeventd \ + --enable-blkid_wiping \ + %{?configure_cluster} \ + %{?configure_cmirror} \ + --with-udevdir=%{_udevdir} --enable-udev_sync \ +%if %{enable_thin} + --with-thin=internal \ +%endif +%if %{enable_cache} + --with-cache=internal \ +%endif +%if %{enable_lvmpolld} + --enable-lvmpolld \ +%endif +%if %{enable_lockd_dlm} + --enable-lvmlockd-dlm --enable-lvmlockd-dlmcontrol \ +%endif +%if %{enable_lockd_sanlock} + --enable-lvmlockd-sanlock \ +%endif +%if %{enable_lvmdbusd} + --enable-dbus-service --enable-notify-dbus \ +%endif +%if %{enable_dmfilemapd} + --enable-dmfilemapd \ +%endif +%if %{enable_writecache} + --with-writecache=internal \ +%endif +%if %{enable_vdo} + --with-vdo=internal --with-vdo-format=%{_bindir}/vdoformat \ +%endif +%if %{enable_integrity} + --with-integrity=internal \ +%endif + --disable-silent-rules + +make %{?_smp_mflags} + +%install +make install DESTDIR=$RPM_BUILD_ROOT +make install_system_dirs DESTDIR=$RPM_BUILD_ROOT +make install_systemd_units DESTDIR=$RPM_BUILD_ROOT +make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT +make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT +%if %{enable_testsuite} +make install DESTDIR=$RPM_BUILD_ROOT -C test +%endif + +%post +%systemd_post blk-availability.service lvm2-monitor.service +if [ "$1" = "1" ] ; then + # FIXME: what to do with this? We do not want to start it in a container/chroot + # enable and start lvm2-monitor.service on completely new installation only, not on upgrades + systemctl enable lvm2-monitor.service + systemctl start lvm2-monitor.service >/dev/null 2>&1 || : +fi + +%if %{enable_lvmpolld} +%systemd_post lvm2-lvmpolld.socket +# lvm2-lvmpolld socket is always enabled and started and ready to serve if lvmpolld is used +# replace direct systemctl calls with systemd rpm macro once this is provided in the macro: +# http://cgit.freedesktop.org/systemd/systemd/commit/?id=57ab2eabb8f92fad5239c7d4492e9c6e23ee0678 +systemctl enable lvm2-lvmpolld.socket +systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : +%endif + +%preun +%systemd_preun blk-availability.service lvm2-monitor.service + +%if %{enable_lvmpolld} +%systemd_preun lvm2-lvmpolld.service lvm2-lvmpolld.socket +%endif + +%postun +%systemd_postun lvm2-monitor.service + +%if %{enable_lvmpolld} +%systemd_postun_with_restart lvm2-lvmpolld.service +%endif + +%triggerun -- %{name} < 2.02.86-2 +%{_bindir}/systemd-sysv-convert --save lvm2-monitor >/dev/null 2>&1 || : +/bin/systemctl --no-reload enable lvm2-monitor.service > /dev/null 2>&1 || : +/sbin/chkconfig --del lvm2-monitor > /dev/null 2>&1 || : +/bin/systemctl try-restart lvm2-monitor.service > /dev/null 2>&1 || : + +%files +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB +%doc README VERSION WHATS_NEW +%doc doc/lvm_fault_handling.txt + +# Main binaries +%defattr(555,root,root,-) +%{_sbindir}/fsadm +%{_sbindir}/lvm +%{_sbindir}/lvmconfig +%{_sbindir}/lvmdevices +%{_sbindir}/lvmdump +%if %{enable_lvmpolld} +%{_sbindir}/lvmpolld +%endif +%{_sbindir}/lvm_import_vdo + +# Other files +%defattr(444,root,root,-) +%{_sbindir}/lvchange +%{_sbindir}/lvconvert +%{_sbindir}/lvcreate +%{_sbindir}/lvdisplay +%{_sbindir}/lvextend +%{_sbindir}/lvmdiskscan +%{_sbindir}/lvmsadc +%{_sbindir}/lvmsar +%{_sbindir}/lvreduce +%{_sbindir}/lvremove +%{_sbindir}/lvrename +%{_sbindir}/lvresize +%{_sbindir}/lvs +%{_sbindir}/lvscan +%{_sbindir}/pvchange +%{_sbindir}/pvck +%{_sbindir}/pvcreate +%{_sbindir}/pvdisplay +%{_sbindir}/pvmove +%{_sbindir}/pvremove +%{_sbindir}/pvresize +%{_sbindir}/pvs +%{_sbindir}/pvscan +%{_sbindir}/vgcfgbackup +%{_sbindir}/vgcfgrestore +%{_sbindir}/vgchange +%{_sbindir}/vgck +%{_sbindir}/vgconvert +%{_sbindir}/vgcreate +%{_sbindir}/vgdisplay +%{_sbindir}/vgexport +%{_sbindir}/vgextend +%{_sbindir}/vgimport +%{_sbindir}/vgimportclone +%{_sbindir}/vgimportdevices +%{_sbindir}/vgmerge +%{_sbindir}/vgmknodes +%{_sbindir}/vgreduce +%{_sbindir}/vgremove +%{_sbindir}/vgrename +%{_sbindir}/vgs +%{_sbindir}/vgscan +%{_sbindir}/vgsplit +%{_mandir}/man5/lvm.conf.5.gz +%{_mandir}/man7/lvmautoactivation.7.gz +%{_mandir}/man7/lvmcache.7.gz +%{_mandir}/man7/lvmraid.7.gz +%{_mandir}/man7/lvmreport.7.gz +%{_mandir}/man7/lvmthin.7.gz +%{_mandir}/man7/lvmvdo.7.gz +%{_mandir}/man7/lvmsystemid.7.gz +%{_mandir}/man8/fsadm.8.gz +%{_mandir}/man8/lvchange.8.gz +%{_mandir}/man8/lvconvert.8.gz +%{_mandir}/man8/lvcreate.8.gz +%{_mandir}/man8/lvdisplay.8.gz +%{_mandir}/man8/lvextend.8.gz +%{_mandir}/man8/lvm.8.gz +%{_mandir}/man8/lvm2-activation-generator.8.gz +%{_mandir}/man8/lvm-config.8.gz +%{_mandir}/man8/lvmconfig.8.gz +%{_mandir}/man8/lvmdevices.8.gz +%{_mandir}/man8/lvm-dumpconfig.8.gz +%{_mandir}/man8/lvmdiskscan.8.gz +%{_mandir}/man8/lvmdump.8.gz +%{_mandir}/man8/lvm-fullreport.8.gz +%{_mandir}/man8/lvmsadc.8.gz +%{_mandir}/man8/lvmsar.8.gz +%{_mandir}/man8/lvreduce.8.gz +%{_mandir}/man8/lvremove.8.gz +%{_mandir}/man8/lvrename.8.gz +%{_mandir}/man8/lvresize.8.gz +%{_mandir}/man8/lvs.8.gz +%{_mandir}/man8/lvscan.8.gz +%{_mandir}/man8/pvchange.8.gz +%{_mandir}/man8/pvck.8.gz +%{_mandir}/man8/pvcreate.8.gz +%{_mandir}/man8/pvdisplay.8.gz +%{_mandir}/man8/pvmove.8.gz +%{_mandir}/man8/pvremove.8.gz +%{_mandir}/man8/pvresize.8.gz +%{_mandir}/man8/pvs.8.gz +%{_mandir}/man8/pvscan.8.gz +%{_mandir}/man8/vgcfgbackup.8.gz +%{_mandir}/man8/vgcfgrestore.8.gz +%{_mandir}/man8/vgchange.8.gz +%{_mandir}/man8/vgck.8.gz +%{_mandir}/man8/vgconvert.8.gz +%{_mandir}/man8/vgcreate.8.gz +%{_mandir}/man8/vgdisplay.8.gz +%{_mandir}/man8/vgexport.8.gz +%{_mandir}/man8/vgextend.8.gz +%{_mandir}/man8/lvm_import_vdo.8.gz +%{_mandir}/man8/vgimport.8.gz +%{_mandir}/man8/vgimportclone.8.gz +%{_mandir}/man8/vgimportdevices.8.gz +%{_mandir}/man8/vgmerge.8.gz +%{_mandir}/man8/vgmknodes.8.gz +%{_mandir}/man8/vgreduce.8.gz +%{_mandir}/man8/vgremove.8.gz +%{_mandir}/man8/vgrename.8.gz +%{_mandir}/man8/vgs.8.gz +%{_mandir}/man8/vgscan.8.gz +%{_mandir}/man8/vgsplit.8.gz +%{_udevdir}/11-dm-lvm.rules +%{_udevdir}/69-dm-lvm-metad.rules +%if %{enable_lvmpolld} +%{_mandir}/man8/lvmpolld.8.gz +%{_mandir}/man8/lvm-lvpoll.8.gz +%endif +%dir %{_sysconfdir}/lvm +%ghost %{_sysconfdir}/lvm/cache/.cache +%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf +%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvmlocal.conf +%dir %{_sysconfdir}/lvm/profile +%{_sysconfdir}/lvm/profile/command_profile_template.profile +%{_sysconfdir}/lvm/profile/metadata_profile_template.profile +%{_sysconfdir}/lvm/profile/thin-generic.profile +%{_sysconfdir}/lvm/profile/thin-performance.profile +%{_sysconfdir}/lvm/profile/cache-mq.profile +%{_sysconfdir}/lvm/profile/cache-smq.profile +%{_sysconfdir}/lvm/profile/lvmdbusd.profile +%{_sysconfdir}/lvm/profile/vdo-small.profile +%dir %{_sysconfdir}/lvm/backup +%dir %{_sysconfdir}/lvm/cache +%dir %{_sysconfdir}/lvm/archive +%dir %{_sysconfdir}/lvm/devices +%dir %{_default_locking_dir} +%dir %{_default_run_dir} +%{_tmpfilesdir}/%{name}.conf +%{_unitdir}/blk-availability.service +%{_unitdir}/lvm2-monitor.service +%{_unitdir}/lvm2-pvscan@.service +%attr(555, -, -) %{_prefix}/lib/systemd/system-generators/lvm2-activation-generator +%if %{enable_lvmpolld} +%{_unitdir}/lvm2-lvmpolld.socket +%{_unitdir}/lvm2-lvmpolld.service +%endif + +############################################################################## +# Library and Development subpackages +############################################################################## +%package devel +Summary: Development libraries and headers +License: LGPLv2 +Requires: %{name} = %{?epoch}:%{version}-%{release} +Requires: device-mapper-devel = %{?epoch}:%{device_mapper_version}-%{release} +Requires: device-mapper-event-devel = %{?epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description devel +This package contains files needed to develop applications that use +the lvm2 libraries. + +%files devel +%defattr(444,root,root,-) +%{_libdir}/liblvm2cmd.so +%{_libdir}/libdevmapper-event-lvm2.so +%{_includedir}/lvm2cmd.h + +%package libs +Summary: Shared libraries for lvm2 +License: LGPLv2 +Requires: device-mapper-event = %{?epoch}:%{device_mapper_version}-%{release} + +%description libs +This package contains shared lvm2 libraries for applications. + +%ldconfig_scriptlets libs + +%files libs +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%defattr(555,root,root,-) +%{_libdir}/liblvm2cmd.so.* +%{_libdir}/libdevmapper-event-lvm2.so.* +%dir %{_libdir}/device-mapper +%{_libdir}/device-mapper/libdevmapper-event-lvm2mirror.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2snapshot.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2raid.so +%{_libdir}/libdevmapper-event-lvm2mirror.so +%{_libdir}/libdevmapper-event-lvm2snapshot.so +%{_libdir}/libdevmapper-event-lvm2raid.so + +%if %{enable_thin} +%{_libdir}/libdevmapper-event-lvm2thin.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2thin.so +%endif + +%{_libdir}/libdevmapper-event-lvm2vdo.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2vdo.so + +############################################################################## +# LVM locking daemon +############################################################################## +%if %{enable_lockd_dlm} || %{enable_lockd_sanlock} +%package lockd +Summary: LVM locking daemon +Requires: lvm2 = %{?epoch}:%{version}-%{release} +%if %{enable_lockd_sanlock} +Requires: sanlock-lib >= %{sanlock_version} +%endif +%if %{enable_lockd_dlm} +Requires: dlm-lib >= %{dlm_version} +%endif +Requires(post): systemd-units >= %{systemd_version} +Requires(preun): systemd-units >= %{systemd_version} +Requires(postun): systemd-units >= %{systemd_version} + +%description lockd + +LVM commands use lvmlockd to coordinate access to shared storage. + +%post lockd +%systemd_post lvmlockd.service + +%preun lockd +%systemd_preun lvmlockd.service + +%postun lockd +%systemd_postun lvmlockd.service + +%files lockd +%defattr(444,root,root,-) +%%attr(555, -, -) %{_sbindir}/lvmlockd +%%attr(555, -, -) %{_sbindir}/lvmlockctl +%{_mandir}/man8/lvmlockd.8.gz +%{_mandir}/man8/lvmlockctl.8.gz +%{_unitdir}/lvmlockd.service +%{_unitdir}/lvmlocks.service + +%endif + +############################################################################### +# Cluster mirror subpackage +# The 'clvm' OCF script to manage cmirrord instance is part of resource-agents. +############################################################################### +%if %{enable_cluster} +%if %{enable_cmirror} + +%package -n cmirror +Summary: Daemon for device-mapper-based clustered mirrors +Requires: corosync >= %{corosync_version} +Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} +Requires: resource-agents >= %{resource_agents_version} + +%description -n cmirror +Daemon providing device-mapper-based mirrors in a shared-storage cluster. + +%files -n cmirror +%defattr(555,root,root,-) +%{_sbindir}/cmirrord +%attr(444, -, -) %{_mandir}/man8/cmirrord.8.gz + +############################################################################## +# Cmirror-standalone subpackage +############################################################################## +%package -n cmirror-standalone +Summary: Additional files to support device-mapper-based clustered mirrors in standalone mode +License: GPLv2 +Requires: cmirror >= %{?epoch}:%{version}-%{release} + +%description -n cmirror-standalone + +Additional files needed to run daemon for device-mapper-based clustered +mirrors in standalone mode as a service without cluster resource manager +involvement (e.g. pacemaker). + +%post -n cmirror-standalone +%systemd_post lvm2-cmirrord.service + +%preun -n cmirror-standalone +%systemd_preun lvm2-cmirrord.service + +%postun -n cmirror-standalone +%systemd_postun lvm2-cmirrord.service + +%files -n cmirror-standalone +%defattr(444,root,root,-) +%{_unitdir}/lvm2-cmirrord.service + +%endif +%endif + +############################################################################## +# LVM D-Bus daemon +############################################################################## +%if %{enable_lvmdbusd} + +%package dbusd +Summary: LVM2 D-Bus daemon +License: GPLv2 +BuildArch: noarch +Requires: lvm2 >= %{?epoch}:%{version}-%{release} +Requires: dbus +Requires: python3-dbus +Requires: python3-pyudev +Requires: python3-gobject-base +Requires(post): systemd-units >= %{systemd_version} +Requires(preun): systemd-units >= %{systemd_version} +Requires(postun): systemd-units >= %{systemd_version} + +%description dbusd + +Daemon for access to LVM2 functionality through a D-Bus interface. + +%post dbusd +%systemd_post lvm2-lvmdbusd.service + +%preun dbusd +%systemd_preun lvm2-lvmdbusd.service + +%postun dbusd +%systemd_postun lvm2-lvmdbusd.service + +%files dbusd +%defattr(555,root,root,-) +%{_sbindir}/lvmdbusd +%defattr(444,root,root,-) +%{_sysconfdir}/dbus-1/system.d/com.redhat.lvmdbus1.conf +%{_datadir}/dbus-1/system-services/com.redhat.lvmdbus1.service +%{_mandir}/man8/lvmdbusd.8.gz +%{_unitdir}/lvm2-lvmdbusd.service +%{python3_sitelib}/lvmdbusd/* + +%endif + +############################################################################## +# Device-mapper subpackages +############################################################################## +%package -n device-mapper +Summary: Device mapper utility +Version: %{device_mapper_version} +License: GPLv2 +URL: http://sources.redhat.com/dm +Requires: device-mapper-libs = %{?epoch}:%{device_mapper_version}-%{release} +Requires: util-linux >= %{util_linux_version} +Requires: systemd >= %{systemd_version} +# We need dracut to install required udev rules if udev_sync +# feature is turned on so we don't lose required notifications. +Conflicts: dracut < %{dracut_version} + +%description -n device-mapper +This package contains the supporting userspace utility, dmsetup, +for the kernel device-mapper. + +%files -n device-mapper +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB +%doc WHATS_NEW_DM VERSION_DM README +%doc udev/12-dm-permissions.rules +%defattr(444,root,root,-) +%attr(555, -, -) %{_sbindir}/dmsetup +%attr(555, -, -) %{_sbindir}/blkdeactivate +%attr(555, -, -) %{_sbindir}/dmstats +%{_mandir}/man8/dmsetup.8.gz +%{_mandir}/man8/dmstats.8.gz +%{_mandir}/man8/blkdeactivate.8.gz +%if %{enable_dmfilemapd} +%attr(555, -, -) %{_sbindir}/dmfilemapd +%{_mandir}/man8/dmfilemapd.8.gz +%endif +%{_udevdir}/10-dm.rules +%{_udevdir}/13-dm-disk.rules +%{_udevdir}/95-dm-notify.rules + +%package -n device-mapper-devel +Summary: Development libraries and headers for device-mapper +Version: %{device_mapper_version} +License: LGPLv2 +Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description -n device-mapper-devel +This package contains files needed to develop applications that use +the device-mapper libraries. + +%files -n device-mapper-devel +%defattr(444,root,root,-) +%{_libdir}/libdevmapper.so +%{_includedir}/libdevmapper.h +%{_libdir}/pkgconfig/devmapper.pc + +%package -n device-mapper-libs +Summary: Device-mapper shared library +Version: %{device_mapper_version} +License: LGPLv2 +Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} + +%description -n device-mapper-libs +This package contains the device-mapper shared library, libdevmapper. + +%ldconfig_scriptlets -n device-mapper-libs + +%files -n device-mapper-libs +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB +%defattr(555,root,root,-) +%{_libdir}/libdevmapper.so.* + +%package -n device-mapper-event +Summary: Device-mapper event daemon +Version: %{device_mapper_version} +Requires: device-mapper = %{?epoch}:%{device_mapper_version}-%{release} +Requires: device-mapper-event-libs = %{?epoch}:%{device_mapper_version}-%{release} +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +%description -n device-mapper-event +This package contains the dmeventd daemon for monitoring the state +of device-mapper devices. + +%post -n device-mapper-event +%systemd_post dm-event.socket +# dm-event.socket is always enabled and started and ready to serve if dmeventd is used +# replace direct systemctl calls with systemd rpm macro once this is provided in the macro: +# http://cgit.freedesktop.org/systemd/systemd/commit/?id=57ab2eabb8f92fad5239c7d4492e9c6e23ee0678 +systemctl enable dm-event.socket +systemctl start dm-event.socket >/dev/null 2>&1 || : +if [ -e %{_default_pid_dir}/dmeventd.pid ]; then + %{_sbindir}/dmeventd -R || echo "Failed to restart dmeventd daemon. Please, try manual restart." +fi + +%preun -n device-mapper-event +%systemd_preun dm-event.service dm-event.socket + +%files -n device-mapper-event +%defattr(444,root,root,-) +%attr(555, -, -) %{_sbindir}/dmeventd +%{_mandir}/man8/dmeventd.8.gz +%{_unitdir}/dm-event.socket +%{_unitdir}/dm-event.service + +%package -n device-mapper-event-libs +Summary: Device-mapper event daemon shared library +Version: %{device_mapper_version} +License: LGPLv2 + +%description -n device-mapper-event-libs +This package contains the device-mapper event daemon shared library, +libdevmapper-event. + +%ldconfig_scriptlets -n device-mapper-event-libs + +%files -n device-mapper-event-libs +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%defattr(555,root,root,-) +%{_libdir}/libdevmapper-event.so.* + +%package -n device-mapper-event-devel +Summary: Development libraries and headers for the device-mapper event daemon +Version: %{device_mapper_version} +License: LGPLv2 +Requires: device-mapper-event = %{?epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description -n device-mapper-event-devel +This package contains files needed to develop applications that use +the device-mapper event library. + +%files -n device-mapper-event-devel +%defattr(444,root,root,-) +%{_libdir}/libdevmapper-event.so +%{_includedir}/libdevmapper-event.h +%{_libdir}/pkgconfig/devmapper-event.pc + +############################################################################## +# Testsuite +############################################################################## +%if %{enable_testsuite} +%package testsuite +Summary: LVM2 Testsuite +# Most of the code is GPLv2, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPLv2... +License: LGPLv2 and GPLv2 and BSD-2-Clause + +%description testsuite +An extensive functional testsuite for LVM2. + +%files testsuite +%license COPYING COPYING.LIB COPYING.BSD +%{_datadir}/lvm2-testsuite/ +%{_libexecdir}/lvm2-testsuite/ +%{_bindir}/lvm2-testsuite +%endif + +%changelog +* Fri Mar 29 2024 MSVSphere Packaging Team - 9:2.03.14-14 +- Rebuilt for MSVSphere 8.10 beta + +* Fri Feb 02 2024 Marian Csontos - 2.03.14-14 +- Fix multisegment RAID1 allocator using one disk for both legs. +- Fix lvconvert -m 0 taking rimage_0 even if it is out of sync. +- Add warning message when mirror images have (r)efresh bit set. +- Document lv_attr volume type bit (g) for raid+integrity in lvs(8). + +* Mon Sep 18 2023 Marian Csontos - 2.03.14-13.el8_9 +- Fix error paths in lvm_import_vdo.sh. + +* Thu Sep 07 2023 Marian Csontos - 2.03.14-12 +- Fix handling of devices with symlinks in lvm_import_vdo.sh. + +* Thu Jul 27 2023 Marian Csontos - 2.03.14-11 +- Fix verbose option in lvm_import_vdo.sh. + +* Thu Jul 13 2023 Marian Csontos - 2.03.14-10 +- Improve VDO support. + +* Thu Dec 08 2022 Marian Csontos - 2.03.14-9 +- Fix handling of invalid values passed to vdo_block_map_era_length. + +* Thu Dec 08 2022 Marian Csontos - 2.03.14-8 +- Fix [vdo_]use_compression options. +- Fix vgimportdevices operating on incomplete VGs fails when nothing to import. +- Fix message processing on thin-pool extension leaving devices behind. + +* Mon Nov 28 2022 Marian Csontos - 2.03.14-7 +- Fix lvm crash when recreating PV with UUID of a missing PV. +- Fix lvconvert --type vdo-pool with --test should not write signature. +- Use correect profile in lvmdbusd preventing messages in JSON output. + +* Fri Jul 29 2022 Marian Csontos - 2.03.14-6 +- Fix effect of setting multipath_component_detection to 0. + +* Thu Jul 14 2022 Marian Csontos - 2.03.14-5 +- Exit with error when --devicesfile used does not exist. + +* Wed Jun 15 2022 Marian Csontos - 2.03.14-4 +- Additional important fixes from upstream up to commit 3b0f9ce. + +* Tue Jan 04 2022 Marian Csontos - 2.03.14-3 +- Fix devices file and autoactivation related issues. + +* Fri Dec 17 2021 Marian Csontos - 2.03.14-2 +- Revert autoactivation changes. + +* Wed Oct 20 2021 Marian Csontos - 2.03.14-1 +- Update to upstream version 2.03.14. +- See WHATS_NEW for list of changes. + +* Mon Sep 20 2021 Marian Csontos - 2.03.12-10 +- Fix incorrect memory free. + +* Fri Sep 17 2021 Marian Csontos - 2.03.12-9 +- Fix various lvm_import_vdo issues. +- Fix conversion to vdo when virtual size is above 2TiB. + +* Thu Aug 26 2021 Marian Csontos - 2.03.12-8 +- Rename vdoimport to lvm_import_vdo. + +* Wed Aug 11 2021 Marian Csontos - 2.03.12-7 +- Fix missing executable flag on vdoimport. + +* Tue Aug 03 2021 Marian Csontos - 2.03.12-6 +- Fix handling of pmspare by vgsplit, vgmerge and vgremove. +- Fix detection of active components of external origin volume. + +* Tue Jul 13 2021 Marian Csontos - 2.03.12-5 +- Fix device_id handling of scsi_debug WWID. +- Add vdoimport support. + +* Tue Jun 22 2021 Marian Csontos - 2.03.12-4 +- Fix conversion of writecache LVs to thin pool data volume. +- Add deviceidtype option for lvmdevices. + +* Tue Jun 15 2021 Marian Csontos - 2.03.12-3 +- Allow extending thin-pool data with writecache on top. +- Fix removing thin-pool data converted to writeache. + +* Tue Jun 01 2021 Marian Csontos - 2.03.12-2 +- Fix loading of VDO kernel module. + +* Wed May 19 2021 Marian Csontos - 2.03.12-1 +- Update to upstream version 2.03.12. +- See WHATS_NEW for list of changes. + +* Thu Feb 11 2021 Marian Csontos - 2.03.11-4 +- Fix "Failed to get primary device" for NVMe devices. + +* Wed Feb 03 2021 Marian Csontos - 2.03.11-3 +- Fix mpath filtering of NVMe devices. +- Check if lvcreate passes read_only_volume_list with tags and skips zeroing. +- Limit pool metadata spare to 16GiB. +- Improves conversion and allocation of pool metadata. +- Fix different limits used for metadata by lvm2 and thin-tools. +- Fix interrupting lvconvert --splitcache command with striped origin volumes. + +* Thu Jan 28 2021 Marian Csontos - 2.03.11-2 +- Fix problem with wiping of converted LVs. +- Fix memleak in scanning. +- Fix corner case allocation for thin-pools. + +* Fri Jan 08 2021 Marian Csontos - 2.03.11-1 +- Fix pvck handling MDA at offset different from 4096. +- Partial or degraded activation of writecache is not allowed. +- Enhance error handling in fsadm and handle correct fsck result. +- Dmeventd lvm plugin ignores higher reserved_stack lvm.conf values. +- Support using BLKZEROOUT for clearing devices. +- Fixed interrup handling. +- Fix block cache when device has too many failing writes. +- Fix block cache waiting for IO completion with failing disks. +- Add configure --enable-editline support as an alternative to readline. +- Enhance reporting and error handling when creating thin volumes. +- Enable vgsplit for VDO volumes. +- Lvextend of vdo pool volumes ensure at least 1 new VDO slab is added. +- Restore lost signal blocking while VG lock is held. +- Improve estimation of needed extents when creating thin-pool. +- Use extra 1% when resizing thin-pool metadata LV with --use-policy. +- Enhance --use-policy percentage rounding. +- Allow pvmove of writecache origin. +- Report integrity fields. +- Integrity volumes defaults to journal mode. + +* Wed Aug 12 2020 Marian Csontos - 2.03.09-5 +- Revert wipe_lv changes. + +* Sun Aug 09 2020 Marian Csontos - 2.03.09-4 +- Merge fixes from upstream. + +* Mon Jun 29 2020 Marian Csontos - 2.03.09-3 +- Merge fixes from upstream. + +* Thu May 21 2020 Marian Csontos - 2.03.09-2 +- Merge fixes from upstream. + +* Fri Apr 24 2020 Marian Csontos - 2.03.09-1 +- Fix support for lvconvert --repair of pools used by third party applications. +- Fix formating of vdopool (vdo_slab_size_mb was smaller by 2 bits). +- Fix busy loop in dmeventd. +- Fix lvmlocks.service using incorrect option. + +* Wed Mar 18 2020 Marian Csontos - 2.03.08-3 +- Attaching writecache require inactive LV. + +* Mon Feb 24 2020 Marian Csontos - 2.03.08-2 +- Writecache bug fixes. + +* Tue Feb 11 2020 Marian Csontos - 2.03.08-1 +- VDO and writecache volume improvements. +- Prohibit reshaping of stacked raid LVs to prevent corruption. + +* Fri Feb 07 2020 Marian Csontos - 2.03.07-2 +- VDO: Adapt for changed vdo_format output. + +* Sat Nov 30 2019 Marian Csontos - 2.03.07-1 +- Ensure minimum required region size on striped RaidLV creation. +- Fix resize of thin-pool with data and metadata of different segtype. +- Improve mirror type leg splitting. +- Fix activation order when removing merged snapshot. +- Experimental VDO support for lvmdbusd. +- Correctly set read_ahead for LVs when pvmove is finished. +- Add support for DM_DEVICE_GET_TARGET_VERSION into device_mapper. +- Activate thin-pool layered volume as 'read-only' device. +- Ignore crypto devices with UUID signature CRYPT-SUBDEV. +- Synchronize with udev when dropping snapshot. +- Add missing device synchronization point before removing pvmove node. +- See WHATS_NEW for more. + +* Wed Sep 25 2019 Marian Csontos - 2.03.05-5 +- Fix lvmlockd is not started with sanlock running. + +* Sun Aug 18 2019 Marian Csontos - 2.03.05-4 +- Update tests. + +* Sun Aug 18 2019 Marian Csontos - 2.03.05-3 +- Remove unsupported OPTIONS+="event_timeout" udev rule from 11-dm-lvm.rules. +- Prevent creating VGs with PVs with different logical block sizes. +- Fix metadata writes from corrupting with large physical block size. + +* Wed Jul 24 2019 Marian Csontos - 2.03.05-2 +- Fix scanning of PVs with size not matching device. +- Allow --stripe/--stripesize in mirror conversions. + +* Sat Jun 15 2019 Marian Csontos - 2.03.05-1 +- Update to upstream release 2.03.05. + +* Mon Jun 10 2019 Marian Csontos - 2.03.04-1 +- Update to upstream release 2.03.04. + +* Fri Feb 22 2019 Marian Csontos - 2.03.02-6 + +* Thu Feb 07 2019 Marian Csontos - 2.03.02-5 +- Improve -lXXX%VG modifier which improves cache segment estimation. + +* Thu Feb 07 2019 Marian Csontos - 2.03.02-4 +- Introduce LVM_SUPPRESS_SYSLOG to suppress syslog usage by generator. +- Fix generator querying config options missing from lvm.conf. + +* Mon Jan 28 2019 Marian Csontos - 2.03.02-3 +- Fix handling of exported VGs lvmdbusd. +- Restore missing man info lvcreate --zero for thin-pools. +- Drop misleadning comment for metadata minimum_io_size for VDO segment. +- Ensure migration_threshold for cache is at least 8 chunks. + +* Fri Jan 04 2019 Marian Csontos - 2.03.02-2 +- Fix dmeventd linking issues related to vdo. +- Fix vdo status parsing. + +* Tue Dec 18 2018 Marian Csontos - 2.03.02-1 +- Fix libdevmapper-event linking issue. +- Fix missing proper initialization of pv_list struct when adding pv. +- Fix (de)activation of RaidLVs with visible SubLVs. +- Prohibit mirrored 'mirror' log via lvcreate and lvconvert. +- Use sync io if async io_setup fails, or use_aio=0 is set in config. +- Fix more issues reported by coverity scan. + +* Thu Nov 01 2018 Marian Csontos - 2.03.01-1 +- Fix possible write beyond metadata area. +- Fix coverity issues. + +* Thu Oct 11 2018 Marian Csontos - 2.03.00-0.4 +- Fix architecture of lvm2-dbusd subpackage. + +* Thu Oct 11 2018 Marian Csontos - 2.03.00-0.3 +- Fix configure file issues. + +* Wed Oct 10 2018 Marian Csontos - 2.03.00-0.2 +- New upstream release. +- Deduplication and compression - support for VDO volumes. +- Dropped lvmetad, clvmd and liblvm2app. + +* Thu Aug 02 2018 Marian Csontos - 2.02.181-1 +- Reject conversions on raid1 LVs with split tracked SubLVs. +- Reject conversions on raid1 split tracked SubLVs. +- Fix dmstats list failing when no regions exist. +- Reject conversions of LVs under snapshot. +- Limit suggested options on incorrect option for lvconvert subcommand. +- Add vdo plugin for monitoring VDO devices. + +* Thu Jul 19 2018 Marian Csontos - 2.02.180-1 +- Never send any discard ioctl with test mode. +- Fix thin-pool alloc which needs same PV for data and metadata. +- Enhance vgcfgrestore to check for active LVs in restored VG. +- Provide possible layouts when converting between linear and striped/raid. +- Fix unmonitoring of merging snapshots. +- Cache can uses metadata format 2 with cleaner policy. +- Avoid showing internal error in lvs output or pvmoved LVs. +- Fix check if resized PV can also fit metadata area. +- Reopen devices RDWR only before writing to avoid udev issues. +- Change pvresize output confusing when no resize took place. +- Fix lvmetad hanging on shutdown. +- Fix mem leak in clvmd and more coverity issues. + +* Tue Jul 10 2018 Marian Csontos - 2.02.179-4 +- Remove deprecated python bindings. + +* Tue Jul 03 2018 Tomas Orsava - 2.02.179-3 +- Switch hardcoded python3 path into the %%{__python3} macro +- Patch is needed for the configure file because it mistakenly unsets the user + defined variable PYTHON before checking it + +* Mon Jun 18 2018 Marian Csontos - 2.02.179-1 +- Bugfix release mainly fixing known cache and lvmlockd issues. +- Remove lvm1 and pool format handling and add filter to ignore them. +- Rework disk scanning and when it is used. +- Add new io layer using libaio for faster scanning. +- Support activation of component LVs in read-only mode. +- Avoid non-exclusive activation of exclusive segment types. +- Restore pvmove support for clusterwide active volumes (2.02.177). +- Add prioritized_section() to restore cookie boundaries (2.02.177). +- Again accept striped LV as COW LV with lvconvert -s (2.02.169). +- Restore usability of thin LV to be again external origin for another thin (2.02.169). +- See WHATS_NEW and WHATS_NEW_DM in the documentation directory for more. + +* Thu May 10 2018 Marian Csontos - 2.02.177-5 +- Remove python2 bindings. +- Remove lvm2-testsuite subpackage. + +* Fri Feb 09 2018 Igor Gnatenko - 2.02.177-4 +- Escape macros in %%changelog + +* Thu Feb 08 2018 Fedora Release Engineering - 2.02.177-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 09 2018 Iryna Shcherbina - 2.02.177-2 +- Update Python 2 dependency declarations to new packaging standards + (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) + +* Tue Dec 19 2017 Marian Csontos - 2.02.177-1 +- When writing text metadata content, use complete 4096 byte blocks. +- Change text format metadata alignment from 512 to 4096 bytes. +- When writing metadata, consistently skip mdas marked as failed. +- Refactor and adjust text format metadata alignment calculation. +- Fix python3 path in lvmdbusd to use value detected by configure. +- Reduce checks for active LVs in vgchange before background polling. +- Ensure _node_send_message always uses clean status of thin pool. +- Fix lvmlockd to use pool lock when accessing _tmeta volume. +- Report expected sanlock_convert errors only when retries fail. +- Avoid blocking in sanlock_convert on SH to EX lock conversion. +- Deactivate missing raid LV legs (_rimage_X-missing_Y_Z) on decativation. +- Skip read-modify-write when entire block is replaced. +- Categorise I/O with reason annotations in debug messages. +- Allow extending of raid LVs created with --nosync after a failed repair. +- Command will lock memory only when suspending volumes. +- Merge segments when pvmove is finished. +- Remove label_verify that has never been used. +- Ensure very large numbers used as arguments are not casted to lower values. +- Enhance reading and validation of options stripes and stripes_size. +- Fix printing of default stripe size when user is not using stripes. +- Activation code for pvmove automatically discovers holding LVs for resume. +- Make a pvmove LV locking holder. +- Do not change critical section counter on resume path without real resume. +- Enhance activation code to automatically suspend pvmove participants. +- Prevent conversion of thin volumes to snapshot origin when lvmlockd is used. +- Correct the steps to change lock type in lvmlockd man page. +- Retry lock acquisition on recognized sanlock errors. +- Fix lock manager error codes in lvmlockd. +- Remove unnecessary single read from lvmdiskscan. +- Check raid reshape flags in vg_validate(). +- Add support for pvmove of cache and snapshot origins. +- Avoid using precommitted metadata for suspending pvmove tree. +- Ehnance pvmove locking. +- Deactivate activated LVs on error path when pvmove activation fails. +- Add "io" to log/debug_classes for logging low-level I/O. +- Avoid importing persistent filter in vgscan/pvscan/vgrename. +- Fix memleak of string buffer when vgcfgbackup runs in secure mode. +- Do not print error when clvmd cannot find running clvmd. +- Prevent start of new merge of snapshot if origin is already being merged. +- Fix offered type for raid6_n_6 to raid5 conversion (raid5_n). +- Deactivate sub LVs when removing unused cache-pool. +- Do not take backup with suspended devices. +- Avoid RAID4 activation on incompatible kernels under all circumstances. +- Reject conversion request to striped/raid0 on 2-legged raid4/5. +- Activation tree of thin pool skips duplicated check of pool status. +- Remove code supporting replicator target. +- Do not ignore failure of _info_by_dev(). +- Propagate delayed resume for pvmove subvolumes. +- Suppress integrity encryption keys in 'table' output unless --showkeys supplied. + +* Thu Dec 14 2017 Marian Csontos - 2.02.176-2 +- Add testsuite subpackage. + +* Fri Nov 03 2017 Marian Csontos - 2.02.176-1 +- Fix segfault in lvm_pv_remove in liblvm. (2.02.173) +- Do not allow storing VG metadata with LV without any segment. +- Fix printed message when thin snapshot was already merged. +- Remove created spare LV when creation of thin-pool failed. +- Avoid reading ignored metadata when MDA gets used again. +- Fix detection of moved PVs in vgsplit. (2.02.175) +- Ignore --stripes/--stripesize on RAID takeover +- Disallow creation of snapshot of mirror/raid subLV (was never supported). +- Keep Install section only in *.socket systemd units. +- Improve used paths for generated systemd units and init shells. +- Fix regression in more advanced vgname extraction in lvconvert (2.02.169). +- Allow lvcreate to be used for caching of _tdata LV. +- Avoid internal error when resizing cache type _tdata LV (not yet supported). +- Show original converted names when lvconverting LV to pool volume. +- Move lib code used only by liblvm into metadata-liblvm.c. +- Distinguish between device not found and excluded by filter. +- Monitor external origin LVs. +- Allow lvcreate --type mirror to work with 100%%FREE. +- Improve selection of resource name for complex volume activation lock. +- Avoid cutting first character of resource name for activation lock. +- Support for encrypted devices in fsadm. +- Improve thin pool overprovisioning and repair warning messages. +- Fix incorrect adjustment of region size on striped RaidLVs. +- Issue a specific error with dmsetup status if device is unknown. +- Fix RT_LIBS reference in generated libdevmapper.pc for pkg-config. + +* Mon Oct 09 2017 Marian Csontos - 2.02.175-1 +- Use --help with blockdev when checking for --getsize64 support in fsadm. +- Dump lvmdbusd debug information with SIGUSR1. +- Fix metadata corruption in vgsplit and vgmerge intermediate states. +- Add PV_MOVED_VG PV status flag to mark PVs moving between VGs. +- Fix lvmdbus hang and recognise unknown VG correctly. +- Improve error messages when command rules fail. +- Require LV name with pvmove in a shared VG. +- Allow shared active mirror LVs with lvmlockd, dlm, and cmirrord. +- Support lvconvert --repair with cache and cachepool volumes. +- lvconvert --repair respects --poolmetadataspare option. +- Fix thin pool creation in a shared VG. (2.02.173) +- Schedule exit when received SIGTERM in dmeventd. +- Fix blkdeactivate regression with failing DM/MD devs deactivation (1.02.142). +- Add blkdeactivate -r wait option to wait for MD resync/recovery/reshape. +- Use blkdeactivate -r wait in blk-availability systemd service/initscript. +- Also try to unmount /boot on blkdeactivate -u if on top of supported device. +- Fix typo in blkdeactivate's '--{dm,lvm,mpath}options' option name. +- Correct return value testing when get reserved values for reporting. +- Take -S with dmsetup suspend/resume/clear/wipe_table/remove/deps/status/table. +- Fix mistakenly commented out %%python_provide line for python3-lvm. + +* Mon Oct 02 2017 Troy Dawson - 2.02.174-2 +- Bump to rebuild on rebuilt corosync +- Cleanup spec file conditionals + +* Wed Sep 20 2017 Marian Csontos - 2.02.174-1.f28 +- NOTE: Deprecating python bindings and liblvm2app. +- Prevent raid1 split with trackchanges in a shared VG. +- Avoid double unlocking of client & lockspace mutexes in lvmlockd. +- Fix leaking of file descriptor for non-blocking filebased locking. +- Fix check for 2nd mda at end of disk fits if using pvcreate --restorefile. +- Use maximum metadataarea size that fits with pvcreate --restorefile. +- Always clear cached bootloaderarea when wiping label e.g. in pvcreate. +- Disallow --bootloaderareasize with pvcreate --restorefile. +- Fix lvmlockd check for running lock managers during lock adoption. +- Add --withgeneralpreamble and --withlocalpreamble to lvmconfig. +- Add warning when creating thin-pool with zeroing and chunk size >= 512KiB. +- Introduce exit code 4 EINIT_FAILED to replace -1 when initialisation fails. +- Add synchronization points with udev during reshape of raid LVs. +- Restore umask when creation of node fails. +- Add --concise to dmsetup create for many devices with tables in one command. +- Accept minor number without major in library when it knows dm major number. +- Introduce single-line concise table output format: dmsetup table --concise. + +* Thu Aug 03 2017 Fedora Release Engineering - 2.02.173-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Sun Jul 30 2017 Florian Weimer - 2.02.173-3 +- Rebuild with binutils fix for ppc64le (#1475636) + +* Wed Jul 26 2017 Fedora Release Engineering - 2.02.173-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 25 2017 Marian Csontos - 2.02.173-1 +- Create /dev/disk/by-part{uuid,label} and gpt-auto-root symlinks with udev. +- Add synchronization points with udev during conversion of raid LVs. +- Improve --size args validation and report more detailed error message. +- Initialize debugging mutex before any debug message in clvmd. +- Log error instead of warn when noticing connection problem with lvmetad. +- Fix memory leak in lvmetad when working with duplicates. +- Remove restrictions on reshaping open and clustered raid devices. +- Add incompatible data_offset to raid metadata to fix reshape activation. +- Accept 'lvm -h' and 'lvm --help' as well as 'lvm help' for help. +- Suppress error message from accept() on clean lvmetad shutdown. +- Tidy clvmd client list processing and fix segfaults. +- Protect clvmd debug log messages with mutex and add client id. +- Fix shellcheck reported issues for script files. + +* Thu Jun 29 2017 Marian Csontos - 2.02.172-1 +- Do not lvdisplay --maps unset settings of cache pool. +- Fix lvdisplay --maps for cache pool without policy settings. +- Support aborting of flushing cache LV. +- Improve lvcreate --cachepool arg validation. +- Cache format2 flag is now using segment name type field. +- Disallow cachepool creation with policy cleaner and mode writeback. +- Lvconvert --repair handles failing raid legs (present but marked 'D'ead). +- Add display_percent helper function for printing percent values. +- Add dm_percent_to_round_float for adjusted percentage rounding. +- Fix lvcreate extent percentage calculation for mirrors. +- Reenable conversion of data and metadata thin-pool volumes to raid. +- Linear to RAID1 upconverts now use "recover" sync action, not "resync". +- No longer necessary to '--force' a repair for RAID1. +- Improve raid status reporting with lvs. +- dm_get_status_raid() handle better some incosistent md statuses. +- Limit maximal size of thin-pool for specific chunk size. +- Print a warning about in-use PVs with no VG using them. +- Disable automatic clearing of PVs that look like in-use orphans. +- Extend validation of filesystems resized by fsadm. +- Properly handle subshell return codes in fsadm. +- Stop using '--yes' mode when fsadm runs without terminal. +- Support storing status flags via segtype name field. +- Enhance lvconvert automatic settings of possible (raid) LV types. +- Add missing NULL to argv array when spliting cmdline arguments. +- Don't reinstate still-missing devices when correcting inconsistent metadata. +- Allow lvchange to change properties on a thin pool data sub LV. +- Fix reusing of dm_task structure for status reading (used by dmeventd). +- Drop unneeded --config option from raid dmeventd plugin. +- Accept truncated files in calls to dm_stats_update_regions_from_fd(). +- Restore Warning by 5% increment when thin-pool is over 80% (1.02.138). +- Reset array with dead rimage devices once raid gets in sync. + +* Fri Jun 09 2017 Marian Csontos - 2.02.171-3 +- Fix lvmdbusd not passing --all with vgreduce --removemissing. + +* Wed May 17 2017 Marian Csontos - 2.02.171-2 +- Fix lvmdbusd mangling config options. + +* Tue May 09 2017 Marian Csontos - 2.02.171-1 +- Add RAID takeover and reshaping. +- Add pvcreate prompt when device size doesn't match setphysicalvolumesize. +- Remove obsolete lvmchange binary - convert to built-in command. +- Support cache segment with configurable metadata format. +- Add option for lvcreate/lvconvert --cachemetadataformat auto|1|2. +- Add allocation/cache_metadata_format profilable settings. +- Command line options, help and man pages using common definitions. +- Add build-time configuration command line to 'lvm version' output. +- Disable lvmetad when lvconvert --repair is run. +- Raise mirror/raid default regionsize to 2MiB. +- Support shrinking of RaidLVs. +- Introduce global/fsadm_executable to make fsadm path configurable. +- Look for limited thin pool metadata size when using 16G metadata. +- Add lvconvert pool creation rule disallowing options with poolmetadata. +- Fix missing lvmlockd LV locks in lvchange and lvconvert. +- Fix dmeventd setup for lvchange --poll. +- Fix use of --poll and --monitor with lvchange and vgchange. +- Disallow lvconvert of hidden LV to a pool. +- Ignore --partial option when not used for activation. +- Allow --activationmode option with lvchange --refresh. +- Allow valid lvconvert --regionsize change +- Fix SIGINT blocking to prevent corrupted metadata +- Fix systemd unit existence check for lvmconf --services --startstopservices. +- Check and use PATH_MAX buffers when creating vgrename device paths. +- Handle known table line parameter order change in specific raid target vsns. +- Show more information for cached volumes in lvdisplay [-m]. +- Use function cache_set_params() for both lvcreate and lvconvert. +- Skip rounding on cache chunk size boudary when create cache LV. +- Improve cache_set_params support for chunk_size selection. +- Fix metadata profile allocation/cache_[mode|policy] setting. +- Fix missing support for using allocation/cache_pool_chunk_size setting. +- Support conversion of raid type, stripesize and number of disks +- Reject writemostly/writebehind in lvchange during resynchronization. +- Deactivate active origin first before removal for improved workflow. +- Fix regression of accepting both --type and -m with lvresize. (2.02.158) +- Add extra memory page when limiting pthread stack size in clvmd. +- Support striped/raid0* <-> raid10_near conversions. +- Support region size changes on existing RaidLVs. +- Avoid parallel usage of cpg_mcast_joined() in clvmd with corosync. +- Support raid6_{ls,rs,la,ra}_6 segment types and conversions from/to it. +- Support raid6_n_6 segment type and conversions from/to it. +- Support raid5_n segment type and conversions from/to it. +- Support new internal command _dmeventd_thin_command. +- Introduce new dmeventd/thin_command configurable setting. +- Use new default units 'r' for displaying sizes. +- Also unmount mount point on top of MD device if using blkdeactivate -u. +- Restore check preventing resize of cache type volumes (2.02.158). +- Add missing udev sync when flushing dirty cache content. +- vgchange -p accepts only uint32 numbers. +- Report thin LV date for merged LV when the merge is in progress. +- Detect if snapshot merge really started before polling for progress. +- Checking LV for merging origin requires also it has merged snapshot. +- Extend validation of metadata processing. +- Enable usage of cached volumes as snapshot origin LV. +- Fix displayed lv name when splitting snapshot (2.02.146). +- Warn about command not making metadata backup just once per command. +- Enable usage of cached volume as thin volume's external origin. +- Support cache volume activation with -real layer. +- Improve search of lock-holder for external origin and thin-pool. +- Support status checking of cache volume used in layer. +- Avoid shifting by one number of blocks when clearing dirty cache volume. +- Extend metadata validation of external origin LV use count. +- Fix dm table when the last user of active external origin is removed. +- Improve reported lvs status for active external origin volume. +- Fix table load for splitted RAID LV and require explicit activation. +- Always active splitted RAID LV exclusively locally. +- Do not use LV RAID status bit for segment status. +- Check segtype directly instead of checking RAID in segment status. +- Reusing exiting code for raid image removal. +- Fix pvmove leaving -pvmove0 error device in clustered VG. +- Avoid adding extra '_' at end of raid extracted images or metadata. +- Optimize another _rmeta clearing code. +- Fix deactivation of raid orphan devices for clustered VG. +- Fix lvconvert raid1 to mirror table reload order. +- Add internal function for separate mirror log preparation. +- Fix segfault in lvmetad from missing NULL in daemon_reply_simple. +- Simplify internal _info_run() and use _setup_task_run() for mknod. +- Better API for internal function _setup_task_run. +- Avoid using lv_has_target_type() call within lv_info_with_seg_status. +- Simplify internal lv_info_with_seg_status API. +- Decide which status is needed in one place for lv_info_with_seg_status. +- Fix matching of LV segment when checking for it info status. +- Report log_warn when status cannot be parsed. +- Test segment type before accessing segment members when checking status. +- Implement compatible target function for stripe segment. +- Use status info to report merge failed and snapshot invalid lvs fields. +- See WHATS_NEW and WHATS_NEW_DM in the documentation directory for more. + +* Fri Feb 10 2017 Fedora Release Engineering - 2.02.168-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Igor Gnatenko - 2.02.168-3 +- Rebuild for readline 7.x + +* Mon Dec 19 2016 Miro Hrončok - 2.02.168-2 +- Rebuild for Python 3.6 + +* Thu Dec 01 2016 Peter Rajnoha - 2.02.168-1 +- Display correct sync_percent on large RaidLVs +- lvmdbusd --blackboxsize added, used to override default size of 16 +- Allow a transiently failed RaidLV to be refreshed +- Use lv_update_and_reload() inside mirror code where it applies. +- Preserve mirrored status for temporary layered mirrors. +- Use transient raid check before repairing raid volume. +- Implement transient status check for raid volumes. +- Only log msg as debug if lvm2-lvmdbusd unit missing for D-Bus notification. +- Avoid duplicated underscore in name of extracted LV image. +- Missing stripe filler now could be also 'zero'. +- lvconvert --repair accepts --interval and --background option. +- More efficiently prepare _rmeta devices when creating a new raid LV. +- Document raid status values. +- Always exit dmsetup with success when asked to display help/version. + +* Tue Nov 15 2016 Peter Rajnoha - 2.02.167-2 +- Only log msg as debug if lvm2-lvmdbusd unit missing for D-Bus notification. + +* Mon Nov 07 2016 Peter Rajnoha - 2.02.167-1 +- Use log_error in regex and sysfs filter to describe reason of failure. +- Fix blkdeactivate to deactivate dev stack if dev on top already unmounted. +- Prevent non-synced raid1 repair unless --force +- Prevent raid4 creation/conversion on non-supporting kernels +- Add direct striped -> raid4 conversion +- Fix raid4 parity image pair position on conversions from striped/raid0* +- Fix a few unconverted return code values for some lvconvert error path. +- Disable lvconvert of thin pool to raid while active. +- Disable systemd service start rate limiting for lvm2-pvscan@.service. +- Log failure of raid device with log_error level. +- Use dm_log_with_errno and translate runtime to dm_log only when needed. +- Make log messages from dm and lvm library different from dmeventd. +- Notice and Info messages are again logged from dmeventd and its plugins. +- Dmeventd now also respects DM_ABORT_ON_INTERNAL_ERRORS as libdm based tool. +- Report as non default dm logging also when logging with errno was changed. +- Use log_level() macro to consistently decode message log level in dmeventd. +- Still produce output when dmsetup dependency tree building finds dev missing. +- Check and report pthread_sigmask() failure in dmeventd. +- Check mem alloc fail in _canonicalize_field_ids(). +- Use unsigned math when checking more then 31 legs of raid. +- Fix 'dmstats delete' with dmsetup older than v1.02.129 +- Fix stats walk segfault with dmsetup older than v1.02.129 + +* Thu Oct 06 2016 Peter Rajnoha - 2.02.166-2 +- Add various fixes for lvmdbusd from upcoming lvm2 version 2.02.167. + +* Mon Sep 26 2016 Peter Rajnoha - 2.02.166-1 +- Fix lvm2-activation-generator to read all LVM2 config sources. (2.02.155) +- Fix lvchange-rebuild-raid.sh to cope with older target versions. +- Use dm_config_parse_without_dup_node_check() to speedup metadata reading. +- Fix lvconvert --repair regression +- Fix reported origin lv field for cache volumes. (2.02.133) +- Always specify snapshot cow LV for monitoring not internal LV. (2.02.165) +- Fix lvchange --discard|--zero for active thin-pool. +- Enforce 4MiB or 25% metadata free space for thin pool operations. +- Fix lock-holder device for thin pool with inactive thin volumes. +- Use --alloc normal for mirror logs even if the mimages were stricter. +- Use O_DIRECT to gather metadata in lvmdump. +- Ignore creation_time when checking for matching metadata for lvmetad. +- Fix possible NULL pointer derefence when checking for monitoring. +- Add lvmreport(7) man page. +- Don't install lvmraid(7) man page when raid excluded. (2.02.165) +- Report 0% as dirty (copy%%) for cache without any used block. +- Fix lvm2api reporting of cache data and metadata percent. +- Restore reporting of metadata usage for cache volumes (2.02.155). +- Support raid scrubbing on cache origin LV. +- Fix man entry for dmsetup status. +- Introduce new dm_config_parse_without_dup_node_check(). +- Don't omit last entry in dmstats list --group. + +* Wed Sep 07 2016 Peter Rajnoha - 2.02.165-1 +- Add lvmraid(7) man page. +- Use udev db to check for mpath components before running pvscan for lvmetad. +- Use lsblk -s and lsblk -O in lvmdump only if these options are supported. +- Fix number of stripes shown in lvcreate raid10 message when too many. +- Change lvmdbusd to use new lvm shell facilities. +- Do not monitor cache-pool metadata when LV is just being cleared. +- Add allocation/cache_pool_max_chunks to prevent misuse of cache target. +- Give error not segfault in lvconvert --splitmirrors when PV lies outside LV. +- Fix typo in report/columns_as_rows config option name recognition (2.02.99). +- Avoid PV tags when checking allocation against parallel PVs. +- Disallow mirror conversions of raid10 volumes. +- Fix dmeventd unmonitoring when segment type (and dso) changes. +- Don't allow lvconvert --repair on raid0 devices or attempt to monitor them. +- No longer adjust incorrect number of raid stripes supplied to lvcreate. +- Move lcm and gcd to lib/misc. +- Fix vgsplit of external origins. (2.02.162) +- Prohibit creation of RAID LVs unless VG extent size is at least the page size. +- Suppress some unnecessary --stripesize parameter warnings. +- Fix 'pvmove -n name ...' to prohibit collocation of RAID SubLVs +- Improve explanation of udev fallback in libdevmapper.h. + +* Mon Aug 15 2016 Peter Rajnoha - 2.02.164-2 +- Fix selection of PVs when allocating raid0_meta. +- Fix sdbus socket leak leading to hang in lvmnotify. +- Specify max stripes for raid LV types: raid0:64; 1:10; 4,5:63; 6:62; 10:32. +- Avoid double suffix when naming _rmeta LV paired with _rimage LV. + +* Wed Aug 10 2016 Peter Rajnoha - 2.02.163-1 +- Add profile for lvmdbusd which uses lvm shell json report output. +- Restrict in-command modification of some parms in lvm shell. +- Apply LVM_COMMAND_PROFILE early for lvm shell. +- Refactor reporting so lvm shell log report collects whole of cmd execution. +- Support LVM_*_FD envvars to redirect output to file descriptors. +- Limit use of --corelog and --mirrorlog to mirrors in lvconvert. +- Reject --nosync option for RAID6 LVs in lvcreate. +- Do not refresh whole cmd context if profile dropped after processing LVM cmd. +- Support straightforward lvconvert between striped and raid4 LVs. +- Support straightforward lvconvert between raid1 and mirror LVs. +- Report supported conversions when asked for unsupported raid lvconvert. +- Add "--rebuild PV" option to lvchange to allow for PV selective rebuilds. +- Preserve existing mirror region size when using --repair. +- Forbid stripe parameters with lvconvert --repair. +- Unify stripe size validation into get_stripe_params to catch missing cases. +- Further lvconvert validation logic refactoring. +- Add "lvm fullreport" man page. +- Add dm_report_destroy_rows/dm_report_group_output_and_pop_all for lvm shell. +- Adjust group handling and json production for lvm shell. + +* Fri Jul 29 2016 Peter Rajnoha - 2.02.162-1 +- Support lvconvert -Zn also when doing full cache pool conversion. +- Suppress not zeroing warn when converting to thin LV for non-zeroing tpool. +- Fix automatic updates of PV extension headers to newest version. +- Improve lvconvert --trackchanges validation to require --splitmirrors 1. +- Add note about lastlog built-in command to lvm man page. +- Fix unrecognised segtype flag message. +- lvconvert not clears cache pool metadata ONLY with -Zn. +- Enabled lvconvert --uncache to work with partial VG. +- Fix json reporting to escape '"' character that may appear in reported string. + +* Thu Jul 21 2016 Peter Rajnoha - 2.02.161-3 +- Enable LVM notifications over dbus for lvmdbusd. + +* Tue Jul 19 2016 Fedora Release Engineering - 2.02.161-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Mon Jul 18 2016 Peter Rajnoha - 2.02.161-1 +- Prohibit some lvchange/lvresize that were failing on raid0 volumes. +- Fix segfaults in complex vgsplits. (2.02.159) +- Reformat unwieldy lvconvert man page. +- Allow --force to be passed through to pvcreate from vgcreate. (2.02.144) +- Fix lvresize of filesystem when LV has already right size (2.02.141) +- New LVM_LOG_FILE_MAX_LINES env var to limit max size of created logs. +- Disable queueing on mpath devs in blk-availability systemd service/initscript. +- Add new -m|--mpathoption disablequeueing to blkdeactivate. +- Automatically group regions with 'create --segments' unless --nogroup. +- Fix resource leak when deleting the first member of a group. +- Allow --bounds with 'create --filemap' for dmstats. +- Enable creation of filemap regions with histograms. +- Enable histogram aggregation for regions with more than one area. +- Enable histogram aggregation for groups of regions. +- Add a --filemap option to 'dmstats create' to allow mapping of files. +- Add dm_stats_create_regions_from_fd() to map file extents to regions. + +* Thu Jul 07 2016 Peter Rajnoha - 2.02.160-1 +- Minor fixes from coverity. + +* Thu Jul 07 2016 Peter Rajnoha - 2.02.159-1 +- Add raid0_meta segment type that provides metadata space for raid conversions. +- Fix created link for a used pool for vgmknode. +- Introduce and use is_power_of_2 macro. +- Support conversions between striped and raid0 segment types. +- Add infrastructure for raid takeover lvconvert options. +- Update default dmstats field selections for groups. +- Add 'obj_type', 'group_id', and 'statsname' fields to dmstats reports. +- Add --area, --region, and --group to dmstats to control object selection. +- Add --alias, --groupid, --regions to dmstats for group creation and deletion. +- Add 'group' and 'ungroup' commands to dmstats. +- Allow dm_stats_delete_group() to optionally delete all group members. +- Add dm_stats_get_object_type() to return the type of object present. +- Add dm_stats_walk_init() allowing control of objects visited by walks. +- Add dm_stats_get_group_descriptor() to return the member list as a string. +- Introduce dm_stats_get_nr_groups() and dm_stats_group_present(). +- Add dm_stats_{get,set}_alias() to set and retrieve alias names for groups. +- Add dm_stats_get_group_id() to return the group ID for a given region. +- Add dm_stats_{create,delete}_group() to allow grouping of stats regions. +- Add enum-driven dm_stats_get_{metric,counter}() interfaces. +- Add dm_bitset_parse_list() to parse a string representation of a bitset. +- Thin dmeventd plugin umounts lvm2 volume only when pool is 95% or more. + +* Tue Jun 28 2016 Peter Rajnoha - 2.02.158-1 +- Add a more efficient native vgimportclone command to replace the script. +- Make lvmlockd always attempt to connect to lvmetad if no connection exists. +- Let lvmetad handle new connections after shutdown signal. +- Disable lvmetad when vgcfgrestore begins and enable it again after. +- Make pvscan do activation if lvmetad is configured but not running. +- Fix rescanning the PVs for a single VG when using lvmetad. +- Pool metadata lvresize uses now same code as resize of normal volume. +- Preserve monitoring status when updating thin-pool metadata. +- Return 0 (inactive) when status cannot be queried in _lv_active(). +- Switch to log_warn() for failing activation status query. +- Replace vgimportclone script with binary. +- While lvmetad is shutting down, continue handling all connections cleanly. +- Refactor lvconvert argument handling code. +- Notify lvmetad when vgcfgrestore changes VG metadata. +- Add --logonly option to report only cmd log for a command, not other reports. +- Add log/command_log_selection to configure default selection used on cmd log. +- Use 'orphan' object type in cmd log for groups to collect PVs not yet in VGs. +- Add lvm lastlog command for query and display of last cmd's log in lvm shell. +- Report per-object return codes via cmd log while processing multiple objects. +- Annotate processing code with log report hooks for per-object command log. +- Also pass common printed messages (besides warnings and errors) to log report. +- Log warnings and errors via report during cmd processing if this is enabled. +- Make it possible to iterate over internal 'orphan' VGs in process_each_vg fn. +- Make -S|--select option groupable that allows this option to be repeated. +- Make -O|--sort option groupable that allows this option to be repeated. +- Add --configreport option to select report for which next options are applied. +- Add support for priorities on grouping command arguments. +- Add report/{pvs,vgs,lvs,pvsegs,segs}_{cols,sort}_full to lvm.conf. +- Add lvm fullreport command for joined PV, VG, LV and segment report per VG. +- Integrate report group handling and cmd log report into cmd processing code. +- Add log/report_command_log to lvm.conf to enable or disable cmd log report. +- Add log/report_output_format to lvm.conf for default report output format. +- Recognize --reportformat {basic|json} option to select report output format. +- Add log/command_log_{sort,cols} to lvm.conf to configure command log report. +- Add log_object_{type,name,id,group,group_id} fields to cmd log. +- Add log_{seq_num,type,context,message,errno,ret_code} fields to cmd log. +- Add CMDLOG report type - a separate report type for command logging. +- Recognize 'all' keyword used in selection as synonym for "" (no selection). +- Add dm_report_set_selection to set selection for multiple output of report. +- Add DM_REPORT_OUTPUT_MULTIPLE_TIMES flag for multiple output of same report. +- Move field width handling/sort init from dm_report_object to dm_report_output. +- Add _LOG_BYPASS_REPORT flag for bypassing any log report currently set. +- Introduce DM_REPORT_GROUP_JSON for report group with JSON output format. +- Introduce DM_REPORT_GROUP_BASIC for report group with basic report output. +- Introduce DM_REPORT_GROUP_SINGLE for report group having single report only. +- Add dm_report_group_{create,push,pop,destroy} to support report grouping. + +* Fri Jun 17 2016 Peter Rajnoha - 2.02.157-2 +- Change pvscan --cache -aay to scan locally if lvmetad fails. + +* Mon Jun 13 2016 Peter Rajnoha - 2.02.156-1 +- Don't allow duplicate orphan PVs to be used with vgcreate/vgextend/pvcreate. +- Improve handling of lvmetad update failures. +- Yes/No prompt accepts '^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'. +- If available, also collect output from lsblk command when running lvmdump -s. + +* Mon Jun 06 2016 Peter Rajnoha - 2.02.155-2 +- Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155) + +* Mon Jun 06 2016 Peter Rajnoha - 2.02.155-1 +- Reject PV tags on pvmove cmdline because only 1 PV is supported. (2.02.141) +- Fix compilation error when building with configure --disable-devmapper. +- Fix lvmconfig --type diff to display complete diff if config cascade used. +- Automatically filter out partitioned loop devices with partscan (losetup -P). +- Fix lvm devtypes internal error if -S used with field name from pvs/vgs/lvs. +- When reporting Data%%,Snap%%,Meta%%,Cpy%%Sync use single ioctl per LV. +- Add lvseg_percent_with_info_and_seg_status() for percent retrieval. +- Enhance internal seg_status handling to understand snapshots better. +- When refresh failed in suspend, call resume upon error path. +- Support passthrough cache mode when waiting for clean cache. +- Check cache status only for 'in-use' cache pools. +- Extend setup_task() to preset flushing for dm_task object. +- When checking LV is a merging COW, validate its a COW LV first. +- Correcting value in copy_percent() for 100%%. +- Update vgreduce to use process_each_vg. +- Update lvconvert to use process_each_lv. +- Update pvscan to use process_each_vg for autoactivation. +- Add basic support for --type raid0 using md. +- Add support for lvchange --cachemode for cached LV. +- Fix liblvm2app error handling when setting up context. +- Delay liblvm2app init in python code until it is needed. +- Simplify thread locking in lvmetad to fix locking problems. +- Allow pvremove -ff to remove a duplicate PV. +- Fix lvm2-activation-generator to read lvm.conf without full command setup. +- Allow a minimal context to be used in lvm2app for reading lvm.conf. +- Report passthrough caching mode when parsing cache mode. + +* Mon May 16 2016 Peter Rajnoha - 2.02.154-1 +- Fix liblvm segfault after failure initialising lvmetad connection. +- Retry open without O_NOATIME if it fails (not file owner/CAP_FOWNER). +- Split _report into one fn for options and arguments and one for processing. +- Show library version in message even if dm driver version is unavailable. + +* Tue May 10 2016 Peter Rajnoha - 2.02.153-2 +- Change warning messages related to duplicate PVs. +- A named device is always processed itself, not switched for a duplicate. +- Add PV attr "d" and report field "duplicate" for duplicate PVs. +- Add config setting to disallow VG changes when duplicate PVs exist. +- Use device size and active LVs to choose the preferred duplicate PV. +- Disable lvmetad when duplicate PVs are seen. +- Support --chunksize option also when caching LV when possible. +- Add function to check for target presence and version via 1 ioctl. + +* Mon May 02 2016 Peter Rajnoha - 2.02.152-1 +- Use any inherited tags when wiping metadata sub LVs to ensure activation. +- Add str_list_wipe. +- Improve support for interrupting procesing of volumes during lvchange. +- Use failed command return code when lvchanging read-only volume. +- Show creation transaction_id and zeroing state of pool with thin volume. +- Stop checking for dm_cache_mq policy with cache target 1.9 (alias to smq). +- Check first /sys/module/dm_* dir existance before using modprobe. +- Remove mpath from 10-dm.rules, superseded by 11-dm-mpath.rules (mpath>=0.6.0). +- Add dm_udev_wait_immediate to libdevmapper for waiting outside the library. + +* Mon Apr 25 2016 Peter Rajnoha - 2.02.151-1 +- Fix error path after reusing of _setup_task (2.02.150). +- Fix memory access for empty sysfs values (2.02.149). +- Disable lvmetad when lvm1 metadata is seen, so commands revert to scanning. +- Suppress errors when snapshot merge gets delayed because volume is in use. +- Avoid internal snapshot LV names in messages. +- Autodetect and use /run/lock dir when available instead of /var/lock. +- lvchange --refresh for merging thin origin will retry to deactivate snapshot. +- Recognize in-progress snapshot merge for thin volumes from dm table. +- Avoid deciding to initiate a pending snapshot merge during resume. +- Improve retrying lvmetad requests while lvmetad is being updated. +- Read devices instead of using the lvmetad cache if rescan fails. +- Move lvmetad token/filter check and device rescan to the start of commands. +- Don't try deactivating fictional internal LV before snapshot merge. (2.02.105) +- When not obtaining devs from udev, check they exist before caching them. +- Detect device mismatch also when compiling without udev support. +- Do not strip LVM- when debug reporting not found uuid. + +* Mon Apr 11 2016 Peter Rajnoha - 2.02.150-1 +- Avoid using flushing dm status ioctl when checking for usable DM device. +- Check for devices without LVM- uuid prefix only with kernels < 3.X. +- Reuse %%FREE size aproximation with lvcreate -l%%PVS thin-pool. +- Allow the lvmdump directory to exist already provided it is empty. +- Show lvconverted percentage with 2 decimal digits. +- Fix regression in suspend when repairing --type mirror (2.02.133). +- Change log_debug ioctl flags from single characters into words. + +* Mon Apr 04 2016 Peter Rajnoha - 2.02.149-2 +- Do not flush thin-pool when checking metadata fullness. +- Remove spurious error about no value in /sys/dev/block/major:minor/dm/uuid. +- Fix device mismatch detection for LV if persistent .cache file is used. +- Fix holder device not being found in /dev while sysfs has it during dev scan. + +* Tue Mar 29 2016 Peter Rajnoha - 2.02.148-1 +- Introduce TARGET_NAME and MODULE NAME macros. +- Replace hard-coded module and target names with macros. +- Add pv_major and pv_minor report fields. +- Detect and warn about mismatch between devices used and assumed for an LV. +- Adjust raid status function. + +* Mon Mar 21 2016 Peter Rajnoha - 2.02.147-5 +- If available, use /proc/self/mountinfo to detect mounted volume in fsadm. +- Fix resize of stacked raid thin data volume (2.02.141). +- Fix test for lvremove failure in lvconvert --uncache (2.02.146). + +* Fri Mar 11 2016 Peter Rajnoha - 2.02.146-4 +- More man page cleanups in lvconvert. +- Fix makefile vpath in /udev when generating udev rules files. +- Another attempt to improve VG name parsing for lvconvert (2.02.144). +- Use new cache status info and skip flushing for failed cache. +- Support --uncache with missing PVs. +- Improve parsing of cache status and report Fail, Error, needs_check, ro. + +* Fri Mar 11 2016 Peter Rajnoha - 2.02.146-3 +- Tidy report field names, headings and widths. +- Add vgscan --notifydbus to send a dbus notification. +- Add dbus notification from commands after a PV/VG/LV changes state. + +* Wed Mar 09 2016 Peter Rajnoha - 2.02.145-2 +- Require python3-gobject-base insetad of python3-gobject. + +* Mon Mar 07 2016 Peter Rajnoha - 2.02.145-1 +- Make it possible to use lvremove and lvrename on historical LVs. +- For historical LVs, report 'none' for lv_layout and 'history' for lv_role. +- Add full_{ancestors,descendants} fields to report LV ancestry with history. +- Report (h)istorical state within 5th bit (State) of the lv_attr field. +- Add lv_historical reporting field to report if LV is historical or not. +- Add lv_time_removed reporting field to display removal time for hist. LVs. +- Report lv_name, lv_uuid, vg_name, lv_time for historical LVs. +- Add --nohistory switch to lvremove to disable history recording on demand. +- Add -H|--history switch to lvs and lvdisplay to include historical LVs. +- Create historical LVs out of removed thin snapshot LVs and record in history. +- Add metadata/lvs_history_retention_time for automatic removal of hist. LVs. +- Add metadata/record_lvs_history config for switching LV history recording. +- Add support and infrastructure for tracking historical LVs. +- Improve lvconvert man page. +- Add kernel_cache_policy lvs field. +- Display [unknown] instead of 'unknown device' in pvs output. +- Fix error path when pvcreate allocation fails (2.02.144). +- Display [unknown] instead of blank for unknown VG names in pvs output. +- Fix dm_config_write_node and variants to return error on subsection failures. +- Remove 4096 char limit due to buffer size if writing dm_config_node. + +* Mon Feb 29 2016 Peter Rajnoha - 2.02.144-1 +- Only show (u)sed pv_attr char when PV is not (a)llocatable. (2.02.143) +- Update makefile to generate lcov output also for lvmpolld and lvmlockd. +- Fix SystemdService lvm2-lvmdbusd.service name. +- Improve support for env LVM_VG_NAME for reference VG name in lvconvert. +- Fix regression when lvresize accepted zero sizes. (2.02.141) +- Always warn user about PV in use even when pvremove uses --force --force. +- Use uninitialized pool header detection in all cases. +- Fix read error detection when checking for uninitialized thin-pool header. +- Fix error path for internal error in lvmetad VG lookup code. +- Fix string boundary check in _get_canonical_field_name(). +- Always initialized hist struct in _stats_parse_histogram(). + +* Wed Feb 24 2016 Peter Rajnoha - 2.02.143-4 +- Reinstate lvm2-lockd on all architectures as sanlock package is fixed now. + +* Tue Feb 23 2016 Peter Rajnoha - 2.02.143-3 +- Remove Requires: sanlock-lib for lvm2-lockd subpackage if sanlock not compiled. + +* Tue Feb 23 2016 Peter Rajnoha - 2.02.143-2 +- Add Requires: python3-gobject dependency for lvm2-dbusd subpackage. +- Build lvm2-lockd with sanlock support only on x86_64, arch64 and power64 arch. + +* Mon Feb 22 2016 Peter Rajnoha - 2.02.143-1 +- Introduce new lvm2-dbusd package providing LVM D-Bus daemon and service. +- Fix error path when sending thin-pool message fails in update_pool_lv(). +- Support reporting CheckNeeded and Fail state for thin-pool and thin LV. +- For failing thin-pool and thin volume correctly report percentage as INVALID. +- Report -1, not 'unkown' for lv_{snapshot_invalid,merge_failed} with --binary. +- Add configure --enable-dbus-service for an LVM D-Bus service. +- Replace configure --enable-python_bindings with python2 and python3 versions. +- If PV belongs to some VG and metadata missing, skip it if system ID is used. +- Automatically change PV header extension to latest version if writing PV/VG. +- Identify used PVs in pv_attr field by new 'u' character. +- Add pv_in_use reporting field to report if PV is used or not. +- Add pv_ext_vsn reporting field to report PV header extension version. +- Add protective flag marking PVs as used even if no metadata available. +- Improve status parsing for thin-pool and thin devices. + +* Mon Feb 15 2016 Peter Rajnoha - 2.02.142-1 +- Fix memory pool corruption in pvmove (2.02.141). +- Support control of spare metadata creation when repairing thin-pool. +- Fix config type of 'log/verbose' from bool to int (2.02.99). +- Fix inverted data LV thinp watermark calc for dmeventd response (2.02.133). +- Use use_blkid_wiping=0 if not defined in lvm.conf and support not compiled in. +- Do not check for suspended devices if scanning for lvmetad update. +- Clear cached bootloader areas when PV format changed. +- Fix partn table filter with external_device_info_source="udev" and blkid<2.20. +- Use fully aligned allocations for dm_pool_strdup/strndup() (1.02.64). +- Fix thin-pool table parameter feature order to match kernel output. + +* Thu Feb 04 2016 Fedora Release Engineering - 2.02.141-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Jan 25 2016 Peter Rajnoha - 2.02.141-1 +- Add metadata/check_pv_device_sizes switch to lvm.conf for device size checks. +- Warn if device size is less than corresponding PV size in metadata. +- Cache device sizes internally. +- Restore support for command breaking in process_each_lv_in_vg() (2.02.118). +- Use correct mempool when process_each_lv_in_vg() (2.02.118). +- Fix lvm.8 man to show again prohibited suffixes. +- Fix configure to set proper use_blkid_wiping if autodetected as disabled. +- Initialise udev in clvmd for use in device scanning. (2.02.116) +- Add seg_le_ranges report field for common format when displaying seg devices. +- Honour report/list_item_separator for seg_metadata_le_ranges report field. +- Don't mark hidden devs in -o devices,metadata_devices,seg_pe_ranges.(2.02.140) +- Change LV sizes in seg_pe_ranges report field to match underlying devices. +- Add kernel_cache_settings report field for cache LV settings used in kernel. +- Fix man page for dmsetup udevcreatecookie. + +* Mon Jan 18 2016 Peter Rajnoha - 2.02.140-3 +- Fix lvm2app to return either 0 or 1 for lvm_vg_is_{clustered,exported}. +- Add kernel_discards report field to display thin pool discard used in kernel. +- Correct checking of target presence when driver access is disabled. +- Eval poolmetadatasize arg earlier in lvresize. +- Fix vgcfgrestore to respect allocatable attribute of PVs. +- Add report/mark_hidden_devices to lvm.conf. +- Use brackets consistently in report fields to mark hidden devices. +- Restore background polling processing during auto-activation (2.02.119). +- Fix invalid memory read when reporting cache LV policy_name (2.02.126). + +* Mon Jan 11 2016 Peter Rajnoha - 2.02.139-2 +- Update lvmlockd with the new VG seqno before devices are suspended. +- Rework vgrename to use the common processing code in toollib. +- Make pvs show new devices on the system since the last .cache update. +- Document F,D and M thin pool health status chars for lv_attr in lvs man page. +- Also add lvm2-activation{-early,-net}.service systemd status for lvmdump -s. + +* Mon Jan 04 2016 Peter Rajnoha - 2.02.138-1 +- Support lvrename for hidden (used) cache pools. +- Fix lvrename for stacked cache pools +- Better support for dmsetup static linkage. +- Extend validity checks on dmeventd client socket. + +* Mon Dec 07 2015 Peter Rajnoha - 2.02.137-1 +- Restore archiving before changing metadata in vgextend (2.02.117). +- Dropped internal usage of log_suppress(2). +- Cleaned logging code for buffer size usage. +- Added internal id_read_format_try() function to check and read valid UUID. +- Change lvcreate, lvrename, lvresize to use process_each_vg. +- Change process_each_vg to handle single VG as separate arg. +- Issue error if ambiguous VG name is supplied in most commands. +- Make process_each fns always work through full list of known VG names. +- Use dm_get_status_mirror() instead of individual parsers. +- Add mem pool arg for check_transient_status() target function. +- Avoid misleading error with -m is omitted with lvconvert to raid types. +- Add system_id to vginfo cache. +- Mirror plugin in dmeventd uses dm_get_status_mirror(). +- Add dm_get_status_mirror() for parsing mirror status line. + +* Wed Dec 02 2015 Peter Rajnoha - 2.02.136-1 +- Add new --sinceversion option for lvmconfig --type new. +- Fix inactive table loaded for wrapping thin-pool when resizing it. +- Extend the list of ignored libraries when locking memory. +- Show error message when trying to create unsupported raid type. +- Improve preloading sequence of an active thin-pool target. +- Drop extra space from cache target line to fix unneded table reloads. + +* Mon Nov 23 2015 Peter Rajnoha - 2.02.135-1 +- Add a model file for Coverity. +- Show correct error message for unsupported yet cache pool repair. +- Allow lvconvert cache pools' data and metadata LV to raid. +- Fix reading of old metadata with missing cache policy or mode settings. +- Issue error if external_device_info_source=udev and udev db record incomplete. +- Update lvmetad duplicate VG name handling to use hash function extensions. +- Detect invalid vgrenames by vgid where the name is unchanged. +- Fix passing of 32bit values through daemons (mostly lvmlockd). +- Use local memory pool for whole alloc_handle manipulation. +- Add missing pointer validation after dm_get_next_target(). +- Do not deref NULL pointer in debug message for _match_pv_tags(). +- Drop unneeded stat() call when checking for sysfs file. +- Fix memory leak on error path of failing thin-pool percentage check. +- Add missing test for failing node allocation in lvmetad. +- Correct configure messages when enabling/disabling lvmlockd. +- Extend dm_hash to support multiple values with the same key. +- Add missing check for allocation inside dm_split_lvm_name(). +- Test dm_task_get_message_response for !NULL in dm_stats_print_region(). +- Add checks for failing dm_stats_create() in dmsetup. +- Add missing fifo close when failed to initialize client connection. + +* Wed Nov 18 2015 Peter Rajnoha - 2.02.134-4 +- Refactor some lvmetad code and adjust some duplicate PV messages. +- No longer repair/wipe VG/PVs if inaccessible because foreign or shared. +- Pass correct data size to mirror log calc so log can be bigger than 1 extent. + +* Tue Nov 10 2015 Fedora Release Engineering - 2.02.133-3 +- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 + +* Mon Nov 02 2015 Peter Rajnoha - 2.02.133-2 +- Shutdown lvmetad automatically after one hour of inactivity. + +* Fri Oct 30 2015 Peter Rajnoha - 2.02.133-1 +- Support repeated -o|--options for reporting commands. +- Support -o- and -o# for reporting commands to remove and compact fields. +- Fix missing PVs from pvs output if vgremove is run concurrently. +- Remove unwanted error message when running pvs/vgs/lvs and vgremove at once. +- Check newly created VG's metadata do not overlap in metadata ring buffer. +- Check metadata area size is at least the minimum size defined for the format. +- Thin pool targets uses low_water_mark from profile. +- Dropping 'yet' from error of unsupported thick snapshot of snapshots. +- Do not support unpartitioned DASD devices with CDL formatted with pvcreate. +- For thins use flush for suspend only when volume size is reduced. +- Enable code which detects the need of flush during suspend. +- Ensure --use-policy will resize volume to fit below threshold. +- Correct percentage evaluation when checking thin-pool over threshold. +- Fix lvmcache to move PV from VG to orphans if VG is removed and lvmetad used. +- Fix lvmcache to not cache even invalid info about PV which got removed. +- Support checking of memlock daemon counter. +- Allow all log levels to be used with the lvmetad -l option. +- Add optional shutdown when idle support for lvmetad. +- Fix missing in-sync progress info while lvconvert used with lvmpolld. +- Add report/compact_output_cols to lvm.conf to define report cols to compact. +- Do not change logging in lvm2 library when it's already set. +- Check for enough space in thin-pool in command before creating new thin. +- Make libblkid detect all copies of the same signature if use_blkid_wiping=1. +- Fix vgimportclone with -n to not add number unnecessarily to base VG name. +- Cleanup vgimportclone script and remove dependency on awk, grep, cut and tr. +- Add vg_missing_pv_count report field to report number of missing PVs in a VG. +- Properly identify internal LV holding sanlock locks within lv_role field. +- Add metadata_devices and seg_metadata_le_ranges report fields for raid vols. +- Fix lvm2-{activation,clvmd,cmirrord,monitor} service to exec before mounting. +- Disable thin monitoring plugin when it fails too often (>10 times). +- Fix/restore parsing of empty field '-' when processing dmeventd event. +- Enhance dm_tree_node_size_changed() to recognize size reduction. +- Support exit on idle for dmenventd (1 hour). +- Add support to allow unmonitor device from plugin itself. +- New design for thread co-operation in dmeventd. +- Dmeventd read device status with 'noflush'. +- Dmeventd closes control device when no device is monitored. +- Thin plugin for dmeventd improved percentage usage. +- Snapshot plugin for dmeventd improved percentage usage. +- Add dm_hold_control_dev to allow holding of control device open. +- Add dm_report_compact_given_fields to remove given empty fields from report. +- Use libdm status parsing and local mem raid dmeventd plugin. +- Use local mem pool and lock only lvm2 execution for mirror dmeventd plugin. +- Lock protect only lvm2 execution for snapshot and thin dmeventd plugin. +- Use local mempool for raid and mirror plugins. +- Reworked thread initialization for dmeventd plugins. +- Dmeventd handles snapshot overflow for now equally as invalid. +- Convert dmeventd to use common logging macro system from libdm. +- Return -ENOMEM when device registration fails instead of 0 (=success). +- Enforce writethrough mode for cleaner policy. +- Add support for recognition and deactivation of MD devices to blkdeactivate. +- Move target status functions out of libdm-deptree. +- Correct use of max_write_behind parameter when generating raid target line. +- Fix dm-event systemd service to make sure it is executed before mounting. + +* Mon Oct 26 2015 Peter Rajnoha - 2.02.132-2 +- Remove %%{epoch} from cmirror requires. + +* Wed Sep 23 2015 Peter Rajnoha - 2.02.132-1 +- Fix lvmconf to set locking_type=2 if external locking library is requested. +- Remove verbose message when rescanning an unchanged device. (2.02.119) +- Add origin_uuid, mirror_log_uuid, move_pv_uuid, convert_lv_uuid report fields. +- Add pool_lv_uuid, metadata_lv_uuid, data_lv_uuid reporting fields. +- Fix PV label processing failure after pvcreate in lvm shell with lvmetad. +- Update man pages for dmsetup and dmstats. +- Improve help text for dmsetup. +- Use --noflush and --nolockfs when removing device with --force. +- Parse new Overflow status string for snapshot target. +- Check dir path components are valid if using dm_create_dir, error out if not. +- Fix /dev/mapper handling to remove dangling entries if symlinks are found. +- Make it possible to use blank value as selection for string list report field. + +* Wed Sep 16 2015 Peter Rajnoha - 2.02.131-1 +- Fix PV label processing failure after pvcreate in lvm shell with lvmetad. +- Rename 'make install_full_man' to install_all_man and add all_man target. +- Fix vgimportclone cache_dir path name (2.02.115). +- Swapping of LV identifiers handles more complex LVs. +- Use passed list of PVS when allocating space in lvconvert --thinpool. +- Disallow usage of --stripe and --stripesize when creating cache pool. +- Warn user when caching raid or thin pool data LV. +- When layering LV, move LV flags with segments. +- Ignore persistent cache if configuration changed. (2.02.127) +- Fix devices/filter to be applied before disk-accessing filters. (2.02.112) +- Make tags only when requested via 'make tags'. +- Configure supports --disable-dependency-tracking for one-time builds. +- Fix usage of configure.h when building in srcdir != builddir. +- Do not check for full thin pool when activating without messages (1.02.107). + +* Mon Sep 07 2015 Peter Rajnoha - 2.02.130-1 +- Fix use of uninitialized device status if reading outdated .cache record. +- Restore support for --monitor option in lvcreate (2.02.112). +- Read thin-pool data and metadata percent without flush. +- Detect blocked thin-pool and avoid scanning their thin volumes. +- Check if dm device is usable before checking its size (2.02.116). +- Extend parsing of cache_check version in configure. +- Make lvpoll error messages visible in lvmpolld's stderr and in syslog. +- Add 'make install_full_man' to install all man pages regardless of config. +- Parse thin-pool status with one single routine internally. +- Add --histogram to select default histogram fields for list and report. +- Add report fields for displaying latency histogram configuration and data. +- Add dmstats --bounds to specify histogram boundaries for a new region. +- Add dm_histogram_to_string() to format histogram data in string form. +- Add public methods to libdm to access numerical histogram config and data. +- Parse and store histogram data in dm_stats_list() and dm_stats_populate(). +- Add an argument to specify histogram bounds to dm_stats_create_region(). +- Add dm_histogram_bounds_from_{string,uint64_t}() to parse histogram bounds. +- Add dm_histogram handle type to represent a latency histogram and its bounds. + +* Wed Sep 02 2015 Peter Rajnoha - 2.02.129-2 +- Reinstate dm_task_get_info@Base to libdevmapper exports. (1.02.106) + +* Thu Aug 27 2015 Peter Rajnoha - 2.02.129-1 +- Drop error message when vgdisplay encounters an exported VG. (2.02.27) +- Fix shared library generation to stop exporting internal functions.(2.02.120) +- Accept --cachemode with lvconvert. +- Fix and improve reporting properties of cache-pool. +- Enable usage of --cachepolicy and --cachesetting with lvconvert. +- Don't allow to reduce size of thin-pool metadata. +- Fix debug buffer overflows in cmirrord logging. +- Add --foreground and --help to cmirrord. +- Add 'precise' column to statistics reports. +- Add --precise switch to 'dmstats create' to request nanosecond counters. +- Add precise argument to dm_stats_create_region(). +- Add support to libdm-stats for precise_timestamps +- Fix devmapper.pc pkgconfig file to declare -lrt dependency properly. + +* Tue Aug 18 2015 Peter Rajnoha - 2.02.128-1 +- Allocation setting cache_pool_cachemode is replaced by cache_mode. +- Don't attempt to close config file that couldn't be opened. +- Check for valid cache mode in validation of cache segment. +- Change internal interface handling cache mode and policy. +- When no cache policy specified, prefer smq (if available) over mq. +- Add demo cache-mq and cache-smq profiles. +- Add cmd profilable allocation/cache_policy,cache_settings,cache_mode. +- Require cache_check 0.5.4 for use of --clear-needs-check-flag. +- Fix lvmetad udev rules to not override SYSTEMD_WANTS, add the service instead. +- Fix 'dmstats list -o all' segfault. +- Separate dmstats statistics fields from region information fields. +- Add interval and interval_ns fields to dmstats reports. +- Do not include internal glibc headers in libdm-timestamp.c (1.02.104) +- Exit immediately if no device is supplied to dmsetup wipe_table. +- Suppress dmsetup report headings when no data is output. (1.02.104) +- Adjust dmsetup usage/help output selection to match command invoked. +- Fix dmsetup -o all to select correct fields in splitname report. +- Restructure internal dmsetup argument handling across all commands. +- Add dm_report_is_empty() to indicate there is no data awaiting output. +- Add more arg validation for dm_tree_node_add_cache_target(). +- Add --alldevices switch to replace use of --force for stats create / delete. + +* Mon Aug 10 2015 Peter Rajnoha - 2.02.127-1 +- Do not init filters, locking, lvmetad, lvmpolld if command doesn't use it. +- Order fields in struct cmd_context more logically. +- Add lock_type to lvmcache VG summary and info structs. +- Fix regression in cache causing some PVs to bypass filters (2.02.105). +- Make configure --enable-realtime the default now. +- Add dmstats.8 man page +- Add dmstats --segments switch to create one region per device segment. +- Add dmstats --regionid, --allregions to specify a single / all stats regions. +- Add dmstats --allprograms for stats commands that filter by program ID. +- Add dmstats --auxdata and --programid args to specify aux data and program ID. +- Add report stats sub-command to provide repeating stats reports. +- Add clear, delete, list, and print stats sub-commands. +- Add create stats sub-command and --start, --length, --areas and --areasize. +- Recognize 'dmstats' as an alias for 'dmsetup stats' when run with this name. +- Add a 'stats' command to dmsetup to configure, manage and report stats data. +- Add statistics fields to dmsetup -o. +- Add libdm-stats library to allow management of device-mapper statistics. +- Add --nosuffix to suppress dmsetup unit suffixes in report output. +- Add --units to control dmsetup report field output units. +- Add support to redisplay column headings for repeating column reports. +- Fix report header and row resource leaks. +- Report timestamps of ioctls with dmsetup -vvv. +- Recognize report field name variants without any underscores too. +- Add dmsetup --interval and --count to repeat reports at specified intervals. +- Add dm_timestamp functions to libdevmapper. +- Recognise vg/lv name format in dmsetup. +- Move size display code to libdevmapper as dm_size_to_string. + +* Mon Jul 27 2015 Peter Rajnoha - 2.02.126-2 +- Fix long option hyphen removal. (2.02.122) +- Fix clvmd freeze if client disappears without first releasing its locks. +- Fix lvconvert segfaults while performing snapshots merge. +- Ignore errors during detection if use_blkid_wiping=1 and --force is used. +- Recognise DM_ABORT_ON_INTERNAL_ERRORS env var override in lvm logging fn. +- Fix alloc segfault when extending LV with fewer stripes than in first seg. +- Fix handling of cache policy name. +- Set cache policy before with the first lvm2 cache pool metadata commit. +- Fix detection of thin-pool overprovisioning (2.02.124). +- Fix lvmpolld segfaults on 32 bit architectures. +- Add lvmlockd lock_args validation to vg_validate. +- Fix ignored --startstopservices option if running lvmconf with systemd. +- Hide sanlock LVs when processing LVs in VG unless named or --all used. +- Introduce libdevmapper wrappers for all malloc-related functions. + +* Tue Jul 14 2015 Peter Rajnoha - 2.02.125-2 +- Add Requires: system-release>=23 for lvmpolld to be enabled by default + instead of original Requires: fedora-release which may break installations + in environments where fedora-release is not available. + +* Tue Jul 07 2015 Peter Rajnoha - 2.02.125-1 +- Fix getline memory usage in lvmpolld. +- Add support --clear-needs-check-flag for cache_check of cache pool metadata. +- Add lvmetactl for developer use only. +- Rename global/lock_retries to lvmlockd_retries. +- Replace --enable-lvmlockd by --enable-lockd-sanlock and --enable-lockd-dlm. +- Include tool.h for default non-library use. +- Introduce format macros with embedded % such as FMTu64. + +* Fri Jul 03 2015 Peter Rajnoha - 2.02.124-1 +- Move sending thin pool messages from resume to suspend phase. +- Report warning when pool is overprovisioned and not auto resized. +- Recognize free-form date/time values for lv_time field in selection criteria. +- Added experimental lvmlockd with configure --enable-lvmlockd. +- Fix regression in select to match string fields if using synonyms (2.02.123). +- Fix regression when printing more lv names via display_lvname (2.02.122). +- Add missing error logging to unlock_vg and sync_local_dev_names callers. +- Add experimental support to passing messages in suspend tree. +- Add dm_report_value_cache_{set,get} to support caching during report/select. +- Add dm_report_reserved_handler to handle report reserved value actions. +- Support dynamic value in select: DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE. +- Support fuzzy names in select: DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES. +- Thin pool trace messages show a device name and major:minor. +- Add new lvm2-lockd subpackage with lvmlockd daemon. + +* Wed Jul 01 2015 Peter Rajnoha - 2.02.123-1 +- Add report/time_format lvm.conf option to define time format for report. +- Fix makefile shell compare == when building lvmetad lvmpolld (2.02.120). +- Add --type full to lvmconfig for full configuration tree view. +- Add undocumented environment variables to lvm man page. (2.02.119) +- Add device synchronization point before activating a new snapshot. +- Add --withspaces to lvmconfig to add spaces in output for better readability. +- Add custom main function to libdaemon. +- Use lvmetad to track out-of-date metadata discovered. +- Fix makefile shell compare == when building lvmetad lvmpolld (2.02.120). +- Add --type full to lvmconfig for full configuration tree view. +- Add undocumented environment variables to lvm man page. (2.02.119) +- Add device synchronization point before activating a new snapshot. +- Add --withspaces to lvmconfig to add spaces in output for better readability. +- Add custom main function to libdaemon. +- Use lvmetad to track out-of-date metadata discovered. +- Add since, after, until and before time operators to be used in selection. +- Add support for time in reports and selection: DM_REPORT_FIELD_TYPE_TIME. +- Support report reserved value ranges: DM_REPORT_FIELD_RESERVED_VALUE_RANGE. +- Support report reserved value names: DM_REPORT_FIELD_RESERVED_VALUE_NAMED. +- Add DM_CONFIG_VALUE_FMT_{INT_OCTAL,STRING_NO_QUOTES} config value format flag. +- Add DM_CONFIG_VALUE_FMT_COMMON_{ARRAY,EXTRA_SPACE} config value format flag. +- Add dm_config_value_{get,set}_format_flags to get and set config value format. + +* Mon Jun 22 2015 Peter Rajnoha - 2.02.122-1 +- Flush stdout before printing to stderr. +- Use pre-allocated buffer for printed LV names in display_lvname. +- Support thins with size of external origin unaligned with thin pool chunk. +- Allow extension of reduced thin volumes with external origins. +- Consider snapshot and origin LV as unusable if component devices suspended. +- Fix lvmconfig segfault on settings with undefined default value (2.02.120). +- Add explicit 's' (shared) LV activation mode. +- Ignore hyphens in long options names (i.e. --long-option == --longoption). +- Distinguish between on-disk and lvmetad versions of text metadata. +- Remove DL_LIBS from Makefiles for daemons that don't need them. +- Zero errno in before strtoul call in dmsetup if tested after the call. +- Zero errno in before strtoul call in lvmpolld. +- Fix a segfault in pvscan --cache --background command. +- Fix test for AREA_PV when checking for failed mirrors. +- Do not use --sysinit in lvm2-activation{-early,-net}.service if lvmpolld used. +- Maintain outdated PV info in lvmetad till all old metadata is gone from disk. +- Do not fail polling when poll LV not found (already finished or removed). +- Replace poll_get_copy_vg/lv fns with vg_read() and find_lv() in polldaemon. +- Close all device fds only in before sleep call in polldaemon. +- Simplify Makefile targets that generate exported symbols. +- Move various -D settings from Makefiles to configure.h. +- New dm_tree_node_set_thin_pool_read_only(DM_1_02_99) for read-only thin pool. +- Enhance error message when thin-pool message fails. +- Fix dmeventd logging to avoid threaded use of static variable. +- Remove redundant dmeventd SIGALRM coded. +- Add dm_task_get_errno() to return any unexpected errno from a dm ioctl call. +- Use copy of errno made after each dm ioctl call in case errno changes later. + +* Wed Jun 17 2015 Fedora Release Engineering - 2.02.120-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu May 21 2015 Peter Rajnoha - 2.02.120-1 +- Enable and use lvmpolld - the LVM polling daemon by default. +- Add Requires: fedora-release>=23-0.13 for lvmpolld to be enabled by default. +- Make various adjustments to Makefile compilation flags. +- Add lvmpolld debug message class. +- Add lvmpolld client mode for querying running server instance for status info. +- Fix some libdaemon socket creation and reuse error paths. +- Daemons (libdaemon) support exit on idle also in non-systemd environment. +- Provide make dist and make rpm targets +- Configure lvm.conf for use_lvmetad and use_lvmpolld. +- Add lvpoll for cmdline communication with lvmpolld. +- Add lvmpolld acting as a free-standing version of polldaemon. +- Avoid repeated identical lvmetad VG lookups in commands processing all VGs. +- Handle switches to alternative duplicate PVs efficiently with lvmetad. +- Properly validate PV size for pvcreate --restorefile. +- Fix check if pvcreate wiped device (2.02.117). +- Fix storing of vgid when caching metadata (2.02.118). +- Fix recursive lvm-config man page. (2.02.119) +- Refactor polldaemon interfaces to poll every operation by VG/LV couple +- Skip wait after testing in _wait_for_single_lv when polling finished +- Return 'None' in python for empty string properties instead of crashing. +- Distinguish signed numerical property type in reports for lvm2app library. +- Reread raid completion status immediately when progress appears to be zero. +- lvm2app closes locking on lvm_quit(). +- Configure detects /run or /var/run. +- Add missing newline in clvmd --help output. +- New dm_task_get_info(DM_1_02_97) supports internal_suspend state. +- New symbols are versioned and comes with versioned symbol name (DM_1_02_97). + +* Mon May 04 2015 Peter Rajnoha - 2.02.119-1 +- New lvm2-python3-libs subpackage to provide Python 3 bindings for LVM2. +- New LVM_LOG_FILE_EPOCH, LVM_EXPECTED_EXIT_STATUS env vars. Man page to follow. +- Remove detailed content from lvm.conf man page: use lvmconfig instead. +- Generate complete config files with lvmconfig or 'make generate'. +- Also display info on deprecated config with lvmconfig --withcomments. +- Display version since which config is deprecated in lvmconfig --withversions. +- Add --showdeprecated to lvmconfig to also display deprecated settings. +- Hide deprecated settings in lvmconfig output for all types but current,diff. +- Introduce support for exit on idle feature in libdaemon +- Add --showunsupported to lvmconfig to also display unsupported settings. +- Display unsupported settings for lvmconfig --type current,diff only by default +- Honour lvmconfig --ignoreunsupported and --ignoreadvanced for all --type. +- Make python bindings usable with python3 (and compatible with 2.6 & 2.7). +- Add lvmconfig -l|--list as shortcut for lvmconfig --type list --withsummary. +- Add lvmconfig --type list to display plain list of configuration settings. +- Introduce lvmconfig as the preferred form of 'lvm dumpconfig'. +- Add lv_ancestors and lv_descendants reporting fields. +- Add --ignorelocal option to dumpconfig to ignore the local section. +- Close connection to lvmetad after fork. +- Make lvchange able to resume background pvmove polling again. +- Split pvmove update metadata fn in an initial one and a subsequent one. +- Refactor shared pvmove and lvconvert code into new _poll files. +- Add --unconfigured option to dumpconfig to print strings unconfigured. +- Add --withsummary option to dumpconfig to print first line - summary comment. +- Use number of device holders to help choose between duplicate PVs. +- Try to make lvmetad and non-lvmetad duplicate PV handling as similar as poss. +- Issue warnings about duplicate PVs discovered by lvmetad. +- Track alternative devices with matching PVIDs in lvmetad. +- Check for lvm binary in blkdeactivate and skip LVM processing if not present. +- Add --enable-halvm and --disable-halvm options to lvmconf script. +- Add --services, --mirrorservice and --startstopservices option to lvmconf. +- Use proper default value of global/use_lvmetad when processing lvmconf script. +- Respect allocation/cling_tag_list during intial contiguous allocation. +- Make changes persist with python addTag/removeTag. +- Set correct vgid when updating cache when writing PV metadata. +- More efficient clvmd singlenode locking emulation. +- Reject lvcreate -m with raid4/5/6 to avoid unexpected layout. +- Don't skip invalidation of cached orphans if vg write lck is held (2.02.118). +- Log relevant PV tags when using cling allocation. +- Fix selection to not match if using reserved value in criteria with >,<,>=,<. +- Fix selection to not match reserved values for size fields if using >,<,>=,<. +- Include uuid or device number in log message after ioctl failure. +- Add DM_INTERNAL_SUSPEND_FLAG to dm-ioctl.h. +- Move blkdeactivate script from lvm2 package to device-mapper subpackage. +- Install blkdeactivate script and its man page with make install_device-mapper. + +* Tue Mar 24 2015 Peter Rajnoha - 2.02.118-1 +- Fix LV processing with selection to always do the selection on initial state. +- Store metadata size + checksum in lvmcache and add struct lvmcache_vgsummary. +- Remove inaccessible clustered PVs from 'pvs -a'. +- Don't invalidate cached orphan information while global lock is held. +- Avoid rescan of all devices when requested pvscan for removed device. +- Measure configuration timestamps with nanoseconds when available. +- Disable lvchange of major and minor of pool LVs. +- Fix pvscan --cache to not scan and read ignored metadata areas on PVs. +- Add After=iscsi-shutdown.service to blk-availability.service systemd unit. +- Disallow vgconvert from changing metadata format when lvmetad is used. +- Don't do a full read of VG when creating a new VG with an existing name. +- Reduce amount of VG metadata parsing when looking for vgname on a PV. +- Avoid reparsing same metadata when reading same metadata from multiple PVs. +- Save extra device open/close when scanning device for size. +- Fix seg_monitor field to report status also for mirrors and thick snapshots. +- Replace LVM_WRITE with LVM_WRITE_LOCKED flags in metadata if system ID is set. +- Preserve original format type field when processing backup files. +- Implement status action for lvm2-monitor initscript to display monitored LVs. +- Allow lvchange -p to change kernel state only if metadata state differs. +- Fix incorrect persistent .cache after report with label fields only (2.02.106). +- Reinstate PV tag recognition for pvs if reporting label fields only (2.02.105). +- Rescan devices before vgimport with lvmetad so exported VG is seen. +- Fix hang by adjusting cluster mirror regionsize, avoiding CPG msg limit. +- Do not crash when --cachepolicy is given without --cachesettings. +- Add NEEDS_FOREIGN_VGS flag to vgimport so --foreign is always supplied. +- Add --foreign to the 6 display and reporting tools and vgcfgbackup. +- Install /etc/lvm/lvmlocal.conf template with local section for systemid. +- Record creation_host_system_id in lvm2 metadata (never set yet). +- Reinstate recursive config file tag section processing. (2.02.99) +- Add 'lvm systemid' to display the current system ID (never set yet). +- Fix configure to properly recognize --with-default-raid10-segtype option. +- Do not refresh filters/rescan if no signature is wiped during pvcreate. +- Enforce none external dev info for wiping during pvcreate to avoid races. +- Add global/system_id_source and system_id_file to lvm.conf (disabled). +- Add support for VG system_id to control host access to VGs. +- Update vgextend to use process_each_vg. +- Add --ignoreskippedcluster to pvchange. +- Allow pvchange to modify several properties at once. +- Update pvchange to use process_each_pv. +- Fix pvs -a used with lvmetad to filter out devices unsuitable for PVs. +- Fix selection to recognize units for ba_start, vg_free and seg_start fields. +- Add support for -S/--select to vgexport and vgimport. +- Add support for -S/--select to vgdisplay, lvdisplay and pvdisplay without -C. +- Add support for -S/--select to vgremove and lvremove. +- Add support for -S/--select to vgchange,lvchange and pvchange. +- Add infrastructure to support selection for non-reporting tools. +- Add LVM_COMMAND_PROFILE env var to set default command profile name to use. +- Set CLOEXEC flag on file descriptors originating in libdaemon. +- Add dm_report_object_is_selected for generalized interface for report/select. + +* Fri Jan 30 2015 Peter Rajnoha - 2.02.116-3 +- Deactivate unused thin pools activated with lvm2 pre-2.02.112 versions. +- Check lock holding LV when lvconverting stacked raid LV in cluster. +- Support udev external dev info for filters: PV min size, mpath, md, partition. +- Add fw_raid_component_detection lvm.conf option to enable FW raid detection. +- Add devices/external_device_info_source lvm.conf option ("none" by default). +- Scan pools in for_each_sub_lv() and add for_each_sub_lv_except_pools(). +- Fix lvm2app lvm_lv_get_property return value for fields with info/status ioctl. +- Fix lvm2app regression in lvm_lv_get_attr causing unknown values (2.02.115). +- Preserve chunk size with repair and metadata swap of a thin pool. +- Fix raid --splitmirror 1 functionality (2.02.112). +- Fix tree preload to handle splitting raid images. +- Do not support unpartitioned DASD devices. +- Improve config validation to check if setting with string value can be empty. + +* Thu Jan 29 2015 Peter Rajnoha - 2.02.115-2 +- Set default cache_mode to writehrough when missing in metadata. +- Add BuildRequires: device-mapper-persistent-data + for proper thin and cache tool configuration. + +* Thu Jan 22 2015 Peter Rajnoha - 2.02.115-1 +- Report segment types without monitoring support as undefined. +- Support lvchange --errorwhenfull for thin pools. +- Improve the processing and reporting of duplicate PVs. +- Report lv_health_status and health attribute also for thin pool. +- Add lv_when_full reporting field. +- Add support for lvcreate --errorwhenfull y|n for thin pools. +- Fix lvconvert --repair to honour resilience requirement for segmented RAID LV. +- Filter out partitioned device-mapper devices as unsuitable for use as PVs. +- Also notify lvmetad about filtered device if using pvscan --cache DevicePath. +- Use LVM's own selection instead of awk expressions in clvmd startup scripts. +- Do not filter out snapshot origin LVs as unusable devices for an LVM stack. +- Fix incorrect rimage names when converting from mirror to raid1 LV (2.02.112). +- Introduce pvremove_many to avoid excessive metadata re-reading and messages. +- Check for cmirror availability during cluster mirror creation and activation. +- Add cache_policy and cache_settings reporting fields. +- Add missing recognition for --binary option with {pv,vg,lv}display -C. +- Fix vgimportclone to notify lvmetad about changes done if lvmetad is used. +- Fix vgimportclone to properly override config if it is missing in lvm.conf. +- Fix automatic use of configure --enable-udev-systemd-background-jobs. +- Correctly rename active split LV with -splitmirrors for raid1. +- Add report/compact_output to lvm.conf to enable/disable compact report output. +- Still restrict mirror region size to power of 2 when VG extent size is not. +- Reduce severity of ioctl error message when dmeventd waitevent is interrupted. +- Report 'unknown version' when incompatible version numbers were not obtained. +- Report more info from thin pool status (out of data, metadata-ro, fail). +- Support error_if_no_space for thin pool target. +- Fix segfault while using selection with regex and unbuffered reporting. +- Add dm_report_compact_fields to remove empty fields from report output. +- Remove unimplemented dm_report_set_output_selection from libdevmapper.h. + +* Fri Nov 28 2014 Alasdair Kergon - 2.02.114-3 +- Avoid file descriptor leak in clients that open repeated lvmetad connections. +- Add --cachepolicy and --cachesettings to lvcreate. +- Fix regression when parsing /dev/mapper dir (2.02.112). +- Fix missing rounding to 64KB when estimating optimal thin pool chunk size. +- Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT var to be ignored. +- Fix size in pvresize "Resizing to ..." verbose msg to show proper result size. + +* Thu Nov 27 2014 Peter Rajnoha - 2.02.113-2 +- Fix regression when parsing /dev/mapper dir (2.02.112). +- Fix missing rounding to 64KB when estimating optimal thin pool chunk size. +- Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT variable to be ignored. +- Fix size in pvresize "Resizing to ..." verbose msg to show proper result size. + +* Tue Nov 25 2014 Alasdair Kergon - 2.02.113-1 +- Add --cachepolicy and --cachesettings options to lvchange. +- Validate that converted volume and specified pool volume differ in lvconvert. +- Fix regression in vgscan --mknodes usage (2.02.112). +- Default to configure --enable-udev-systemd-background-jobs for systemd>=205. +- Fix ignore_vg() to properly react on various vg_read errors (2.02.112). +- Failed recovery returns FAILED_RECOVERY status flag for vg_read(). +- Exit with non-zero status code when pvck encounters a problem. +- Fix clean_tree after activation/resume for cache target (2.02.112). +- Fix memory corruption with sorting empty string lists (1.02.86). +- Fix man dmsetup.8 syntax warning of groff. +- Accept unquoted strings and / in place of {} when parsing configs. + +* Tue Nov 11 2014 Peter Rajnoha - 2.02.112-1 +- Add cache_{read,write}_{hits,misses} reporting fields. +- Add cache_{total,used,dirty}_blocks reporting fields. +- Add _corig as reserved suffix. +- Reduce number of VG writes and commits when creating spare volumes. +- When remove_layer_from_lv() removes layer, restore subLV names. +- Cache-pool in use becomes invisible LV. +- Don't prompt for removal of _pmspare in VG without pool metadata LV. +- Deactivation of snapshot origin detects and deactivates left-over snapshots. +- Properly report error when taking snapshot of any cache type LV. +- Add basic thread debugging messages to dmeventd. +- Include threads being shutdown in dmeventd device registration responses. +- Inital support for external users of thin pools based on transaction_id. +- Report some basic percentage info for cache pools. +- Introduce size_mb_arg_with_percent() for advanced size arg reading. +- Add extra support for '.' as decimal point in size args. +- Add configure parameters for default segment type choices. +- Add global/sparse_segtype_default setting to use thin for --type sparse. +- Update and correct lvcreate and lvcovert man pages. +- Mark pools and snapshots as unzeroable volumes. +- Check for zeroing of volume after segment type is fully detected. +- Better support for persistent major and minor options with lvcreate. +- Refactor lvcreate towards more complete validation of all supported options. +- Support lvcreate --type linear. +- Improve _should_wipe_lv() to warn with message. +- Inform about temporarily created volumes only in verbose mode. +- Better support for --test mode with pool creation. +- Query lock holding LV when replacing and converting raid volumes. +- Add extra validate for locked lv within validate_lv_cache_create(). +- Add internal lvseg_name() function. +- Skip use of lock files for virtual internal VG names. +- Fix selection on {vg,lv}_permissions fields to properly match selection criteria. +- Fix lv_permissions reporting to display read-only{-override} instead of blank. +- Fix liblvm2cmd and lvm shell to respect quotes around args in cmd line string. +- Permit extent sizes > 128KB that are not power of 2 with lvm2 format. +- Remove workaround for lvm2-monitor.service hang on stop if lvmetad stopped. +- Change vgremove to use process_each_lv_in_vg. +- Allow lvconvert --repair and --splitmirrors on internal LVs. +- Introduce WARN_ flags to control some metadata warning messages. +- Use process_each_pv in vgreduce. +- Refactor process_each_pv in toollib. +- Introduce single validation routine for pool chunk size. +- Support --yes like --force in vg/lvremove to skip y|n prompt. +- Support --yes with lvconvert --splitsnapshot. +- Fix detection of unsupported thin external lvconversions. +- Fix detection of unsupported cache and thin pool lvconversions. +- Fix detection of unsupported lvconversion of cache to snapshot. +- Improve code for creation of cache and cache pool volumes. +- Check cluster-wide (not local) active status before removing LV. +- Properly check if activation of removed cached LV really activated. +- lvremove cached LV removes cachepool (keep with lvconvert --splitcache). +- Always remove spare LV with last removed pool volume. +- Support lvconvert --splitcache and --uncache of cached LV. +- Option --cache has also shortcut -H (i.e. lvcreate -H). +- Refactor lvcreate code and better preserve --type argument. +- Refactor filter processing around lvmetad. +- Refactor process_each_lv in toollib. +- Refactor process_each_vg in toollib. +- Pools cannot be used as external origin. +- Use lv_update_and_reload() for snapshot reload. +- Don't print message in adjusted_mirror_region_size() in activation. +- Improve lv_update_and_reload() to find out proper lock holding LV. +- Improve search of LV in lv_ondisk(). +- Do not scan sysfs in lv_check_not_in_use() when device is closed. +- Backup final metadata after resync of mirror/raid. +- Unify handling of --persistent option for lvcreate and lvchange. +- Validate major and minor numbers stored in metadata. +- Use -fPIE when linking -pie executables. +- Support DEBUG_MEMLOCK to trap unsupported mmap usage. +- Enable cache segment type by default. +- Ensure only supported volume types are used with cache segments. +- Fix inablility to specify cachemode when 'lvconvert'ing to cache-pool. +- Grab cluster lock for active LVs when setting clustered attribute. +- Use va_copy to properly pass va_list through functions. +- Add function to detect rotational devices. +- Review internal checks for mirror/raid/pvmove volumes. +- Track mirror segment type with separate MIRROR flag. +- Fix cmirror endian conversions. +- Introduce lv_is_pvmove/locked/converting/merging macros. +- Avoid leaving linear logical volume when thin pool creation fails. +- Don't leak alloc_handle on raid target error path. +- Properly validate raid leg names. +- Archive metadata before starting their modification in raid target. +- Add missing vg_revert() in suspend_lv() raid and snapshot error path. +- Add missing backup of lvm2 metadata after some raid modifications. +- Use vg memory pool for extent allocation. +- Add allocation/physical_extent_size config option for default PE size of VGs. +- Demote an error to a warning when devices known to lvmetad are filtered out. +- Re-order filter evaluation, making component filters global. +- Fix logic that checks for full scan before iterating through devices. +- Introduce common code to modify metadata and reload updated LV. +- Fix rename of active snapshot volume in cluster. +- Make sure shared libraries are built with RELRO option. +- Update cache creation and dm_config_node to pass policy. +- Allow activation of any thin-pool if transaction_id supplied is 0. +- Don't print uninitialized stack bytes when non-root uses dm_check_version(). +- Fix selection criteria to not match reserved values when using >, <, >=, <. +- Add DM_LIST_HEAD_INIT macro to libdevmapper.h. +- Fix dm_is_dm_major to not issue error about missing /proc lines for dm module. + +* Mon Sep 01 2014 Peter Rajnoha - 2.02.111-1 +- Pass properly sized char buffers for sscanf when initializing clvmd. +- Reinstate nosync logic when extending mirror. (2.02.110) +- Fix total area extent calculation when allocating cache pool. (2.02.110) +- Restore proper buffer size for parsing mountinfo line (1.02.89) + +* Wed Aug 27 2014 Peter Rajnoha - 2.02.110-1 +- Fix manipulation with thin-pools which are excluded via volume_list. +- Support lv/vgremove -ff to remove thin vols from broken/inactive thin pools. +- Fix typo breaking configure --with-lvm1=shared. +- Modify lvresize code to handle raid/mirrors and physical extents. +- Don't allow pvcreate to proceed if scanning or filtering fails. +- Cleanly error when creating RAID with stripe size < PAGE_SIZE. +- Print name of LV which on activation triggers delayed snapshot merge. +- Add lv_layout and lv_role LV reporting fields. +- Properly display lvs lv_attr volume type and target type bit for cache origin. +- Fix pvcreate_check() to update cache correctly after signature wiping. +- Fix primary device lookup failure for partition when processing mpath filter. +- If LV inactive and non-clustered, do not issue "Cannot deactivate" on -aln. +- Remove spurious "Skipping mirror LV" message on pvmove of clustered mirror. +- Improve libdevmapper-event select() error handling. +- Add extra check for matching transation_id after message submitting. +- Add dm_report_field_string_list_unsorted for str. list report without sorting. +- Support --deferred with dmsetup remove to defer removal of open devices. +- Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag. +- Add support for selection to match string list subset, recognize { } operator. +- Fix string list selection with '[value]' to not match list that's superset. +- Fix string list selection to match whole words only, not prefixes. + +* Sun Aug 17 2014 Fedora Release Engineering - 2.02.109-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Aug 5 2014 Alasdair Kergon - 2.02.109-1 +- Allow approximate allocation with +%%FREE in lvextend. +- Fix a segfault in lvscan --cache when devices were already missing. (2.02.108) +- Display actual size changed when resizing LV. +- Remove possible spurious "not found" message on PV create before wiping. +- Handle upgrade from 2.02.105 when an LV now gaining a uuid suffix is active. +- Remove lv_volume_type field from reports. (2.02.108) +- Fix incorrect persistent .cache after vgcreate with PV creation. (2.02.108) +- Add dm_tree_set_optional_uuid_suffixes to libdevmapper to handle upgrades. + +* Wed Jul 23 2014 Alasdair Kergon - 2.02.108-1 +- Remove an erroneous duplicate const from libdevmapper.h. (2.02.107) +- Add lvscan --cache which re-scans constituents of a particular LV. +- Make dmeventd's RAID plugin re-scan failed PVs when lvmetad is in use. +- Improve code sharing for lvconvert and lvcreate and pools (cache & thin). +- Improve lvconvert --merge validation. +- Improve lvconvert --splitsnapshot validation. +- Add report/list_item_separator lvm.conf option. +- Add lv_active_{locally,remotely,exclusively} LV reporting fields. +- Enhance lvconvert thin, thinpool, cache and cachepool command line support. +- Display 'C' only for cache and cache-pool target types in lvs. +- Prompt for confirmation before change LV into a snapshot exception store. +- Return proper error codes for some failing lvconvert funtions. +- Add initial code to use cache tools (cache_check|dump|repair|restore). +- Support lvdisplay --maps for raid. +- Add --activationmode degraded to activate degraded raid volumes by default. +- Add separate lv_active_{locally,remotely,exclusively} LV reporting fields. +- Recognize "auto"/"unmanaged" values in selection for appropriate fields only. +- Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1. +- Add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C for 0/1 on reports. +- Add separate reporting fields for each each {pv,vg,lv}_attr bit. +- Separate LV device status reporting fields out of LV fields. +- Fix regression causing PVs not in VGs to be marked as allocatable (2.02.59). +- Fix VG component of lvid in vgsplit/vgmerge and check in vg_validate. +- Add lv_full_name, lv_parent and lv_dm_path fields to reports. +- Change lv_path field to suppress devices that never appear in /dev/vg. +- Postpone thin pool lvconvert prompts (2.02.107). +- Require --yes option to skip prompt to lvconvert thin pool chunksize. +- Support lvremove -ff to remove thin volumes from broken thin pools. +- Require --yes to skip raid repair prompt. +- Change makefile %%.d generation to handle filename changes without make clean. +- Fix use of buildir in make pofile. +- Enhance private volumes UUIDs with suffixed for easier detection. +- Do not use reserved _[tc]meta volumes for temporary LVs. +- Leave backup pool metadata with _meta%%d suffix instead of reserved _tmeta%%d. +- Allow RAID repair to reuse PVs from same image that suffered a failure. +- New RAID images now avoid allocation on any PVs in the same parent RAID LV. +- Always reevaluate filters just before creating PV. +- Fix dm_report_field_string_list to handle delimiter with multiple chars. +- Add dm_report_field_reserved_value for per-field reserved value definition. + +* Fri Jul 18 2014 Tom Callaway - 2.02.107-2 +- fix license handling + +* Tue Jun 24 2014 Peter Rajnoha - 2.02.107-1 +- Add cmirror-standalone subpackage containing new lvm2-cmirrord.service + systemd unit for standalone cmirrord daemon management without cluster + resource manager involvement. +- Add lvm2-cluster-standalone subpackage containing new lvm2-clvmd.service + and lvm2-cluster-activation.service systemd unit for standalone clvmd + daemon management without cluster resource manager involvement. +- Add Requires: resource-agents for lvm2-cluster and cmirror subpackages. + The resource-agents package provides "clvm" cluster resource to manage + clvmd and cmirrord instances. This replaces obsolete clvmd and cmirrord + initscripts. +- Introduce LCK_ACTIVATION to avoid concurrent activation of basic LV types. +- Fix open_count test for lvchange --refresh or mirrors and raids. +- Update pvs,vgs,lvs and lvm man page for selection support. +- Add -S/--select to lvm devtypes for report selection. +- Add -S/--select to pvs,vgs,lvs and {pv,vg,lv}display -C for report selection. +- Use dm_report_init_with_selection now, implicit "selected" field appears. +- Make use of libdm's DM_REPORT_FIELD_TYPE{SIZE,PERCENT,STRING_LIST} for fields. +- Support all-or-nothing pvmove --atomic. +- Automatically add snapshot metadata size for -l %%ORIGIN calculation. +- When converting RAID origin to cache LV, properly rename sub-LVs. +- Use RemoveOnStop for lvm2-lvmetad.socket systemd unit. +- Add thin-generic configuration profile for generic thin settings. +- Fix crash when reporting empty labels on pvs. +- Use retry_deactivation also when cleaning orphan devices. +- Wait for client threads when shutting down lvmetad. +- Remove PV from cache on pvremove. +- Avoid repeatedly reporting of failure to connect to lvmetad. +- Introduce MDA_FAILED to permit metadata updates even if some mdas are missing. +- Prompt when setting the VG cluster attr if the cluster is not setup. +- Allow --yes to skip prompt in vgextend (worked only with -f). +- Don't use name mangling for LVM - it never uses dm names with wrong char set. +- Remove default.profile and add {command,metadata}_profile_template.profile. +- Use proper umask for systemd units generated by lvm2-activation-generator. +- Check for failing mirror_remove_missing() function. +- Prompt before converting volumes to thin pool and thin pool metadata. +- Add dumpconfig --type profilable-{metadata,command} to select profile type. +- Exit immediately with error if command profile is found invalid. +- Separate --profile cmd line arg into --commandprofile and --metadataprofile. +- Strictly separate command profiles and per-VG/LV profiles referenced in mda. +- Fix dumpconfig --type diff when run as second and later cmd in lvm shell. +- Fix wrong profile reuse from previous run if another cmd is run in lvm shell. +- Move cache description from lvm(8) to new lvmcache(7) man page. +- Display skipped prompt in silent mode. +- Make reporting commands show help about possible sort keys on '-O help'. +- Add metadata_percent to lvs_cols. +- Take account of parity areas with alloc anywhere in _calc_required_extents. +- Use proper uint64 casting for calculation of cache metadata size. +- Better support for nesting of blocking signals. +- Use only sigaction handler and drop duplicate signal handler. +- Separate signal handling and flock code out into lib/misc. +- Don't start dmeventd checking seg_monitor and monitoring is disabled. +- Catch CTRL-c during pvremove prompts. +- Show correct availability status for snapshot origin in lvscan. +- Move segment thin pool/volume info into segment display 'lvdisplay --maps'. +- Display thin pool usage even when just thin volume is available. +- Display monitoring status for monitorable segments in 'lvdisplay --maps'. +- Display virtual extents for virtual LVs in 'lvdisplay --maps'. +- Make vgsplit fail cleanly when not all PVs are specified for RAID 4/5/6. +- Make vgsplit work on mirrors with logs that share PVs with images. +- Use devices/ignore_suspended_devices=0 by default if not defined in lvm.conf. +- Use proper libmem mempool for allocation of unknown segment name. +- Add --readonly to reporting and display tools for lock-free metadata access. +- Add locking_type 5 for dummy locking for tools that do not need any locks. +- Fix _recover_vg() error path when lock conversion fails. +- Use X for LV attributes that are unknown when activation disabled. +- Only output lvdisplay 'LV Status' field when activation is enabled. +- Use lvmetad_used() in pvscan instead of config_tree. +- Configure --enable-udev-systemd-background-jobs if not disabled explicitly. +- Add lvmdump -s to collect system info and context (currently systemd only). +- Refactor allocation code to make A_POSITIONAL_FILL explicit. +- Use thread-safe ctime_r() for clvmd debug logging. +- Skip adding replies to already finished reply thread. +- Use mutex to check number of replies in request_timed_out() in clvmd. +- Drop usage of extra reply_mutex for localsock in clvmd. +- Protect manipulation with finished flag with mutex in clvmd. +- Shift mutex creation and destroy for localsock in clvmd to correct place. +- Fix usage of --test option in clvmd. +- Skip more libraries to be mlocked in memory. +- Remove LOCKED flag for pvmove replaced with error target. +- Return invalid command when specifying negative polling interval. +- Make "help" and "?" reporting fields implicit. +- Recognize implicit "selected" field if using dm_report_init_with_selection. +- Add support for implicit reporting fields which are predefined in libdm. +- Add DM_REPORT_FIELD_TYPE_PERCENT: separate number and percent fields. +- Add dm_percent_range_t,dm_percent_to_float,dm_make_percent to libdm for reuse. +- Add dm_report_reserved_value to libdevmapper for reserved value definition. +- Also display field types when listing all fields in selection help. +- Recognize "help" keyword in selection string to show brief help for selection. +- Always order items reported as string list field lexicographically. +- Add dm_report_field_string_list to libdevmapper for direct string list report. +- Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields. +- Add dm_str_list to libdevmapper for string list type definition and its reuse. +- Add dmsetup -S/--select to define selection criteria for dmsetup reports. +- Add dm_report_init_with_selection to intialize report with selection criteria. +- Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields. +- Use RemoveOnStop for dm-event.socket systemd unit. +- Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page. +- Warn user about incorrect use of cookie with 'dmsetup remove --force'. +- Also recognize 'help'/'?' as reserved sort key name to show help. +- Add dm_units_to_factor for size unit parsing. +- Increase bitset size for minors for thin dmeventd plugin. + +* Mon Jun 09 2014 Alasdair Kergon - 2.02.106-5 +- Remove separate sub-package release tags to fix last commit. + +* Sat Jun 07 2014 Fedora Release Engineering - 2.02.106-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Apr 29 2014 Peter Rajnoha - 2.02.106-3 +- Remove obsolete lvm2-sysvinit subpackage. + +* Thu Apr 24 2014 Peter Rajnoha - 2.02.106-2 +- Require exact lvm2/device-mapper version among LVM2 subpackages + so all of them are always updated synchronously within one update. + +* Fri Apr 11 2014 Peter Rajnoha - 2.02.106-1 +- Require latest device-mapper-persistent-data 0.3.2-1. +- Fix ignored --dataalignment/dataalignmentoffset for pvcreate --restorefile. +- Fix lost information about bootloader area when using lvmetad. +- Don't require --major to be specified when using -My option on kernels > 2.4. +- Add configure --disable-thin_check_needs_check to support old thin_check. +- Use thin_check --clear-needs-check-flag by default. +- Add lvmthin man page to section 7. +- Ensure mapped device names are not too long in vg_validate and lvrename. +- Ensure resume failure in lvrename results in command failure. +- Add explicit error message when using lvdisplay -c -m. +- Report error if superfluous argument (e.g. PV name) supplied to pvscan. +- Fix error message for pvdisplay -c -m and add one for pvdisplay -c -s. +- Use EINVALID_CMD_LINE correctly instead of ECMD_FAILED in vgimport/export. +- Obtain list of known VGs from lvmetad for pvchange --all. +- Add man page for lvm-dumpconfig to section 8. +- Validate name for renamed sub LVs. +- When lvrename fails on argument parsing return EINVALID_CMD_LINE. +- Fix exit code regression in failing pvchange command (2.02.66). +- Include 'lvm dumpconfig --type missing' and '--type diff' output to lvmdump. +- Return failure when specifying negative size for pvresize. +- Fix memory corruption in cmd context refresh if clvmd leaks opened device. +- Reinitialise lvmcache properly on fork to fix premature polldaemon exit. +- Add 'lvm dumpconfig --type diff' to show differences from defaults. +- Fix swap signature detection for devices smaller then 2MB. +- Resolve memory release order for clvmd shutdown. +- Report error when lvm2 activation is released in critical_section. +- Fix memory corruption when pvscan reports long pv names. +- Do not report internal orphan VG names when reporting pvdisplay/pvscan. +- Fix pvdisplay -c man page referencing KB instead of sectors. +- Skip redundant synchronization calls on local clvmd. +- Use correct PATH_MAX for locking dir path. +- Do not check for backups when when its creation is disabled. +- Don't allow --mergedconfig without --type current in dumpconfig. Fix memleak. +- Make global/lvdisplay_shows_full_device_path lvm.conf setting profilable. +- Make global/{units|si_unit_consistency|suffix} lvm.conf setting profilable. +- Validate minimal chunk size for snapshot COW volume in lvconvert. +- Disallow lvconvert of origin to snapshot COW volume. +- Make report lvm.conf settings profilable. +- Add existing report settings to lvm.conf. +- Use VG read lock during 'pvscan --cache -aay' autoactivation. +- Issue a VG refresh before autoactivation only if the PV has changed/is new. +- Add flag to lvmetad protocol to indicate the PV scanned has changed/is new. +- Also add vgname to lvmetad protocol when referencing VGs for PVs scanned. +- Add man page for lvm2-activation-generator. +- Don't print an error and accept empty value for global/thin_disabled_features. +- Do not try to check empty pool with scheduled messages. +- Fix return value in pool_has_message() when quering for any message. +- Cleanup all client resources on clvmd exit. +- Use BLKID_CFLAGS when compiling with blkid support. +- Make lvm 'dumpconfig --type default' complete for it to be consumed by lvm. +- Run pvscan --cache via systemd-run in udev if the PV label is detected lost. +- Fix memleak when lvmetad discovers PV to appear on another device. +- Fix calculation of maximum size of COW device for snapshot (2.02.99). +- Do not allow stripe size to be bigger then extent size for lvresize. +- Zero snapshot COW header when creating read-only snapshot. +- Comment out config lines in dumpconfig output without default values defined. +- Improve detection of clustered mirror support. +- Enhance raid code with feature flags, for now checks for raid10. +- Move parsing of VG metadata from vg_commit() back to vg_write() (2.02.99) +- Avoid a PV label scan while in a critical section. +- Create /dev/disk/by-id/lvm-pv-uuid- symlink for each PV via udev. +- lvcreate computes RAID4/5/6 stripes if not given from # of allocatable PVs. +- Fix merging of old snapshot into thin volume origin. +- Use --ignoreskippedcluster in lvm2-monitor initscript/systemd unit. +- Do not use VG read/write state for LV read/write state. +- Use --ignoreskippedcluster in activation systemd units if use_lvmetad=0. +- Allow approximate allocation when specifying size in percentage terms. +- Add basic LVM support for cache[pool] segment types. +- Use local exclusive activation for creation of raid in cluster. +- Use correctly signed 64b constant when selecting raid volumes. +- Remove ExecReload from lvmetad systemd unit: lvmetad -R undefined. (2.02.98) +- Do not fork lvmetad if running under systemd. +- Wipe DM_snapshot_cow signature without prompt in new LVs with blkid wiping. +- Avoid exposing temporary devices when initializing raid metadata volumes. +- Add internal tags command to display any tags defined on the host. +- Prohibit use of external origin with size incompatible with thin pool. +- Avoid trying to convert single to thin pool and volume at the same time. +- Add support for partitions on ZFS zvol. +- Fix unwanted drop of hold flocks on forked children. +- Respect LVM_LVMETAD_PIDFILE env var for lvm command. +- Fix test when checking target version for available thin features. +- Detect thin feature external_origin_extend and limit extend when missing. +- Issue error if libbblkid detects signature and fails to return offset/length. +- Update autoconf config.guess/sub to 2014-01-01. +- Online thin pool metadata resize requires 1.10 kernel thin pool target. +- Check for sprintf error when building internal device path. +- Check for sprintf error when creating path for dm control node. +- When buffer for dm_get_library_version() is too small, return error code. +- Always reinitialize _name_mangling_mode in dm_lib_init(). +- Stop timeout thread immediately when the last worker thread is finished. +- Fix dmeventd logging with parallel wait event processing. +- Reuse _node_send_messages() for validation of transaction_id in preload. +- Transaction_id could be lower by one only when messages are prepared. +- Wrap is_selinux_enabled() to be called just once. +- Use correctly signed 64b constant when working with raid volumes. +- Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request. +- Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol. +- Do not use systemd's reload for dmeventd restart, use dmeventd -R instead. + +* Mon Jan 27 2014 Peter Rajnoha - 2.02.105-2 +- Avoid exposing temporary devices when initializing thin pool volume. +- Remove udev rule for multipath's PATH_FAILED event processing, + multipath handles that properly in its own udev rules now. +- Remove duplicate udev rule for cryptsetup temporary devices, + cryptsetup handles that properly directly in its code. + +* Tue Jan 21 2014 Peter Rajnoha - 2.02.105-1 +- Fix thin LV flagging for udev to skip scanning only if the LV is wiped. +- Replace use of xfs_check with xfs_repair in fsadm. +- Mark lvm1 format metadata as FMT_OBSOLETE. Do not use it with lvmetad. +- Invalidate cached VG struct after a PV in it gets orphaned. (2.02.87) +- Mark pool format metadata as FMT_OBSOLETE. +- Use major:minor in lvm2-pvscan@.service for proper global_filter application. +- Syntax and spelling fixes in some man pages. +- Dependency scan counts with snapshots and external origins. +- Make sure VG extent size is always greater or equal to PV phys. block size. +- Optimize double call of stat() for cached devices. +- Enable support for thin provisioning for default configuration. +- Disable online thin pool metadata resize for 1.9 kernel thin target. +- Shortened code for initialization of raid segment types. +- Test for remote exclusive activation after activation fails. +- Support lvconvert --merge for thin snapshots. +- Add support to read thin device id from table line entry. +- Drop extra test for origin when testing merging origin in lv_refresh(). +- Extend lv_remove_single() to not print info about removed LV. +- Replace open_count check with lv_check_not_in_use() for snapshot open test. +- Add error messages with LV names for failing lv refresh. +- Compile/link executables with new RELRO and PIE options (non-static builds). +- Support per-object compilation cflags via CFLAGS_object.o. +- Automatically detect support for compiler/linker options to use RELRO and PIE. +- Add --splitsnapshot to lvconvert to separate out cow LV. +- Reinstate origin reload to complete lvconvert -s with active LVs. (2.02.98) +- Select only active volume groups if vgdisplay -A is used. +- Add -p and LVM_LVMETAD_PID env var to lvmetad to change pid file. +- Allow lvmetad to reuse stale socket. +- Only unlink lvmetad socket on error if created by the same process. +- Append missing newline to lvmetad missing socket path error message. +- Add allocation/use_blkid_wiping to lvm.conf to enable blkid wiping. +- Enable blkid_wiping by default if the blkid library is present. +- Add configure --disable-blkid_wiping to disable libblkid signature detection. +- Add -W/--wipesignatures lvcreate option to support wiping on new LVs. +- Add allocation/wipe_signatures_when_zeroing_new_lvs to lvm.conf. +- Do not fail the whole autoactivation if the VG refresh done before fails. +- Do not connect to lvmetad on vg/lvchange --sysinit -aay and socket absent. +- Use lv_check_not_in_use() when testing device in use before merging. +- Check for failure of lvmcache_add_mda() when writing pv. +- Check for failure of dev_get_size() when reporting device size. +- Drop extra unneeded '/' when scanning sysfs directory. +- Fix undef value if skipped clustered VG ignored for toollib PV seg. (2.02.103) +- Support validation of VG/LV names in liblvm/python. +- Allow creation of PVs with arguments to liblvm/python. +- Ensure sufficient metadata copies retained in liblvm/python vgreduce. +- Fix installation of profiles from conf subdir when not building in srcdir. +- Show UUIDs for missing PVs in reports. +- Add reporting of thin_id device id for thin volumes. +- Fix reporting of empty numerical values for recently-added fields. +- Revert activation of activated nodes if a node preload callback fails. +- Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY. +- Ensure global mutex is held when working with dmeventd thread. +- Drop taking timeout mutex for un/registering dmeventd monitor. +- Allow section names in config file data to be quoted strings. +- Close fifos before exiting in dmeventd restart() error path. +- Catch invalid use of string sort values when reporting numerical fields. +- Require util-linux >= 2.24 for blkid wiping support (via device-mapper pkg). +- Add BuildRequires: libblkid-devel to build with blkid wiping functionality. +- Do not install /run and /run/lvm directory but only own them by lvm2 package. + These dirs are controlled by systemd's tmpfiles.d/lvm2.conf configuration. +- Consolidate file permissions for all packaged files. + +* Thu Jan 16 2014 Ville Skyttä - 2.02.104-4 +- Drop INSTALL from docs, escape percents in %%changelog. + +* Fri Dec 13 2013 Peter Rajnoha - 2.02.104-3 +- Change lvm2-python-libs to require lvm2, not just lvm2-libs. + +* Wed Dec 11 2013 Peter Rajnoha - 2.02.104-2 +- Fix SYSTEMD_READY assignment for foreign devs in lvmetad rules. + +* Thu Nov 14 2013 Peter Rajnoha - 2.02.104-1 +- Workaround VG refresh race during autoactivation by retrying the refresh. +- Handle failures in temporary mirror used when adding images to mirrors. +- Fix and improve logic for implicitely exclusive activations. +- Return success when LV cannot be activated because of volume_list filter. +- Return proper error state for remote exclusive activation. +- Fix clvmd message verification to not reject REMOTE flag. (2.02.100) +- Compare equality of double values with DBL_EPSILON predefined constant. +- Use additional gcc warning flags by default. +- Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors. +- Use #ifdef __linux__ instead of linux throughout. +- Consistently report on stderr when device is not found for dmsetup info. +- Skip race errors when non-udev dmsetup build runs on udev-enabled system. +- Skip error message when holders are not present in sysfs. + +* Wed Oct 30 2013 Peter Rajnoha - 2.02.103-3 +- Fix missing lvmetad scan for PVs found on MD partitions. +- Respect DM_UDEV_DISABLE_OTHER_RULES_FLAG in lvmetad udev rules. + +* Fri Oct 25 2013 Peter Rajnoha - 2.02.103-2 +- Add internal flag for temporary LVs to properly direct udev to not interfere. +- Fix endless loop in blkdeactivate ... if unable to umount/deactivate. +- Add dev-block-:.device systemd alias for complete PV tracking. +- Use major:minor as short form of --major and --minor arg for pvscan --cache. +- Remove 2>/dev/null from three lvm commands executed by vgimportclone. +- Add configure --enable-udev-systemd-background-jobs. +- Add lvm2-pvscan@.service to run pvscan as a service for lvmetad/autoactivation. +- Fix lvconvert swap of poolmetadata volume for active thin pool. +- Check for open count with a timeout before removal/deactivation of an LV. +- Report RAID images split with tracking as out-of-sync ("I"). +- Improve parsing of snapshot lv segment. +- Add workaround for deactivation problem of opened virtual snapshot. +- Disable unsupported merge for virtual snapshot. +- Move code to remove virtual snapshot from tools to lib for lvm2app. +- Fix possible race during daemon worker thread creation (lvmetad). +- Fix possible deadlock while clearing lvmetad cache for full rescan. +- Fix possible race while creating/destroying memory pools. +- Recognise NVM Express devices in filter. +- Fix failing metadata repair when lvmetad is used. +- Fix incorrect memory handling when reading messages from lvmetad. +- Fix locking in lvmetad when handling the PV which is gone. +- Recognize new flag to skip udev scanning in udev rules and act appropriately. +- Add support for flagging an LV to skip udev scanning during activation. +- Improve message when unable to change discards setting on active thin pool. +- Run full scan before vgrename operation to avoid any cache name collision. +- Fix lvconvert when converting to a thin pool and thin LV at once. +- Skip race errors when non-udev dmsetup build runs on udev-enabled system. +- Skip error message when holders are not present in sysfs. +- Use __linux__ instead of linux define to make libdevmapper.h C compliant. + +* Fri Oct 04 2013 Peter Rajnoha - 2.02.103-1 +- Ensure vgid matches before removing vgname entry from lvmetad cache. +- Add --ignoreskippedcluster for exit status success when clustered VGs skipped. +- Fix 3 minute udev timeout so that it is applied for all LVM volumes. +- Fix thin/raid & activation config defaults with configure --disable-devmapper. +- Fix RAID calculation for sufficient allocatable space. +- lvconvert from linear to mirror or RAID1 now honors mirror_segtype_default. +- Add thin-performance configuration profile. +- Add lvm.conf allocation/thin_pool_chunk_size_policy option. +- Fix contiguous & cling allocation policies for parity RAID. (2.02.100) +- Have lvmconf --enable/disable-cluster reset/set use_lvmetad. +- Add seg_size_pe field to reports. +- Support start+length notation with command line PE ranges. +- Exit cleanly with message when pvmove cannot restart because LV is inactive. +- Define symbolic names for subsystem udev flags in libdevmapper for easier use. +- Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*. + +* Tue Sep 24 2013 Peter Rajnoha - 2.02.102-1 +- Fix missing build dependency for scripts subdir in Makefile. +- Fix node up/down handling in clvmd corosync module. +- Fix 3-thread clvmd deadlock triggered by cleanup on EOF from client. +- Remove VG from lvmetad before restoring it with vgcfgrestore. +- Add devtypes report command to display built-in recognised block device types. +- Fix CC Makefile override which had reverted to using built-in value. (2.02.75) +- Recognise bcache block devices in filter (experimental). +- Run lvm2-activation-net after lvm2-activation service to prevent parallel run. +- Add man page entries for lvmdump's -u and -l options. +- Fix lvm2app segfault while using lvm_list_pvs_free fn if there are no PVs. +- Improve of clvmd singlenode locking simulation. +- lvconvert no longer converts LVs of "mirror" segment type to thinpool. +- lvconvert no longer converts thinpool sub-LVs to "mirror" segment type. +- Direct udev to use 3min timeout for LVM devices. Recent udev has default 30s. +- Do not scan multipath or RAID components and avoid incorrect autoactivation. +- Fix MD/loop udev handling to fire autoactivation after setup or coldplug only. +- Make RAID capable of single-machine exclusive operations in a cluster. +- Drop calculation of read ahead for deactivated volume. +- Check for exactly one lv segment in validation of thin pools and volumes. +- Fix dmeventd unmonitoring of thin pools. +- Fix lvresize for stacked thin pool volumes (i.e. mirrors). +- Write Completed debug message before reinstating log defaults after command. +- Refresh existing VG before autoactivation (event retrigger/device reappeared). +- Use pvscan -b in udev rules to avoid a deadlock on udev process count limit. +- Add pvscan -b/--background for the command to be processed in the background. +- Don't assume stdin file descriptor is readable. +- Avoid unlimited recursion when creating dtree containing inactive pvmove LV. +- Require exactly 3 arguments for lvm2-activation-generator. Remove defaults. +- Inform lvmetad about any lost PV label to make it in sync with system state. +- Support most of lvchange operations on stacked thin pool meta/data LVs. +- Enable non-clustered pvmove of snapshots and snapshot origins. +- Add ability to pvmove non-clustered RAID, mirror, and thin volumes. +- Make lvm2-activation-generator silent unless it's in error state. +- Remove "mpath major is not dm major" msg for mpath component scan (2.02.94). +- Prevent cluster mirror logs from being corrupted by redundant checkpoints. +- Fix ignored lvmetad update on loop device configuration (2.02.99). +- Use LVM_PATH instead of hardcoded value in lvm2 activation systemd generator. +- Fix vgck to notice on-disk corruption even if lvmetad is used. +- Move mpath device filter before partitioned filter (which opens devices). +- Require confirmation for vgchange -c when no VGs listed explicitly. +- Also skip /var and /var/log by default in blkdeactivate when unmounting. +- Add support for bind mounts in blkdeactivate. +- Add blkdeactivate -v/--verbose for debug output from external tools used. +- Add blkdeactivate -e/--errors for error messages from external tools used. +- Suppress messages from external tools called in blkdeactivate by default. +- Fix inability to remove a VG's cluster flag if it contains a mirror. +- Fix bug making lvchange unable to change recovery rate for RAID. +- Prohibit conversion of thin pool to external origin. +- Workaround gcc v4.8 -O2 bug causing failures if config/checks=1 (32bit arch). +- Verify clvmd message validity before processing and log error if incorrect. +- When creating PV on existing LV don't forbid reserved LV names on LVs below. +- When converting mirrors, default segtype should be the same unless specified. +- Make "raid1" the default mirror segment type. +- Fix clogd descriptor leak when daemonizing. +- Fix clvmd descriptor leak on restart. +- Add pipe_open/close() to use instead of less efficient/secure popen(). +- Inherit and apply any profile attached to a VG if creating new thin pool. +- Add initial support thin pool lvconvert --repair. +- Add --with-thin-repair and --with-thin-dump configure options. +- Add lvm.conf thin_repair/dump_executable and thin_repair_options. +- Require 1.9 thin pool target version for online thin pool metadata resize. +- Ignore previous LV seg with alloc contiguous & cling when num stripes varies. +- Fix segfault if devices/global_filter is not specified correctly. +- Tidy dmeventd fifo initialisation. +- Detect invalid sector supplied to 'dmsetup message'. +- Free any previously-set string if a dm_task_set_* function is called again. +- Do not allow passing empty new name for dmsetup rename. +- Display any output returned by 'dmsetup message'. +- Add dm_task_get_message_response to libdevmapper. +- Create dmeventd timeout threads as "detached" so exit status is freed. +- Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors. + +* Tue Aug 06 2013 Peter Rajnoha - 2.02.99-2 +- Fix metadata area offset/size overflow if it's >= 4g and while using lvmetad. +- Require the newest device-mapper-persistent-data-0.2.3-1. +- Fix spec file's util-linux version definition for proper expansion when used. + +* 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. +- 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. +- 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. +- Automatically restore MISSING PVs with no MDAs. +- 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. +- 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. +- Remove python liblvm object. systemdir can only be changed using env var now. +- 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(). +- 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 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. +- 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. +- When no --stripes argument is given when creating a RAID10 volume, default to 2 stripes. +- Do not allow lvconvert --splitmirrors on RAID10 logical volumes. +- Repair a mirrored log before the mirror itself when both fail. +- Avoid trying to read a mirror that has a failed device in its mirrored log. +- 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. +- Check for memory failure of dm_config_write_node() in lvmetad. +- 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. +- 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. +- 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. +- 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). +- Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). +- 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. +- 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. +- 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. +- 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. + +* Fri May 03 2013 Peter Rajnoha - 2.02.98-8 +- Fix non-functional autoactivation of LVM volumes on top of MD devices. + +* Fri Apr 19 2013 Peter Rajnoha - 2.02.98-7 +- Autoactivate VG/LV on coldplug of DM-based PVs at boot. + +* Tue Apr 09 2013 Peter Rajnoha - 2.02.98-6 +- 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. + +* Thu Feb 14 2013 Fedora Release Engineering - 2.02.98-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Dec 06 2012 Peter Rajnoha - 2.02.98-4 +- Skip mlocking [vectors] on arm architecture. + +* Sat Nov 17 2012 Peter Rajnoha - 2.02.98-3 +- Add lvm2-activation-generator systemd generator to automatically generate + systemd units to activate LVM2 volumes even if lvmetad is not used. + This replaces lvm activation part of the former fedora-storage-init + script that was included in the initscripts package before. +- Enable lvmetad - the LVM metadata daemon by default. +- 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. +- Init lvmetad lazily to avoid early socket access on config overrides. +- Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. +- Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. + +* Sat Oct 20 2012 Peter Rajnoha - 2.02.98-2 +- Incorporate former python-lvm package in lvm2 as lvm2-python-libs subpackage. + +* Tue Oct 16 2012 Peter Rajnoha - 2.02.98-1 +- Don't try to issue discards to a missing PV to avoid segfault. +- Fix vgchange -aay not to activate non-matching LVs that follow a matching LV. +- Fix lvchange --resync for RAID LVs which had no effect. +- Add RAID10 support (--type raid10). +- Introduce blkdeactivate script to deactivate block devs with dependencies. +- Apply 'dmsetup mangle' for dm UUIDs besides dm names. +- Use -q as short form of --quiet. +- Suppress non-essential stdout with -qq. +- Add log/silent to lvm.conf equivalent to -qq. +- Add (p)artial attribute to lvs. +- Implement devices/global_filter to hide devices from lvmetad. +- Add lvmdump -l, to collect a state dump from lvmetad. +- Add --discards to lvconvert. +- Add support for lvcreate --discards. +- Add --poolmetadata to lvconvert and support thin meta/data dev stacking. +- Support creation of read-only thin volumes (lvcreate -p r). +- Support changes of permissions for thin snapshot volumes. +- Make lvremove ask before discarding data areas. +- Prohibit not yet supported change of thin-pool to read-only. +- Using autoextend percent 0 for thin pool fails 'lvextend --use-policies'. +- Make vgscan --cache an alias for pvscan --cache. +- Clear lvmetad metadata/PV cache before a rescan. +- Fix a segmentation fault upon receiving a corrupt lvmetad response. +- Give inconsistent metadata warnings in pvscan --cache. +- Avoid overlapping locks that could cause a deadlock in lvmetad. +- Fix memory leaks in libdaemon and lvmetad. +- Optimize libdaemon logging for a fast no-output path. +- Only create lvmetad pidfile when running as a daemon (no -f). +- Warn if lvmetad is running but disabled. +- Warn about running lvmetad with use_lvmetad = 0 in example.conf. +- Update lvmetad help output (flags and their meaning). +- Make pvscan --cache read metadata from LVM1 PVs. +- Make libdaemon buffer handling asymptotically more efficient. +- Make --sysinit suppress lvmetad connection failure warnings. +- Prohibit usage of lvcreate --thinpool with --mirrors. +- Fix lvm2api origin reporting for thin snapshot volume. +- Add implementation of lvm2api function lvm_percent_to_float. +- Allow non power of 2 thin chunk sizes if thin pool driver supports that. +- Allow limited metadata changes when PVs are missing via [vg|lv]change. +- Do not start dmeventd for lvchange --resync when monitoring is off. +- Remove pvscan --cache from lvm2-lvmetad init script. +- Remove ExecStartPost with pvscan --cache from lvm2-lvmetad.service. +- Report invalid percentage for property snap_percent of non-snaphot LVs. +- Disallow conversion of thin LVs to mirrors. +- Fix lvm2api data_percent reporting for thin volumes. +- Do not allow RAID LVs in a clustered volume group. +- Enhance insert_layer_for_lv() with recursive rename for _tdata LVs. +- Skip building dm tree for thin pool when called with origin_only flag. +- Ensure descriptors 0,1,2 are always available, using /dev/null if necessary. +- Use /proc/self/fd when available for closing opened descriptors efficiently. +- Fix inability to create, extend or convert to a large (> 1TiB) RAID LV. +- Update lvmetad communications to cope with clients using different filters. +- Clear LV_NOSYNCED flag when a RAID1 LV is converted to a linear LV. +- Disallow RAID1 upconvert if the LV was created with --nosync. +- Depend on systemd-udev-settle in units generated by activation generator. +- Disallow addition of RAID images until the array is in-sync. +- Fix RAID LV creation with '--test' so valid commands do not fail. +- Add lvm_lv_rename() to lvm2api. +- Fix setvbuf code by closing and reopening stream before changing buffer. +- Disable private buffering when using liblvm. +- When private stdin/stdout buffering is not used always use silent mode. +- Fix 32-bit device size arithmetic needing 64-bit casting throughout tree. +- Fix dereference of NULL in lvmetad error path logging. +- Fix buffer memory leak in lvmetad logging. +- Correct the discards field in the lvs manpage (2.02.97). +- Use proper condition to check for discards settings unsupported by kernel. +- Reinstate correct default to ignore discards for thin metadata from old tools. +- Issue error message when -i and -m args do not match specified RAID type. +- Change lvmetad logging syntax from -ddd to -l {all|wire|debug}. +- Add new libdaemon logging infrastructure. +- Support unmount of thin volumes from pool above thin pool threshold. +- Update man page to reflect that dm UUIDs are being mangled as well. +- Add 'mangled_uuid' and 'unmangled_uuid' fields to dmsetup info -c -o. +- Mangle device UUID on dm_task_set_uuid/newuuid call if necessary. +- Add dm_task_get_uuid_mangled/unmangled to libdevmapper. +- Always reset delay_resume_if_new flag when stacking thin pool over anything. +- Don't create value for dm_config_node and require dm_config_create_value call. +- Check for existing new_name for dmsetup rename. +- Fix memory leak in dmsetup _get_split_name() error path. +- Clean up spec file and keep support only for Fedora 18 upwards. +- Use systemd macros in rpm scriptlets to set up systemd units. +- Add Requires: bash >= 4.0 for blkdeactivate script. + +* Tue Aug 07 2012 Alasdair Kergon - 2.02.97-1 +- Improve documention of allocation policies in lvm.8. +- Increase limit for major:minor to 4095:1048575 when using -My option. +- Add generator for lvm2 activation systemd units. +- Add lvm_config_find_bool lvm2app fn to retrieve bool value from config tree. +- Respect --test when using lvmetad. +- No longer capitalise first LV attribute char for invalid snapshots. +- Allow vgextend to add PVs to a VG that is missing PVs. +- Recognise Micron PCIe SSDs in filter and move array out to device-types.h. +- Fix dumpconfig to print only without its siblings. (2.02.89) +- Do not issue "Failed to handle a client connection" error if lvmetad killed. +- Support lvchange --discards and -Z with thin pools. +- Add discard LV segment field to reports. +- Add --discards to lvcreate --thin. +- Set discard and external snapshot features if thin pool target is vsn 1.1+. +- Count percentage of completeness upwards not downwards when merging snapshot. +- Skip activation when using vg/lvchange --sysinit -a ay and lvmetad is active. +- Fix extending RAID 4/5/6 logical volumes +- Fix test for PV with unknown VG in process_each_pv to ignore ignored mdas. +- Fix _alloc_parallel_area to avoid picking already-full areas for raid devices. +- Never issue discards when LV extents are being reconfigured, not deleted. +- Allow release_lv_segment_area to fail as functions it calls can fail. +- Fix missing sync of filesystem when creating thin volume snapshot. +- Allow --noflush with dmsetup status and wait (for thin target). +- Add dm_config_write_one_node to libdevmapper. +- Add dm_vasprintf to libdevmapper. +- Support thin pool message release/reserve_metadata_snap in libdevmapper. +- Support thin pool discards and external origin features in libdevmapper. + +* Thu Jul 19 2012 Fedora Release Engineering - 2.02.96-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 04 2012 Peter Rajnoha - 2.02.96-3 +- Use configure --with-default-pid-dir=/run. +- Use globally set prefix for udev rules path. + +* Mon Jul 02 2012 Peter Rajnoha - 2.02.96-2 +- Compile with lvmetad support enabled. +- Add support for volume autoactivation using lvmetad. +- Update man pages with --activate ay option and auto_activation_volume_list. +- Use vgchange -aay instead of vgchange -ay in clmvd init script. +- Add activation/auto_activation_volume_list to lvm.conf. +- Add --activate ay to lvcreate, lvchange, pvscan and vgchange. +- Add --activate synonym for --available arg and prefer --activate. +- Open device read-only to obtain readahead value. +- Add configure --enable-udev-rule-exec-detection to detect exec path in rules. +- Use sbindir in udev rules by default and remove executable path detection. +- Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir. +- Add configure --with-lvmetad-pidfile to remove hard-coded value. +- Add configure --with-default-pid-dir for common directory with pid files. +- Add configure --with-default-dm-run-dir to set run directory for dm tools. +- Add documentation references in systemd units. +- Clean up spec file and keep support only for Fedora 17 upwards. + +* Mon Jun 18 2012 Alasdair Kergon - 2.02.96-1 +- Require device-mapper-persistent-data package for thin provisioning. +- Set delay_resume_if_new on deptree snapshot origin. +- Log value chosen in _find_config_bool like other variable types do. +- Wait for dmeventd to exit after sending it DM_EVENT_CMD_DIE when restarting. +- Append 'Used' to {Blk}DevNames/DevNos dmsetup report headers for clarity. +- Remove dmeventd fifos on exit if they are not managed by systemd. +- Use SD_ACTIVATION environment variable in systemd units to detect systemd. +- Only start a new dmeventd instance on restart if one was already running. +- Extend the time waited for input from dmeventd fifo to 5 secs. (1.02.73) +- Fix error paths for regex filter initialization. +- Re-enable partial activation of non-thin LVs until it can be fixed. (2.02.90) +- Fix alloc cling to cling to PVs already found with contiguous policy. +- Fix cling policy not to behave like normal policy if no previous LV seg. +- Fix allocation loop not to use later policies when --alloc cling without tags. +- Fix division by zero if PV with zero PE count is used during vgcfgrestore. +- Add initial support for thin pool lvconvert. +- Fix lvrename for thin volumes (regression in for_each_sub_lv). (2.02.89) +- Fix up-convert when mirror activation is controlled by volume_list and tags. +- Warn of deadlock risk when using snapshots of mirror segment type. +- Fix bug in cmirror that caused incorrect status info to print on some nodes. +- Remove statement that snapshots cannot be tagged from lvm man page. +- Disallow changing cluster attribute of VG while RAID LVs are active. +- Fix lvconvert error message for non-mergeable volumes. +- Allow subset of failed devices to be replaced in RAID LVs. +- Prevent resume from creating error devices that already exist from suspend. +- Update and correct lvs man page with supported column names. +- Handle replacement of an active device that goes missing with an error device. +- Change change raid1 segtype always to request a flush when suspending. +- Add udev info and context to lvmdump. +- Add lvmetad man page. +- Fix RAID device replacement code so that it works under snapshot. +- Fix inability to split RAID1 image while specifying a particular PV. +- Update man pages to give them all the same look&feel. +- Fix lvresize of thin pool for striped devices. +- For lvresize round upward when specifying number of extents. +- For lvcreate with %%FREE support rounding downward stripe alignment. +- Change message severity to log_very_verbose for missing dev info in udev db. +- Fix lvconvert when specifying removal of a RAID device other than last one. +- Fix ability to handle failures in mirrored log in dmeventd plugin. (2.02.89) +- Fix unlocking volume group in vgreduce in error path. +- Cope when VG name is part of the supplied name in lvconvert --splitmirrors -n. +- Fix exclusive lvchange running from other node. (2.02.89) +- Add 'vgscan --cache' functionality for consistency with 'pvscan --cache'. +- Keep exclusive activation in pvmove if LV is already active. +- Disallow exclusive pvmove if some affected LVs are not exclusively activated. +- Remove unused and wrongly set cluster VG flag from clvmd lock query command. +- Fix pvmove for exclusively activated LV pvmove in clustered VG. (2.02.86) +- Update and fix monitoring of thin pool devices. +- Check hash insert success in lock_vg in clvmd. +- Check for buffer overwrite in get_cluster_type() in clvmd. +- Fix global/detect_internal_vg_cache_corruption config check. +- Fix initializiation of thin monitoring. (2.02.92) +- Cope with improperly formatted device numbers in /proc/devices. (2.02.91) +- Exit if LISTEN_PID environment variable incorrect in lvmetad systemd handover. +- Fix fsadm propagation of -e option. +- Fix fsadm parsing of /proc/mounts files (don't check for substrings). +- Fix fsadm usage of arguments with space. +- Fix arg_int_value alongside ARG_GROUPABLE --major/--minor for lvcreate/change. +- Fix name conflicts that prevent down-converting RAID1 when specifying a device +- Improve thin_check option passing and use configured path. +- Add --with-thin-check configure option for path to thin_check. +- Fix error message when pvmove LV activation fails with name already in use. +- Better structure layout for device_info in dev_subsystem_name(). +- Change message severity for creation of VG over uninitialised devices. +- Fix error path for failed toolcontext creation. +- Don't unlink socket on lvmetad shutdown if instantiated from systemd. +- Restart lvmetad automatically from systemd if it exits from uncaught signal. +- Fix warn msg for thin pool chunk size and update man for chunksize. (2.02.89) + +* Thu Jun 07 2012 Kay Sievers - 2.02.95-8 +- Remove explicit Requires: libudev, rpm takes care of that: + $ rpm -q --requires device-mapper | grep udev + libudev.so... + +* Tue Jun 05 2012 Peter Rajnoha - 2.02.95-7 +- Use BuildRequires: systemd-devel instead of BuildRequires: libudev-devel. +- Remove unsupported udev_get_dev_path libudev call used for checking udev dir. + +* Thu Mar 29 2012 Fabio M. Di Nitto - 2.02.95-6 +- BuildRequires and Requires on newer version of corosync and dlm. +- Restart clvmd on upgrades. + +* Mon Mar 19 2012 Peter Rajnoha - 2.02.95-5 +- Do not strictly require openais for cmirror subpackage. + +* Mon Mar 19 2012 Peter Rajnoha - 2.02.95-4 +- Reinstate cmirror support. +- Detect lvm binary path in lvmetad udev rules. +- Use pvscan --cache instead of vgscan in systemd units/init scripts. + +* Fri Mar 16 2012 Fabio M. Di Nitto - 2.02.95-3 +- Rebuild against new corosync (soname change). +- BuildRequires and Requires on newer version of corosync. + +* Thu Mar 08 2012 Peter Rajnoha - 2.02.95-2 +- Reload dm-event systemd service on upgrade. + +* Tue Mar 06 2012 Alasdair Kergon - 2.02.95-1 +- If unspecified, adjust thin pool metadata and chunk size to fit into 128MB. +- Deactivation of failed thin check on thin pool returns success. +- Check for multiply-mangled names in auto mangling mode. +- Fix dm_task_get_name_unmangled to not unmangle already unmangled name. +- Check whether device names are properly mangled on ioctl return. + +* Sat Mar 03 2012 Alasdair Kergon - 2.02.94-1 +- Add support to execute thin_check with each de/active of thin pool. +- Fix automatic estimation of metadata device size for thin pool. +- Wipe initial 4KiB of non zeroed thin volumes. +- Update code-base to incorporate new metadata daemon. (Not used in Fedora yet.) +- Numerous minor cleanups across the code-base. +- Fix dmsetup / dm_task_set_name to properly resolve path to dm name. (2.02.93) + +* Thu Feb 23 2012 Alasdair Kergon - 2.02.93-1 +- Moved systemd tmpfiles installation upstream for lvm2 lock and run dirs. +- Require number of stripes to be greater than parity devices in higher RAID. +- Fix allocation code to allow replacement of single RAID 4/5/6 device. +- Check all tags and LV names are in a valid form before writing any metadata. +- Allow 'lvconvert --repair' to operate on RAID 4/5/6. +- Fix build_parallel_areas_from_lv to account correctly for raid parity devices. +- Print message when faulty raid devices have been replaced. + +* Mon Feb 20 2012 Alasdair Kergon - 2.02.92-1 +- Read dmeventd monitoring config settings for every lvm command. +- For thin devices, initialize monitoring only for thin pools not thin volumes. +- Make conversion from a synced 'mirror' to 'raid1' not cause a full resync. +- Add clvmd init dependency on dlm service when running with new corosync. +- Switch to using built-in blkid in 13-dm-disk.rules. +- Add "watch" rule to 13-dm-disk.rules. +- Detect failing fifo and skip 20s retry communication period. +- Replace any '\' char with '\\' in dm table specification on input. +- New 'mangle' options in dmsetup/libdevmapper for transparent reversible + encoding of characters that udev forbids in device names. +- Add --manglename option to dmsetup to select the name mangling mode. +- Add mangle command to dmsetup to provide renaming to correct mangled form. +- Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o. +- Mangle device name on dm_task_set_name/newname call if necessary. +- Add dm_task_get_name_mangled/unmangled to libdevmapper. +- Add dm_set/get_name_mangling_mode to set/get name mangling in libdevmapper. + +* Mon Feb 13 2012 Peter Rajnoha - 2.02.91-2 +- Add configure --with-systemdsystemunitdir. + +* Sun Feb 12 2012 Alasdair Kergon - 2.02.91-1 +- New upstream with trivial fixes and refactoring of some lvmcache and orphan code. + +* Wed Feb 1 2012 Alasdair Kergon - 2.02.90-1 +- Drop support for cman, openais and cmirror for f17. Require dlm not cluster. +- Automatically detect whether corosync clvmd needs to use confdb or cmap. +- Disable partial activation for thin LVs and LVs with all missing segments. +- sync_local_dev_names before (re)activating mirror log for initialisation. +- Do not print warning for pv_min_size between 512KB and 2MB. +- Clean up systemd unit ordering and requirements. +- Allow ALLOC_NORMAL to track reserved extents for log and data on same PV. +- Fix data%% report for thin volume used as origin for non-thin snapshot. + +* Thu Jan 26 2012 Alasdair Kergon - 2.02.89-2 +- New upstream release with experimental support for thinly-provisioned devices. +- The changelog for this release is quite long and contained in + WHATS_NEW and WHATS_NEW_DM in the documentation directory. + +* Fri Jan 13 2012 Fedora Release Engineering - 2.02.88-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Dec 30 2011 Peter Robinson - 2.02.88-2 +- update util-linux-ng -> util-linux dependency as it changed long ago. + +* Mon Aug 22 2011 Alasdair Kergon - 2.02.88-1 +- Remove incorrect 'Breaking' error message from allocation code. (2.02.87) +- Add lvconvert --merge support for raid1 devices split with --trackchanges. +- Add --trackchanges support to lvconvert --splitmirrors option for raid1. +- Add dm_tree_node_add_null_area for temporarily-missing raid devs tracked. +- Support lvconvert of -m1 raid1 devices to a higher number. +- Support splitting off a single raid1 rimage in lvconvert --splitmirrors. +- Add -V as short form of --virtualsize in lvcreate. + +* Fri Aug 12 2011 Peter Rajnoha - 2.02.87-1 +- Cache and share generated VG structs to improve performance. +- Suppress locking error messages in monitoring init scripts. +- Add global/detect_internal_vg_cache_corruption to lvm.conf. +- If pipe in clvmd fails return busy instead of using uninitialised descriptors. +- Initialise clvmd locks before lvm context to avoid open descriptor leaks. +- Suppress low-level locking errors and warnings while using --sysinit. +- Add test for fcntl error in singlenode client code. +- Compare file size (as well as timestamp) to detect changed config file. +- Change DEFAULT_UDEV_SYNC to 1 so udev_sync is used if there is no config file. +- Update udev rules to skip DM flags decoding for removed devices. +- Remove device name prefix from dmsetup line output if -j & -m or -u supplied. +- Add new segtype 'raid' for MD RAID 1/4/5/6 support with dmeventd plugin. +- Add ability to reduce the number of mirrors in raid1 arrays to lvconvert. +- Add support for systemd file descriptor handover in dmeventd. +- Add systemd unit file to provide lvm2 monitoring. +- Add systemd unit files for dmeventd. +- Use new oom killer adjustment interface (oom_score_adj) when available. +- Fix read-only identical table reload supression. +- Remove --force option from lvrename manpage. + +* Wed Aug 03 2011 Peter Rajnoha - 2.02.86-5 +- Change DEFAULT_UDEV_SYNC to 1 so udev_sync is used even without any config. + +* Thu Jul 28 2011 Peter Rajnoha - 2.02.86-4 +- Add support for systemd file descriptor handover to dmeventd. +- Add support for new oom killer adjustment interface (oom_score_adj). + +* Wed Jul 20 2011 Peter Rajnoha - 2.02.86-3 +- Fix broken lvm2-sysinit Requires: lvm2 dependency. + +* Mon Jul 18 2011 Peter Rajnoha - 2.02.86-2 +- Add dm-event and lvm2-monitor unit files for use with systemd. +- Add sysvinit subpackage for legacy SysV init script support. + +* 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. +- Add activation/checks to lvm.conf to perform additional ioctl validation. +- Append 'm' attribute to pv_attr for missing PVs. +- Fix to preserve exclusive activation of mirror while up-converting. +- Reject allocation if number of extents is not divisible by area count. +- Fix cluster mirror creation to work with new mirror allocation algorithm. +- Ignore activation/verify_udev_operations if dm kernel driver vsn < 4.18. +- Add activation/verify_udev_operations to lvm.conf, disabled by default. +- Ignore inconsistent pre-commit metadata on MISSING_PV devs while activating. +- Add proper udev library context initialization and finalization to liblvm. +- Downgrade critical_section errors to debug level until it is moved to libdm. +- Fix ignored background polling default in vgchange -ay. +- Fix reduction of mirrors with striped segments to always align to stripe size. +- Validate mirror segments size. +- Fix extent rounding for striped volumes never to reduce more than requested. +- Fix create_temp_name to replace any '/' found in the hostname with '?'. +- Always use append to file in lvmdump. selinux policy may ban file truncation. +- Propagate test mode to clvmd to skip activation and changes to held locks. +- Permit --available with lvcreate so non-snapshot LVs need not be activated. +- Clarify error message when unable to convert an LV into a snapshot of an LV. +- Do not issue an error message when unable to remove .cache on read-only fs. +- Avoid memlock size mismatch by preallocating stdio line buffers. +- Report internal error if suspending a device using an already-suspended dev. +- Report internal error if any table is loaded while any dev is known suspended. +- Report error if a table load requiring target parameters has none supplied. +- Add dmsetup --checks and dm_task_enable_checks framework to validate ioctls. +- Add age_in_minutes parameter to dmsetup udevcomplete_all. +- Disable udev fallback by default and add --verifyudev option to dmsetup. +- Add dm_get_suspended_counter() for number of devs in suspended state by lib. +- Fix "all" report field prefix matching to include label fields with pv_all. +- Delay resuming new preloaded mirror devices with core logs in deptree code. + +* Wed Jun 22 2011 Zdenek Kabelac - 2.02.84-3 +- Updated uname string test. + +* Sat Jun 4 2011 Milan Broz - 2.02.84-2 +- Accept kernel 3.0 uname string in libdevmapper initialization. +- Make systemd initscripts configurable. + +* Wed Feb 9 2011 Alasdair Kergon - 2.02.84-1 +- Fix big-endian CRC32 checksumming broken since 2.02.75. If affected, + ensure metadata backups in /etc/lvm/backup are up-to-date (vgcfgbackup) + then after updating to 2.02.84 restore metadata from them (using pvcreate + with -Zn --restorefile and -u if PVs can no longer be seen, then + vgcfgrestore -f). +- Reinstate libdevmapper DEBUG_MEM support. (Removed in 1.02.62.) + +* Tue Feb 08 2011 Fedora Release Engineering - 2.02.83-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Feb 4 2011 Alasdair Kergon - 2.02.83-1 +- Allow exclusive activation of snapshots in a cluster. +- Don't lose LV exclusive lock state when suspending clustered devices. +- Fix fs operation stack handling when multiple operations on same device. +- Increase hash table sizes to 1024 LV names and 64 PV uuids. +- When setting up mda wipe first 4k of it as was intended. +- Remove unneeded checks for open_count in lv_info(). +- Synchronize with udev before checking open_count in lv_info(). +- Add "dmsetup ls --tree" output to lvmdump. +- Fix udev synchronization with no-locking --sysinit (2.02.80). +- Improve man page style consistency for pvcreate, pvremove, pvresize, pvscan. +- Avoid rebuilding of uuid validation table. +- Improve lvcreate error text from insufficient "extents" to "free space". +- Always use O_DIRECT when opening block devices to check for partitioning. +- Move creation of device nodes from 'create' to 'resume'. +- Add --addnodeonresume and --addnodeoncreate options to dmsetup. +- Add dm_task_set_add_node to libdevmapper to control dev node creation time. +- Add dm_task_secure_data to libdevmapper to wipe ioctl buffers in kernel. +- Log debug message when expected uevent is not generated. +- Set DM_UDEV_DISABLE_OTHER_RULES_FLAG for suspended DM devices in udev rules. +- Begin a new pool object for each row in _output_as_rows() correctly. + +* Mon Jan 24 2011 Alasdair Kergon - 2.02.82-2 +- Bring lvscan man page up-to-date. +- Fix lvchange --test to exit cleanly. +- Add change_tag to toollib. +- Allow multiple pvchange command line options to be specified together. +- Do not fail pvmove polling if another process cleaned up first. +- Avoid clvmd incrementing dlm lockspace reference count more than once. +- Add -f (don't fork) option to clvmd and fix clvmd -d description. + +* Mon Jan 17 2011 Alasdair Kergon - 2.02.81-1 +- Add disk to allowed mirrored log type conversions. +- Accept fusion fio in device type filter. +- Speed up command processing by caching resolved config tree. +- Use same dm cookie for consecutive dm ops in same VG to reduce udev waits. +- Do not scan devices in dev_reset_error_count() when forking. +- Skip unnecessary LOCK_NULL unlock call during volume deactivation. +- Skip fs_unlock when calling exec_cmd within activation code (for modprobe). +- Replace fs_unlock by sync_local_dev_names to notify local clvmd. (2.02.80) +- Fix wrongly paired unlocking of VG_GLOBAL in pvchange. (2.02.66) +- Return 0 from cmirrord initscript 'start' if daemon is already running. +- Add DM_COOKIE_AUTO_CREATE to libdevmapper.h. +- Improve general lvconvert man page description. +- Detect NULL handle in get_property(). +- Fix memory leak in persistent filter creation error path. +- Check for errors setting up dm_task struct in _setup_task(). +- Fail polldaemon creation when lvmcache_init() fails. +- Return PERCENT_INVALID for errors in _copy_percent() and _snap_percent(). +- Detect errors from dm_task_set calls in _get_device_info (dmeventd). +- Fix memory leak in debug mode of restart_clvmd() error path. +- Log error message for pthread_join() failure in clvmd. +- Use tmpfiles.d/lvm2.conf to create /var/lock/lvm and /var/run/lvm at boot. +- Require initscripts for tmpfiles.d/lvm2.conf. + +* Tue Dec 21 2010 Alasdair Kergon - 2.02.79-1 +- Create /var/run/lvm directory during clvmd initialisation if missing. +- Avoid revalidating the label cache immediately after scanning. +- Support scanning for a single VG in independent mdas. +- Don't skip full scan when independent mdas are present even if memlock is set. +- Add copy_percent and snap_percent to liblvm. +- Add new dm_prepare_selinux_context fn to libdevmapper and use it throughout. +- Enhance vg_validate to ensure integrity of LV and PV structs referenced. +- Enhance vg_validate to check composition of pvmove LVs. +- Avoid writing to freed memory in vg_release. (2.02.78) +- Add missing test for reallocation error in _find_parallel_space(). +- Add checks for allocation errors in config node cloning. +- Fix error path if regex engine cannot be created in _build_matcher(). +- Check read() and close() results in _get_cmdline(). +- Fix NULL pointer check in error path in clvmd do_command(). (2.02.78) +- Check for unlink failure in remove_lockfile() in dmeventd. +- Use dm_free for dm_malloc-ed areas in _clog_ctr/_clog_dtr in cmirrord. +- Change dm_regex_create() API to accept const char * const *patterns. + +* Mon Dec 6 2010 Alasdair Kergon - 2.02.78-1 +- Miscellaneous error path corrections and minor leaks fixed. +- Avoid misleading PV missing warnings in vgextend --restoremissing. +- Ignore unrecognised allocation policy found in metadata instead of aborting. +- Disallow lvconvert ops that both allocate & free supplied PEs in a single cmd. +- Fix liblvm seg_size to give bytes not sectors. +- Add functions to look up LV/PV by name/uuid to liblvm. +- Suppress 'No PV label' message when removing several PVs without mdas. +- Fix default /etc/lvm permissions to be 0755. (2.02.66) + +* Mon Nov 22 2010 Alasdair Kergon - 2.02.77-1 +- Add PV and LV segment types and functions to liblvm. +- Add set_property functions to liblvm. +- Remove tag length restriction and allow / = ! : # & characters. +- Support repetition of --addtag and --deltag arguments. +- Add infrastructure for specific cmdline arguments to be repeated in groups. +- Fix fsadm no longer to require '-f' to resize an unmounted filesystem. +- Fix fsadm to detect mounted filesystems on older systems. (2.0.75) +- Extend cling allocation policy to recognise PV tags (cling_by_tags). +- Add allocation/cling_tag_list to lvm.conf. + +* Tue Nov 9 2010 Alasdair Kergon - 2.02.76-1 +- Clarify error messages when activation fails due to activation filter use. +- Fix handling of online filesystem resize (using new fsadm return code). +- Modify fsadm to return different status code for check of mounted filesystem. +- Add DIAGNOSTICS section to fsadm man page. +- Update VG metadata only once in vgchange when making multiple changes. +- Allow independent vgchange arguments to be used together. +- Fix vgchange to process -a, --refresh, --monitor and --poll like lvchange. +- Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56) +- Automatically unmount invalidated snapshots in dmeventd. +- Add lvm2app functions to query any pv, vg, or lv property / report field. +- Fix a deadlock caused by double close in clvmd. +- Fix NULL pointer dereference on too-large MDA error path in _vg_read_raw_area. +- Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. +- Fix memory leak of field_id in _output_field function. +- Allocate buffer for reporting functions dynamically to support long outputs. + +* Mon Oct 25 2010 Alasdair Kergon - 2.02.75-1 +- Fix pthread mutex usage deadlock in clvmd. +- Avoid segfault by limiting partial mode for lvm1 metadata. (2.02.74) +- Skip dm devices in scan if they contain only error targets or are empty. +- Don't take write lock in vgchange --refresh, --poll or --monitor. +- Fix hang when repairing a mirrored-log that had both devs fail. +- Speed up unquoting of quoted double quotes and backslashes. +- Speed up CRC32 calculations by using a larger lookup table. +- Implement dmeventd -R to restart without state loss. +- Add --setuuid to dmsetup rename. +- Add global/metadata_read_only to use unrepaired metadata in read-only cmds. +- Automatically extend snapshots with dmeventd according to policy in lvm.conf. +- Add activation/snapshot_autoextend_threshold/percent to lvm.conf. +- Add devices/disable_after_error_count config to limit access to failing devs. +- Implement vgextend --restoremissing to reinstate missing devs that return. +- Read whole /proc/self/maps file before working with maps entries. +- Convey need for snapshot-merge target in lvconvert error message and man page. +- Give correct error message when creating a too-small snapshot. +- Make lvconvert respect --yes and --force when converting an inactive log. +- Better support of noninteractive shell execution of fsadm. +- Fix usage of --yes flag for ReiserFS resize in fsadm. +- Fix detection of mounted filesystems for fsadm when udev is used. +- Fix assignment of default value to LVM variable in fsadm. +- Fix support for --yes flag for fsadm. +- Do not execute lvresize from fsadm --dry-run. +- Fix fsadm return error code from user's break action. +- Return const pointer from dm_basename() in libdevmapper. +- Add dm_zalloc and use it and dm_pool_zalloc throughout. +- Add dm_task_set_newuuid to set uuid of mapped device post-creation. +- Fix missing variable initialization in cluster_send() function from cmirrord. +- Fix pointer for VG name in _pv_resize_single error code path. +- Fix vg_read memory leak with directory-based metadata. +- Fix memory leak of config_tree in reinitialization code path. +- Fix pool destruction order in dmeventd_lvm2_exit() to avoid leak debug mesg. +- Remove dependency on libm by replacing floor() by an integer-based algorithm. +- Refactor and add 'get' functions for pv, vg and lv properties/fields. +- Add pv_get_property and create generic internal _get_property function. +- Make generic GET_*_PROPERTY_FN macros with secondary macro for vg, pv & lv. + +* Fri Oct 15 2010 Alasdair Kergon - 2.02.73-3 +- Add --setuuid to dmsetup rename. +- Add dm_task_set_newuuid to set uuid of mapped device post-creation. + +* Wed Sep 29 2010 jkeating - 2.02.74-2 +- Rebuilt for gcc bug 634757 + +* Fri Sep 24 2010 Alasdair Kergon - 2.02.74-1 +- Fix the way regions are marked complete to avoid slow --nosync cmirror I/O. +- Add DM_REPORT_FIELD_TYPE_ID_LEN to libdevmapper.h. +- Allow : and @ to be escaped with \ in device names of PVs. +- Avoid stack corruption when reading in large metadata. +- Fix partial mode operations for lvm1 metadata format. +- Track recursive filter iteration to avoid refreshing while in use. (2.02.56) +- Allocate buffer for metadata tags dynamically to remove 4k limit. +- Add random suffix to archive file names to prevent races when being created. +- Reinitialize archive and backup handling on toolcontext refresh. +- Make poll_mirror_progress report PROGRESS_CHECK_FAILED if LV is not a mirror. +- Like mirrors, don't scan origins if ignore_suspended_devices() is set. +- Automatically generate tailored LSB Requires-Start for clvmd init script. +- Fix return code of pvmove --abort PV. +- Fix pvmove --abort to remove even for empty pvmove LV. +- Add implementation for simple numeric 'get' property functions. +- Simplify MD/swap signature detection in pvcreate and allow aborting. +- Allow --yes to be used without --force mode. +- Fix file descriptor leak in swap signature detection error path. +- Detect and allow abort in pvcreate if LUKS signature is detected. + +* Wed Aug 25 2010 Peter Rajnoha - 2.02.73-2 +- Add configure --with-default-data-alignment. +- Update heuristic used for default and detected data alignment. +- Add "devices/default_data_alignment" to lvm.conf. + +* Wed Aug 18 2010 Alasdair Kergon - 2.02.73-1 +- Change default alignment of data extents to 1MB. +- Add --norestorefile option to pvcreate. +- Require --restorefile when using pvcreate --uuid. +- Fix potential for corruption during cluster mirror device failure. +- Ignore snapshots when performing mirror recovery beneath an origin. +- Monitor origin -real device below snapshot instead of overlay device. +- Don't really change monitoring status when in test mode. +- Fix some exit statuses when starting/stopping monitoring fails. +- Enable snapshot monitoring by default when dmeventd is enabled. +- Fix 'lvconvert --splitmirrors' in cluster operation. +- Fix clvmd init script exit code to return 4 when executed as non-root user. +- Recognise and give preference to md device partitions (blkext major). +- Never scan internal LVM devices. +- Don't ignore user-specified PVs in split-mirror operations. (2.02.71) +- Fix data corruption bug in cluster mirrors. +- Require logical volume(s) to be explicitly named for lvconvert --merge. +- Avoid changing aligned pe_start as a side-effect of a log message. +- Use built-in rule for device aliases: block/ < dm- < disk/ < mapper/ < other. +- Handle failure of all mirrored log devices and all but one mirror leg. +- Disallow 'mirrored' log type for cluster mirrors. +- Fix configure to supply DEFAULT_RUN_DIR to Makefiles. +- Fix allocation of wrong number of mirror logs with 'remove' fault policy. +- Add dmeventd/executable to lvm.conf to test alternative dmeventd. +- Fix udev rules to support udev database content generated by older rules. +- Reinstate detection of inappropriate uevent with DISK_RO set and suppress it. +- Fix regex ttree off-by-one error. +- Fix segfault in regex matcher with characters of ordinal value > 127. +- Wait for node creation before displaying debug info in dmsetup. +- Fix return status 0 for "dmsetup info -c -o help". + +* Mon Aug 2 2010 Alasdair Kergon - 2.02.72-5 +- Make udev configurable and merge with f12. + +* Mon Aug 2 2010 Alasdair Kergon - 2.02.72-4 +- Merge f13, f14 and rawhide spec files. + +* Sat Jul 31 2010 Alasdair Kergon - 2.02.72-3 +- Address lvm2-cluster security flaw CVE-2010-2526. + https://bugzilla.redhat.com/CVE-2010-2526 +- Change clvmd to communicate with lvm2 via a socket in /var/run/lvm. +- Return controlled error if clvmd is run by non-root user. +- Never use clvmd singlenode unless explicitly requested with -Isinglenode. +- Fix exported_symbols generation to use standard compiler arguments. +- Use #include <> not "" in lvm2app.h which gets installed on the system. +- Make liblvm.device-mapper wait for include file generation. +- Fix configure to supply DEFAULT_RUN_DIR to Makefiles. +- Fix wrong number of mirror log at allocate policy + +* Wed Jul 28 2010 Alasdair Kergon - 2.02.71-1 +- Make vgck warn about missing PVs. +- Revert failed table load preparation after "create, load and resume". +- Check if cluster log daemon is running before allowing cmirror create. +- Add dm_create_lockfile to libdm and use for pidfiles for all daemons. +- Correct LV list order used by lvconvert when splitting a mirror. +- Check if LV with specified name already exists when splitting a mirror. +- Fix suspend/resume logic for LVs resulting from splitting a mirror. +- Fix possible hang when all mirror images of a mirrored log fail. +- Adjust auto-metadata repair and caching logic to try to cope with empty mdas. +- Update pvcreate, {pv|vg}change, and lvm.conf man pages about metadataignore. +- Prompt if metadataignore with vgextend or pvchange would adjust vg_mda_copies. +- Adjust vg_mda_copies if metadataignore given with vgextend or pvchange. +- Speed up the regex matcher. +- Use "nowatch" udev rule for inappropriate devices. +- Document LVM fault handling in lvm_fault_handling.txt. +- Clarify help text for vg_mda_count. +- Add more verbose messages while checking volume_list and hosttags settings. +- Add log_error when strdup fails in {vg|lv}_change_tag(). +- Do not log backtrace in valid _lv_resume() code path. + +* Wed Jul 7 2010 Alasdair Kergon - 2.02.70-1 +- Remove log directly if all mirror images of a mirrored log fail. +- Randomly select which mdas to use or ignore. +- Add printf format attributes to yes_no_prompt and fix a caller. +- Always pass unsuspended dm devices through persistent filter to other filters. +- Move test for suspended dm devices ahead of other filters. +- Fix another segfault in clvmd -R if no response from daemon received. (2.02.68) +- Remove superfluous suspended device counter from clvmd. +- Fix lvm shell crash when input is entirely whitespace. +- Update partial mode warning message. +- Preserve memlock balance in clvmd when activation triggers a resume. +- Restore the removemissing behaviour of lvconvert --repair --use-policies. + +* Wed Jun 30 2010 Alasdair Kergon - 2.02.69-1 +- Fix vgremove to allow removal of VG with missing PVs. (2.02.52) +- Add metadata/vgmetadatacopies to lvm.conf. +- Add --metadataignore to pvcreate and vgextend. +- Add vg_mda_copies, pv_mda_used_count and vg_mda_used_count to reports. +- Describe --vgmetadatacopies in lvm.conf and other man pages. +- Add --[vg]metadatacopies to select number of mdas to use in a VG. +- Make the metadata ignore bit control read/write metadata areas in a PV. +- Add pvchange --metadataignore to set or clear a metadata ignore bit. +- Refactor metadata code to prepare for --metadataignore / --vgmetadatacopies. +- Ensure region_size of mirrored log does not exceed its full size. +- Preload libc locale messages to prevent reading it in memory locked state. +- Fix handling of simultaneous mirror image and mirrored log image failure. + +* Thu Jun 24 2010 Peter Rajnoha - 2.02.68-2 +- Fix udev rules to handle spurious events properly. +- Add Requires: udev >= 158-1 (needed for the change in udev rules). + +* Wed Jun 23 2010 Alasdair Kergon - 2.02.68-1 +- Have device-mapper-libs require device-mapper (circular) for udev rules. +- Clear exec_prefix. +- Use early udev synchronisation and update of dev nodes for clustered mirrors. +- Add lv_path to reports to offer full /dev pathname. +- Avoid abort when generating cmirror status. +- Fix clvmd initscript status to print only active clustered LVs. +- Fix segfault in clvmd -R if no response from daemon received. +- Honour log argument when down-converting stacked mirror. +- Sleep to workaround clvmd -S race: socket closed early and server drops cmd. +- Exit successfully when using -o help (but not -o +help) with LVM reports. +- Add man pages for lvmconf, dmeventd and non-existent lvmsadc and lvmsar tools. +- Add --force, --nofsck and --resizefs to lvresize/extend/reduce man pages. +- Fix lvm2cmd example in documentation. +- Fix typo in warning message about missing device with allocated data areas. +- Add device name and offset to raw_read_mda_header error messages. +- Allow use of lvm2app and lvm2cmd headers in C++ code. + +* Fri Jun 4 2010 Alasdair Kergon - 2.02.67-1 +- Require partial option in lvchange --refresh for partial LVs. +- Don't merge unchanged persistent cache file before dumping if tool scanned. +- Avoid selecting names under /dev/block if there is an alternative. +- Fix semctl parameter (union) to avoid misaligned parameter on some arches. +- Fix clvmd initscript restart command to start clvmd if not yet running. +- Handle failed restart of clvmd using -S switch properly. +- Use built-in absolute paths in clvmd (clvmd restart and PV and LV queries). +- Consistently return ECMD_FAILED if interrupted processing multiple LVs. +- Add --type parameter description to the lvcreate man page. +- Document 'clear' in dmsetup man page. +- Replace strncmp kernel version number checks with proper ones. +- Update clustered log kernel module name to log-userspace for 2.6.31 onwards. +- Support autoloading of dm-mod module for kernels from 2.6.35. +- Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating. +- Do not fail lvm_init() if init_logging() or _init_rand() generates an errno. +- Fix incorrect memory pool deallocation while using vg_read for files. + +* Thu May 20 2010 Alasdair Kergon - 2.02.66-2 +- Simplify and fix Requires package headers. +- If unable to obtain snapshot percentage leave value blank on reports. +- Use new install_system_dirs and install_initscripts makefile targets. +- Add lvm2app functions to lookup a vgname from a pvid and pvname. +- Change internal processing of PVs in pvchange. +- Validate internal lock ordering of orphan and VG_GLOBAL locks. + +* Mon May 17 2010 Alasdair Kergon - 2.02.65-1 +- Disallow vgchange --clustered if there are active mirrors or snapshots. +- Fix truncated total size displayed by pvscan. +- Skip internal lvm devices in scan if ignore_suspended_devices is set. +- Do not merge old device cache after we run full scan. (2.02.56) +- Add new --sysinit compound option to vgchange and lvchange. +- Fix clvmd init script never to deactivate non-clustered volume groups. +- Drop duplicate errors for read failures and missing devices to verbose level. +- Do not print encryption key in message debug output (cryptsetup luksResume). +- Use -d to control level of messages sent to syslog by dmeventd. +- Change -d to -f to run dmeventd in foreground. +- Fix udev flags on remove in create_and_load error path. +- Add dm_list_splice() function to join two lists together. +- Use /bin/bash for scripts with bashisms. +- Switch Libs.private to Requires.private in devmapper.pc and lvm2app.pc. +- Use pkgconfig Requires.private for devmapper-event.pc. + +* Fri Apr 30 2010 Alasdair Kergon - 2.02.64-1 +- Avoid pointless initialisation when the 'version' command is run directly. +- Fix memory leak for invalid regex pattern input. +- Display invalid regex pattern for filter configuration in case of error. +- Fix -M and --type to use strings, not pointers that change on config refresh. +- Fix lvconvert error message when existing mirrored LV is not found. +- Set appropriate udev flags for reserved LVs. +- Disallow the direct removal of a merging snapshot. +- Don't preload the origin when removing a snapshot whose merge is pending. +- Disallow the addition of mirror images while a conversion is happening. +- Disallow primary mirror image removal when mirror is not in-sync. +- Remove obsolete --name parameter from vgcfgrestore. +- Add -S command to clvmd to restart the daemon preserving exclusive locks. +- Increment lvm2app version from 1 to 2 (memory allocation changes). +- Change lvm2app memory alloc/free for pv/vg/lv properties. +- Change daemon lock filename from lvm2_monitor to lvm2-monitor for consistency. +- Add support for new IMPORT{db} udev rule. +- Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events. +- Also include udev libs in libdevmapper.pc. +- Cache bitset locations to speed up _calc_states. +- Add a regex optimisation pass for shared prefixes and suffixes. +- Add dm_bit_and and dm_bitset_equal to libdevmapper. +- Speed up dm_bit_get_next with ffs(). + +* Thu Apr 15 2010 Alasdair Kergon - 2.02.63-2 +- Remove 'lvmconf --lockinglibdir' from cluster post: locking is now built-in. +- Move libdevmapper-event-lvm2.so to devel package. +- Explicitly specify libdevmapper-event.so* attributes. +- Drop support for upgrades from very old versions that used lvm not lvm2. +- Move libdevmapper-event plug-in libraries into new device-mapper subdirectory. +- Don't verify lvm.conf contents when using rpm --verify. + +* Wed Apr 14 2010 Alasdair Kergon - 2.02.63-1 +- Move development links to shared objects to /usr (hard-coded temporarily). +- Change libdevmapper deactivation to fail if device is open. +- Wipe memory buffers for libdevmapper dm-ioctl parameters before releasing. +- Strictly require libudev if udev_sync is used. +- Add support for ioctl's DM_UEVENT_GENERATED_FLAG. +- Allow incomplete mirror restore in lvconvert --repair upon insufficient space. +- Do not reset position in metadata ring buffer on vgrename and vgcfgrestore. +- Allow VGs with active LVs to be renamed. +- Only pass visible LVs to tools in cmdline VG name/tag expansions without -a. +- Use C locale and mlockall in clvmd and dmeventd. +- Mask LCK_HOLD in cluster VG locks for upgrade compatibility with older clvmd. +- Add activation/polling_interval to lvm.conf as --interval default. +- Don't ignore error if resuming any LV fails when resuming groups of LVs. +- Skip closing persistent filter cache file if open failed. +- Permit mimage LVs to be striped in lvcreate, lvresize and lvconvert. +- Fix pvmove allocation to take existing parallel stripes into account. +- Fix incorrect removal of symlinks after LV deactivation fails. +- Fix is_partitioned_dev not to attempt to reopen device. +- Fix another thread race in clvmd. +- Improve vg_validate to detect some loops in lists. +- Change most remaining log_error WARNING messages to log_warn. +- Always use blocking lock for VGs and orphan locks. +- Allocate all memory for segments from private VG mempool. +- Optimise searching PV segments for seeking the most recently-added. +- Remove duplicated vg_validate checks when parsing cached metadata. +- Use hash table of LVs to speed up parsing of text metadata with many LVs. +- Fix two vg_validate messages, adding whitespace and parentheses. +- When dmeventd is not forking because of -d flag, don't kill parent process. +- Fix dso resource leak in error path of dmeventd. +- Fix --alloc contiguous policy only to allocate one set of parallel areas. +- Do not allow {vg|lv}change --ignoremonitoring if on clustered VG. +- Add ability to create mirrored logs for mirror LVs. +- Fix clvmd cluster propagation of dmeventd monitoring mode. +- Allow ALLOC_ANYWHERE to split contiguous areas. +- Add some assertions to allocation code. +- Introduce pv_area_used into allocation algorithm and add debug messages. +- Add activation/monitoring to lvm.conf. +- Add --monitor and --ignoremonitoring to lvcreate. +- Don't allow resizing of internal logical volumes. +- Fix libdevmapper-event pkgconfig version string to match libdevmapper. +- Avoid scanning all pvs in the system if operating on a device with mdas. +- Disable long living process flag in lvm2app library. +- Fix pvcreate device md filter check. +- Suppress repeated errors about the same missing PV uuids. +- Bypass full device scans when using internally-cached VG metadata. +- Only do one full device scan during each read of text format metadata. +- Look up missing PVs by uuid not dev_name in pvs to avoid invalid stat. + +* Tue Mar 09 2010 Alasdair Kergon - 2.02.62-1 +- Rewrite clvmd init script. +- Add default alternative to mlockall using mlock to reduce pinned memory size. +- Add use_mlockall and mlock_filter to activation section of lvm.conf. +- Handle misaligned devices that report alignment_offset of -1. +- Extend core allocation code in preparation for mirrored log areas. +- No longer fall back to looking up active devices by name if uuid not found. +- Don't touch /dev in vgmknodes if activation is disabled. +- Add --showkeys parameter description to dmsetup man page. +- Add --help option as synonym for help command. +- Add lvm2app functions lvm_{vg|lv}_{get|add|remove}_tag() functions. +- Refactor snapshot-merge deptree and device removal to support info-by-uuid. + +* Fri Mar 05 2010 Peter Rajnoha - 2.02.61-2 +- Change spec file to support excluding cluster components from the build. + +* Tue Feb 16 2010 Alasdair Kergon - 2.02.61-1 +- Add %%ORIGIN support to lv{create,extend,reduce,resize} --extents. +- Accept a list of LVs with 'lvconvert --merge @tag' using process_each_lv. +- Remove false "failed to find tree node" error when activating merging origin. +- Exit with success when lvconvert --repair --use-policies performs no action. +- Avoid unnecessary second resync when adding mimage to core-logged mirror. +- Make clvmd -V return status zero. +- Fix cmirrord segfault in clog_cpg list processing when converting mirror log. +- Deactivate temporary pvmove mirror cluster-wide when activating it fails. +- Add missing metadata vg_reverts in pvmove error paths. +- Unlock shared lock in clvmd if activation calls fail. +- Add lvm_pv_get_size, lvm_pv_get_free and lvm_pv_get_dev_size to lvm2app. +- Change lvm2app to return all sizes in bytes as documented (not sectors). +- Exclude internal VG names and uuids from lists returned through lvm2app. +- Add LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES environment variable. +- Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only. +- Remove hard-coding that skipped _mimage devices from 11-dm-lvm.rules. +- Export dm_udev_create_cookie function to create new cookies on demand. +- Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup. +- Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING. +- Set udev state automatically instead of using LVM_UDEV_DISABLE_CHECKING. +- Remove pointless versioned symlinks to dmeventd plugin libraries. + +* Fri Jan 29 2010 Alasdair Kergon - 2.02.60-5 +- Replace spaces with tabs in a couple of places in spec file. + +* Sat Jan 23 2010 Alasdair Kergon - 2.02.60-4 +- Extend cmirrord man page. +- Sleep before first progress check iff pvmove/lvconvert interval has prefix '+'. +- Fix cmirror initscript syntax problems. +- Fix first syslog message prefix for dmeventd plugins. +- Make failed locking initialisation messages more descriptive. + +* Fri Jan 22 2010 Alasdair Kergon - 2.02.59-3 +- Fix dmeventd lvm2 wrapper (plug-ins unusable in last build). +- Make failed locking initialisation messages more descriptive. + +* Fri Jan 22 2010 Fabio M. Di Nitto - 2.02.59-2 +- Drop duplicated BuildRequires on openaislib-devel. +- Drop Requires on clusterlib for cmirror subpackage. +- clvmd subpackage should Requires cman (#506592). + +* Fri Jan 22 2010 Alasdair Kergon - 2.02.59-1 +- Add cmirror subpackage for clustered mirrors. +- Set 'preferred_names' in default lvm.conf. +- Add libdevmapper-event-lvm2.so to serialise dmeventd plugin liblvm2cmd use. +- Stop dmeventd trying to access already-removed snapshots. +- Fix clvmd to never scan suspended devices. +- Fix detection of completed snapshot merge. +- Improve snapshot merge metadata import validation. + +* Thu Jan 14 2010 Alasdair Kergon - 2.02.58-1 +- Fix clvmd automatic target module loading crash. +- Fix allocation code not to stop at the first area of a PV that fits. +- Add support for the "snapshot-merge" kernel target (2.6.33-rc1). +- Add --merge to lvconvert to merge a snapshot into its origin. + +* Tue Jan 12 2010 Alasdair Kergon - 2.02.57-1 +- Add --splitmirrors to lvconvert to split off part of a mirror. +- Allow vgremove to remove a VG with PVs missing after a prompt. +- Add activation/udev_rules config option in lvm.conf. +- Add --poll flag to vgchange and lvchange to control background daemon launch. +- Impose limit of 8 mirror images to match the in-kernel kcopyd restriction. +- Log failure type and recognise type 'F' (flush) in dmeventd mirror plugin. +- Add --noudevrules option for dmsetup to disable /dev node management by udev. +- Fix 'dmsetup info -c -o all' to show all fields. +- Fix coredump and memory leak for 'dmsetup help -c'. +- Rename mirror_device_fault_policy to mirror_image_fault policy. +- Use extended status of new kernel snapshot target 1.8.0 to detect when empty. +- Allow use of precommitted metadata when a PV is missing. +- Add global/abort_on_internal_errors to lvm.conf to assist testing. +- If aborting due to internal error, always send that message to stderr. +- Keep log type consistent when changing mirror image count. +- Exit with success in lvconvert --repair --use-policies on failed allocation. +- Ensure any background daemon exits without duplicating parent's functionality. +- Change background daemon process names to "(lvm2)". +- Fix internal lock state after forking. +- Remove empty PV devices if lvconvert --repair is using defined policies. +- Use fixed buffer to prevent stack overflow in persistent filter dump. +- Propagate metadata commit and revert notifications to other cluster nodes. +- Fix metadata caching and lock state propagation to remote nodes in clvmd. +- Properly decode all flags in clvmd messages including VG locks. +- Drop cached metadata after device was auto-repaired and removed from VG. +- Clear MISSING_PV flag if PV reappeared and is empty. +- Fix removal of multiple devices from a mirror. +- Also clean up PVs flagged as missing in vgreduce --removemissing --force. +- Fix some pvresize and toollib error paths with missing VG releases/unlocks. +- Explicitly call suspend for temporary mirror layer. +- Add memlock information to do_lock_lv debug output. +- Always bypass calls to remote cluster nodes for non-clustered VGs. +- Permit implicit cluster lock conversion in pre/post callbacks on local node. +- Permit implicit cluster lock conversion to the lock mode already held. +- Fix lock flag masking in clvmd so intended code paths get invoked. +- Remove newly-created mirror log from metadata if initial deactivation fails. +- Improve pvmove error message when all source LVs are skipped. +- Fix memlock imbalance in lv_suspend if already suspended. +- Fix pvmove test mode not to poll (and fail). +- Fix vgcreate error message if VG already exists. +- Fix tools to use log_error when aborted due to user response to prompt. +- Fix ignored readahead setting in lvcreate --readahead. +- Fix clvmd memory leak in lv_info_by_lvid by calling release_vg. +- If LVM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings. +- If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings. +- Always set environment variables for an LVM2 device in 11-dm-lvm.rules. +- Disable udev rules for change events with DISK_RO set. +- Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags. +- Correct activated or deactivated text in vgchange summary message. +- Fix fsadm man page typo (fsdam). + +* Tue Nov 24 2009 Alasdair Kergon - 2.02.56-2 +- Revert vg_read_internal change as clvmd was not ready for vg_read. (2.02.55) +- Fix unbalanced memory locking when deactivating LVs. +- Add missing vg_release to pvs and pvdisplay to fix memory leak. +- Do not try to unlock VG which is not locked when processing a VG. +- Update .cache file after every full device rescan in clvmd. +- Refresh all device filters (including sysfs) before each full device rescan. +- Return error status if vgchange fails to activate any volume. + +* Thu Nov 19 2009 Alasdair Kergon - 2.02.55-1 +- Fix deadlock when changing mirrors due to unpaired memlock refcount changes. +- Fix pvmove region_size overflow for very large PVs. +- Fix lvcreate and lvresize %%PVS argument always to use sensible total size. +- Directly restrict vgchange to activating visible LVs. +- Fix hash lookup segfault when keys compared are different lengths. +- Flush stdout after yes/no prompt. +- Recognise DRBD devices and handle them like md devices. +- Add dmsetup --inactive support (requires kernel support targetted for 2.6.33). + +* Fri Nov 13 2009 Peter Rajnoha - 2.02.54-3 +- Support udev flags even when udev_sync is disabled. +- Remove last_rule from udev_rules. +- Udev rules cleanup. + +* Tue Nov 3 2009 Peter Rajnoha - 2.02.54-2 +- Enable udev synchronisation code. +- Install default udev rules for device-mapper and LVM2. +- Add BuildRequires: libudev-devel. +- Add Requires: libudev (to check udev is running). +- Add Requires: util-linux-ng (blkid used in udev rules). +- Add Conflicts: dracut < 002-18 (for dracut to install required udev rules) + +* Tue Oct 27 2009 Alasdair Kergon - 2.02.54-1 +- Add implict pvcreate support to vgcreate and vgextend. +- Add --pvmetadatacopies for pvcreate, vgcreate, vgextend, vgconvert. +- Distinguish between powers of 1000 and powers of 1024 in unit suffixes. +- Restart lvconverts in vgchange. +- Don't attempt to deactivate an LV if any of its snapshots are in use. +- Return error if lv_deactivate fails to remove device from kernel. +- Treat input units of both 's' and 'S' as 512-byte sectors. (2.02.49) +- Use standard output units for 'PE Size' and 'Stripe size' in pv/lvdisplay. +- Add global/si_unit_consistency to enable cleaned-up use of units in output. +- Only do lock conversions in clvmd if we are explicitly asked for one. +- Fix clvmd segfault when refresh_toolcontext fails. +- Cleanup mimagetmp LV if allocation fails for new lvconvert mimage. +- Handle metadata with unknown segment types more gracefully. +- Make clvmd return 0 on success rather than 1. +- Correct example.conf to indicate that lvm2 not lvm1 is the default format. +- Delay announcing mirror monitoring to syslog until initialisation succeeded. +- Update lvcreate/lvconvert man pages to explain PhysicalVolume parameter. +- Document --all option in man pages and cleanup {pv|vg|lv}{s|display} pages. + +* Mon Oct 19 2009 Fabio M. Di Nitto - 2.02.53-3 +- Enable openais support in clvmd. + +* Fri Sep 25 2009 Alasdair Kergon - 2.02.53-2 +- Reissued tarball to fix compilation warning from lvm2_log_fn prototype. + +* Fri Sep 25 2009 Alasdair Kergon - 2.02.53-1 +- Create any directories in /dev with umask 022. (#507397) +- Handle paths supplied to dm_task_set_name by getting name from /dev/mapper. +- Add splitname and --yes to dmsetup man page. + +* Thu Sep 24 2009 Peter Rajnoha - 2.02.52-4 +- Disable udev synchronisation code (revert previous build). + +* Mon Sep 21 2009 Peter Rajnoha - 2.02.52-3 +- Enable udev synchronisation code. +- Install default udev rules for device-mapper and LVM2. +- Add BuildRequires: libudev-devel. +- Add Requires: libudev (to check udev is running). +- Add Requires: util-linux-ng (blkid used in udev rules). + +* Wed Sep 16 2009 Alasdair Kergon - 2.02.52-2 +- Build dmeventd and place into a separate set of subpackages. +- Remove no-longer-needed BuildRoot tag and buildroot emptying at install. + +* Tue Sep 15 2009 Alasdair Kergon - 2.02.52-1 +- Prioritise write locks over read locks by default for file locking. +- Add local lock files with suffix ':aux' to serialise locking requests. +- Fix readonly locking to permit writeable global locks (for vgscan). (2.02.49) +- Make readonly locking available as locking type 4. +- Fix global locking in PV reporting commands (2.02.49). +- Make lvchange --refresh only take a read lock on volume group. +- Fix race where non-blocking file locks could be granted in error. +- Fix pvcreate string termination in duplicate uuid warning message. +- Don't loop reading sysfs with pvcreate on a non-blkext partition (2.02.51). +- Fix vgcfgrestore error paths when locking fails (2.02.49). +- Make clvmd check corosync to see what cluster interface it should use. +- Fix vgextend error path - if ORPHAN lock fails, unlock / release vg (2.02.49). +- Clarify use of PE ranges in lv{convert|create|extend|resize} man pages. +- Restore umask when device node creation fails. +- Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table. + +* Mon Aug 24 2009 Milan Broz - 2.02.51-3 +- Fix global locking in PV reporting commands (2.02.49). +- Fix pvcreate on a partition (2.02.51). +- Build clvmd with both cman and corosync support. + +* Thu Aug 6 2009 Alasdair Kergon - 2.02.51-2 +- Fix clvmd locking broken in 2.02.50-1. +- Only change LV /dev symlinks on ACTIVATE not PRELOAD (so not done twice). +- Make lvconvert honour log mirror options combined with downconversion. +- Add devices/data_alignment_detection to lvm.conf. +- Add devices/data_alignment_offset_detection to lvm.conf. +- Add --dataalignmentoffset to pvcreate to shift start of aligned data area. +- Update synopsis in lvconvert manpage to mention --repair. +- Document -I option of clvmd in the man page. + +* Thu Jul 30 2009 Alasdair Kergon - 2.02.50-2 +- lvm2-devel requires device-mapper-devel. +- Fix lvm2app.pc filename. + +* Tue Jul 28 2009 Alasdair Kergon - 2.02.50-1 +- Add libs and devel subpackages to include shared libraries for applications. + N.B. The liblvm2app API is not frozen yet and may still be changed + Send any feedback to the mailing list lvm-devel@redhat.com. +- Remove obsolete --with-dmdir from configure. +- Add global/wait_for_locks to lvm.conf so blocking for locks can be disabled. +- Fix race condition with vgcreate and vgextend on same device since 2.02.49. +- Add an API version number, LVM_LIBAPI, to the VERSION string. +- Return EINVALID_CMD_LINE not success when invalid VG name format is used. +- Remove unnecessary messages after vgcreate/vgsplit code change in 2.02.49. +- Store any errno and error messages issued while processing each command. + +* Sat Jul 25 2009 Fedora Release Engineering - 2.02.49-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 15 2009 Alasdair Kergon - 2.02.49-1 +- Exclude VG_GLOBAL from vg_write_lock_held so scans open devs read-only again. +- Fix dev name mismatch in vgcreate man page example. +- Check md devices for a partition table during device scan. +- Add extended device (blkext) and md partition (mdp) types to filters. +- Make text metadata read errors for segment areas more precise. +- Fix text segment metadata read errors to mention correct segment name. +- Include segment and LV names in text segment import error messages. +- Fix memory leak in vgsplit when re-reading the vg. +- Permit several segment types to be registered by a single shared object. +- Update the man pages to document size units uniformly. +- Allow commandline sizes to be specified in terms of bytes and sectors. +- Update 'md_chunk_alignment' to use stripe-width to align PV data area. +- Fix segfault in vg_release when vg->cmd is NULL. +- Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns. +- Fix whitespace in linear target line to fix identical table line detection. +- Add device number to more log messages during activation. + +* Fri Jul 10 2009 Fabio M. Di Nitto 2.02.48-2 +- BuildRequires and Requires on stable versions of both corosync-lib (1.0.0-1) + and cluster-lib (3.0.0-20). + +* Tue Jun 30 2009 Alasdair Kergon - 2.02.48-1 +- Abort if automatic metadata correction fails when reading VG to update it. +- Don't fallback to default major number in libdm: use dm_task_set_major_minor. +- Explicitly request fallback to default major number in device mapper. +- Ignore suspended devices during repair. +- Suggest using lvchange --resync when adding leg to not-yet-synced mirror. +- Destroy toolcontext on clvmd exit to avoid memory pool leaks. +- Fix lvconvert not to poll mirror if no conversion in progress. +- Fix memory leaks in toolcontext error path. +- Reinstate partial activation support in clustered mode. +- Allow metadata correction even when PVs are missing. +- Use 'lvm lvresize' instead of 'lvresize' in fsadm. +- Do not use '-n' realine option in fsadm for rescue disk compatiblity. +- Round up requested readahead to at least one page and print warning. +- Try to repair vg before actual vgremove when force flag provided. +- Unify error messages when processing inconsistent volume group. +- Introduce lvconvert --use_policies (repair policy according to lvm.conf). +- Fix rename of active snapshot with virtual origin. +- Fix convert polling to ignore LV with different UUID. +- Cache underlying device readahead only before activation calls. +- Fix segfault when calculating readahead on missing device in vgreduce. +- Remove verbose 'visited' messages. +- Handle multi-extent mirror log allocation when smallest PV has only 1 extent. +- Add LSB standard headers and functions (incl. reload) to clvmd initscript. +- When creating new LV, double-check that name is not already in use. +- Remove /dev/vgname/lvname symlink automatically if LV is no longer visible. +- Rename internal vorigin LV to match visible LV. +- Suppress 'removed' messages displayed when internal LVs are removed. +- Fix lvchange -a and -p for sparse LVs. +- Fix lvcreate --virtualsize to activate the new device immediately. +- Make --snapshot optional with lvcreate --virtualsize. +- Generalise --virtualoriginsize to --virtualsize. +- Skip virtual origins in process_each_lv_in_vg() without --all. +- Fix counting of virtual origin LVs in vg_validate. +- Attempt to load dm-zero module if zero target needed but not present. +- Add crypt target handling to libdevmapper tree nodes. +- Add splitname command to dmsetup. +- Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports. +- Make mempool optional in dm_split_lvm_name() in libdevmapper. + +* Wed Jun 10 2009 Fabio M. Di Nitto - 2.02.47-2 +- BuildRequire newer version of corosynclib (0.97-1) to link against + latest libraries version (soname 4.0.0). +- Add lvm2-2_02_48-cluster-cpg-new-api.patch to port clvmd-corosync + to new corosync cpg API. + +* Fri May 22 2009 Alasdair Kergon - 2.02.47-1 +- Inherit readahead setting from underlying devices during activation. +- Detect LVs active on remote nodes by querying locks if supported. +- Enable online resizing of mirrors. +- Use suspend with flush when device size was changed during table preload. +- Implement query_resource_fn for cluster_locking. +- Support query_resource_fn in locking modules. +- Fix pvmove to revert operation if temporary mirror creation fails. +- Fix metadata export for VG with missing PVs. +- Add vgimportclone and install it and the man page by default. +- Force max_lv restriction only for newly created LV. +- Do not query nonexistent devices for readahead. +- Reject missing PVs from allocation in toollib. +- Fix PV datalignment for values starting prior to MDA area. (2.02.45) +- Add sparse devices: lvcreate -s --virtualoriginsize (hidden zero origin). +- Fix minimum width of devices column in reports. +- Add lvs origin_size field. +- Implement lvconvert --repair for repairing partially-failed mirrors. +- Fix vgreduce --removemissing failure exit code. +- Fix remote metadata backup for clvmd. +- Fix metadata backup to run after vg_commit always. +- Fix pvs report for orphan PVs when segment attributes are requested. +- Fix pvs -a output to not read volume groups from non-PV devices. +- Introduce memory pools per volume group (to reduce memory for large VGs). +- Always return exit error status when locking of volume group fails. +- Fix mirror log convert validation question. +- Enable use of cached metadata for pvs and pvdisplay commands. +- Fix memory leak in mirror allocation code. +- Save and restore the previous logging level when log level is changed. +- Fix error message when archive initialization fails. +- Make sure clvmd-corosync releases the lockspace when it exits. +- Fix segfault for vgcfgrestore on VG with missing PVs. +- Block SIGTERM & SIGINT in clvmd subthreads. +- Detect and conditionally wipe swapspace signatures in pvcreate. +- Fix maximal volume count check for snapshots if max_lv set for volume group. +- Fix lvcreate to remove unused cow volume if the snapshot creation fails. +- Fix error messages when PV uuid or pe_start reading fails. +- Flush memory pool and fix locking in clvmd refresh and backup command. +- Fix unlocks in clvmd-corosync. (2.02.45) +- Fix error message when adding metadata directory to internal list fails. +- Fix size and error message of memory allocation at backup initialization. +- Remove old metadata backup file after renaming VG. +- Restore log_suppress state when metadata backup file is up-to-date. +- Export dm_tree_node_size_changed() from libdevmapper. +- Fix segfault when getopt processes dmsetup -U, -G and -M options. +- Add _smp_mflags to compilation and remove DESTDIR. + +* Fri Apr 17 2009 Milan Broz - 2.02.45-4 +- Add MMC (mmcblk) device type to filters. (483686) + +* Mon Mar 30 2009 Jussi Lehtola 2.02.45-3 +- Add FTP server location to Source0. + +* Mon Mar 30 2009 Fabio M. Di Nitto - 2.02.45-2 +- BuildRequires a newer version of corosync (0.95-2) to fix linking. + +* Tue Mar 3 2009 Alasdair Kergon - 2.02.45-1 +- Update clusterlib and corosync dependencies. +- Attempt proper clean up in child before executing fsadm or modprobe. +- Do not scan devices if reporting only attributes from PV label. +- Use pkgconfig to obtain corosync library details during configuration. +- Fix error returns in clvmd-corosync interface to DLM. +- Add --refresh to vgchange and vgmknodes man pages. +- Pass --test from lvresize to fsadm as --dry-run. +- Prevent fsadm from checking mounted filesystems. +- No longer treats any other key as 'no' when prompting in fsadm. +- Add --dataalignment to pvcreate to specify alignment of data area. +- Fix unblocking of interrupts after several commands. +- Provide da and mda locations in debug message when writing text format label. +- Mention the restriction on file descriptors at invocation on the lvm man page. +- Index cached vgmetadata by vgid not vgname to cope with duplicate vgnames. +- No longer require kernel and metadata major numbers to match. +- If kernel supports only one dm major number, use in place of any supplied. +- Add option to /etc/sysconfig/cluster to select cluster type for clvmd. +- Allow clvmd to start up if its lockspace already exists. +- Separate PV label attributes which do not need parse metadata when reporting. +- Remove external dependency on the 'cut' command from fsadm. +- Fix pvs segfault when pv mda attributes requested for unavailable PV. +- Add fsadm support for reszing ext4 filesysystems. +- Change lvm2-cluster to corosync instead of cman. +- Fix some old changelog typos in email addresses. + +* Wed Feb 25 2009 Fedora Release Engineering - 2.02.44-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Jan 27 2009 Alasdair Kergon - 2.02.44-1 +- Add --nameprefixes, --unquoted, --rows to pvs, vgs, lvs man pages. +- Fix lvresize size conversion for fsadm when block size is not 1K. +- Fix pvs segfault when run with orphan PV and some VG fields. +- Display a 'dev_size' of zero for missing devices in reports. +- Add pv_mda_size to pvs and vg_mda_size to vgs. +- Fix lvmdump /sys listing to include virtual devices directory. +- Add "--refresh" functionality to vgchange and vgmknodes. +- Avoid exceeding LV size when wiping device. +- Calculate mirror log size instead of using 1 extent. +- Ensure requested device number is available before activating with it. +- Fix incorrect exit status from 'help '. +- Fix vgrename using UUID if there are VGs with identical names. +- Fix segfault when invalid field given in reporting commands. +- Use better random seed value in temp file creation. +- Add read_urandom to read /dev/urandom. Use in uuid calculation. +- Fix race in vgcreate that would result in second caller overwriting first. +- Fix uninitialised lv_count in vgdisplay -c. +- Don't skip updating pvid hash when lvmcache_info struct got swapped. +- Fix startup race in clvmd. +- Cope with snapshot dependencies when removing a whole VG with lvremove. +- Make man pages and tool help text consistent using | for alternative options. +- Add "all" field to reports expanding to all fields of report type. +- Enforce device name length and character limitations in libdm. + +* Mon Nov 10 2008 Alasdair Kergon - 2.02.43-1 +- Upstream merge of device-mapper and lvm2 source. +- Correct prototype for --permission on lvchange and lvcreate man pages. +- Exit with non-zero status from vgdisplay if couldn't show any requested VG. +- libdevmapper.pc: Use simplified x.y.z version number. +- Accept locking fallback_to_* options in the global section as documented. +- Several fixes to lvconvert involving mirrors. +- Avoid overwriting in-use on-disk text metadata when metadataarea fills up. +- Generate man pages from templates and include version. +- Fix misleading error message when there are no allocatable extents in VG. +- Fix handling of PVs which reappeared with old metadata version. +- Fix validation of --minor and --major in lvcreate to require -My always. +- Allow lvremove to remove LVs from VGs with missing PVs. +- In VG with PVs missing, by default allow activation of LVs that are complete. +- Require --force with --removemissing in vgreduce to remove partial LVs. +- No longer write out PARTIAL flag into metadata backups. +- Treat new default activation/missing_stripe_filler "error" as an error target. +- Add devices/md_chunk_alignment to lvm.conf. +- Pass struct physical_volume to pe_align and adjust for md chunk size. +- Avoid shuffling remaining mirror images when removing one, retaining primary. +- Prevent resizing an LV while lvconvert is using it. +- Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan. +- Fix pvresize to not allow resize if PV has two metadata areas. +- Fix setting of volume limit count if converting to lvm1 format. +- Fix vgconvert logical volume id metadata validation. +- Fix lvmdump metadata gather option (-m) to work correctly. +- Fix allocation bug in text metadata format write error path. +- Fix vgcfgbackup to properly check filename if template is used. +- vgremove tries to remove lv snapshot first. +- Improve file descriptor leak detection to display likely culprit and filename. +- Avoid looping forever in _pv_analyze_mda_raw used by pvck. +- Change lvchange exit status to indicate if any part of the operation failed. +- Fix pvchange and pvremove to handle PVs without mdas. +- Fix pvchange -M1 -u to preserve existing extent locations when there's a VG. +- Cease recognising snapshot-in-use percentages returned by early devt kernels. +- Add backward-compatible flags field to on-disk format_text metadata. +- libdevmapper: Only resume devices in dm_tree_preload_children if size changes. +- libdevmapper: Extend deptree buffers so the largest possible device numbers fit. +- libdevmapper: Underline longer report help text headings. + +* Tue Oct 7 2008 Alasdair Kergon - 2.02.39-6 +- Only set exec_prefix once and configure explicit directories to work with + new version of rpm. + +* Fri Sep 26 2008 Fabio M. Di Nitto - 2.02.39-5 +- Add BuildRequires on cmanlib-devel. This is required after libcman split + from cman and cman-devel into cmanlib and cmanlib-devel. +- Make versioned BuildRequires on cman-devel and cmanlib-devel more strict + to guarantee to get the right version. + +* Thu Sep 25 2008 Fabio M. Di Nitto - 2.02.39-5 +- Add versioned BuildRequires on new cman-devel. + +* Sun Sep 21 2008 Ville Skyttä - 2.02.39-5 +- Change %%patch to %%patch0 to match Patch0 as required by RPM package update. + +* Thu Aug 7 2008 Tom "spot" Callaway - 2.02.39-4 +- Fix license tag. + +* Fri Jun 27 2008 Alasdair Kergon - 2.02.39-3 +- Fix up cache for PVs without mdas after consistent VG metadata is processed. +- Update validation of safe mirror log type conversions in lvconvert. +- Fix lvconvert to disallow snapshot and mirror combinations. +- Fix reporting of LV fields alongside unallocated PV segments. +- Add --unquoted and --rows to reporting tools. +- Avoid undefined status code after _memlock commands in lvm shell. +- Fix and improve readahead 'auto' calculation for stripe_size. +- Fix lvchange output for -r auto setting if auto is already set. +- Fix add_mirror_images not to dereference uninitialized log_lv upon failure. +- Add --force to lvextend and lvresize. +- Fix vgchange to not activate component mirror volumes directly. + +* Wed Jun 25 2008 Alasdair Kergon - 2.02.38-2 +- dmsetup: Add --unquoted and --rows to 'info -c' command. +- libdevmapper: Fix inverted no_flush debug message. + +* Fri Jun 13 2008 Alasdair Kergon - 2.02.38-1 +- libdevmapper: Make dm_hash_iter safe against deletion. +- libdevmapper: Accept a NULL pointer to dm_free silently. +- libdevmapper: Calculate string size within dm_pool_grow_object. +- libdevmapper: Send reporting field help text to stderr not stdout. + +- dmsetup: Add tables_loaded, readonly and suspended columns to reports. +- dmsetup: Add --nameprefixes for new report output format FIELD=VALUE. + +- Add --nameprefixes to reporting tools for field name prefix output format. +- Fix return values for reporting commands when run with no PVs, LVs, or VGs. +- Add omitted unlock_vg() call when sigint_caught() during vg processing. +- Fix free_count when reading pool metadata. +- Fix segfault when using pvcreate on a device containing pool metadata. +- In script-processing mode, stop if any command fails. +- Warn if command exits with non-zero status code without a prior log_error. +- Correct config file line numbers in messages when parsing comments. +- Add missing deactivation after activation failure in lvcreate -Zy. +- When removing LV symlinks, skip any where the VG name is not determined. +- Fix vgsplit internal counting of snapshot LVs. +- Update vgsplit to only restrict split with active LVs involved in split. +- Fix vgsplit to only move hidden 'snapshotN' LVs when necessary. +- Update vgsplit man page to reflect lvnames on the cmdline. +- Update vgsplit to take "-n LogicalVolumeName" on the cmdline. +- Fix vgsplit error paths to release vg_to lock. +- Avoid spurious duplicate VG messages referring to VGs that are gone. +- Drop dev_name_confirmed error message to debug level. +- Fix setpriority error message to signed int. +- Add assertions to trap deprecated P_ and V_ lock usage. +- Avoid using DLM locks with LCK_CACHE type P_ lock requests. +- Don't touch /dev in vgrename if activation is disabled. +- Exclude VG_GLOBAL from internal concurrent VG lock counter. +- Fix vgmerge snapshot_count when source VG contains snapshots. +- Fix internal LV counter when a snapshot is removed. +- Fix metadata corruption writing lvm1-formatted metadata with snapshots. +- Fix lvconvert -m0 allocatable space check. +- Don't attempt remote metadata backups of non-clustered VGs. +- Improve preferred_names lvm.conf example. +- Fix vgdisplay 'Cur LV' field to match lvdisplay output. +- Fix lv_count report field to exclude hidden LVs. +- Fix some pvmove error status codes. +- Indicate whether or not VG is clustered in vgcreate log message. +- Mention default --clustered setting in vgcreate man page. +- Fix vgreduce to use vg_split_mdas to check sufficient mdas remain. +- Update lvmcache VG lock state for all locking types now. +- Fix output if overriding command_names on cmdline. +- Add check to vg_commit() ensuring VG lock held before writing new VG metadata. +- Add validation of LV name to pvmove -n. +- Add some basic internal VG lock validation. +- Fix vgsplit internal counting of snapshot LVs. +- Update vgsplit to only restrict split with active LVs involved in split. +- Fix vgsplit to only move hidden 'snapshotN' LVs when necessary. +- Update vgsplit man page to reflect lvnames on the cmdline. +- Update vgsplit to take "-n LogicalVolumeName" on the cmdline. +- Fix vgsplit error paths to release vg_to lock. +- Fix vgsplit locking of new VG. +- Avoid erroneous vgsplit error message for new VG. +- Suppress duplicate message when lvresize fails because of invalid vgname. +- Cache VG metadata internally while VG lock is held. +- Fix redundant lvresize message if vg doesn't exist. +- Make clvmd-cman use a hash rather than an array for node updown info. +- Decode numbers in clvmd debugging output. +- Fix uninitialised mutex in clvmd if all daemons are not running at startup. +- Add config file overrides to clvmd when it reads the active LVs list. +- Make clvmd refresh the context correctly when lvm.conf is updated. +- Fix another allocation bug with clvmd and large node IDs. +- Fix uninitialised variable in clvmd that could cause odd hangs. +- Correct command name in lvmdiskscan man page. +- clvmd no longer crashes if it sees nodeids over 50. +- Fix potential deadlock in clvmd thread handling. +- Update usage message for clvmd. +- Fix clvmd man page not to print
and clarified debug options. +- Escape double quotes and backslashes in external metadata and config data. +- Correct a function name typo in _line_append error message. +- Fix resetting of MIRROR_IMAGE and VISIBLE_LV after removal of LV. +- Fix remove_layer_from_lv to empty the LV before removing it. +- Add missing no-longer-used segs_using_this_lv test to check_lv_segments. +- Fix lvconvert detection of mirror conversion in progress. +- Avoid automatic lvconvert polldaemon invocation when -R specified. +- Fix 'pvs -a' to detect VGs of PVs without metadata areas. +- Divide up internal orphan volume group by format type. +- Fix lvresize to support /dev/mapper prefix in the LV name. +- Fix lvresize to pass new size to fsadm when extending device. +- Fix unfilled parameter passed to fsadm from lvresize. +- Update fsadm to call lvresize if the partition size differs (with option -l). +- Fix fsadm to support VG/LV names. + +* Wed Apr 2 2008 Jeremy Katz - 2.02.33-11 +- Adjust for new name for vio disks (from danpb) +- And fix the build (also from danpb) + +* Wed Mar 5 2008 Jeremy Katz - 2.02.33-10 +- recognize vio disks + +* Thu Jan 31 2008 Alasdair Kergon - 2.02.33-9 +- Improve internal label caching performance while locks are held. +- Fix mirror log name construction during lvconvert. + +* Tue Jan 29 2008 Alasdair Kergon - 2.02.32-8 +- Fix pvs, vgs, lvs error exit status on some error paths. +- Fix new parameter validation in vgsplit and test mode. +- Fix internal metadata corruption in lvchange --resync. + +* Sat Jan 19 2008 Alasdair Kergon - 2.02.31-7 +- Avoid readahead error message when using default setting of lvcreate -M1. +- Fix lvcreate --nosync not to wait for non-happening sync. +- Add very_verbose lvconvert messages. + +* Thu Jan 17 2008 Alasdair Kergon - 2.02.30-6 +- Remove static libraries and binaries and move most binaries out of /usr. +- Fix a segfault if using pvs with --all argument. +- Fix vgreduce PV list processing not to process every PV in the VG. +- Reinstate VG extent size and stripe size defaults (halved). +- Set default readahead to twice maximium stripe size. +- Detect non-orphans without MDAs correctly. +- Prevent pvcreate from overwriting MDA-less PVs belonging to active VGs. +- Don't use block_on_error with mirror targets version 1.12 and above. +- Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes. +- Update vgsplit to accept vgcreate options when new VG is destination. +- Update vgsplit to accept existing VG as destination. +- Major restructuring of pvmove and lvconvert code, adding stacking support. +- Add new convert_lv field to lvs output. +- Permit LV segment fields with PV segment reports. +- Extend lvconvert to use polldaemon and wait for completion of initial sync. +- Add seg_start_pe and seg_pe_ranges to reports. +- Add fsadm interface to filesystem resizing tools. +- Update --uuid argument description in man pages. +- Print warning when lvm tools are running as non-root. + +* Thu Dec 20 2007 Alasdair Kergon - 2.02.29-5 +- Fix libdevmapper readahead processing with snapshots (for example). + +* Thu Dec 13 2007 Alasdair Kergon - 2.02.29-4 +- Add missing lvm2 build & runtime dependencies on module-init-tools (modprobe). + +* Thu Dec 6 2007 Jeremy Katz - 2.02.29-3 +- fix requirements + +* Thu Dec 06 2007 Alasdair Kergon - 2.02.29-2 +- Fold device-mapper build into this lvm2 spec file. + +* Wed Dec 05 2007 Alasdair Kergon - 2.02.29-1 +- Make clvmd backup vg metadata on remote nodes. +- Decode cluster locking state in log message. +- Change file locking state messages from debug to very verbose. +- Fix --addtag to drop @ prefix from name. +- Stop clvmd going haywire if a pre_function fails. +- Avoid nested vg_reads when processing PVs in VGs and fix associated locking. +- Attempt to remove incomplete LVs with lvcreate zeroing/activation problems. +- Add full read_ahead support. +- Add lv_read_ahead and lv_kernel_read_ahead fields to reports and lvdisplay. +- Prevent lvconvert -s from using same LV as origin and snapshot. +- Fix human-readable output of odd numbers of sectors. +- Add pv_mda_free and vg_mda_free fields to reports for raw text format. +- Add LVM2 version to 'Generated by' comment in metadata. +- Show 'not usable' space when PV is too large for device in pvdisplay. +- Ignore and fix up any excessive device size found in metadata. +- Fix error message when fixing up PV size in lvm2 metadata (2.02.11). +- Fix orphan-related locking in pvdisplay and pvs. +- Fix missing VG unlocks in some pvchange error paths. +- Add some missing validation of VG names. +- Detect md superblocks version 1.0, 1.1 and 1.2. +- Add some pv-related error paths. +- Handle future sysfs subsystem/block/devices directory structure. +- Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries. +- Fix underquotations in lvm_dump.sh. +- Print --help output to stdout, not stderr. +- After a cmdline processing error, don't print help text but suggest --help. +- Add %%PVS extents option to lvresize, lvextend, and lvcreate. +- Remove no-longer-correct restrictions on PV arg count with stripes/mirrors. +- Fix strdup memory leak in str_list_dup(). +- Link with -lpthread when static SELinux libraries require that. +- Detect command line PE values that exceed their 32-bit range. +- Include strerror string in dev_open_flags' stat failure message. +- Avoid error when --corelog is provided without --mirrorlog. (2.02.28) +- Correct --mirrorlog argument name in man pages (not --log). +- Clear MIRROR_NOTSYNCED LV flag when converting from mirror to linear. +- 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. + +* 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]. +- Add more cluster info to lvmdump. +- Fix lvdisplay man page to say LV size is reported in sectors, not KB. +- Fix loading of persistent cache if cache_dir is used. +- Only permit --force, --verbose and --debug arguments to be repeated. +- Add support for renaming mirrored LVs. +- Add --mirrorlog argument to specify log type for mirrors. +- Don't leak a file descriptor if flock or fcntl fails. +- Detect stream write failure reliably. +- Reduce severity of lstat error messages to very_verbose. +- Update to use autoconf 2.61, while still supporting 2.57. + +* Thu Aug 09 2007 Alasdair Kergon - 2.02.27-3 +- Clarify GPL licence as being version 2. + +* Wed Aug 01 2007 Milan Broz - 2.02.27-2 +- Add SUN's LDOM virtual block device (vdisk) and ps3disk to filters. + +* Wed Jul 18 2007 Alasdair Kergon - 2.02.27-1 +- Add -f to vgcfgrestore to list metadata backup files. +- Add pvdisplay --maps implementation. +- Add devices/preferred_names config regex list for displayed device names. +- Add vg_mda_count and pv_mda_count columns to reports. +- Change cling alloc policy attribute character from 'C' to l'. +- Print warnings to stderr instead of stdout. +- Fix snapshot cow area deactivation if origin is not active. +- Reinitialise internal lvmdiskscan variables when called repeatedly. +- Allow keyboard interrupt during user prompts when appropriate. +- Fix deactivation code to follow dependencies and remove symlinks. +- Fix a segfault in device_is_usable() if a device has no table. +- Fix creation and conversion of mirrors with tags. +- Add command stub for pvck. +- Handle vgsplit of an entire VG as a vgrename. +- Fix vgsplit for lvm1 format (set and validate VG name in PVs metadata). +- Split metadata areas in vgsplit properly. +- Fix and clarify vgsplit error messages. +- Update lists of attribute characters in man pages. +- Remove unsupported LVM1 options from vgcfgrestore man page. +- Update vgcfgrestore man page to show mandatory VG name. +- Update vgrename man page to include UUID and be consistent with lvrename. +- Add some more debug messages to clvmd startup. +- Fix thread race in clvmd. +- Make clvmd cope with quorum devices. +- Add extra internal error checking to clvmd. +- Fix missing lvm_shell symbol in lvm2cmd library. +- Move regex functions into libdevmapper. +- Add kernel and device-mapper targets versions to lvmdump. +- Add /sys/block listings to lvmdump. +- Make lvmdump list /dev recursively. +- Mark /etc/lvm subdirectories as directories in spec file. + +* Mon Mar 19 2007 Alasdair Kergon - 2.02.24-1 +- Add BuildRequires readline-static until makefiles get fixed. +- Fix processing of exit status in init scripts +- Fix vgremove to require at least one vg argument. +- Fix reading of striped LVs in LVM1 format. +- Flag nolocking as clustered so clvmd startup sees clustered LVs. +- Add a few missing pieces of vgname command line validation. +- Support the /dev/mapper prefix on most command lines. + +* Thu Mar 08 2007 Alasdair Kergon - 2.02.23-1 +- Fix vgrename active LV check to ignore differing vgids. +- Fix two more segfaults if an empty config file section encountered. +- Fix a leak in a reporting error path. +- Add devices/cache_dir & devices/cache_file_prefix, deprecating devices/cache. + +* Tue Feb 27 2007 Alasdair Kergon - 2.02.22-3 +- Move .cache file to /etc/lvm/cache. + +* Wed Feb 14 2007 Alasdair Kergon - 2.02.22-2 +- Rebuild after device-mapper package split. + +* Wed Feb 14 2007 Alasdair Kergon - 2.02.22-1 +- Add ncurses-static BuildRequires after package split. +- Fix loading of segment_libraries. +- If a PV reappears after it was removed from its VG, make it an orphan. +- Don't update metadata automatically if VGIDs don't match. +- Fix some vgreduce --removemissing command line validation. +- Trivial man page corrections (-b and -P). +- Add global/units to example.conf. +- Remove readline support from lvm.static. + +* Mon Feb 05 2007 Alasdair Kergon - 2.02.21-4 +- Remove file wildcards and unintentional lvmconf installation. + +* Mon Feb 05 2007 Alasdair Kergon - 2.02.21-3 +- Add build dependency on new device-mapper-devel package. + +* Wed Jan 31 2007 Alasdair Kergon - 2.02.21-2 +- Remove superfluous execute perm from .cache data file. + +* Tue Jan 30 2007 Alasdair Kergon - 2.02.21-1 +- Fix vgsplit to handle mirrors. +- Reorder fields in reporting field definitions. +- Fix vgs to treat args as VGs even when PV fields are displayed. +- Fix md signature check to handle both endiannesses. + +* Fri Jan 26 2007 Alasdair Kergon - 2.02.20-1 +- Fix exit statuses of reporting tools. +- Add some missing close() and fclose() return code checks. +- Add devices/ignore_suspended_devices to ignore suspended dm devices. +- Fix refresh_toolcontext() always to wipe persistent device filter cache. +- Long-lived processes write out persistent dev cache in refresh_toolcontext(). +- Streamline dm_report_field_* interface. +- Update reporting man pages. +- Add --clustered to man pages. +- Add field definitions to report help text. + +* Mon Jan 22 2007 Milan Broz - 2.02.19-2 +- Remove BuildRequires libtermcap-devel + Resolves: #223766 + +* Wed Jan 17 2007 Alasdair Kergon - 2.02.19-1 +- Fix a segfault if an empty config file section encountered. +- Fix partition table processing after sparc changes. +- Fix cmdline PE range processing segfault. +- Move basic reporting functions into libdevmapper. + +* Fri Jan 12 2007 Alasdair Kergon - 2.02.18-2 +- Rebuild. + +* Thu Jan 11 2007 Alasdair Kergon - 2.02.18-1 +- Use CFLAGS when linking so mixed sparc builds can supply -m64. +- Prevent permission changes on active mirrors. +- Print warning instead of error message if lvconvert cannot zero volume. +- Add snapshot options to lvconvert man page. +- dumpconfig accepts a list of configuration variables to display. +- Change dumpconfig to use --file to redirect output to a file. +- Avoid vgreduce error when mirror code removes the log LV. +- Fix ambiguous vgsplit error message for split LV. +- Fix lvextend man page typo. +- Use no flush suspending for mirrors. +- Fix create mirror with name longer than 22 chars. + +* Thu Dec 14 2006 Alasdair Kergon - 2.02.17-1 +- Add missing pvremove error message when device doesn't exist. +- When lvconvert allocates a mirror log, respect parallel area constraints. +- Check for failure to allocate just the mirror log. +- Support mirror log allocation when there is only one PV: area_count now 0. +- Fix detection of smallest area in _alloc_parallel_area() for cling policy. +- Add manpage entry for clvmd -T +- Fix hang in clvmd if a pre-command failed. + +* Fri Dec 01 2006 Alasdair Kergon - 2.02.16-1 +- Fix VG clustered read locks to use PR not CR. +- Adjust some alignments for ia64/sparc. +- Fix mirror segment removal to use temporary error segment. +- Always compile debug logging into clvmd. +- Add startup timeout to clvmd startup script. +- Add -T (startup timeout) switch to clvmd. +- Improve lvm_dump.sh robustness. + +* Tue Nov 21 2006 Alasdair Kergon - 2.02.15-3 +- Fix clvmd init script line truncation. + +* Tue Nov 21 2006 Alasdair Kergon - 2.02.15-2 +- Fix lvm.conf segfault. + +* Mon Nov 20 2006 Alasdair Kergon - 2.02.15-1 +- New upstream - see WHATS_NEW. + +* 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 +- Fix high-level free-space check on partial allocation. + Resolves: #212774 + +* Fri Oct 27 2006 Alasdair Kergon - 2.02.13-1 +- New upstream - see WHATS_NEW. + Resolves: #205818 + +* Fri Oct 20 2006 Alasdair Kergon - 2.02.12-2 +- Remove no-longer-used ldconfig from lvm2-cluster and fix lvmconf + to cope without the shared library. + +* Mon Oct 16 2006 Alasdair Kergon - 2.02.12-1 +- New upstream. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-6 +- Incorporate lvm2-cluster as a subpackage. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-5 +- Install lvmdump script. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-4 +- Build in cluster locking with fallback if external locking fails to load. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-3 +- Drop .0 suffix from release. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-2.0 +- Append distribution to release. + +* Fri Oct 13 2006 Alasdair Kergon - 2.02.11-1.0 +- New upstream with numerous fixes and small enhancements. + (See the WHATS_NEW documentation file for complete upstream changelog.) + +* Thu Sep 28 2006 Peter Jones - 2.02.06-4 +- Fix metadata and map alignment problems on ppc64 (#206202) + +* Tue Aug 1 2006 Jeremy Katz - 2.02.06-3 +- require new libselinux to avoid segfaults on xen (#200783) + +* Thu Jul 27 2006 Jeremy Katz - 2.02.06-2 +- free trip through the buildsystem + +* Wed Jul 12 2006 Jesse Keating - 2.02.06-1.2.1 +- rebuild + +* Tue Jun 6 2006 Stephen C. Tweedie - 2.02.06-1.2 +- Rebuild to pick up new nosegneg libc.a for lvm.static + +* Mon May 22 2006 Alasdair Kergon - 2.02.06-1.1 +- Reinstate archs now build system is back. +- BuildRequires libsepol-devel. + +* Fri May 12 2006 Alasdair Kergon - 2.02.06-1.0 +- New upstream release. + +* Sat Apr 22 2006 Alasdair Kergon - 2.02.05-1.1 +- Exclude archs that aren't building. + +* Fri Apr 21 2006 Alasdair Kergon - 2.02.05-1.0 +- Fix VG uuid comparisons. + +* Wed Apr 19 2006 Alasdair Kergon - 2.02.04-1.0 +- New release upstream, including better handling of duplicated VG names. + +* Fri Feb 10 2006 Jesse Keating - 2.02.01-1.2.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2.02.01-1.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Fri Dec 2 2005 Peter Jones - 2.02.01-1 +- update to 2.02.01 + +* Tue Nov 8 2005 Jeremy Katz - 2.01.14-4 +- add patch for xen block devices + +* Sat Oct 15 2005 Florian La Roche +- add -lselinux -lsepol to the static linking -ldevice-mapper requires it + +* Wed Sep 14 2005 Jeremy Katz - 2.01.14-2 +- the distro doesn't really work without a 2.6 kernel, so no need to require it + +* Thu Aug 4 2005 Alasdair Kergon - 2.01.14-1.0 +- And a few more bugs fixes. + +* Wed Jul 13 2005 Alasdair Kergon - 2.01.13-1.0 +- Fix several bugs discovered in the last release. + +* Tue Jun 14 2005 Alasdair Kergon - 2.01.12-1.0 +- New version upstream with a lot of fixes and enhancements. + +* Wed Apr 27 2005 Alasdair Kergon - 2.01.08-2.1 +- Add /etc/lvm + +* Wed Apr 27 2005 Alasdair Kergon - 2.01.08-2.0 +- No longer abort read operations if archive/backup directories aren't there. +- Add runtime directories and file to the package. + +* Tue Mar 22 2005 Alasdair Kergon - 2.01.08-1.0 +- Improve detection of external changes affecting internal cache. +- Add clustered VG attribute. +- Suppress rmdir opendir error message. + +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.3 +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.2 +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.1 +- Suppress some new compiler messages. + +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.0 +- Remove build directory from built-in path. +- Extra /dev scanning required for clustered operation. + +* Thu Mar 03 2005 Alasdair Kergon - 2.01.06-1.0 +- Allow anaconda to suppress warning messages. + +* Fri Feb 18 2005 Alasdair Kergon - 2.01.05-1.0 +- Upstream changes not affecting Fedora. + +* Wed Feb 09 2005 Alasdair Kergon - 2.01.04-1.0 +- Offset pool minors; lvm2cmd.so skips open fd check; pvmove -f gone. + +* Tue Feb 01 2005 Alasdair Kergon - 2.01.03-1.0 +- Fix snapshot device size & 64-bit display output. + +* Fri Jan 21 2005 Alasdair Kergon - 2.01.02-1.0 +- Minor fixes. + +* Mon Jan 17 2005 Alasdair Kergon - 2.01.01-1.0 +- Update vgcreate man page. Preparation for snapshot origin extension fix. + +* Mon Jan 17 2005 Alasdair Kergon - 2.01.00-1.0 +- Fix metadata auto-correction. Only request open_count when needed. + +* Wed Jan 12 2005 Tim Waugh - 2.00.33-2.0 +- Rebuilt for new readline. + +* Fri Jan 7 2005 Alasdair Kergon - 2.00.33-1.0 +- pvcreate wipes ext label +- several clvm fixes + +* Thu Jan 6 2005 Alasdair Kergon - 2.00.32-2.0 +- Remove temporary /sbin symlinks no longer needed. +- Include read-only pool support in the build. + +* Wed Dec 22 2004 Alasdair Kergon - 2.00.32-1.0 +- More fixes (143501). + +* Sun Dec 12 2004 Alasdair Kergon - 2.00.31-1.0 +- Fix pvcreate install issues. + +* Fri Dec 10 2004 Alasdair Kergon - 2.00.30-1.0 +- Additional debugging code. +- Some trivial man page corrections. + +* Tue Nov 30 2004 Alasdair Kergon - 2.00.29-1.3 +- Reinstate all archs. + +* Sun Nov 28 2004 Alasdair Kergon - 2.00.29-1.2 +- Try excluding more archs. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.29-1.1 +- Exclude s390x which fails. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.29-1 +- Fix last fix. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.28-1 +- Endian fix to partition/md signature detection. + +* Wed Nov 24 2004 Alasdair Kergon - 2.00.27-1 +- Fix partition table detection & an out of memory segfault. + +* Tue Nov 23 2004 Alasdair Kergon - 2.00.26-1 +- Several installation-related fixes & man page updates. + +* Mon Oct 25 2004 Elliot Lee - 2.00.25-1.01 +- Fix 2.6 kernel requirement + +* Wed Sep 29 2004 Alasdair Kergon - 2.00.25-1 +- Fix vgmknodes return code & vgremove locking. + +* Fri Sep 17 2004 Alasdair Kergon - 2.00.24-2 +- Obsolete old lvm1 packages; refuse install if running kernel 2.4. [bz 128185] + +* Thu Sep 16 2004 Alasdair Kergon - 2.00.24-1 +- More upstream fixes. (Always check WHATS_NEW file for details.) +- Add requested BuildRequires. [bz 124916, 132408] + +* Wed Sep 15 2004 Alasdair Kergon - 2.00.23-1 +- Various minor upstream fixes. + +* 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 +- fix permissions on vg dirs + +* Thu Aug 19 2004 Alasdair Kergon - 2.00.21-1 +- New upstream release incorporating fixes plus minor enhancements. + +* Tue Aug 17 2004 Jeremy Katz - 2.00.20-2 +- add patch for iSeries viodasd support +- add patch to check file type using stat(2) if d_type == DT_UNKNOWN (#129674) + +* Sat Jul 3 2004 Alasdair Kergon - 2.00.20-1 +- New upstream release fixes 2.6 kernel device numbers. + +* Tue Jun 29 2004 Alasdair Kergon - 2.00.19-1 +- Latest upstream release. Lots of changes (see WHATS_NEW). + +* Tue Jun 15 2004 Elliot Lee - 2.00.15-5 +- rebuilt + +* Wed May 26 2004 Alasdair Kergon - 2.00.15-4 +- clone %%description from LVM rpm + +* Wed May 26 2004 Alasdair Kergon - 2.00.15-3 +- vgscan shouldn't return error status when no VGs present + +* Thu May 06 2004 Warren Togami - 2.00.15-2 +- i2o patch from Markus Lidel + +* Tue Apr 20 2004 Bill Nottingham - 2.00.15-1.1 +- handle disabled SELinux correctly, so that LVMs can be detected in a + non-SELinux context + +* Mon Apr 19 2004 Alasdair Kergon - 2.00.15-1 +- Fix non-root build with current version of 'install'. + +* Fri Apr 16 2004 Alasdair Kergon - 2.00.14-1 +- Use 64-bit file offsets. + +* Fri Apr 16 2004 Alasdair Kergon - 2.00.13-1 +- Avoid scanning devices containing md superblocks. +- Integrate ENOTSUP patch. + +* Thu Apr 15 2004 Jeremy Katz - 2.00.12-4 +- don't die if we get ENOTSUP setting selinux contexts + +* Thu Apr 15 2004 Alasdair Kergon 2.00.12-3 +- Add temporary pvscan symlink for LVM1 until mkinitrd gets updated. + +* Wed Apr 14 2004 Alasdair Kergon 2.00.12-2 +- Mark config file noreplace. + +* Wed Apr 14 2004 Alasdair Kergon 2.00.12-1 +- Install default /etc/lvm/lvm.conf. +- Move non-static binaries to /usr/sbin. +- Add temporary links in /sbin to lvm.static until rc.sysinit gets updated. + +* Thu Apr 08 2004 Alasdair Kergon 2.00.11-1 +- Fallback to using LVM1 tools when using a 2.4 kernel without device-mapper. + +* Wed Apr 07 2004 Alasdair Kergon 2.00.10-2 +- Install the full toolset, not just 'lvm'. + +* Wed Apr 07 2004 Alasdair Kergon 2.00.10-1 +- Update to version 2.00.10, which incorporates the RH-specific patches + and includes various fixes and enhancements detailed in WHATS_NEW. + +* Wed Mar 17 2004 Jeremy Katz 2.00.08-5 +- Fix sysfs patch to find sysfs +- Take patch from dwalsh and tweak a little for setting SELinux contexts on + device node creation and also do it on the symlink creation. + Part of this should probably be pushed down to device-mapper instead + +* Thu Feb 19 2004 Stephen C. Tweedie 2.00.08-4 +- Add sysfs filter patch +- Allow non-root users to build RPM + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Dec 5 2003 Jeremy Katz 2.00.08-2 +- add static lvm binary + +* Tue Dec 2 2003 Jeremy Katz +- Initial build. + + +