Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package lvm2 for openSUSE:Factory checked in at 2022-03-05 14:43:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lvm2 (Old) and /work/SRC/openSUSE:Factory/.lvm2.new.1958 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lvm2" Sat Mar 5 14:43:42 2022 rev:151 rq:958733 version:2.03.15 Changes: -------- --- /work/SRC/openSUSE:Factory/lvm2/lvm2.changes 2022-02-06 23:53:29.835134321 +0100 +++ /work/SRC/openSUSE:Factory/.lvm2.new.1958/lvm2.changes 2022-03-05 14:44:22.783715495 +0100 @@ -1,0 +2,152 @@ +Tue Mar 1 15:45:00 UTC 2022 - heming.z...@suse.com + +- Update lvm2 from LVM2.2.03.12 to LVM2.2.03.15 + + *** WHATS_NEW from 2.03.13 to 2.03.15 *** + + Version 2.03.15 - 07th February 2022 + ==================================== + Remove service based autoactivation. global/event_activation = 0 is NOOP. + Improve support for metadata profiles for --type writecache. + Use cache or active DM device when available with new kernels. + Introduce function to utilize UUIDs from DM_DEVICE_LIST. + Increase some hash table size to better support large device sets. + + Version 2.03.14 - 20th October 2021 + =================================== + Device scanning is skipping directories on different filesystems. + Print info message with too many or too large archived files. + Reduce metadata readings during scanning phase. + Optimize computation of crc32 check sum with multiple PVs. + Enhance recover path on cache creation failure. + Filter out unsupported MQ/SMQ cache policy setting. + Fix memleak in mpath filter. + Support newer location for VDO statistics. + Add support for VDO async-unsafe write policy. + Improve lvm_import_vdo script. + Support VDO LV with lvcreate -ky. + Fix lvconvert for VDO LV bigger then 2T. + Create VDO LVs automatically without zeroing. + Rename vdoimport to lvm_import_vdo. + + Version 2.03.13 - 11th August 2021 + ================================== + Changes in udev support: + - obtain_device_list_from_udev defaults to 0. + - see devices/external_device_info_source, + devices/obtain_device_list_from_udev, and devices/multipath_wwids_file help + in lvm.conf + Fix devices file handling of loop with deleted backing file. + Fix devices file handling of scsi_debug WWIDs. + Fix many static analysis issues. + Support --poolmetadataspare with vgsplit and vgmerge. + Fix detection of active components of external origin volume. + Add vdoimport tool to support conversion of VDO volumes. + Support configurable allocation/vdo_pool_header_size. + Fix handling of lvconvert --type vdo-pool --virtualsize. + Simplified handling of archive() and backup() internal calls. + Add 'idm' locking type for IDM lock manager. + Fix load of kvdo target when it is not present in memory (2.03.12). + + + *** WHATS_NEW_DM from 1.02.179 to 1.02.183 *** + + Version 1.02.183 - 07th February 2022 + ===================================== + Unmangle UUIDs for DM_DEVICE_LIST ioctl. + + Version 1.02.181 - 20th October 2021 + ==================================== + Add IMA support with 'dmsetup measure' command. + Add defines DM_NAME_LIST_FLAG_HAS_UUID, DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID. + Enhance tracking of activated devices when preloading dm tree. + Fix bug in construction of cache table line (regression from 1.02.159). + + Version 1.02.179 - 11th August 2021 + =================================== + (empty) + +- Drop patches that have been merged into upstream + - 0001-lvmlockd-idm-Introduce-new-locking-scheme.patch + - 0002-lvmlockd-idm-Hook-Seagate-IDM-wrapper-APIs.patch + - 0003-lib-locking-Add-new-type-idm.patch + - 0004-lib-locking-Parse-PV-list-for-IDM-locking.patch + - 0005-tools-Add-support-for-idm-lock-type.patch + - 0006-configure-Add-macro-LOCKDIDM_SUPPORT.patch + - 0007-enable-command-syntax-for-thin-and-writecache.patch + - 0008-lvremove-fix-removing-thin-pool-with-writecache-on-d.patch + - 0009-vdo-fix-preload-of-kvdo.patch + - 0010-writecache-fix-lv_on_pmem.patch + - 0011-writecache-don-t-pvmove-device-used-by-writecache.patch + - 0012-pvchange-fix-file-locking-deadlock.patch + - 0013-tests-Enable-the-testing-for-IDM-locking-scheme.patch + - 0014-tests-Support-multiple-backing-devices.patch + - 0015-tests-Cleanup-idm-context-when-prepare-devices.patch + - 0016-tests-Add-checking-for-lvmlockd-log.patch + - 0017-tests-stress-Add-single-thread-stress-testing.patch + - 0018-tests-stress-Add-multi-threads-stress-testing-for-VG.patch + - 0019-tests-stress-Add-multi-threads-stress-testing-for-PV.patch + - 0020-tests-Support-idm-failure-injection.patch + - 0021-tests-Add-testing-for-lvmlockd-failure.patch + - 0022-tests-idm-Add-testing-for-the-fabric-failure.patch + - 0023-tests-idm-Add-testing-for-the-fabric-failure-and-tim.patch + - 0024-tests-idm-Add-testing-for-the-fabric-s-half-brain-fa.patch + - 0025-tests-idm-Add-testing-for-IDM-lock-manager-failure.patch + - 0026-tests-multi-hosts-Add-VG-testing.patch + - 0027-tests-multi-hosts-Add-LV-testing.patch + - 0028-tests-multi-hosts-Test-lease-timeout-with-LV-exclusi.patch + - 0029-tests-multi-hosts-Test-lease-timeout-with-LV-shareab.patch + - 0030-fix-empty-mem-pool-leak.patch + - 0031-tests-writecache-blocksize-add-dm-cache-tests.patch + - 0032-tests-rename-test.patch + - 0033-tests-add-writecache-cache-blocksize-2.patch + - 0034-lvmlockd-Fix-the-compilation-warning.patch + - 0035-devices-don-t-use-deleted-loop-backing-file-for-devi.patch + - 0036-man-help-fix-common-option-listing.patch + - 0037-archiving-take-archive-automatically.patch + - 0038-backup-automatically-store-data-on-vg_unlock.patch + - 0039-archive-avoid-abuse-of-internal-flag.patch + - 0040-pvck-add-lock_global-before-clean_hint_file.patch + - 0041-lvmdevices-add-deviceidtype-option.patch + - bug-1188141_toolcontext-fix-double-free-core-dumped-issue.patch + - 0043-udev-create-symlinks-and-watch-even-in-suspended-sta.patch + - bug-1179691_config-set-external_device_info_source-none.patch + +- Add upstream patch + - 0001-post-release.patch + - 0002-asan-fix-some-reports-from-libasan.patch + - 0003-make-generate.patch + - 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch + - 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch + - 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch + - 0007-dev_manager-fix-dm_task_get_device_list.patch + - 0008-dev_manager-failing-status-is-not-internal-error.patch + - 0009-clang-add-extra-check.patch + - 0010-clang-possible-better-compilation-with-musl-c.patch + - 0011-dev_manager-do-not-query-for-open_count.patch + - 0012-dev_manager-use-list-info-for-preset-devs.patch + - 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch + - 0014-man-update-cachesettings-option-description.patch + - 0015-man-lvmcache-mention-writecache-memory-usage.patch + - 0016-writecache-display-block-size-from-lvs.patch + - 0017-devices-simplify-dev_cache_get_by_devt.patch + - 0018-devices-drop-incorrect-paths-from-aliases-list.patch + - 0019-devices-initial-use-of-existing-option.patch + - 0020-devices-fix-dev_name-assumptions.patch + - 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch + - 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch + - 0023-writecache-check-memory-usage.patch + +- Update patch + - fate-309425_display-dm-name-for-lv-name.patch + +- lvm2.spec + - add new binraries: lvmdevices vgimportdevices + - add config item "--with-cluster=internal" for cluster test + - add config item "--with-integrity=internal" + - add new man lvmautoactivation.7 + - remove lvm2-activation-generator & man page + - remove lvm2-pvscan@.service + - replace 69-dm-lvm-metad.rules with 69-dm-lvm.rules + +------------------------------------------------------------------- Old: ---- 0001-lvmlockd-idm-Introduce-new-locking-scheme.patch 0002-lvmlockd-idm-Hook-Seagate-IDM-wrapper-APIs.patch 0003-lib-locking-Add-new-type-idm.patch 0004-lib-locking-Parse-PV-list-for-IDM-locking.patch 0005-tools-Add-support-for-idm-lock-type.patch 0006-configure-Add-macro-LOCKDIDM_SUPPORT.patch 0007-enable-command-syntax-for-thin-and-writecache.patch 0008-lvremove-fix-removing-thin-pool-with-writecache-on-d.patch 0009-vdo-fix-preload-of-kvdo.patch 0010-writecache-fix-lv_on_pmem.patch 0011-writecache-don-t-pvmove-device-used-by-writecache.patch 0012-pvchange-fix-file-locking-deadlock.patch 0013-tests-Enable-the-testing-for-IDM-locking-scheme.patch 0014-tests-Support-multiple-backing-devices.patch 0015-tests-Cleanup-idm-context-when-prepare-devices.patch 0016-tests-Add-checking-for-lvmlockd-log.patch 0017-tests-stress-Add-single-thread-stress-testing.patch 0018-tests-stress-Add-multi-threads-stress-testing-for-VG.patch 0019-tests-stress-Add-multi-threads-stress-testing-for-PV.patch 0020-tests-Support-idm-failure-injection.patch 0021-tests-Add-testing-for-lvmlockd-failure.patch 0022-tests-idm-Add-testing-for-the-fabric-failure.patch 0023-tests-idm-Add-testing-for-the-fabric-failure-and-tim.patch 0024-tests-idm-Add-testing-for-the-fabric-s-half-brain-fa.patch 0025-tests-idm-Add-testing-for-IDM-lock-manager-failure.patch 0026-tests-multi-hosts-Add-VG-testing.patch 0027-tests-multi-hosts-Add-LV-testing.patch 0028-tests-multi-hosts-Test-lease-timeout-with-LV-exclusi.patch 0029-tests-multi-hosts-Test-lease-timeout-with-LV-shareab.patch 0030-fix-empty-mem-pool-leak.patch 0031-tests-writecache-blocksize-add-dm-cache-tests.patch 0032-tests-rename-test.patch 0033-tests-add-writecache-cache-blocksize-2.patch 0034-lvmlockd-Fix-the-compilation-warning.patch 0035-devices-don-t-use-deleted-loop-backing-file-for-devi.patch 0036-man-help-fix-common-option-listing.patch 0037-archiving-take-archive-automatically.patch 0038-backup-automatically-store-data-on-vg_unlock.patch 0039-archive-avoid-abuse-of-internal-flag.patch 0040-pvck-add-lock_global-before-clean_hint_file.patch 0041-lvmdevices-add-deviceidtype-option.patch 0043-udev-create-symlinks-and-watch-even-in-suspended-sta.patch LVM2.2.03.12.tgz LVM2.2.03.12.tgz.asc bug-1179691_config-set-external_device_info_source-none.patch bug-1188141_toolcontext-fix-double-free-core-dumped-issue.patch New: ---- 0001-post-release.patch 0002-asan-fix-some-reports-from-libasan.patch 0003-make-generate.patch 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch 0007-dev_manager-fix-dm_task_get_device_list.patch 0008-dev_manager-failing-status-is-not-internal-error.patch 0009-clang-add-extra-check.patch 0010-clang-possible-better-compilation-with-musl-c.patch 0011-dev_manager-do-not-query-for-open_count.patch 0012-dev_manager-use-list-info-for-preset-devs.patch 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch 0014-man-update-cachesettings-option-description.patch 0015-man-lvmcache-mention-writecache-memory-usage.patch 0016-writecache-display-block-size-from-lvs.patch 0017-devices-simplify-dev_cache_get_by_devt.patch 0018-devices-drop-incorrect-paths-from-aliases-list.patch 0019-devices-initial-use-of-existing-option.patch 0020-devices-fix-dev_name-assumptions.patch 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch 0023-writecache-check-memory-usage.patch LVM2.2.03.15.tgz LVM2.2.03.15.tgz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lvm2.spec ++++++ --- /var/tmp/diff_new_pack.MgiqQq/_old 2022-03-05 14:44:24.083715822 +0100 +++ /var/tmp/diff_new_pack.MgiqQq/_new 2022-03-05 14:44:24.095715826 +0100 @@ -1,5 +1,5 @@ # -# spec file +# spec file for package lvm2 # # Copyright (c) 2022 SUSE LLC # @@ -21,8 +21,8 @@ %define libname_event libdevmapper-event1_03 %define _udevdir %(pkg-config --variable=udevdir udev) %define cmdlib liblvm2cmd2_03 -%define lvm2_version 2.03.12 -%define device_mapper_version 1.02.177 +%define lvm2_version 2.03.15 +%define device_mapper_version 1.02.185 %define thin_provisioning_version 0.7.0 %define _supportsanlock 0 %define dlm_version 4.0.9 @@ -63,61 +63,39 @@ Source99: baselibs.conf # Upstream patches -Patch0001: 0001-lvmlockd-idm-Introduce-new-locking-scheme.patch -Patch0002: 0002-lvmlockd-idm-Hook-Seagate-IDM-wrapper-APIs.patch -Patch0003: 0003-lib-locking-Add-new-type-idm.patch -Patch0004: 0004-lib-locking-Parse-PV-list-for-IDM-locking.patch -Patch0005: 0005-tools-Add-support-for-idm-lock-type.patch -Patch0006: 0006-configure-Add-macro-LOCKDIDM_SUPPORT.patch -Patch0007: 0007-enable-command-syntax-for-thin-and-writecache.patch -Patch0008: 0008-lvremove-fix-removing-thin-pool-with-writecache-on-d.patch -Patch0009: 0009-vdo-fix-preload-of-kvdo.patch -Patch0010: 0010-writecache-fix-lv_on_pmem.patch -Patch0011: 0011-writecache-don-t-pvmove-device-used-by-writecache.patch -Patch0012: 0012-pvchange-fix-file-locking-deadlock.patch -Patch0013: 0013-tests-Enable-the-testing-for-IDM-locking-scheme.patch -Patch0014: 0014-tests-Support-multiple-backing-devices.patch -Patch0015: 0015-tests-Cleanup-idm-context-when-prepare-devices.patch -Patch0016: 0016-tests-Add-checking-for-lvmlockd-log.patch -Patch0017: 0017-tests-stress-Add-single-thread-stress-testing.patch -Patch0018: 0018-tests-stress-Add-multi-threads-stress-testing-for-VG.patch -Patch0019: 0019-tests-stress-Add-multi-threads-stress-testing-for-PV.patch -Patch0020: 0020-tests-Support-idm-failure-injection.patch -Patch0021: 0021-tests-Add-testing-for-lvmlockd-failure.patch -Patch0022: 0022-tests-idm-Add-testing-for-the-fabric-failure.patch -Patch0023: 0023-tests-idm-Add-testing-for-the-fabric-failure-and-tim.patch -Patch0024: 0024-tests-idm-Add-testing-for-the-fabric-s-half-brain-fa.patch -Patch0025: 0025-tests-idm-Add-testing-for-IDM-lock-manager-failure.patch -Patch0026: 0026-tests-multi-hosts-Add-VG-testing.patch -Patch0027: 0027-tests-multi-hosts-Add-LV-testing.patch -Patch0028: 0028-tests-multi-hosts-Test-lease-timeout-with-LV-exclusi.patch -Patch0029: 0029-tests-multi-hosts-Test-lease-timeout-with-LV-shareab.patch -Patch0030: 0030-fix-empty-mem-pool-leak.patch -Patch0031: 0031-tests-writecache-blocksize-add-dm-cache-tests.patch -Patch0032: 0032-tests-rename-test.patch -Patch0033: 0033-tests-add-writecache-cache-blocksize-2.patch -Patch0034: 0034-lvmlockd-Fix-the-compilation-warning.patch -Patch0035: 0035-devices-don-t-use-deleted-loop-backing-file-for-devi.patch -Patch0036: 0036-man-help-fix-common-option-listing.patch -Patch0037: 0037-archiving-take-archive-automatically.patch -Patch0038: 0038-backup-automatically-store-data-on-vg_unlock.patch -Patch0039: 0039-archive-avoid-abuse-of-internal-flag.patch -Patch0040: 0040-pvck-add-lock_global-before-clean_hint_file.patch -Patch0041: 0041-lvmdevices-add-deviceidtype-option.patch -Patch0042: bug-1188141_toolcontext-fix-double-free-core-dumped-issue.patch -Patch0043: 0043-udev-create-symlinks-and-watch-even-in-suspended-sta.patch - +Patch0001: 0001-post-release.patch +Patch0002: 0002-asan-fix-some-reports-from-libasan.patch +Patch0003: 0003-make-generate.patch +Patch0004: 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch +Patch0005: 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch +Patch0006: 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch +Patch0007: 0007-dev_manager-fix-dm_task_get_device_list.patch +Patch0008: 0008-dev_manager-failing-status-is-not-internal-error.patch +Patch0009: 0009-clang-add-extra-check.patch +Patch0010: 0010-clang-possible-better-compilation-with-musl-c.patch +Patch0011: 0011-dev_manager-do-not-query-for-open_count.patch +Patch0012: 0012-dev_manager-use-list-info-for-preset-devs.patch +Patch0013: 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch +Patch0014: 0014-man-update-cachesettings-option-description.patch +Patch0015: 0015-man-lvmcache-mention-writecache-memory-usage.patch +Patch0016: 0016-writecache-display-block-size-from-lvs.patch +Patch0017: 0017-devices-simplify-dev_cache_get_by_devt.patch +Patch0018: 0018-devices-drop-incorrect-paths-from-aliases-list.patch +Patch0019: 0019-devices-initial-use-of-existing-option.patch +Patch0020: 0020-devices-fix-dev_name-assumptions.patch +Patch0021: 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch +Patch0022: 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch +Patch0023: 0023-writecache-check-memory-usage.patch # SUSE patches: 1000+ for LVM # Never upstream Patch1001: cmirrord_remove_date_time_from_compilation.patch Patch1002: fate-309425_display-dm-name-for-lv-name.patch Patch1003: bug-935623_dmeventd-fix-dso-name-wrong-compare.patch Patch1004: bug-998893_make_pvscan_service_after_multipathd.patch -Patch1005: bug-1179691_config-set-external_device_info_source-none.patch -Patch1006: bug-1184687_Add-nolvm-for-kernel-cmdline.patch -Patch1007: fate-31841-01_fsadm-add-support-to-resize-check-btrfs-filesystem.patch -Patch1008: fate-31841-02_man-add-support-for-btrfs.patch -Patch1009: fate-31841-03_tests-new-test-suite-of-fsadm-for-btrfs.patch +Patch1005: bug-1184687_Add-nolvm-for-kernel-cmdline.patch +Patch1006: fate-31841-01_fsadm-add-support-to-resize-check-btrfs-filesystem.patch +Patch1007: fate-31841-02_man-add-support-for-btrfs.patch +Patch1008: fate-31841-03_tests-new-test-suite-of-fsadm-for-btrfs.patch # SUSE patches 2000+ for device mapper, udev rules Patch2001: bug-1012973_simplify-special-case-for-md-in-69-dm-lvm-metadata.patch # SUSE patches 3000+ for test code @@ -190,26 +168,6 @@ %patch0021 -p1 %patch0022 -p1 %patch0023 -p1 -%patch0024 -p1 -%patch0025 -p1 -%patch0026 -p1 -%patch0027 -p1 -%patch0028 -p1 -%patch0029 -p1 -%patch0030 -p1 -%patch0031 -p1 -%patch0032 -p1 -%patch0033 -p1 -%patch0034 -p1 -%patch0035 -p1 -%patch0036 -p1 -%patch0037 -p1 -%patch0038 -p1 -%patch0039 -p1 -%patch0040 -p1 -%patch0041 -p1 -%patch0042 -p1 -%patch0043 -p1 %patch1001 -p1 %patch1002 -p1 %patch1003 -p1 @@ -218,7 +176,6 @@ %patch1006 -p1 %patch1007 -p1 %patch1008 -p1 -%patch1009 -p1 %patch2001 -p1 %patch3001 -p1 @@ -230,7 +187,6 @@ %if !%{with devicemapper} && !%{with lockd} extra_opts=" --enable-blkid_wiping - --enable-lvmpolld --enable-realtime --with-cache=internal --with-writecache=internal @@ -239,7 +195,6 @@ --with-default-run-dir=/run/lvm --enable-cmirrord --enable-fsadm - --disable-silent-rules --enable-write_install --with-vdo=internal --with-vdo-format=%{_bindir}/vdoformat @@ -248,17 +203,16 @@ %if %{with lockd} extra_opts=" --enable-blkid_wiping - --enable-lvmpolld --enable-realtime --with-default-locking-dir=/run/lock/lvm --with-default-pid-dir=/run --with-default-run-dir=/run/lvm + --with-cluster=internal --enable-lvmlockd-dlm --enable-lvmlockd-dlmcontrol %if 0%{_supportsanlock} == 1 --enable-lvmlockd-sanlock %endif - --disable-silent-rules " %endif @@ -268,6 +222,7 @@ sed -ie "s/%{device_mapper_version}/1.03.01/g" VERSION_DM %configure \ --enable-dmeventd \ + --enable-lvmpolld \ --enable-cmdlib \ --enable-udev_rules \ --enable-udev_sync \ @@ -286,6 +241,8 @@ --with-thin-check=%{_sbindir}/thin_check \ --with-thin-dump=%{_sbindir}/thin_dump \ --with-thin-repair=%{_sbindir}/thin_repair \ + --with-integrity=internal \ + --disable-silent-rules \ $extra_opts ### COMMON-CONFIG-END ### @@ -339,11 +296,8 @@ rm %{buildroot}%{_unitdir}/dm-event.service rm %{buildroot}%{_unitdir}/dm-event.socket rm %{buildroot}%{_unitdir}/lvm2-monitor.service -rm %{buildroot}%{_mandir}/man8/lvm2-activation-generator.8 -rm %{buildroot}%{_systemdgeneratordir}/lvm2-activation-generator rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.service rm %{buildroot}%{_unitdir}/lvm2-lvmpolld.socket -rm %{buildroot}%{_unitdir}/lvm2-pvscan@.service %else %make_install make install_system_dirs DESTDIR=%{buildroot} @@ -595,8 +549,10 @@ %{_sbindir}/fsadm %{_sbindir}/lvm %{_sbindir}/lvmconfig +%{_sbindir}/lvmdevices %{_sbindir}/lvmdump %{_sbindir}/lvmpolld +%{_sbindir}/lvm_import_vdo # Other files %{_sbindir}/lvchange %{_sbindir}/lvconvert @@ -632,6 +588,7 @@ %{_sbindir}/vgextend %{_sbindir}/vgimport %{_sbindir}/vgimportclone +%{_sbindir}/vgimportdevices %{_sbindir}/vgmerge %{_sbindir}/vgmknodes %{_sbindir}/vgreduce @@ -646,7 +603,9 @@ # compat symlinks in /sbin %if !0%{?usrmerged} /sbin/lvm +/sbin/lvm_import_vdo /sbin/lvmconfig +/sbin/lvmdevices /sbin/lvmdump /sbin/lvmpolld /sbin/lvchange @@ -683,6 +642,7 @@ /sbin/vgextend /sbin/vgimport /sbin/vgimportclone +/sbin/vgimportdevices /sbin/vgmerge /sbin/vgmknodes /sbin/vgreduce @@ -693,6 +653,7 @@ /sbin/vgsplit %endif %{_mandir}/man5/lvm.conf.5%{?ext_man} +%{_mandir}/man7/lvmautoactivation.7%{?ext_man} %{_mandir}/man7/lvmcache.7%{?ext_man} %{_mandir}/man7/lvmraid.7%{?ext_man} %{_mandir}/man7/lvmreport.7%{?ext_man} @@ -706,9 +667,9 @@ %{_mandir}/man8/lvdisplay.8%{?ext_man} %{_mandir}/man8/lvextend.8%{?ext_man} %{_mandir}/man8/lvm.8%{?ext_man} -%{_mandir}/man8/lvm2-activation-generator.8%{?ext_man} %{_mandir}/man8/lvm-config.8%{?ext_man} %{_mandir}/man8/lvmconfig.8%{?ext_man} +%{_mandir}/man8/lvmdevices.8%{?ext_man} %{_mandir}/man8/lvm-dumpconfig.8%{?ext_man} %{_mandir}/man8/lvmdiskscan.8%{?ext_man} %{_mandir}/man8/lvmdump.8%{?ext_man} @@ -741,6 +702,7 @@ %{_mandir}/man8/vgextend.8%{?ext_man} %{_mandir}/man8/vgimport.8%{?ext_man} %{_mandir}/man8/vgimportclone.8%{?ext_man} +%{_mandir}/man8/vgimportdevices.8%{?ext_man} %{_mandir}/man8/vgmerge.8%{?ext_man} %{_mandir}/man8/vgmknodes.8%{?ext_man} %{_mandir}/man8/vgreduce.8%{?ext_man} @@ -753,7 +715,7 @@ %{_mandir}/man8/lvmpolld.8%{?ext_man} %{_mandir}/man8/lvm-lvpoll.8%{?ext_man} %{_udevdir}/rules.d/11-dm-lvm.rules -%{_udevdir}/rules.d/69-dm-lvm-metad.rules +%{_udevdir}/rules.d/69-dm-lvm.rules %dir %{_sysconfdir}/lvm %config(noreplace) %{_sysconfdir}/lvm/lvm.conf %config(noreplace) %{_sysconfdir}/lvm/lvmlocal.conf @@ -773,10 +735,8 @@ %{_tmpfilesdir}/%{name}.conf %{_unitdir}/blk-availability.service %{_unitdir}/lvm2-monitor.service -%{_unitdir}/lvm2-pvscan@.service %{_unitdir}/lvm2-lvmpolld.socket %{_unitdir}/lvm2-lvmpolld.service -%{_systemdgeneratordir}/lvm2-activation-generator %dir %{_libdir}/device-mapper %{_libdir}/device-mapper/libdevmapper-event-lvm2*.so %{_libdir}/libdevmapper-event-lvm2*.so ++++++ 0001-post-release.patch ++++++ >From 8dccc2314e2482370bc6e5cf007eb210994abdef Mon Sep 17 00:00:00 2001 From: Marian Csontos <mcson...@redhat.com> Date: Mon, 7 Feb 2022 18:02:07 +0100 Subject: post-release --- VERSION | 2 +- VERSION_DM | 2 +- WHATS_NEW | 3 +++ WHATS_NEW_DM | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 0e6ab70a9c50..fba090956ba1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.03.15(2) (2022-02-07) +2.03.16(2)-git (2022-02-07) diff --git a/VERSION_DM b/VERSION_DM index d6704212f283..d122183b2c63 100644 --- a/VERSION_DM +++ b/VERSION_DM @@ -1 +1 @@ -1.02.183 (2022-02-07) +1.02.185-git (2022-02-07) diff --git a/WHATS_NEW b/WHATS_NEW index dda9954fe52f..006d0acb141c 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,3 +1,6 @@ +Version 2.03.16 - +==================================== + Version 2.03.15 - 07th February 2022 ==================================== Remove service based autoactivation. global/event_activation = 0 is NOOP. diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 77843726211c..c634362217a5 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,3 +1,6 @@ +Version 1.02.185 - +===================================== + Version 1.02.183 - 07th February 2022 ===================================== Unmangle UUIDs for DM_DEVICE_LIST ioctl. -- 2.34.1 ++++++ 0002-asan-fix-some-reports-from-libasan.patch ++++++ >From f83b3962c10bf4e196fec0e3e735820ba908661f Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Mon, 7 Feb 2022 19:58:04 +0100 Subject: asan: fix some reports from libasan When compiled and used with: CFLAGS="-fsanitize=address -g -O0" ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 we have few reported issue - they where not normally spotted, since we were still accessing our own memory - but ouf of buffer-range. TODO: there is still something to enhance with handling of #orphan vgids --- lib/config/config.c | 4 +++- lib/format_text/format-text.c | 2 +- lib/format_text/text_label.c | 6 ++++-- lib/metadata/metadata-exported.h | 2 +- lib/uuid/uuid.c | 5 +++++ tools/Makefile.in | 4 ++-- tools/command.c | 2 +- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/config/config.c b/lib/config/config.c index c8dab5683a20..f9614779a743 100644 --- a/lib/config/config.c +++ b/lib/config/config.c @@ -522,7 +522,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r if (!(dev->flags & DEV_REGULAR) || size2) use_plain_read = 0; - if (!(buf = zalloc(size + size2))) { + /* Ensure there is extra '\0' after end of buffer since we pass + * buffer to funtions like strtoll() */ + if (!(buf = zalloc(size + size2 + 1))) { log_error("Failed to allocate circular buffer."); return 0; } diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index 00443faa12f7..07aaa0b28880 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -2601,7 +2601,7 @@ struct format_type *create_text_format(struct cmd_context *cmd) fmt->ops = &_text_handler; fmt->name = FMT_TEXT_NAME; fmt->alias = FMT_TEXT_ALIAS; - fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME); + strncpy(fmt->orphan_vg_name, ORPHAN_VG_NAME(FMT_TEXT_NAME), sizeof(fmt->orphan_vg_name)); fmt->features = FMT_SEGMENTS | FMT_TAGS | FMT_PRECOMMIT | FMT_UNLIMITED_VOLS | FMT_RESIZE_PV | FMT_UNLIMITED_STRIPESIZE | FMT_CONFIG_PROFILE | diff --git a/lib/format_text/text_label.c b/lib/format_text/text_label.c index 29b470271170..324c86e44978 100644 --- a/lib/format_text/text_label.c +++ b/lib/format_text/text_label.c @@ -410,6 +410,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct { struct lvmcache_vgsummary vgsummary; char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 }; + char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 }; struct lvmcache_info *info; const struct format_type *fmt = labeller->fmt; struct label_header *lh = (struct label_header *) label_buf; @@ -433,6 +434,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct pvhdr = (struct pv_header *) ((char *) label_buf + xlate32(lh->offset_xl)); memcpy(pvid, &pvhdr->pv_uuid, ID_LEN); + strncpy(vgid, FMT_TEXT_ORPHAN_VG_NAME, ID_LEN); /* * FIXME: stop adding the device to lvmcache initially as an orphan @@ -449,8 +451,8 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct * Other reasons for lvmcache_add to return NULL are internal errors. */ if (!(info = lvmcache_add(cmd, labeller, pvid, dev, label_sector, - FMT_TEXT_ORPHAN_VG_NAME, - FMT_TEXT_ORPHAN_VG_NAME, 0, is_duplicate))) + vgid, + vgid, 0, is_duplicate))) return_0; lvmcache_set_device_size(info, xlate64(pvhdr->device_size_xl)); diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 7bac5b900343..fd370d4b261a 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -371,7 +371,7 @@ struct format_type { struct labeller *labeller; const char *name; const char *alias; - const char *orphan_vg_name; + char orphan_vg_name[ID_LEN]; struct volume_group *orphan_vg; /* Only one ever exists. */ uint32_t features; void *library; diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c index be4cbc3ec194..d8b72422bc0f 100644 --- a/lib/uuid/uuid.c +++ b/lib/uuid/uuid.c @@ -168,6 +168,11 @@ int id_write_format(const struct id *id, char *buffer, size_t size) assert(ID_LEN == 32); + if (id->uuid[0] == '#') { + (void) dm_strncpy(buffer, (char*)id->uuid, size); + return 1; + } + /* split into groups separated by dashes */ if (size < (32 + 6 + 1)) { if (size > 0) diff --git a/tools/Makefile.in b/tools/Makefile.in index e0e180474789..25fe3b6b36d8 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -190,9 +190,9 @@ command-lines-input.h: $(srcdir)/command-lines.in Makefile $(Q) set -o pipefail && \ ( cat $(srcdir)/license.inc && \ echo "/* Do not edit. This file is generated by the Makefile. */" && \ - echo -en "const char _command_input[] =\n\n\"" && \ + echo -en "static const char _command_input[] =\n\n\"" && \ $(EGREP) -v '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \ - echo "\\n\";" \ + echo "\\n\\n\";" \ ) > $@ $(SOURCES:%.c=%.d) $(SOURCES2:%.c=%.d): command-lines-input.h command-count.h cmds.h diff --git a/tools/command.c b/tools/command.c index 18ffd64ed986..8de8825e4cbd 100644 --- a/tools/command.c +++ b/tools/command.c @@ -2549,7 +2549,7 @@ static const char *_man_long_opt_name(const char *cmdname, int opt_enum) } if (strchr(long_opt, '[')) { - for (i = 0; i < sizeof(long_opt_name) - 1; ++long_opt, ++i) { + for (i = 0; *long_opt && i < sizeof(long_opt_name) - 1; ++long_opt, ++i) { if (i < (sizeof(long_opt_name) - 8)) switch(*long_opt) { case '[': -- 2.34.1 ++++++ 0003-make-generate.patch ++++++ >From 13122bcc3329f3c1aee0a1cc478eda8906cd96df Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Sun, 6 Feb 2022 20:05:54 +0100 Subject: make: generate --- conf/example.conf.in | 15 +++----- man/lvdisplay.8_pregen | 12 ------- man/lvmdevices.8_pregen | 3 +- man/pvdisplay.8_pregen | 12 ------- man/pvscan.8_pregen | 77 ++++++++++++++++++++++------------------- man/vgchange.8_pregen | 12 +++++++ man/vgdisplay.8_pregen | 12 ------- 7 files changed, 60 insertions(+), 83 deletions(-) diff --git a/conf/example.conf.in b/conf/example.conf.in index a78ed7333310..94f7a23fdb11 100644 --- a/conf/example.conf.in +++ b/conf/example.conf.in @@ -1151,16 +1151,11 @@ global { # lvdisplay_shows_full_device_path = 0 # Configuration option global/event_activation. - # Activate LVs based on system-generated device events. - # When a PV appears on the system, a system-generated uevent triggers - # the lvm2-pvscan service which runs the pvscan --cache -aay command. - # If the new PV completes a VG, pvscan autoactivates LVs in the VG. - # When event_activation is disabled, the lvm2-activation services are - # generated and run at fixed points during system startup. These - # services run vgchange -aay to autoactivate LVs in VGs that happen - # to be present at that point in time. - # See the --setautoactivation option or the auto_activation_volume_list - # setting to configure autoactivation for specific VGs or LVs. + # Disable event based autoactivation commands. + # WARNING: setting this to zero may cause machine startup to fail. + # Previously, setting this to zero would enable static autoactivation + # services (via the lvm2-activation-generator), but the autoactivation + # services and generator have been removed. # This configuration option has an automatic default value. # event_activation = 1 diff --git a/man/lvdisplay.8_pregen b/man/lvdisplay.8_pregen index a1740ebed152..04aab4c0970c 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/lvmdevices.8_pregen b/man/lvmdevices.8_pregen index d64c3a31abe7..a2391a62bb3e 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 diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen index 22a0992b52bb..2f26a8727d43 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 9eb6b5bf96be..4622e145e564 100644 --- a/man/pvscan.8_pregen +++ b/man/pvscan.8_pregen @@ -15,6 +15,8 @@ pvscan \(em List all physical volumes .P .ad l \fB-a\fP|\fB--activate\fP \fBy\fP|\fBn\fP|\fBay\fP +.br + \fB--autoactivation\fP \fIString\fP .br \fB--cache\fP .br @@ -91,59 +93,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 . @@ -215,6 +208,8 @@ Record that a PV is online and autoactivate the VG if complete. .br [ \fB--noudevsync\fP ] .br +[ \fB--autoactivation\fP \fIString\fP ] +.br [ COMMON_OPTIONS ] .ad b .RE @@ -239,6 +234,8 @@ Record that a PV is online and list the VG using the PV. .br [ \fB--udevoutput\fP ] .br +[ \fB--autoactivation\fP \fIString\fP ] +.br [ COMMON_OPTIONS ] .ad b .RE @@ -342,6 +339,14 @@ Auto-activate LVs in a VG when the PVs scanned have completed the VG. (Only \fBay\fP is applicable.) . .HP +\fB--autoactivation\fP \fIString\fP +.br +Specify if autoactivation is being used from an event. +This allows the command to apply settings that are specific +to event activation, such as device scanning optimizations +using pvs_online files created by event-based pvscans. +. +.HP \fB--cache\fP .br Scan one or more devices and record that they are online. diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen index 05c67aeada56..9dbad3faad87 100644 --- a/man/vgchange.8_pregen +++ b/man/vgchange.8_pregen @@ -24,6 +24,8 @@ vgchange \(em Change volume group attributes .nh \%\fBcontiguous\fP|\:\fBcling\fP|\:\fBcling_by_tags\fP|\:\fBnormal\fP|\:\fBanywhere\fP|\:\fBinherit\fP .hy +.br + \fB--autoactivation\fP \fIString\fP .br \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP .br @@ -286,6 +288,8 @@ Activate or deactivate LVs. .br [ \fB--poll\fP \fBy\fP|\fBn\fP ] .br +[ \fB--autoactivation\fP \fIString\fP ] +.br [ \fB--ignoremonitoring\fP ] .br [ \fB--noudevsync\fP ] @@ -516,6 +520,14 @@ which PVs the command will use for allocation. See \fBlvm\fP(8) for more information about allocation. . .HP +\fB--autoactivation\fP \fIString\fP +.br +Specify if autoactivation is being used from an event. +This allows the command to apply settings that are specific +to event activation, such as device scanning optimizations +using pvs_online files created by event-based pvscans. +. +.HP \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP .br Specifies if metadata should be backed up automatically after a change. diff --git a/man/vgdisplay.8_pregen b/man/vgdisplay.8_pregen index 9c694921dee8..0a12b3c395bb 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.1 ++++++ 0004-tests-udev-pvscan-vgchange-fix-service-wait.patch ++++++ >From 61f23fe15e0c6e5b7882263e0d527f363535da4d Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Mon, 7 Feb 2022 16:44:57 -0600 Subject: tests: udev-pvscan-vgchange fix service wait As a result of removing -r from systemd-run in commit fbd8b0cf43dc67f51f86f060dce748f446985855 this test needs to change how it handles the transient services. --- test/shell/udev-pvscan-vgchange.sh | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh index a209dc048cce..eb698407881f 100644 --- a/test/shell/udev-pvscan-vgchange.sh +++ b/test/shell/udev-pvscan-vgchange.sh @@ -75,7 +75,7 @@ wait_lvm_activate() { local vgw=$1 local wait=0 - while systemctl status lvm-activate-$vgw | grep "active (running)" && test "$wait" -le 30; do + while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do sleep .2 wait=$(( wait + 1 )) done @@ -382,7 +382,6 @@ lvcreate -l1 -an -n $lv1 $vg9 lvcreate -l1 -an -n $lv2 $vg9 mdadm --stop "$mddev" -systemctl stop lvm-activate-$vg9 || true _clear_online_files mdadm --assemble "$mddev" "$dev1" "$dev2" @@ -405,17 +404,6 @@ mdadm --stop "$mddev" aux udev_wait wipe_all -systemctl stop lvm-activate-$vg1 -systemctl stop lvm-activate-$vg2 -systemctl stop lvm-activate-$vg3 -systemctl stop lvm-activate-$vg4 -systemctl stop lvm-activate-$vg5 -systemctl stop lvm-activate-$vg6 -systemctl stop lvm-activate-$vg7 -systemctl stop lvm-activate-$vg8 -systemctl stop lvm-activate-$vg9 - - # no devices file, filter with symlink of PV # the pvscan needs to look at all dev names to # match the symlink in the filter with the @@ -439,7 +427,6 @@ udevadm trigger --settle -c add /sys/block/$BDEV1 ls /dev/disk/by-id/lvm-pv-uuid-$OPVID1 vgchange -an $vg10 -systemctl stop lvm-activate-$vg10 _clear_online_files aux lvmconf "devices/filter = [ \"a|/dev/disk/by-id/lvm-pv-uuid-$OPVID1|\", \"r|.*|\" ]" -- 2.34.1 ++++++ 0005-devices-file-do-not-clear-PVID-of-unread-devices.patch ++++++ >From d59382c772483d3c09b4fcff90c01d81742feac6 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Thu, 10 Feb 2022 14:00:25 -0600 Subject: 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 9e471a9b514a..8c3a8c30e086 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 4618247ba1f2..003f10a96641 100644 --- a/lib/device/device_id.c +++ b/lib/device/device_id.c @@ -1746,6 +1746,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. @@ -1828,6 +1835,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 93dfdd5c1d9a..35ae7f5cc8df 100644 --- a/lib/label/hints.c +++ b/lib/label/hints.c @@ -236,6 +236,7 @@ static int _touch_newhints(void) return_0; if (fclose(fp)) stack; + log_debug("newhints created"); return 1; } @@ -506,6 +507,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 8676b9e4a642..fe2bc8fec743 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -687,6 +687,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 @@ -702,6 +704,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; } } @@ -725,6 +728,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); @@ -1389,6 +1393,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.1 ++++++ 0006-tests-skip-vgchange-pvs-online.sh-on-rhel5.patch ++++++ >From 6626adb46789e329a53242822dc6e9d233320adb Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Tue, 15 Feb 2022 15:56:01 -0600 Subject: tests: skip vgchange-pvs-online.sh on rhel5 the /dev/mapper/ paths to test devices don't seem to work there --- test/shell/vgchange-pvs-online.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/shell/vgchange-pvs-online.sh b/test/shell/vgchange-pvs-online.sh index ced03f4daef7..9bcf70e4b245 100644 --- a/test/shell/vgchange-pvs-online.sh +++ b/test/shell/vgchange-pvs-online.sh @@ -19,6 +19,9 @@ _clear_online_files() { aux prepare_devs 4 +# skip rhel5 which doesn't seem to have /dev/mapper/LVMTESTpv1 +aux driver_at_least 4 15 || skip + DFDIR="$LVM_SYSTEM_DIR/devices" mkdir -p "$DFDIR" || true DF="$DFDIR/system.devices" -- 2.34.1 ++++++ 0007-dev_manager-fix-dm_task_get_device_list.patch ++++++ >From 6ffb150f3075da69597e6f3e84d7533f2d8a36fa Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Wed, 16 Feb 2022 00:33:25 +0100 Subject: dev_manager: fix dm_task_get_device_list With very old version of DM target driver we have to avoid trying to use newuuid setting - otherwise we get error during ioctl preparation phase. Patch is fixing regression from commit: 988ea0e94c79a496f2619eab878fd9db6168711d --- lib/activate/dev_manager.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 6cf4c718c389..3fd6aaff76a9 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -107,6 +107,8 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info, int with_flush, int query_inactive) { + char vsn[80]; + unsigned maj, min; struct dm_task *dmt; if (!(dmt = dm_task_create(task))) @@ -142,7 +144,11 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info, case DM_DEVICE_TARGET_MSG: return dmt; /* TARGET_MSG needs more local tweaking before task_run() */ case DM_DEVICE_LIST: - if (!dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here + /* Use 'newuuid' only with DM version that supports it */ + if (driver_version(vsn, sizeof(vsn)) && + (sscanf(vsn, "%u.%u", &maj, &min) == 2) && + (maj == 4 ? min >= 19 : maj > 4) && + !dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here log_warn("WARNING: Failed to query uuid with LIST."); break; default: -- 2.34.1 ++++++ 0008-dev_manager-failing-status-is-not-internal-error.patch ++++++ >From c2679f76e5c1733451361b593fa45ba9545250b1 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Tue, 15 Feb 2022 21:16:10 +0100 Subject: dev_manager: failing status is not internal error Different target type for LV it's not an internal error. i.e. when target type is replaced with 'error' type - it should be reported as regular warning and not cause interruption of command with internall error. --- 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 3fd6aaff76a9..4d18d9838736 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -204,7 +204,7 @@ static int _get_segment_status_from_target_params(const char *target_name, /* If kernel's type isn't an exact match is it compatible? */ (!segtype->ops->target_status_compatible || !segtype->ops->target_status_compatible(target_name))) { - log_warn(INTERNAL_ERROR "WARNING: Segment type %s found does not match expected type %s for %s.", + log_warn("WARNING: Detected %s segment type does not match expected type %s for %s.", target_name, segtype->name, display_lvname(seg_status->seg->lv)); return 0; } -- 2.34.1 ++++++ 0009-clang-add-extra-check.patch ++++++ >From d2e7a05573f54750d13c1154036ae2c67478539b Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Tue, 8 Feb 2022 19:17:30 +0100 Subject: clang: add extra check Make clang happier. --- lib/metadata/metadata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index db0e511ec8ea..1cda1888f356 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -2197,7 +2197,7 @@ static int _validate_lock_args_chars(const char *lock_args) static int _validate_vg_lock_args(struct volume_group *vg) { - if (!_validate_lock_args_chars(vg->lock_args)) { + if (!vg->lock_args || !_validate_lock_args_chars(vg->lock_args)) { log_error(INTERNAL_ERROR "VG %s has invalid lock_args chars", vg->name); return 0; } -- 2.34.1 ++++++ 0010-clang-possible-better-compilation-with-musl-c.patch ++++++ >From 4fd76de4b69f8e5e6d5afa03d54cb4b8986c4bcc Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Wed, 16 Feb 2022 00:48:49 +0100 Subject: clang: possible better compilation with musl c Try to help resolving reported compilation problem with clang & musl C. https://github.com/lvmteam/lvm2/issues/61 --- libdaemon/server/daemon-server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c index 88905a7ddd5a..96cfc392e22b 100644 --- a/libdaemon/server/daemon-server.c +++ b/libdaemon/server/daemon-server.c @@ -18,6 +18,7 @@ #include <dlfcn.h> #include <errno.h> +#include <fcntl.h> /* help musl C */ #include <pthread.h> #include <sys/file.h> #include <sys/stat.h> -- 2.34.1 ++++++ 0011-dev_manager-do-not-query-for-open_count.patch ++++++ >From fa7b67eeebfc28bce355991eebe1b5f21f075e9a Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Fri, 11 Feb 2022 23:55:08 +0100 Subject: dev_manager: do not query for open_count Oepn count is not used along this code path. --- 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 4d18d9838736..feea06a47e53 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2268,7 +2268,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, return 1; } - if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL)) + if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL)) return_0; /* -- 2.34.1 ++++++ 0012-dev_manager-use-list-info-for-preset-devs.patch ++++++ >From d4a0816a5824dc375d662e76823ee8ed77bb9983 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac <zkabe...@redhat.com> Date: Wed, 16 Feb 2022 00:33:32 +0100 Subject: dev_manager: use list info for preset devs In some cases we can also use cached info obtained from DM_DEVICE_LIST also to avoid extra ioctl check for present devices. --- lib/activate/dev_manager.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index feea06a47e53..63bfd9b74b90 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2254,6 +2254,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, { char *dlid, *name; struct dm_info info, info2; + const struct dm_active_device *dev; if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) return_0; @@ -2262,15 +2263,20 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, return_0; if (!dm->cmd->disable_dm_devs && - dm->cmd->cache_dm_devs && - !dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, NULL)) { - log_debug("Cached as not present %s.", name); - return 1; - } - - if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL)) + dm->cmd->cache_dm_devs) { + if (!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, &dev)) { + log_debug("Cached as not present %s.", name); + return 1; + } + info = (struct dm_info) { + .exists = 1, + .major = dev->major, + .minor = dev->minor, + }; + log_debug("Cached as present %s %s (%d:%d).", + name, dlid, info.major, info.minor); + } else if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL)) return_0; - /* * For top level volumes verify that existing device match * requested major/minor and that major/minor pair is available for use -- 2.34.1 ++++++ 0013-man-lvmcache-add-more-writecache-cachesettings-info.patch ++++++ >From ec2119beddde9e38681cb096b93048ee25034c1e Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Wed, 16 Feb 2022 15:21:09 -0600 Subject: man lvmcache: add more writecache cachesettings info --- man/lvmcache.7_main | 51 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/man/lvmcache.7_main b/man/lvmcache.7_main index 8d7d3d17b766..dddd33cfa02c 100644 --- a/man/lvmcache.7_main +++ b/man/lvmcache.7_main @@ -243,15 +243,40 @@ can be used. . .SS dm-writecache settings . -Tunable parameters can be passed to the dm-writecache kernel module using -the --cachesettings option when caching is started, e.g. +To specify dm-writecache tunable settings on the command line, use: +.br +--cachesettings 'option=N' or +.br +--cachesettings 'option1=N option2=N ...' +.P +For example, --cachesettings 'high_watermark=90 writeback_jobs=4'. +.P +To include settings when caching is started, run: .P .nf # lvconvert --type writecache --cachevol fast \\ - --cachesettings 'high_watermark=N writeback_jobs=N' vg/main + --cachesettings 'option=N' vg/main +.fi +.P +To change settings for an existing writecache, run: +.P +.nf +# lvchange --cachesettings 'option=N' vg/main +.fi +.P +To clear all settings that have been applied, run: +.P +.nf +# lvchange --cachesettings '' vg/main +.fi +.P +To view the settings that are applied to a writecache LV, run: +.P +.nf +# lvs -o cachesettings vg/main .fi .P -Tunable options are: +Tunable settings are: . .TP high_watermark = <percent> @@ -301,11 +326,14 @@ writecache. Adding cleaner=0 to the splitcache command will skip the cleaner mode, and any required flushing is performed in device suspend. .SS dm-writecache using metadata profiles - -Writecache allows to set a variety of options. Lots of these settings -can be specified in lvm.conf or profile settings. You can prepare -a number of different profiles in the \fI#DEFAULT_SYS_DIR#/profile\fP directory -and just specify the metadata profile file name when writecaching LV. +. +In addition to specifying writecache settings on the command line, they +can also be set in lvm.conf, or in a profile file, using the +allocation/cache_settings/writecache config structure shown below. +.P +It's possible to prepare a number of different profile files in the +\fI#DEFAULT_SYS_DIR#/profile\fP directory and specify the file name +of the profile when starting writecache. .P .I Example .nf @@ -327,11 +355,10 @@ writeback_jobs=1024 EOF .P -# lvcreate -an -L10G --name wcache vg /dev/fast_ssd -# lvcreate --type writecache -L10G --name main --cachevol wcache \\ +# lvcreate -an -L10G --name fast vg /dev/fast_ssd +# lvcreate --type writecache -L10G --name main --cachevol fast \\ --metadataprofile cache_writecache vg /dev/slow_hdd .fi - . .SS dm-cache with separate data and metadata LVs . -- 2.34.1 ++++++ 0014-man-update-cachesettings-option-description.patch ++++++ >From 96c99d647ef783abcd26a1f3f63f12e033195633 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Wed, 16 Feb 2022 15:36:44 -0600 Subject: man: update cachesettings option description to be more consistent with man page description --- tools/args.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/args.h b/tools/args.h index 3f4580b8d9eb..56669645d2a1 100644 --- a/tools/args.h +++ b/tools/args.h @@ -862,12 +862,13 @@ arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0, "See \\fBlvmcache\\fP(7) for more information.\n") arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0, - "Specifies tunable values for a cache LV in \"Key = Value\" form.\n" - "Repeat this option to specify multiple values.\n" - "(The default values should usually be adequate.)\n" - "The special string value \\fBdefault\\fP switches\n" - "settings back to their default kernel values and removes\n" - "them from the list of settings stored in LVM metadata.\n" + "Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n" + "Use the form 'option=value' or 'option1=value option2=value', or\n" + "repeat --cachesettings for each option being set.\n" + "These settings override the default kernel behaviors which are\n" + "usually adequate. To remove cachesettings and revert to the default\n" + "kernel behaviors, use --cachesettings 'default' for dm-cache or\n" + "an empty string --cachesettings '' for dm-writecache.\n" "See \\fBlvmcache\\fP(7) for more information.\n") arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0, -- 2.34.1 ++++++ 0015-man-lvmcache-mention-writecache-memory-usage.patch ++++++ >From 6144dac897728a4857294d70645df8ed7a5ff11f Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Mon, 21 Feb 2022 11:35:58 -0600 Subject: 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 dddd33cfa02c..ce440bf49983 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.1 ++++++ 0016-writecache-display-block-size-from-lvs.patch ++++++ >From ac1f4bbbfd4c5f1387c3e0607f7d556409e7a4b4 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Mon, 21 Feb 2022 16:09:57 -0600 Subject: 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 12b78b766f15..7e450dacef66 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 12ea890f4b09..6f302360f5d0 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 60df417a40f5..c06b22674f21 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 ce440bf49983..8b8289c74ac7 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 2579ef7b7bac..4e17effe5f1f 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.1 ++++++ 0017-devices-simplify-dev_cache_get_by_devt.patch ++++++ >From 1126be8f8dbce482e82d8f98a7e7f4b7cd2cac34 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Thu, 24 Feb 2022 15:57:29 -0600 Subject: 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 | 6 ++--- 3 files changed, 9 insertions(+), 59 deletions(-) diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c index d3fae494869d..1777628a81a0 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 449bfeb7511c..a88e3c282207 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 fe2bc8fec743..66d6e7db7a6e 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -1134,7 +1134,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname, dm_list_iterate_items(po, &pvs_online) { if (po->dev) continue; - if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno, NULL, NULL))) { + if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) { log_error("No device found for %d:%d PVID %s", (int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid); goto bad; @@ -1722,7 +1722,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); } } @@ -1742,7 +1742,7 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs) if (dm_dev->uuid && strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) { devt = MKDEV(dm_dev->major, dm_dev->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); } /* ATM no further caching for any lvconvert command -- 2.34.1 ++++++ 0018-devices-drop-incorrect-paths-from-aliases-list.patch ++++++ >From 7e70041e324e1a4d49134a93323072e1b6ec661f Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Thu, 24 Feb 2022 16:03:21 -0600 Subject: 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 1777628a81a0..8db28bd84a01 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 a88e3c282207..622335982a10 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 b4f1930b1605..811ad897851b 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 8c3a8c30e086..572994bb9f14 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.1 ++++++ 0019-devices-initial-use-of-existing-option.patch ++++++ >From 00c3069872ab488f66f14c8c2727bd080affc05e Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Thu, 24 Feb 2022 16:10:37 -0600 Subject: 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 003f10a96641..c8df47345e72 100644 --- a/lib/device/device_id.c +++ b/lib/device/device_id.c @@ -1577,7 +1577,7 @@ void device_ids_match_device_list(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? */ @@ -1625,7 +1625,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 b08c044fab7c..897adec347ae 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -1488,7 +1488,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; @@ -3925,7 +3925,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 { @@ -5261,7 +5261,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.1 ++++++ 0020-devices-fix-dev_name-assumptions.patch ++++++ >From 4eb04c8c05e52776891f62863375ceacf866de77 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Tue, 22 Feb 2022 15:03:11 -0600 Subject: 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 | 23 ++++++++++++++++++++++- 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, 75 insertions(+), 8 deletions(-) diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 63bfd9b74b90..2cae3bed1fde 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2947,6 +2947,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 || @@ -2965,7 +2969,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 0e77a009d072..c67a86fa33f6 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 c8df47345e72..7ce955b11c8d 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; @@ -955,6 +957,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 @@ -1842,6 +1848,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)); @@ -2225,14 +2234,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 35ae7f5cc8df..edce6f517133 100644 --- a/lib/label/hints.c +++ b/lib/label/hints.c @@ -500,6 +500,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 66d6e7db7a6e..ffb39389188a 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -1130,6 +1130,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname, * sure to find the device. */ if (try_dev_scan) { + log_debug("Repeat dev cache scan to translate devnos."); dev_cache_scan(cmd); dm_list_iterate_items(po, &pvs_online) { if (po->dev) @@ -1736,6 +1737,12 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs) struct lv_list *lvl; dev_t devt; + /* + * FIXME: this is all unnecessary unless there are PVs stacked on LVs, + * so we can skip all of this if scan_lvs=0. + */ + log_debug("invalidating devs for any pvs on lvs"); + if (get_device_list(NULL, &devs, &devs_features)) { if (devs_features & DM_DEVICE_LIST_HAS_UUID) { dm_list_iterate_items(dm_dev, devs) @@ -1879,10 +1886,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 */ @@ -1912,7 +1933,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 b598df3d6b79..60c80f1b1e5c 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 e2bf191a1ef0..46da57948f00 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 813e8e525052..fc3667db0a9a 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 85482552aefe..adc954babe67 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 99f552ad1268..670568945953 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.1 ++++++ 0021-devices-use-dev-cache-aliases-handling-from-label-sc.patch ++++++ >From 7b1a857d5ac480b789af07d85e55bc87c6a76934 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Mon, 28 Feb 2022 17:37:12 -0600 Subject: [PATCH 1/3] 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 8db28bd84a01..5607beefc40f 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 622335982a10..46b1da72c1ad 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 ffb39389188a..c208638757af 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -459,7 +459,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; @@ -479,14 +478,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); @@ -514,50 +522,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; @@ -605,37 +597,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) @@ -663,10 +624,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; @@ -677,7 +636,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)); @@ -701,9 +659,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; } @@ -787,41 +745,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.1 ++++++ 0022-devices-only-close-PVs-on-LVs-when-scan_lvs-is-enabl.patch ++++++ >From cc73d99886dfd6e0da3c6ca685669f77fac3c1cd Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Tue, 1 Mar 2022 12:22:46 -0600 Subject: [PATCH 2/3] devices: only close PVs on LVs when scan_lvs is enabled This code is only needed when lvm scans PVs that are stacked on LVs. --- lib/label/label.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/label/label.c b/lib/label/label.c index c208638757af..e6bc791a78ff 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -1661,9 +1661,11 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs) dev_t devt; /* - * FIXME: this is all unnecessary unless there are PVs stacked on LVs, - * so we can skip all of this if scan_lvs=0. + * This is only needed when the command sees PVs stacked on LVs which + * will only happen with scan_lvs=1. */ + if (!cmd->scan_lvs) + return; log_debug("invalidating devs for any pvs on lvs"); if (get_device_list(NULL, &devs, &devs_features)) { -- 2.34.1 ++++++ 0023-writecache-check-memory-usage.patch ++++++ >From bef1363c0064f42e8063571143a428ad163d1bd9 Mon Sep 17 00:00:00 2001 From: David Teigland <teigl...@redhat.com> Date: Tue, 1 Mar 2022 14:31:39 -0600 Subject: [PATCH 3/3] 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 a3eb60b20006..1c4351e9d481 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -6070,6 +6070,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) @@ -6158,6 +6221,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.1 ++++++ LVM2.2.03.12.tgz -> LVM2.2.03.15.tgz ++++++ ++++ 35076 lines of diff (skipped) ++++++ fate-309425_display-dm-name-for-lv-name.patch ++++++ --- /var/tmp/diff_new_pack.MgiqQq/_old 2022-03-05 14:44:24.811716006 +0100 +++ /var/tmp/diff_new_pack.MgiqQq/_new 2022-03-05 14:44:24.815716007 +0100 @@ -15,7 +15,7 @@ +cfg(global_display_dm_name_for_lv_name_CFG, "display_dm_name_for_lv_name", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_DISPLAY_DM_NAME_FOR_LV_NAME, vsn(2, 2, 98), NULL, 0, NULL, + "Display dm name for lv name.\n") + - cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SYSTEM_ID_SOURCE, vsn(2, 2, 117), NULL, 0, NULL, + cfg(global_system_id_source_CFG, "system_id_source", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_SYSTEM_ID_SOURCE, vsn(2, 2, 117), NULL, 0, NULL, "The method LVM uses to set the local system ID.\n" "Volume Groups can also be given a system ID (by vgcreate, vgchange,\n" Index: LVM2.2.02.170/lib/config/defaults.h @@ -23,7 +23,7 @@ --- LVM2.2.02.170.orig/lib/config/defaults.h +++ LVM2.2.02.170/lib/config/defaults.h @@ -33,6 +33,7 @@ - #define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1 + #define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 0 #define DEFAULT_EXTERNAL_DEVICE_INFO_SOURCE "none" #define DEFAULT_SYSFS_SCAN 1 +#define DEFAULT_DISPLAY_DM_NAME_FOR_LV_NAME 0