From 92d48a4401175e7a8a7434b57f429053b045f789 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Tue, 26 Nov 2024 17:28:43 +0300 Subject: [PATCH] import mdadm-4.3-3.el10 --- .gitignore | 1 + .mdadm.metadata | 1 + ...rdcoded-checkpoint-interval-checking.patch | 64 + ...2-monitor-refactor-checkpoint-update.patch | 96 + ...r-intel-Fix-first-checkpoint-restart.patch | 47 + ...e-update_tail-assign-to-Grow_reshape.patch | 61 + ...-understanding-output-section-in-man.patch | 56 + ...-add_disk_to_super-fix-resource-leak.patch | 48 + .../0007-mdadm-signal_s-init-variables.patch | 35 + ...ile-before-check-in-check_one_sharer.patch | 48 + ...emove-dead-condition-in-Grow_reshape.patch | 34 + ...before-passing-to-get_dev_size-in-ad.patch | 34 + ...efactor-md-device-name-check-in-main.patch | 66 + ...test-run-tests-on-system-level-mdadm.patch | 138 ++ ...tor-Allow-no-PID-in-check_one_sharer.patch | 43 + ...-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch | 47 + SOURCES/0015-mdadm-remove-TODO.patch | 236 ++ SOURCES/0016-mdadm-remove-makedist.patch | 119 + SOURCES/0017-mdadm-remove-mdadm.spec.patch | 69 + .../0018-mdadm-remove-mkinitramfs-stuff.patch | 209 ++ ...9-mdadm-move-documentation-to-folder.patch | 1044 +++++++++ .../0020-Detail-remove-duplicated-code.patch | 75 + ...ions-for-spare-criteria-verification.patch | 286 +++ ...adm-drop-get_required_spare_criteria.patch | 357 +++ ...ge-fix-check-after-dereference-issue.patch | 64 + ...Manage-implement-manage_add_external.patch | 184 ++ ...-introduce-sysfs_get_container_devnm.patch | 138 ++ ...m.h-Introduce-custom-device-policies.patch | 115 + ...d_add-device-policies-implementation.patch | 144 ++ SOURCES/0028-Create-Use-device-policies.patch | 124 + ...vice-policies-in-manage_add_external.patch | 60 + ...itor-Incremental-use-device-policies.patch | 142 ++ ...d_add_device_policies-implementation.patch | 187 ++ ...dadm-drop-get_disk_controller_domain.patch | 75 + ...Avoid-to-take-spare-without-defined-.patch | 42 + .../0034-mdadm-remove-inventory-file.patch | 307 +++ ...not-require-libudev.h-if-DNO_LIBUDEV.patch | 31 + ...ts.h-include-for-NAME_MAX-definition.patch | 29 + ...7-mdadm-set-swapuuid-in-all-handlers.patch | 59 + .../0038-mdadm-Fix-native-detail-export.patch | 247 ++ ...-vers-parameter-from-sysfs_set_array.patch | 87 + ...040-mdadm-fix-grow-segfault-for-IMSM.patch | 55 + SOURCES/0041-Remove-all-if-zeros-pt.2.patch | 85 + ...-mdadm-Move-pr_vrb-define-to-mdadm.h.patch | 44 + ...ing-Opal-NVMe-encryption-information.patch | 463 ++++ ...-reading-SATA-encryption-information.patch | 459 ++++ ...Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch | 163 ++ ...sm-print-disk-encryption-information.patch | 217 ++ ...ive-encryption-policy-implementation.patch | 114 + SOURCES/0048-mdadm-add-CHANGELOG.md.patch | 2010 +++++++++++++++++ SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch | 66 + SOURCES/0050-mdadm-Add-README.md.patch | 106 + SOURCES/0051-Create.c-fix-uclibc-build.patch | 41 + ...struct-context-for-external-reshapes.patch | 309 +++ ...-use-struct-context-in-reshape_super.patch | 296 +++ ...imsm-add-support-for-literal-RAID-10.patch | 184 ++ ...55-imsm-refactor-RAID-level-handling.patch | 345 +++ SOURCES/0056-imsm-bump-minimal-version.patch | 180 ++ .../0057-imsm-define-RAID_10-attribute.patch | 67 + ...-imsm-simplify-imsm_check_attributes.patch | 153 ++ ...port-RAID-10-with-more-than-4-drives.patch | 168 ++ SOURCES/0060-tests-01r5fail-enhance.patch | 41 + SOURCES/0061-tests-01r5integ.broken.patch | 32 + ...s-01raid6integ.broken-can-be-removed.patch | 31 + .../0063-Makefile-Move-pie-to-LDFLAGS.patch | 38 + ...064-tests-23rdev-lifetime-fix-a-typo.patch | 30 + ...ge-devnm-to-const-in-mdmon-functions.patch | 55 + ...-mdmon-when-it-is-stared-via-systemd.patch | 121 + ...dadm-Fix-compilation-for-32-bit-arch.patch | 62 + ...king-of-return-status-on-fstat-calls.patch | 267 +++ ...71-super-intel-fix-typo-in-error-msg.patch | 28 + ...2-mdadm-super-intel-remove-dead-code.patch | 45 + ...0073-mdadm-super-intel-fix-bad-shift.patch | 55 + ...4-mdadm-deprecate-bitmap-custom-file.patch | 438 ++++ .../0075-Makefile-fix-make-s-detection.patch | 31 + ...ge-some-error-messages-to-info-level.patch | 81 + .../0077-mdadm-Start-update_opt-from-0.patch | 40 + ...on-t-control-reshape-speed-in-daemon.patch | 49 + SOURCES/0079-mdadm-tests-test-enhance.patch | 119 + ...-don-t-fail-when-systemd-reports-err.patch | 31 + ...1-mdadm-tests-names_template-enhance.patch | 109 + ...082-mdadm-tests-03assem-incr-enhance.patch | 67 + .../0083-mdadm-tests-03r0assem-enhance.patch | 38 + ...-mdadm-tests-remove-03r5assem-failed.patch | 35 + SOURCES/0085-mdadm-tests-03r5assemV1.patch | 52 + ...6-mdadm-tests-remove-04r5swap.broken.patch | 30 + ...-tests-04update-metadata-skip-linear.patch | 116 + ...0088-mdadm-tests-05r5-internalbitmap.patch | 68 + SOURCES/0089-mdadm-tests-06name-enhance.patch | 38 + SOURCES/0090-mdadm-tests-07autoassemble.patch | 108 + ...s-07autodetect.broken-can-be-removed.patch | 28 + .../0092-mdadm-tests-07changelevelintr.patch | 73 + .../0093-mdadm-tests-disable-selinux.patch | 68 + ...tform-intel-buffer-overflow-detected.patch | 44 + ...095-mdadm-tests-bitmap-cases-enhance.patch | 279 +++ SOURCES/0096-mdadm-tests-04update-uuid.patch | 39 + ...0097-mdadm-tests-05r1-re-add-nosuper.patch | 30 + .../0098-mdadm-tests-remove-strace-test.patch | 44 + ...e-basename-if-GLIBC-is-not-avialable.patch | 37 + ...olume-autolayout-with-IMSM_NO_PLATFO.patch | 79 + ...eesize-required-to-volume-autolayout.patch | 50 + ...ace-condition-in-wait_for_zero_forks.patch | 86 + ...HLD-processes-before-starting-childr.patch | 37 + .../0104-test-pass-flags-to-services.patch | 137 ++ ...-connection-failure-when-mdmon-runs-.patch | 68 + ...06-Makefile-Do-not-call-gcc-directly.patch | 50 + ...ts-judge-foreign-array-in-test-cases.patch | 103 + ...-socket-connection-failure-when-mdmo.patch | 58 + ...mdadm-Assemble.c-fix-coverity-issues.patch | 149 ++ ...-connection-failure-when-mdmon-runs-.patch | 118 + ...c-Fix-memory-leak-in-load_containers.patch | 28 + ...14-mdadm-Build.c-fix-coverity-issues.patch | 40 + ...5-mdadm-Create.c-fix-coverity-issues.patch | 45 + ...dadm-super-ddf.c-fix-coverity-issues.patch | 473 ++++ ...tests-add-some-APIs-in-func.sh-to-su.patch | 102 + ...tests-adjust-test-cases-to-support-m.patch | 81 + ...-mapfile.c-Fix-STRING_OVERFLOW-issue.patch | 40 + ...0-mdadm-Manage.c-fix-coverity-issues.patch | 484 ++++ SOURCES/0121-Manage-fix-is_remove_safe.patch | 29 + ...sm-add-indent-for-encryption-details.patch | 28 + ...-mdadm-Monitor.c-fix-coverity-issues.patch | 67 + ...24-mdadm-Query.c-fix-coverity-issues.patch | 42 + ...0125-mdadm-lib.c-fix-coverity-issues.patch | 43 + ...-allow-leading-dot-in-MD-device-name.patch | 158 ++ ...tail-fix-detail-export-for-uuid_zero.patch | 36 + ...ryption-Fix-ata-passthrough12-verify.patch | 84 + ...ine-for-char-array-in-examine_super0.patch | 46 + ...131-Makefile-add-more-compiler-flags.patch | 61 + ...work-mdstat-external-arrays-handling.patch | 575 +++++ ...dadm-managemon.c-fix-coverity-issues.patch | 56 + ...0135-mdadm-msg.c-fix-coverity-issues.patch | 40 + .../0136-imsm-refactor-chunk-size-print.patch | 150 ++ ...ow-fix-coverity-issue-CHECKED_RETURN.patch | 109 + ...row-fix-coverity-issue-RESOURCE_LEAK.patch | 166 ++ ...w-fix-coverity-issue-STRING_OVERFLOW.patch | 29 + ...dadm-Incremental-fix-coverity-issues.patch | 87 + ...on-fix-coverity-issue-CHECKED_RETURN.patch | 46 + ...mon-fix-coverity-issue-RESOURCE_LEAK.patch | 49 + ...en-fix-coverity-issue-CHECKED_RETURN.patch | 33 + ...n-fix-coverity-issue-STRING_OVERFLOW.patch | 29 + ...at-fix-coverity-issue-CHECKED_RETURN.patch | 46 + ...-coverity-issue-CHECKED_RETURN-and-E.patch | 56 + ...r1-fix-coverity-issue-CHECKED_RETURN.patch | 67 + ...m-super1-fix-coverity-issue-DEADCODE.patch | 29 + ...-fix-coverity-issue-EVALUATION_ORDER.patch | 46 + ...er1-fix-coverity-issue-RESOURCE_LEAK.patch | 41 + ...ix-check_return-issue-in-Write_rules.patch | 66 + ...c-Fix-check_return-issue-in-load_gpt.patch | 40 + ...53-super-intel-fix-compilation-error.patch | 46 + ...uper-intel-add-define-for-migr_state.patch | 92 + ...et-only-component_size-for-size-grow.patch | 52 + .../0157-mdstat-fix-list-detach-issues.patch | 43 + SOURCES/md-auto-readd.rule | 27 + SOURCES/md-auto-readd.sh | 17 + SOURCES/mdadm-2.5.2-static.patch | 23 + SOURCES/mdadm-raid-check-sysconfig | 60 + SOURCES/mdadm-udev.patch | 26 + SOURCES/mdadm.conf | 1 + SOURCES/mdadm_event.conf | 5 + SOURCES/mdcheck | 166 ++ SOURCES/mdmonitor.service | 12 + SOURCES/raid-check | 135 ++ SOURCES/raid-check.service | 6 + SOURCES/raid-check.timer | 10 + SPECS/mdadm.spec | 1312 +++++++++++ 165 files changed, 20286 insertions(+) create mode 100644 .gitignore create mode 100644 .mdadm.metadata create mode 100644 SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch create mode 100644 SOURCES/0002-monitor-refactor-checkpoint-update.patch create mode 100644 SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch create mode 100644 SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch create mode 100644 SOURCES/0005-Add-understanding-output-section-in-man.patch create mode 100644 SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch create mode 100644 SOURCES/0007-mdadm-signal_s-init-variables.patch create mode 100644 SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch create mode 100644 SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch create mode 100644 SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch create mode 100644 SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch create mode 100644 SOURCES/0012-test-run-tests-on-system-level-mdadm.patch create mode 100644 SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch create mode 100644 SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch create mode 100644 SOURCES/0015-mdadm-remove-TODO.patch create mode 100644 SOURCES/0016-mdadm-remove-makedist.patch create mode 100644 SOURCES/0017-mdadm-remove-mdadm.spec.patch create mode 100644 SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch create mode 100644 SOURCES/0019-mdadm-move-documentation-to-folder.patch create mode 100644 SOURCES/0020-Detail-remove-duplicated-code.patch create mode 100644 SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch create mode 100644 SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch create mode 100644 SOURCES/0023-Manage-fix-check-after-dereference-issue.patch create mode 100644 SOURCES/0024-Manage-implement-manage_add_external.patch create mode 100644 SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch create mode 100644 SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch create mode 100644 SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch create mode 100644 SOURCES/0028-Create-Use-device-policies.patch create mode 100644 SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch create mode 100644 SOURCES/0030-Monitor-Incremental-use-device-policies.patch create mode 100644 SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch create mode 100644 SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch create mode 100644 SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch create mode 100644 SOURCES/0034-mdadm-remove-inventory-file.patch create mode 100644 SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch create mode 100644 SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch create mode 100644 SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch create mode 100644 SOURCES/0038-mdadm-Fix-native-detail-export.patch create mode 100644 SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch create mode 100644 SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch create mode 100644 SOURCES/0041-Remove-all-if-zeros-pt.2.patch create mode 100644 SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch create mode 100644 SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch create mode 100644 SOURCES/0044-Add-reading-SATA-encryption-information.patch create mode 100644 SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch create mode 100644 SOURCES/0046-imsm-print-disk-encryption-information.patch create mode 100644 SOURCES/0047-imsm-drive-encryption-policy-implementation.patch create mode 100644 SOURCES/0048-mdadm-add-CHANGELOG.md.patch create mode 100644 SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch create mode 100644 SOURCES/0050-mdadm-Add-README.md.patch create mode 100644 SOURCES/0051-Create.c-fix-uclibc-build.patch create mode 100644 SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch create mode 100644 SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch create mode 100644 SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch create mode 100644 SOURCES/0055-imsm-refactor-RAID-level-handling.patch create mode 100644 SOURCES/0056-imsm-bump-minimal-version.patch create mode 100644 SOURCES/0057-imsm-define-RAID_10-attribute.patch create mode 100644 SOURCES/0058-imsm-simplify-imsm_check_attributes.patch create mode 100644 SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch create mode 100644 SOURCES/0060-tests-01r5fail-enhance.patch create mode 100644 SOURCES/0061-tests-01r5integ.broken.patch create mode 100644 SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch create mode 100644 SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch create mode 100644 SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch create mode 100644 SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch create mode 100644 SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch create mode 100644 SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch create mode 100644 SOURCES/0070-add-checking-of-return-status-on-fstat-calls.patch create mode 100644 SOURCES/0071-super-intel-fix-typo-in-error-msg.patch create mode 100644 SOURCES/0072-mdadm-super-intel-remove-dead-code.patch create mode 100644 SOURCES/0073-mdadm-super-intel-fix-bad-shift.patch create mode 100644 SOURCES/0074-mdadm-deprecate-bitmap-custom-file.patch create mode 100644 SOURCES/0075-Makefile-fix-make-s-detection.patch create mode 100644 SOURCES/0076-Change-some-error-messages-to-info-level.patch create mode 100644 SOURCES/0077-mdadm-Start-update_opt-from-0.patch create mode 100644 SOURCES/0078-Don-t-control-reshape-speed-in-daemon.patch create mode 100644 SOURCES/0079-mdadm-tests-test-enhance.patch create mode 100644 SOURCES/0080-mdadm-tests-test-don-t-fail-when-systemd-reports-err.patch create mode 100644 SOURCES/0081-mdadm-tests-names_template-enhance.patch create mode 100644 SOURCES/0082-mdadm-tests-03assem-incr-enhance.patch create mode 100644 SOURCES/0083-mdadm-tests-03r0assem-enhance.patch create mode 100644 SOURCES/0084-mdadm-tests-remove-03r5assem-failed.patch create mode 100644 SOURCES/0085-mdadm-tests-03r5assemV1.patch create mode 100644 SOURCES/0086-mdadm-tests-remove-04r5swap.broken.patch create mode 100644 SOURCES/0087-tests-04update-metadata-skip-linear.patch create mode 100644 SOURCES/0088-mdadm-tests-05r5-internalbitmap.patch create mode 100644 SOURCES/0089-mdadm-tests-06name-enhance.patch create mode 100644 SOURCES/0090-mdadm-tests-07autoassemble.patch create mode 100644 SOURCES/0091-mdadm-tests-07autodetect.broken-can-be-removed.patch create mode 100644 SOURCES/0092-mdadm-tests-07changelevelintr.patch create mode 100644 SOURCES/0093-mdadm-tests-disable-selinux.patch create mode 100644 SOURCES/0094-mdadm-platform-intel-buffer-overflow-detected.patch create mode 100644 SOURCES/0095-mdadm-tests-bitmap-cases-enhance.patch create mode 100644 SOURCES/0096-mdadm-tests-04update-uuid.patch create mode 100644 SOURCES/0097-mdadm-tests-05r1-re-add-nosuper.patch create mode 100644 SOURCES/0098-mdadm-tests-remove-strace-test.patch create mode 100644 SOURCES/0099-mdadm.h-provide-basename-if-GLIBC-is-not-avialable.patch create mode 100644 SOURCES/0100-imsm-fix-first-volume-autolayout-with-IMSM_NO_PLATFO.patch create mode 100644 SOURCES/0101-imsm-make-freesize-required-to-volume-autolayout.patch create mode 100644 SOURCES/0102-mdadm-Fix-hang-race-condition-in-wait_for_zero_forks.patch create mode 100644 SOURCES/0103-mdadm-Block-SIGCHLD-processes-before-starting-childr.patch create mode 100644 SOURCES/0104-test-pass-flags-to-services.patch create mode 100644 SOURCES/0105-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch create mode 100644 SOURCES/0106-Makefile-Do-not-call-gcc-directly.patch create mode 100644 SOURCES/0107-mdadm-tests-judge-foreign-array-in-test-cases.patch create mode 100644 SOURCES/0108-Revert-mdadm-Fix-socket-connection-failure-when-mdmo.patch create mode 100644 SOURCES/0109-mdadm-Assemble.c-fix-coverity-issues.patch create mode 100644 SOURCES/0111-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch create mode 100644 SOURCES/0113-config.c-Fix-memory-leak-in-load_containers.patch create mode 100644 SOURCES/0114-mdadm-Build.c-fix-coverity-issues.patch create mode 100644 SOURCES/0115-mdadm-Create.c-fix-coverity-issues.patch create mode 100644 SOURCES/0116-mdadm-super-ddf.c-fix-coverity-issues.patch create mode 100644 SOURCES/0117-mdadm-clustermd_tests-add-some-APIs-in-func.sh-to-su.patch create mode 100644 SOURCES/0118-mdadm-clustermd_tests-adjust-test-cases-to-support-m.patch create mode 100644 SOURCES/0119-mapfile.c-Fix-STRING_OVERFLOW-issue.patch create mode 100644 SOURCES/0120-mdadm-Manage.c-fix-coverity-issues.patch create mode 100644 SOURCES/0121-Manage-fix-is_remove_safe.patch create mode 100644 SOURCES/0122-imsm-add-indent-for-encryption-details.patch create mode 100644 SOURCES/0123-mdadm-Monitor.c-fix-coverity-issues.patch create mode 100644 SOURCES/0124-mdadm-Query.c-fix-coverity-issues.patch create mode 100644 SOURCES/0125-mdadm-lib.c-fix-coverity-issues.patch create mode 100644 SOURCES/0126-mdadm-do-not-allow-leading-dot-in-MD-device-name.patch create mode 100644 SOURCES/0128-Detail-fix-detail-export-for-uuid_zero.patch create mode 100644 SOURCES/0129-drive_encryption-Fix-ata-passthrough12-verify.patch create mode 100644 SOURCES/0130-super0-use-define-for-char-array-in-examine_super0.patch create mode 100644 SOURCES/0131-Makefile-add-more-compiler-flags.patch create mode 100644 SOURCES/0133-mdstat-Rework-mdstat-external-arrays-handling.patch create mode 100644 SOURCES/0134-mdadm-managemon.c-fix-coverity-issues.patch create mode 100644 SOURCES/0135-mdadm-msg.c-fix-coverity-issues.patch create mode 100644 SOURCES/0136-imsm-refactor-chunk-size-print.patch create mode 100644 SOURCES/0137-mdadm-Grow-fix-coverity-issue-CHECKED_RETURN.patch create mode 100644 SOURCES/0138-mdadm-Grow-fix-coverity-issue-RESOURCE_LEAK.patch create mode 100644 SOURCES/0139-mdadm-Grow-fix-coverity-issue-STRING_OVERFLOW.patch create mode 100644 SOURCES/0140-mdadm-Incremental-fix-coverity-issues.patch create mode 100644 SOURCES/0141-mdadm-mdmon-fix-coverity-issue-CHECKED_RETURN.patch create mode 100644 SOURCES/0142-mdadm-mdmon-fix-coverity-issue-RESOURCE_LEAK.patch create mode 100644 SOURCES/0143-mdadm-mdopen-fix-coverity-issue-CHECKED_RETURN.patch create mode 100644 SOURCES/0144-mdadm-mdopen-fix-coverity-issue-STRING_OVERFLOW.patch create mode 100644 SOURCES/0145-mdadm-mdstat-fix-coverity-issue-CHECKED_RETURN.patch create mode 100644 SOURCES/0146-mdadm-super0-fix-coverity-issue-CHECKED_RETURN-and-E.patch create mode 100644 SOURCES/0147-mdadm-super1-fix-coverity-issue-CHECKED_RETURN.patch create mode 100644 SOURCES/0148-mdadm-super1-fix-coverity-issue-DEADCODE.patch create mode 100644 SOURCES/0149-mdadm-super1-fix-coverity-issue-EVALUATION_ORDER.patch create mode 100644 SOURCES/0150-mdadm-super1-fix-coverity-issue-RESOURCE_LEAK.patch create mode 100644 SOURCES/0151-policy.c-Fix-check_return-issue-in-Write_rules.patch create mode 100644 SOURCES/0152-super-gpt.c-Fix-check_return-issue-in-load_gpt.patch create mode 100644 SOURCES/0153-super-intel-fix-compilation-error.patch create mode 100644 SOURCES/0154-super-intel-add-define-for-migr_state.patch create mode 100644 SOURCES/0156-Grow_reshape-set-only-component_size-for-size-grow.patch create mode 100644 SOURCES/0157-mdstat-fix-list-detach-issues.patch create mode 100644 SOURCES/md-auto-readd.rule create mode 100644 SOURCES/md-auto-readd.sh create mode 100644 SOURCES/mdadm-2.5.2-static.patch create mode 100644 SOURCES/mdadm-raid-check-sysconfig create mode 100644 SOURCES/mdadm-udev.patch create mode 100644 SOURCES/mdadm.conf create mode 100644 SOURCES/mdadm_event.conf create mode 100644 SOURCES/mdcheck create mode 100644 SOURCES/mdmonitor.service create mode 100644 SOURCES/raid-check create mode 100644 SOURCES/raid-check.service create mode 100644 SOURCES/raid-check.timer create mode 100644 SPECS/mdadm.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa86236 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mdadm-4.3.tar.xz diff --git a/.mdadm.metadata b/.mdadm.metadata new file mode 100644 index 0000000..de33b58 --- /dev/null +++ b/.mdadm.metadata @@ -0,0 +1 @@ +fb0bace919325b42a005372b5a5cfa999da6567a SOURCES/mdadm-4.3.tar.xz diff --git a/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch b/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch new file mode 100644 index 0000000..c797842 --- /dev/null +++ b/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch @@ -0,0 +1,64 @@ +From aec3b907de48be54106600a1ecb69d1231f4801d Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:15 +0100 +Subject: [PATCH 01/41] Remove hardcoded checkpoint interval checking + +Mdmon assumes that kernel marks checkpoint every 1/16 of the volume size +and that the checkpoints are equal in size. This is not true, kernel may +mark checkpoints more frequently depending on several factors, including +sync speed. This results in checkpoints reported by mdadm --examine +falling behind the one reported by kernel. + +Remove hardcoded checkpoint interval checking. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + monitor.c | 22 ++++++---------------- + 1 file changed, 6 insertions(+), 16 deletions(-) + +diff --git a/monitor.c b/monitor.c +index 4acec678..b8d9e881 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -564,22 +564,10 @@ static int read_and_act(struct active_array *a, fd_set *fds) + } + } + +- /* Check for recovery checkpoint notifications. We need to be a +- * minimum distance away from the last checkpoint to prevent +- * over checkpointing. Note reshape checkpointing is handled +- * in the second branch. ++ /* Handle reshape checkpointing + */ +- if (sync_completed > a->last_checkpoint && +- sync_completed - a->last_checkpoint > a->info.component_size >> 4 && +- a->curr_action > reshape) { +- /* A (non-reshape) sync_action has reached a checkpoint. +- * Record the updated position in the metadata +- */ +- a->last_checkpoint = sync_completed; +- a->container->ss->set_array_state(a, a->curr_state <= clean); +- } else if ((a->curr_action == idle && a->prev_action == reshape) || +- (a->curr_action == reshape && +- sync_completed > a->last_checkpoint)) { ++ if ((a->curr_action == idle && a->prev_action == reshape) || ++ (a->curr_action == reshape && sync_completed > a->last_checkpoint)) { + /* Reshape has progressed or completed so we need to + * update the array state - and possibly the array size + */ +@@ -607,8 +595,10 @@ static int read_and_act(struct active_array *a, fd_set *fds) + a->last_checkpoint = sync_completed; + } + +- if (sync_completed > a->last_checkpoint) ++ if (sync_completed > a->last_checkpoint) { + a->last_checkpoint = sync_completed; ++ a->container->ss->set_array_state(a, a->curr_state <= clean); ++ } + + if (sync_completed >= a->info.component_size) + a->last_checkpoint = 0; +-- +2.40.1 + diff --git a/SOURCES/0002-monitor-refactor-checkpoint-update.patch b/SOURCES/0002-monitor-refactor-checkpoint-update.patch new file mode 100644 index 0000000..236be98 --- /dev/null +++ b/SOURCES/0002-monitor-refactor-checkpoint-update.patch @@ -0,0 +1,96 @@ +From cf87fe75fd83dac008ea116c2c52ec69783fdf6a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:16 +0100 +Subject: [PATCH 02/41] monitor: refactor checkpoint update + +"if" statements of checkpoint updates have too many responsibilties. +This results in unclear code flow and duplicated code. + +Refactor checkpoint update code and simplify "if" statements. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + monitor.c | 51 +++++++++++++++++++++++++-------------------------- + 1 file changed, 25 insertions(+), 26 deletions(-) + +diff --git a/monitor.c b/monitor.c +index b8d9e881..be0bec78 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -412,6 +412,7 @@ static int read_and_act(struct active_array *a, fd_set *fds) + int ret = 0; + int count = 0; + struct timeval tv; ++ bool write_checkpoint = false; + + a->next_state = bad_word; + a->next_action = bad_action; +@@ -564,40 +565,38 @@ static int read_and_act(struct active_array *a, fd_set *fds) + } + } + +- /* Handle reshape checkpointing +- */ +- if ((a->curr_action == idle && a->prev_action == reshape) || +- (a->curr_action == reshape && sync_completed > a->last_checkpoint)) { +- /* Reshape has progressed or completed so we need to +- * update the array state - and possibly the array size +- */ ++ /* Update reshape checkpoint, depending if it finished or progressed */ ++ if (a->curr_action == idle && a->prev_action == reshape) { ++ char buf[SYSFS_MAX_BUF_SIZE]; ++ + if (sync_completed != 0) + a->last_checkpoint = sync_completed; +- /* We might need to update last_checkpoint depending on +- * the reason that reshape finished. +- * if array reshape is really finished: +- * set check point to the end, this allows +- * set_array_state() to finalize reshape in metadata +- * if reshape if broken: do not set checkpoint to the end +- * this allows for reshape restart from checkpoint ++ ++ /* ++ * If reshape really finished, set checkpoint to the end to finalize it. ++ * Do not set checkpoint if reshape is broken. ++ * Reshape will restart from last checkpoint. + */ +- if ((a->curr_action != reshape) && +- (a->prev_action == reshape)) { +- char buf[SYSFS_MAX_BUF_SIZE]; +- if ((sysfs_get_str(&a->info, NULL, +- "reshape_position", +- buf, +- sizeof(buf)) >= 0) && +- str_is_none(buf) == true) ++ if (sysfs_get_str(&a->info, NULL, "reshape_position", buf, sizeof(buf)) >= 0) ++ if (str_is_none(buf) == true) + a->last_checkpoint = a->info.component_size; +- } +- a->container->ss->set_array_state(a, a->curr_state <= clean); +- a->last_checkpoint = sync_completed; ++ ++ write_checkpoint = true; + } + +- if (sync_completed > a->last_checkpoint) { ++ if (a->curr_action >= reshape && sync_completed > a->last_checkpoint) { ++ /* Update checkpoint if neither reshape nor idle action */ + a->last_checkpoint = sync_completed; ++ ++ write_checkpoint = true; ++ } ++ ++ /* Save checkpoint */ ++ if (write_checkpoint) { + a->container->ss->set_array_state(a, a->curr_state <= clean); ++ ++ if (a->curr_action <= reshape) ++ a->last_checkpoint = sync_completed; + } + + if (sync_completed >= a->info.component_size) +-- +2.40.1 + diff --git a/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch b/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch new file mode 100644 index 0000000..0a347ea --- /dev/null +++ b/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch @@ -0,0 +1,47 @@ +From fdb7e802f4cf64d067c3abaafa35056e2bc1ed43 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:17 +0100 +Subject: [PATCH 03/41] Super-intel: Fix first checkpoint restart + +When imsm based array is stopped after reaching first checkpoint and +then assembled, first checkpoint is reported as 0. + +This behaviour is valid only for initial checkpoint, if the array was +stopped while performing some action. + +Last checkpoint value is not taken from metadata but always starts +with 0 and it's incremented when sync_completed in sysfs changes. + +In simplification, read_and_act() is responsible for checkpoint updates +and is executed each time sysfs checkpoint update happens. For first +checkpoint it is executed twice and due to marking checkpoint before +triggering any action on the array, it is impossible to read +sync_completed from sysfs in just two iterations. + +The workaround to this is not marking any checkpoint for first +sysfs checkpoint after RAID assembly, to preserve checkpoint value +stored in metadata. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index dbea235d..e61f3f6f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8771,6 +8771,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent) + super->updates_pending++; + } + ++ if (a->prev_action == idle) ++ goto skip_mark_checkpoint; ++ + mark_checkpoint: + /* skip checkpointing for general migration, + * it is controlled in mdadm +-- +2.40.1 + diff --git a/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch b/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch new file mode 100644 index 0000000..3ccc2ae --- /dev/null +++ b/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch @@ -0,0 +1,61 @@ +From ea2ca7ed3dbbf881ce08d80fe371f2aaf05011c3 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:18 +0100 +Subject: [PATCH 04/41] Grow: Move update_tail assign to Grow_reshape() + +Due to e919fb0af245 ("FIX: Enable metadata updates for raid0") code +can't enter super-intel.c:3415, resulting in checkpoint not being +saved to metadata for second volume in matrix raid array. +This results in checkpoint being stuck at last value for the +first volume. + +Move st->update_tail to Grow_reshape() so it is assigned for each +volume. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/Grow.c b/Grow.c +index f95dae82..5498e54f 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2085,9 +2085,10 @@ int Grow_reshape(char *devname, int fd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(container); +- if (mdmon_running(st->container_devnm) && +- st->update_tail == NULL) +- st->update_tail = &st->updates; ++ if (mdmon_running(st->container_devnm) == false) { ++ pr_err("No mdmon found. Grow cannot continue.\n"); ++ goto release; ++ } + } + + if (s->size == MAX_SIZE) +@@ -3048,6 +3049,8 @@ static int reshape_array(char *container, int fd, char *devname, + dprintf("Cannot get array information.\n"); + goto release; + } ++ if (st->update_tail == NULL) ++ st->update_tail = &st->updates; + if (array.level == 0 && info->component_size == 0) { + get_dev_size(fd, NULL, &array_size); + info->component_size = array_size / array.raid_disks; +@@ -5152,9 +5155,7 @@ int Grow_continue_command(char *devname, int fd, + start_mdmon(container); + ping_monitor(container); + +- if (mdmon_running(container)) +- st->update_tail = &st->updates; +- else { ++ if (mdmon_running(container) == false) { + pr_err("No mdmon found. Grow cannot continue.\n"); + ret_val = 1; + goto Grow_continue_command_exit; +-- +2.40.1 + diff --git a/SOURCES/0005-Add-understanding-output-section-in-man.patch b/SOURCES/0005-Add-understanding-output-section-in-man.patch new file mode 100644 index 0000000..fa4fd55 --- /dev/null +++ b/SOURCES/0005-Add-understanding-output-section-in-man.patch @@ -0,0 +1,56 @@ +From 37eeae381a8ed07a1fabb64184fe45d95a861496 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:19 +0100 +Subject: [PATCH 05/41] Add understanding output section in man + +Add new section in man for explaining mdadm outputs. +Describe checkpoint entry. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.8.in | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 96a4a08e..9ba66825 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -3179,7 +3179,7 @@ environment. This can be useful for testing or for disaster + recovery. You should be aware that interoperability may be + compromised by setting this value. + +-These change can also be suppressed by adding ++These change can also be suppressed by adding + .B mdadm.imsm.test=1 + to the kernel command line. This makes it easy to test IMSM + code in a virtual machine that doesn't have IMSM virtual hardware. +@@ -3454,6 +3454,25 @@ is any string. These names are supported by + since version 3.3 provided they are enabled in + .IR mdadm.conf . + ++.SH UNDERSTANDING OUTPUT ++ ++.TP ++EXAMINE ++ ++.TP ++.B checkpoint ++Checkpoint value is reported when array is performing some action including ++resync, recovery or reshape. Checkpoints allow resuming action from certain ++point if it was interrupted. ++ ++Checkpoint is reported as combination of two values: current migration unit ++and number of blocks per unit. By multiplying those values and dividing by ++array size checkpoint progress percentage can be obtained in relation to ++current progress reported in /proc/mdstat. Checkpoint is also related to (and ++sometimes based on) sysfs entry sync_completed but depending on action units ++may differ. Even if units are the same, it should not be expected that ++checkpoint and sync_completed will be exact match nor updated simultaneously. ++ + .SH NOTE + .I mdadm + was previously known as +-- +2.40.1 + diff --git a/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch b/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch new file mode 100644 index 0000000..13eb094 --- /dev/null +++ b/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch @@ -0,0 +1,48 @@ +From b8f5523a795b8f7e56dfbc139ce7f64728b67726 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:07 +0100 +Subject: [PATCH 06/41] Create: add_disk_to_super() fix resource leak + +Fixes resource leak in add_disk_to_super(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/Create.c b/Create.c +index 8082f54a..7e9170b6 100644 +--- a/Create.c ++++ b/Create.c +@@ -279,8 +279,10 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + dv->devname); + return 1; + } +- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) ++ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) { ++ close(fd); + return 1; ++ } + info->disk.major = major(rdev); + info->disk.minor = minor(rdev); + } +@@ -289,6 +291,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, + dv->data_offset)) { + ioctl(mdfd, STOP_ARRAY, NULL); ++ close(fd); + return 1; + } + st->ss->getinfo_super(st, info, NULL); +@@ -297,6 +300,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + *zero_pid = write_zeroes_fork(fd, s, st, dv); + if (*zero_pid <= 0) { + ioctl(mdfd, STOP_ARRAY, NULL); ++ close(fd); + return 1; + } + } +-- +2.40.1 + diff --git a/SOURCES/0007-mdadm-signal_s-init-variables.patch b/SOURCES/0007-mdadm-signal_s-init-variables.patch new file mode 100644 index 0000000..6be72c2 --- /dev/null +++ b/SOURCES/0007-mdadm-signal_s-init-variables.patch @@ -0,0 +1,35 @@ +From 38cb95dd28fa790ae6d90b169f1fd2b1d09a02f2 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:08 +0100 +Subject: [PATCH 07/41] mdadm: signal_s() init variables + +Init sigaction structs in signal_s(). +This approach might throw warnings for GCC 4.x and lower. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 1f28b3e7..75c887e4 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1856,11 +1856,10 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) + */ + static inline sighandler_t signal_s(int sig, sighandler_t handler) + { +- struct sigaction new_act; +- struct sigaction old_act; ++ struct sigaction new_act = {0}; ++ struct sigaction old_act = {0}; + + new_act.sa_handler = handler; +- new_act.sa_flags = 0; + + if (sigaction(sig, &new_act, &old_act) == 0) + return old_act.sa_handler; +-- +2.40.1 + diff --git a/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch b/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch new file mode 100644 index 0000000..2ca98c4 --- /dev/null +++ b/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch @@ -0,0 +1,48 @@ +From b7d7837128e90c8b496ebc3d88eda1a8ff477392 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:09 +0100 +Subject: [PATCH 08/41] Monitor: open file before check in check_one_sharer() + +Open file before performing checks in check_one_sharer() to avoid +file tampering. +Remove redundant access check. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Monitor.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 824a69fc..7cee95d4 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -451,20 +451,17 @@ static int check_one_sharer(int scan) + return 2; + } + +- if (access(AUTOREBUILD_PID_PATH, F_OK) != 0) +- return 0; +- +- if (!is_file(AUTOREBUILD_PID_PATH)) { +- pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); +- return 2; +- } +- + fp = fopen(AUTOREBUILD_PID_PATH, "r"); + if (!fp) { + pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); + return 2; + } + ++ if (!is_file(AUTOREBUILD_PID_PATH)) { ++ pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); ++ return 2; ++ } ++ + if (fscanf(fp, "%d", &pid) != 1) { + pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); + fclose(fp); +-- +2.40.1 + diff --git a/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch b/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch new file mode 100644 index 0000000..437143e --- /dev/null +++ b/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch @@ -0,0 +1,34 @@ +From e44d13f466e30c018887cd5aaf1212ed9f510813 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:10 +0100 +Subject: [PATCH 09/41] Grow: remove dead condition in Grow_reshape() + +Remove dead "if" condition from Grow_reshape(). Sysfs read check is +performed earlier in the code. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 5498e54f..c69a342d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2098,11 +2098,7 @@ int Grow_reshape(char *devname, int fd, + /* got truncated to 32bit, write to + * component_size instead + */ +- if (sra) +- rv = sysfs_set_num(sra, NULL, +- "component_size", s->size); +- else +- rv = -1; ++ rv = sysfs_set_num(sra, NULL, "component_size", s->size); + } else { + rv = md_set_array_info(fd, &array); + +-- +2.40.1 + diff --git a/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch b/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch new file mode 100644 index 0000000..256b233 --- /dev/null +++ b/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch @@ -0,0 +1,34 @@ +From 7ccf947eb595c1bb729c32ba18ce171dada76a68 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:11 +0100 +Subject: [PATCH 10/41] super1: check fd before passing to get_dev_size() in + add_to_super1() + +Check if file descriptor is valid before passing it to get_dev_size() in +add_to_super(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/super1.c b/super1.c +index 871d19f0..5439b7bb 100644 +--- a/super1.c ++++ b/super1.c +@@ -1752,7 +1752,10 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + di->devname = devname; + di->disk = *dk; + di->data_offset = data_offset; +- get_dev_size(fd, NULL, &di->dev_size); ++ ++ if (is_fd_valid(fd)) ++ get_dev_size(fd, NULL, &di->dev_size); ++ + di->next = NULL; + *dip = di; + +-- +2.40.1 + diff --git a/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch b/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch new file mode 100644 index 0000000..7038b2d --- /dev/null +++ b/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch @@ -0,0 +1,66 @@ +From c8772da4b53307546a9a374507bcec3398fc82c4 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:12 +0100 +Subject: [PATCH 11/41] mdmon: refactor md device name check in main() + +Refactor mdmon main function to verify if fd is valid prior to checking +device name. This is due to static code analysis complaining after +change b938519e7719 ("util: remove obsolete code from get_md_name"). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdmon.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index a2038fe6..5fdb5cdb 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -302,12 +302,12 @@ static int mdmon(char *devnm, int must_fork, int takeover); + int main(int argc, char *argv[]) + { + char *container_name = NULL; +- char *devnm = NULL; + int status = 0; + int opt; + int all = 0; + int takeover = 0; + int dofork = 1; ++ int mdfd = -1; + bool help = false; + static struct option options[] = { + {"all", 0, NULL, 'a'}, +@@ -410,19 +410,20 @@ int main(int argc, char *argv[]) + free_mdstat(mdstat); + + return status; +- } else { +- int mdfd = open_mddev(container_name, 0); +- devnm = fd2devnm(mdfd); ++ } ++ ++ mdfd = open_mddev(container_name, 0); ++ if (is_fd_valid(mdfd)) { ++ char *devnm = fd2devnm(mdfd); + + close(mdfd); +- } + +- if (!devnm) { +- pr_err("%s is not a valid md device name\n", +- container_name); +- return 1; ++ if (devnm) ++ return mdmon(devnm, dofork && do_fork(), takeover); + } +- return mdmon(devnm, dofork && do_fork(), takeover); ++ ++ pr_err("%s is not a valid md device name\n", container_name); ++ return 1; + } + + static int mdmon(char *devnm, int must_fork, int takeover) +-- +2.40.1 + diff --git a/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch b/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch new file mode 100644 index 0000000..8dea720 --- /dev/null +++ b/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch @@ -0,0 +1,138 @@ +From 4c12714d1ca06533fe7a887966df2558fd2f96b2 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 17:04:44 +0100 +Subject: [PATCH 12/41] test: run tests on system level mdadm + +The tests run with MDADM_NO_SYSTEMCTL flag by default, however it has +no effect on udev. In case of external metadata, even if flag is set, +udev will trigger systemd to launch mdmon. + +This commit changes test execution level, so the tests are run on system +level mdadm, meaning local build must be installed prior to running +tests. + +Add warning that the tests are run on system level mdadm and local +build must be installed first. + +Do not call mdadm with "quiet" as it makes it not display critical +messages necessary for debug. + +Remove forcing speed_limit and add restoring system speed_limit_max +after test execution. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + test | 27 ++++++++++++++++++--------- + tests/func.sh | 1 - + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/test b/test +index 49a36c3b..338c2db4 100755 +--- a/test ++++ b/test +@@ -1,11 +1,12 @@ + #!/bin/bash + # + # run test suite for mdadm +-mdadm=$PWD/mdadm ++mdadm=`which mdadm` + targetdir="/var/tmp" + logdir="$targetdir" + config=/tmp/mdadm.conf + testdir=$PWD/tests ++system_speed_limit=`cat /proc/sys/dev/raid/speed_limit_max` + devlist= + + savelogs=0 +@@ -20,9 +21,6 @@ DEVTYPE=loop + INTEGRITY=yes + LVM_VOLGROUP=mdtest + +-# make sure to test local mdmon, not system one +-export MDADM_NO_SYSTEMCTL=1 +- + # assume md0, md1, md2 exist in /dev + md0=/dev/md0 + md1=/dev/md1 +@@ -41,7 +39,10 @@ ctrl_c() { + ctrl_c_error=1 + } + +-# mdadm always adds --quiet, and we want to see any unexpected messages ++restore_system_speed_limit() { ++ echo $system_speed_limit > /proc/sys/dev/raid/speed_limit_max ++} ++ + mdadm() { + rm -f $targetdir/stderr + case $* in +@@ -63,10 +64,10 @@ mdadm() { + $mdadm --zero $args > /dev/null + } + done +- $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes ++ $mdadm 2> $targetdir/stderr "$@" --auto=yes + ;; + * ) +- $mdadm 2> $targetdir/stderr --quiet "$@" ++ $mdadm 2> $targetdir/stderr "$@" + ;; + esac + rv=$? +@@ -99,8 +100,6 @@ do_test() { + fi + + rm -f $targetdir/stderr +- # this might have been reset: restore the default. +- echo 2000 > /proc/sys/dev/raid/speed_limit_max + do_clean + # source script in a subshell, so it has access to our + # namespace, but cannot change it. +@@ -122,6 +121,7 @@ do_test() { + echo " (KNOWN BROKEN TEST: $_broken_msg)" + fi + fi ++ restore_system_speed_limit + [ "$savelogs" == "1" ] && + mv -f $targetdir/log $logdir/$_basename.log + [ "$ctrl_c_error" == "1" ] && exit 1 +@@ -299,7 +299,15 @@ parse_args() { + done + } + ++print_warning() { ++ cat <<-EOF ++ Warning! Tests are performed on system level mdadm! ++ If you want to test local build, you need to install it first! ++ EOF ++} ++ + main() { ++ print_warning + do_setup + + echo "Testing on linux-$(uname -r) kernel" +@@ -329,6 +337,7 @@ main() { + break + fi + done ++ + exit 0 + } + +diff --git a/tests/func.sh b/tests/func.sh +index 1c1a28a2..b474442b 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -213,7 +213,6 @@ do_setup() { + path1=$dev7 + ulimit -c unlimited + [ -f /proc/mdstat ] || modprobe md_mod +- echo 2000 > /proc/sys/dev/raid/speed_limit_max + echo 0 > /sys/module/md_mod/parameters/start_ro + } + +-- +2.40.1 + diff --git a/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch b/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch new file mode 100644 index 0000000..78650d7 --- /dev/null +++ b/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch @@ -0,0 +1,43 @@ +From 3c3ddeeccc1eb4accb62ce9920de430a564be806 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 28 Feb 2024 16:37:20 +0100 +Subject: [PATCH 13/41] Monitor: Allow no PID in check_one_sharer() + +Commit 5fb5479ad100 ("Monitor: open file before check in +check_one_sharer()") introduced a regression that prohibits monitor +from starting if PID file does not exist. + +Add check for no PID file. +Add missing fclose(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Monitor.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Monitor.c b/Monitor.c +index 7cee95d4..9be2b528 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -453,12 +453,17 @@ static int check_one_sharer(int scan) + + fp = fopen(AUTOREBUILD_PID_PATH, "r"); + if (!fp) { ++ /* PID file does not exist */ ++ if (errno == ENOENT) ++ return 0; ++ + pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); + return 2; + } + + if (!is_file(AUTOREBUILD_PID_PATH)) { + pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); ++ fclose(fp); + return 2; + } + +-- +2.40.1 + diff --git a/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch b/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch new file mode 100644 index 0000000..5047232 --- /dev/null +++ b/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch @@ -0,0 +1,47 @@ +From d1cd231ae41d98b2555dbff08d0c79876b5059fe Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Feb 2024 07:36:39 +0100 +Subject: [PATCH 14/41] super-intel: respect IMSM_DEVNAME_AS_SERIAL flag + +IMSM_DEVNAME_AS_SERIAL flag was respected only when searching +serial using nvme or scsi device wasn't successful. This +flag shall be applied first, to have user settings with +the highest priority. + +Signed-off-by: Kinga Tanska +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index e61f3f6f..4babec9f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4174,17 +4174,17 @@ static int imsm_read_serial(int fd, char *devname, + + memset(buf, 0, sizeof(buf)); + ++ if (check_env("IMSM_DEVNAME_AS_SERIAL")) { ++ memset(serial, 0, serial_buf_len); ++ fd2devname(fd, (char *) serial); ++ return 0; ++ } ++ + rv = nvme_get_serial(fd, buf, sizeof(buf)); + + if (rv) + rv = scsi_get_serial(fd, buf, sizeof(buf)); + +- if (rv && check_env("IMSM_DEVNAME_AS_SERIAL")) { +- memset(serial, 0, MAX_RAID_SERIAL_LEN); +- fd2devname(fd, (char *) serial); +- return 0; +- } +- + if (rv != 0) { + if (devname) + pr_err("Failed to retrieve serial for %s\n", +-- +2.40.1 + diff --git a/SOURCES/0015-mdadm-remove-TODO.patch b/SOURCES/0015-mdadm-remove-TODO.patch new file mode 100644 index 0000000..7c3e1c8 --- /dev/null +++ b/SOURCES/0015-mdadm-remove-TODO.patch @@ -0,0 +1,236 @@ +From a944da4e1a56cd926e6b21f5aaebc13198265419 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:42 +0100 +Subject: [PATCH 15/41] mdadm: remove TODO + +This file is not updated in 16 years. +No reasons to keep it. Remove it. + +Signed-off-by: Mariusz Tkaczyk +--- + TODO | 213 ----------------------------------------------------------- + 1 file changed, 213 deletions(-) + delete mode 100644 TODO + +diff --git a/TODO b/TODO +deleted file mode 100644 +index 279d20db..00000000 +--- a/TODO ++++ /dev/null +@@ -1,213 +0,0 @@ +- - add 'name' field to metadata type and use it. +- - use validate_geometry more +- - metadata should be able to check/reject bitmap stuff. +- +-DDF: +- Three new metadata types: +- ddf - used only to create a container. +- ddf-bvd - used to create an array in a container +- ddf-svd - used to create a secondary array from bvds. +- +- Usage: +- mdadm -C /dev/ddf1 /dev/sd[abcdef] +- mdadm -C /dev/md1 -e ddf /dev/sd[a-f] +- mdadm -C /dev/md1 -l container /dev/sd[a-f] +- +- Each of these create a new ddf container using all those +- devices. The name 'ddf*' signals that ddf metadata should be used. +- '-e ddf' only supports one level - 'container'. 'container' is only +- supported by ddf. +- +- mdadm -C /dev/md1 -l0 -n4 /dev/ddf1 # or maybe not ??? +- mdadm -C /dev/md1 -l1 -n2 /dev/sda /dev/sdb +- If exactly one device is given, and it is a container, we select +- devices from that container. +- If devices are given that are already in use, they must be in use by +- a container, and the array is created in the container. +- If devices given are bvds, we slip under the hood to make +- the svd arrays. +- +- mdadm -A /dev/ddf ...... +- base drives make a container. Anything in that container is started +- auto-read-only. +- if /dev/ddf is already assembled, we assemble bvds and svds inside it. +- +- +-2005-dec-20 +- Want an incremental assembly mode to work nicely with udev. +- Core usage would be something like +- mdadm --incr-assemble /dev/newdevice +- This would +- - examine the device to determine uuid etc. +- - look for a match in /etc/mdadm.conf, abort if not found +- - find that device and collect current contents +- - perform an 'assemble' analysis to make sure we have the best set of devices. +- - remove or add devices as appropriate +- - possibly start the array if it was complete +- +- Other usages could involve +- - specify which array to auto-add to. +- This requires an existing array for uuid matching... is there any point? +- +- - +- +- +-2004-june-02 +- * Don't print 'errors' flag, it is meaningless. DONE +- * Handle new superblock format +- * create device file on demand, particularly partitionable devices. DONE +- BUT figure a way to create the partition devices. +- auto=partN +- * Use Event: interface to listen for events. DONE, untested +- * Make sure mdadm -As can assemble multi-level RAIDs ok. +- * --build to build raid1 or multipath arrays +- clean or not ??? +- +----------------------------------------------------------------------------- +-* mdadm --monitor to monitor failed multipath paths and re-instate them. +- +-* Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE +- +- +-* maybe "missing" instead of missing in doco DONE +-* possibly wait for resync to start, or even finish while assembling.- NO +- +-* -Db should have a devices= entry if possible. - DONE +-* when assembling multipath arrays, ignore any error indicators. - DONE +-* rationalise --monitor usage: +- mdadm --monitor +- doesn't do as expected. DONE +- +-* --assemble could have a --update option. - DONE +- following word can be: +- sparc2.2 +- super-minor +- +-* mdadm /dev/md11, where md11 is raid0 can segfault, particularly when looking in the +- [UU_UUU] string ... which doesn't exist ! +-It should be more sensible. DONE +- +-Example: +- +-from Raimund Sacherer +- +-mke2fs -m0 -q /dev/ram1 300 +-mount -n -t ext2 /dev/ram1 /tmp +-echo DEVICE /dev/[sh]* >> /tmp/mdadm.conf +-mdadm -Esb /dev/[sh]* 2>/dev/null >> /tmp/mdadm.conf +-mdadm -ARsc /tmp/mdadm.conf +-umount /tmp +- +- +-?? Allow -S /dev/md? - current complains subsequent not a/d/r - DONE +- +-* new "Query" mode to subsume --detail and --examine. +- --query or -Q, takes a device and tells if it is an MD device, +- and also tells in a raid superblock is found. +- DONE +- +-* write mdstat.c to parse /proc/mdstat file +- Build list of arrays: name, rebuild-percent +- DONE +- +-* parse /proc/partitions and map major/minor into /dev/* names, +- and use that for default DEVICE list ???? +- +-* --detail --scan to read /proc/mdstat, and then iterate over these, +- but assume --brief. --verbose can override +- check each subdevice to see if it is in conf_get_devs. +- Warn if not. +- DONE, but don't warn yet... +- +-* Support multipath ... maybe... +- maybe DONE +- +-* --follow to syslog +- +-* --follow to move spares around DONE +- +-* --follow to notice other events: DONE +- rebuild started +- spare activated +- spare removed +- spare added +- +------------------------------------- +-- --examine --scan scans all drives and build an mdadm.conf file DONE +- +-- check superblock checksum in examine DONE +-- report "chunk" or "rounding" depending on raid level DONE +-- report "linear" instead of "-1" for raid level DONE +-- decode ayout depending on raid level DONE +-- --verbose and --force flags. DONE +- +-- set md_minor, *_disks for Create - DONE +-- for create raid5, how to choose between +- all working, but not insync +- one missing, one spare, insync DONE (--force) +-- and for raid1 - some failed drives... (missing) +- +-- when RUN_ARRAY, make sure *_disks counts are right +- +-- get --detail to extract extra stuff from superblock, +- like uuid DONE +-- --detail --brief to give a config file line DONE +-- parse config file. DONE +-- test... +- +-- when --assemble --scan, if an underlying device is an md device, +- then try to assemble that device first. +- +- +-- mdadm -S /dev/md0 /dev/md1 gives internal error FIXED +- +-- mdadm --detail --scan print summary of what it can find? DONE +- +- +---------- +-Assemble doesn't add spares. - DONE +-Create to allow "missing" name for devices. +-Create to accept "--force" for do exactly what is requested +-- get Assemble to upgrade devices if force flag. +-ARRAY lines in config file to have super_minor=n +-ARRAY lines in config file to have device=pattern, and only accept +- those devices +- If UUID given, insist on that +- If not, but super_minor given, require all found with that minor +- to have same uuid +- If only device given, all valid supers on those devices must have +- same uuid +-allow /dev/mdX as first argument before any options +-Possible --dry-run option for create and assemble--force +- +-Assemble to check that all devices mentioned in superblock +- are present. +- +-New mode: --Monitor (or --Follow) +- Periodically check status of all arrays (listed in config file). +- Log every event and apparent cause - or differences +- Email and alert - or run a program - for important events +- Move spares around if necessary. +- +- An Array line can have a spare-group= field that indicates that +- the array shares spares with other arrays with the same +- spare-group name. +- If an array has a failed and no spares, then check all other +- arrays in the spare group. If one has no failures and a spare, +- then consider that spare. +- Choose the smallest considered spare that is large enough. +- If there is one, then hot-remove it from it's home, and +- hot-add it to the array in question. +- +- --mail-to address +- --alert-handler program +- +- Will also extract information from /proc/mdstat if present, +- and consider 20% marks in rebuild as events. +- +- Events are: +- drive fails - causes mail to be sent +- rebuild started +- spare activated +- spare removed +- spare added +-- +2.40.1 + diff --git a/SOURCES/0016-mdadm-remove-makedist.patch b/SOURCES/0016-mdadm-remove-makedist.patch new file mode 100644 index 0000000..5905472 --- /dev/null +++ b/SOURCES/0016-mdadm-remove-makedist.patch @@ -0,0 +1,119 @@ +From 84d5e05d6fa6bbe6f4a3bdbdb1165dcc463b5207 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:43 +0100 +Subject: [PATCH 16/41] mdadm: remove makedist + +Archives are generated kernel.org automation, no need to submit +them manually, so remove legacy solution. + +Signed-off-by: Mariusz Tkaczyk +--- + makedist | 96 -------------------------------------------------------- + 1 file changed, 96 deletions(-) + delete mode 100755 makedist + +diff --git a/makedist b/makedist +deleted file mode 100755 +index 0c4b39eb..00000000 +--- a/makedist ++++ /dev/null +@@ -1,96 +0,0 @@ +-#!/bin/sh +-# avoid silly sorting +-export LANG=C +-arg=$1 +-target=~/public_html/source/mdadm +-if [ " $arg" = " test" ] +-then +- target=/tmp/mdadm-test +- rm -rf $target +- mkdir -p $target +-fi +-if [ -d $target ] +-then : +-else echo $target is not a directory +- exit 2 +-fi +-set `grep '^#define VERSION' ReadMe.c ` +-version=`echo $3 | sed -e 's/"//g'` +-grep "^.TH MDADM 8 .. v$version" mdadm.8.in > /dev/null 2>&1 || +- { +- echo mdadm.8.in does not mention version $version. +- exit 1 +- } +-grep "^.TH MDMON 8 .. v$version" mdmon.8 > /dev/null 2>&1 || +- { +- echo mdmon.8 does not mention version $version. +- exit 1 +- } +-rpmv=`echo $version | tr - _` +-grep "^Version: *$rpmv$" mdadm.spec > /dev/null 2>&1 || +- { +- echo mdadm.spec does not mention version $version. +- exit 1 +- } +-if [ -f ANNOUNCE-$version ] +-then : +-else +- echo ANNOUNCE-$version does not exist +- exit 1 +-fi +-if grep "^ANNOUNCE-$version\$" inventory +-then : +-else { cat inventory ; echo ANNOUNCE-$version ; } | sort -o inventory +-fi +- +-echo version = $version +-base=mdadm-$rpmv.tar.gz +-if [ " $arg" != " diff" ] +-then +- if [ -f $target/$base ] +- then +- echo $target/$base exists. +- exit 1 +- fi +- trap "rm $target/$base; exit" 1 2 3 +- git archive --prefix=mdadm-$rpmv/ HEAD | gzip --best > $target/$base +- chmod a+r $target/$base +- ls -l $target/$base +- if tar tzf $target/$base | sed 's,[^/]*/,,' | sort | diff -u inventory - +- then : correct files found +- else echo "Extra files, or inventory is out-of-date" +- rm $target/$base +- exit 1 +- fi +- rpmbuild -ta $target/$base || exit 1 +- find ~/rpmbuild/RPMS -name "*mdadm-$version-*" \ +- -exec cp {} $target/RPM \; +- cp ANNOUNCE-$version $target/ANNOUNCE +- cp ChangeLog $target/ChangeLog +- if [ " $arg" != " test" ] +- then +- echo -n "Confirm signing this release? " +- read a +- if [ " $a" != " y" ]; then echo OK - bye. ; exit 1; fi +- if zcat $target/$base | gpg -ba > $target/$base.sign && gpg -ba $target/ANNOUNCE +- then +- kup put $target/$base $target/$base.sign \ +- /pub/linux/utils/raid/mdadm/mdadm-$version.tar.gz +- kup put $target/ANNOUNCE $target/ANNOUNCE.asc /pub/linux/utils/raid/mdadm/ANNOUNCE +- else +- echo signing failed +- exit 1 +- fi +- fi +-else +- if [ ! -f $target/$base ] +- then +- echo $target/$base does not exist. +- exit 1 +- fi +- ( cd .. ; ln -s mdadm.v2 mdadm-$version ; tar chf - --exclude=.git --exclude="TAGS" --exclude='*,v' --exclude='*~' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz +- mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - ) +- mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - ) +- diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new +- rm -rf /var/tmp/mdadm-old /var/tmp/mdadm-new /var/tmp/mdadm-new.tgz +-fi +-- +2.40.1 + diff --git a/SOURCES/0017-mdadm-remove-mdadm.spec.patch b/SOURCES/0017-mdadm-remove-mdadm.spec.patch new file mode 100644 index 0000000..7e1de14 --- /dev/null +++ b/SOURCES/0017-mdadm-remove-mdadm.spec.patch @@ -0,0 +1,69 @@ +From 9cdcc193cec92c624841d5b70f1b96daafdc4314 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:44 +0100 +Subject: [PATCH 17/41] mdadm: remove mdadm.spec + +This file is outdated, distributions have their own specs. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.spec | 47 ----------------------------------------------- + 1 file changed, 47 deletions(-) + delete mode 100644 mdadm.spec + +diff --git a/mdadm.spec b/mdadm.spec +deleted file mode 100644 +index 12e7859a..00000000 +--- a/mdadm.spec ++++ /dev/null +@@ -1,47 +0,0 @@ +-Summary: mdadm is used for controlling Linux md devices (aka RAID arrays) +-Name: mdadm +-Version: 4.3 +-Release: 1 +-Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz +-URL: https://neil.brown.name/blog/mdadm +-License: GPL +-Group: Utilities/System +-BuildRoot: %{_tmppath}/%{name}-root +-Obsoletes: mdctl +- +-%description +-mdadm is a program that can be used to create, manage, and monitor +-Linux MD (Software RAID) devices. +- +-%prep +-%setup -q +-# we want to install in /sbin, not /usr/sbin... +-%define _exec_prefix %{nil} +- +-%build +-# This is a debatable issue. The author of this RPM spec file feels that +-# people who install RPMs (especially given that the default RPM options +-# will strip the binary) are not going to be running gdb against the +-# program. +-make CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}" +- +-%install +-make DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} BINDIR=%{_sbindir} install +-install -D -m644 mdadm.conf-example $RPM_BUILD_ROOT/%{_sysconfdir}/mdadm.conf +- +-%clean +-rm -rf $RPM_BUILD_ROOT +- +-%files +-%defattr(-,root,root) +-%doc TODO ChangeLog mdadm.conf-example COPYING +-%{_sbindir}/mdadm +-%{_sbindir}/mdmon +-/usr/lib/udev/rules.d/01-md-raid-creating.rules +-/usr/lib/udev/rules.d/63-md-raid-arrays.rules +-/usr/lib/udev/rules.d/64-md-raid-assembly.rules +-/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules +-%config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf +-%{_mandir}/man*/md* +- +-%changelog +-- +2.40.1 + diff --git a/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch b/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch new file mode 100644 index 0000000..4c32496 --- /dev/null +++ b/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch @@ -0,0 +1,209 @@ +From 9282e1169f19676553a82dd49f780285a16e3b9a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:45 +0100 +Subject: [PATCH 18/41] mdadm: remove mkinitramfs stuff + +This script uses mdadm.static which is known to not be abandoned +(probably not working) from years. Mdadm is integrated with dracut +and mkinitramfs these days. + +Signed-off-by: Mariusz Tkaczyk +--- + README.initramfs | 122 ----------------------------------------------- + mkinitramfs | 55 --------------------- + 2 files changed, 177 deletions(-) + delete mode 100644 README.initramfs + delete mode 100644 mkinitramfs + +diff --git a/README.initramfs b/README.initramfs +deleted file mode 100644 +index c5fa6680..00000000 +--- a/README.initramfs ++++ /dev/null +@@ -1,122 +0,0 @@ +-Assembling md arrays at boot time. +---------------------------------- +-December 2005 +- +-These notes apply to 2.6 kernels only and, in some cases, +-to 2.6.15 or later. +- +-Md arrays can be assembled at boot time using the 'autodetect' functionality +-which is triggered by storing components of an array in partitions of type +-'fd' - Linux Raid Autodetect. +-They can also be assembled by specifying the component devices in a +-kernel parameter such as +- md=0,/dev/sda,/dev/sdb +-In this case, /dev/md0 will be assembled (because of the 0) from the listed +-devices. +- +-These mechanisms, while useful, do not provide complete functionality +-and are unlikely to be extended. The preferred way to assemble md +-arrays at boot time is using 'mdadm'. To assemble an array which +-contains the root filesystem, mdadm needs to be run before that +-filesystem is mounted, and so needs to be run from an initial-ram-fs. +-It is how this can work that is the primary focus of this document. +- +-It should be noted up front that only the array containing the root +-filesystem should be assembled from the initramfs. Any other arrays +-should be assembled under the control of files on the main filesystem +-as this enhanced flexibility and maintainability. +- +-A minimal initramfs for assembling md arrays can be created using 3 +-files and one directory. These are: +- +-/bin Directory +-/bin/mdadm statically linked mdadm binary +-/bin/busybox statically linked busybox binary +-/bin/sh hard link to /bin/busybox +-/init a shell script which call mdadm appropriately. +- +-An example init script is: +- +-============================================== +-#!/bin/sh +- +-echo 'Auto-assembling boot md array' +-mkdir /proc +-mount -t proc proc /proc +-if [ -n "$rootuuid" ] +-then arg=--uuid=$rootuuid +-elif [ -n "$mdminor" ] +-then arg=--super-minor=$mdminor +-else arg=--super-minor=0 +-fi +-echo "Using $arg" +-mdadm -Acpartitions $arg --auto=part /dev/mda +-cd / +-mount /dev/mda1 /root || mount /dev/mda /root +-umount /proc +-cd /root +-exec chroot . /sbin/init < /dev/console > /dev/console 2>&1 +-============================================= +- +-This could certainly be extended, or merged into a larger init script. +-Though tested and in production use, it is not presented here as +-"The Right Way" to do it, but as a useful example. +-Some key points are: +- +- /proc needs to be mounted so that /proc/partitions can be accessed +- by mdadm, and so that /proc/filesystems can be accessed by mount. +- +- The uuid of the array can be passed in as a kernel parameter +- (rootuuid). As the kernel doesn't use this value, it is made available +- in the environment for /init +- +- If no uuid is given, we default to md0, (--super-minor=0) which is a +- commonly used to store the root filesystem. This may not work in +- all situations. +- +- We assemble the array as a partitionable array (/dev/mda) even if we +- end up using the whole array. There is no cost in using the partitionable +- interface, and in this context it is simpler. +- +- We try mounting both /dev/mda1 and /dev/mda as they are the most like +- part of the array to contain the root filesystem. +- +- The --auto flag is given to mdadm so that it will create /dev/md* +- files automatically. This is needed as /dev will not contain +- and md files, and udev will not create them (as udev only created device +- files after the device exists, and mdadm need the device file to create +- the device). Note that the created md files may not exist in /dev +- of the mounted root filesystem. This needs to be deal with separately +- from mdadm - possibly using udev. +- +- We do not need to create device files for the components which will +- be assembled into /dev/mda. mdadm finds the major/minor numbers from +- /proc/partitions and creates a temporary /dev file if one doesn't already +- exist. +- +-The script "mkinitramfs" which is included with the mdadm distribution +-can be used to create a minimal initramfs. It creates a file called +-'init.cpio.gz' which can be specified as an 'initrd' to lilo or grub +-(or whatever boot loader is being used). +- +- +- +- +-Resume from an md array +------------------------ +- +-If you want to make use of the suspend-to-disk/resume functionality in Linux, +-and want to have swap on an md array, you will need to assemble the array +-before resume is possible. +-However, because the array is active in the resumed image, you do not want +-anything written to any drives during the resume process, such as superblock +-updates or array resync. +- +-This can be achieved in 2.6.15-rc1 and later kernels using the +-'start_readonly' module parameter. +-Simply include the command +- echo 1 > /sys/module/md_mod/parameters/start_ro +-before assembling the array with 'mdadm'. +-You can then echo +- 9:0 +-or whatever is appropriate to /sys/power/resume to trigger the resume. +diff --git a/mkinitramfs b/mkinitramfs +deleted file mode 100644 +index c6275ddb..00000000 +--- a/mkinitramfs ++++ /dev/null +@@ -1,55 +0,0 @@ +-#!/bin/sh +- +-# make sure we are being run in the right directory... +-if [ -f mkinitramfs ] +-then : +-else +- echo >&2 mkinitramfs must be run from the mdadm source directory. +- exit 1 +-fi +-if [ -f /bin/busybox ] +-then : good, it exists +- case `file /bin/busybox` in +- *statically* ) : good ;; +- * ) echo >&2 mkinitramfs: /bin/busybox is not statically linked: cannot proceed. +- exit 1 +- esac +-else +- echo >&2 "mkinitramfs: /bin/busybox doesn't exist - please install it statically linked." +- exit 1 +-fi +- +-rm -rf initramfs +-mkdir initramfs +-mkdir initramfs/bin +-make mdadm.static +-cp mdadm.static initramfs/bin/mdadm +-cp /bin/busybox initramfs/bin/busybox +-ln initramfs/bin/busybox initramfs/bin/sh +-cat <<- END > initramfs/init +- #!/bin/sh +- +- echo 'Auto-assembling boot md array' +- mkdir /proc +- mount -t proc proc /proc +- if [ -n "$rootuuid" ] +- then arg=--uuid=$rootuuid +- elif [ -n "$mdminor" ] +- then arg=--super-minor=$mdminor +- else arg=--super-minor=0 +- fi +- echo "Using $arg" +- mdadm -Acpartitions $arg --auto=part /dev/mda +- cd / +- mount /dev/mda1 /root || mount /dev/mda /root +- umount /proc +- cd /root +- exec chroot . /sbin/init < /dev/console > /dev/console 2>&1 +-END +-chmod +x initramfs/init +- +-(cd initramfs +- find init bin | cpio -o -H newc | gzip --best +-) > init.cpio.gz +-rm -rf initramfs +-ls -l init.cpio.gz +-- +2.40.1 + diff --git a/SOURCES/0019-mdadm-move-documentation-to-folder.patch b/SOURCES/0019-mdadm-move-documentation-to-folder.patch new file mode 100644 index 0000000..dc9bcc8 --- /dev/null +++ b/SOURCES/0019-mdadm-move-documentation-to-folder.patch @@ -0,0 +1,1044 @@ +From 3aa5bb0af1051432a83b2f7a9fd5c2763444c937 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:46 +0100 +Subject: [PATCH 19/41] mdadm: move documentation to folder + +Move documentation text files to directory. + +Signed-off-by: Mariusz Tkaczyk +--- + documentation/external-reshape-design.txt | 280 ++++++++++++++++++++++ + documentation/mdadm.conf-example | 65 +++++ + documentation/mdmon-design.txt | 146 +++++++++++ + external-reshape-design.txt | 280 ---------------------- + mdadm.conf-example | 65 ----- + mdmon-design.txt | 146 ----------- + 6 files changed, 491 insertions(+), 491 deletions(-) + create mode 100644 documentation/external-reshape-design.txt + create mode 100644 documentation/mdadm.conf-example + create mode 100644 documentation/mdmon-design.txt + delete mode 100644 external-reshape-design.txt + delete mode 100644 mdadm.conf-example + delete mode 100644 mdmon-design.txt + +diff --git a/documentation/external-reshape-design.txt b/documentation/external-reshape-design.txt +new file mode 100644 +index 00000000..e4cf4e16 +--- /dev/null ++++ b/documentation/external-reshape-design.txt +@@ -0,0 +1,280 @@ ++External Reshape ++ ++1 Problem statement ++ ++External (third-party metadata) reshape differs from native-metadata ++reshape in three key ways: ++ ++1.1 Format specific constraints ++ ++In the native case reshape is limited by what is implemented in the ++generic reshape routine (Grow_reshape()) and what is supported by the ++kernel. There are exceptional cases where Grow_reshape() may block ++operations when it knows that the kernel implementation is broken, but ++otherwise the kernel is relied upon to be the final arbiter of what ++reshape operations are supported. ++ ++In the external case the kernel, and the generic checks in ++Grow_reshape(), become the super-set of what reshapes are possible. The ++metadata format may not support, or have yet to implement a given ++reshape type. The implication for Grow_reshape() is that it must query ++the metadata handler and effect changes in the metadata before the new ++geometry is posted to the kernel. The ->reshape_super method allows ++Grow_reshape() to validate the requested operation and post the metadata ++update. ++ ++1.2 Scope of reshape ++ ++Native metadata reshape is always performed at the array scope (no ++metadata relationship with sibling arrays on the same disks). External ++reshape, depending on the format, may not allow the number of member ++disks to be changed in a subarray unless the change is simultaneously ++applied to all subarrays in the container. For example the imsm format ++requires all member disks to be a member of all subarrays, so a 4-disk ++raid5 in a container that also houses a 4-disk raid10 array could not be ++reshaped to 5 disks as the imsm format does not support a 5-disk raid10 ++representation. This requires the ->reshape_super method to check the ++contents of the array and ask the user to run the reshape at container ++scope (if all subarrays are agreeable to the change), or report an ++error in the case where one subarray cannot support the change. ++ ++1.3 Monitoring / checkpointing ++ ++Reshape, unlike rebuild/resync, requires strict checkpointing to survive ++interrupted reshape operations. For example when expanding a raid5 ++array the first few stripes of the array will be overwritten in a ++destructive manner. When restarting the reshape process we need to know ++the exact location of the last successfully written stripe, and we need ++to restore the data in any partially overwritten stripe. Native ++metadata stores this backup data in the unused portion of spares that ++are being promoted to array members, or in an external backup file ++(located on a non-involved block device). ++ ++The kernel is in charge of recording checkpoints of reshape progress, ++but mdadm is delegated the task of managing the backup space which ++involves: ++1/ Identifying what data will be overwritten in the next unit of reshape ++ operation ++2/ Suspending access to that region so that a snapshot of the data can ++ be transferred to the backup space. ++3/ Allowing the kernel to reshape the saved region and setting the ++ boundary for the next backup. ++ ++In the external reshape case we want to preserve this mdadm ++'reshape-manager' arrangement, but have a third actor, mdmon, to ++consider. It is tempting to give the role of managing reshape to mdmon, ++but that is counter to its role as a monitor, and conflicts with the ++existing capabilities and role of mdadm to manage the progress of ++reshape. For clarity the external reshape implementation maintains the ++role of mdmon as a (mostly) passive recorder of raid events, and mdadm ++treats it as it would the kernel in the native reshape case (modulo ++needing to send explicit metadata update messages and checking that ++mdmon took the expected action). ++ ++External reshape can use the generic md backup file as a fallback, but in the ++optimal/firmware-compatible case the reshape-manager will use the metadata ++specific areas for managing reshape. The implementation also needs to spawn a ++reshape-manager per subarray when the reshape is being carried out at the ++container level. For these two reasons the ->manage_reshape() method is ++introduced. This method in addition to base tasks mentioned above: ++1/ Processed each subarray one at a time in series - where appropriate. ++2/ Uses either generic routines in Grow.c for md-style backup file ++ support, or uses the metadata-format specific location for storing ++ recovery data. ++This aims to avoid a "midlayer mistake"[1] and lets the metadata handler ++optionally take advantage of generic infrastructure in Grow.c ++ ++2 Details for specific reshape requests ++ ++There are quite a few moving pieces spread out across md, mdadm, and mdmon for ++the support of external reshape, and there are several different types of ++reshape that need to be comprehended by the implementation. A rundown of ++these details follows. ++ ++2.0 General provisions: ++ ++Obtain an exclusive open on the container to make sure we are not ++running concurrently with a Create() event. ++ ++2.1 Freezing sync_action ++ ++ Before making any attempt at a reshape we 'freeze' every array in ++ the container to ensure no spare assignment or recovery happens. ++ This involves writing 'frozen' to sync_action and changing the '/' ++ after 'external:' in metadata_version to a '-'. mdmon knows that ++ this means not to perform any management. ++ ++ Before doing this we check that all sync_actions are 'idle', which ++ is racy but still useful. ++ Afterwards we check that all member arrays have no spares ++ or partial spares (recovery_start != 'none') which would indicate a ++ race. If they do, we unfreeze again. ++ ++ Once this completes we know all the arrays are stable. They may ++ still have failed devices as devices can fail at any time. However ++ we treat those like failures that happen during the reshape. ++ ++2.2 Reshape size ++ ++ 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally ++ initializes st->update_tail ++ 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the size change ++ is allowed (being performed at subarray scope / enough room) prepares a ++ metadata update ++ 3/ mdadm::Grow_reshape(): flushes the metadata update (via ++ flush_metadata_update(), or ->sync_metadata()) ++ 4/ mdadm::Grow_reshape(): post the new size to the kernel ++ ++ ++2.3 Reshape level (simple-takeover) ++ ++"simple-takeover" implies the level change can be satisfied without touching ++sync_action ++ ++ 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally ++ initializes st->update_tail ++ 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the level change ++ is allowed (being performed at subarray scope) prepares a ++ metadata update ++ 2a/ raid10 --> raid0: degrade all mirror legs prior to calling ++ ->reshape_super ++ 3/ mdadm::Grow_reshape(): flushes the metadata update (via ++ flush_metadata_update(), or ->sync_metadata()) ++ 4/ mdadm::Grow_reshape(): post the new level to the kernel ++ ++2.4 Reshape chunk, layout ++ ++2.5 Reshape raid disks (grow) ++ ++ 1/ mdadm::Grow_reshape(): unconditionally initializes st->update_tail ++ because only redundant raid levels can modify the number of raid disks ++ 2/ mdadm::Grow_reshape(): calls ->reshape_super() to check that the level ++ change is allowed (being performed at proper scope / permissible ++ geometry / proper spares available in the container), chooses ++ the spares to use, and prepares a metadata update. ++ 3/ mdadm::Grow_reshape(): Converts each subarray in the container to the ++ raid level that can perform the reshape and starts mdmon. ++ 4/ mdadm::Grow_reshape(): Pushes the update to mdmon. ++ 5/ mdadm::Grow_reshape(): uses container_content to find details of ++ the spares and passes them to the kernel. ++ 6/ mdadm::Grow_reshape(): gives raid_disks update to the kernel, ++ sets sync_max, sync_min, suspend_lo, suspend_hi all to zero, ++ and starts the reshape by writing 'reshape' to sync_action. ++ 7/ mdmon::monitor notices the sync_action change and tells ++ managemon to check for new devices. managemon notices the new ++ devices, opens relevant sysfs file, and passes them all to ++ monitor. ++ 8/ mdadm::Grow_reshape() calls ->manage_reshape to oversee the ++ rest of the reshape. ++ ++ 9/ mdadm::->manage_reshape(): saves data that will be overwritten by ++ the kernel to either the backup file or the metadata specific location, ++ advances sync_max, waits for reshape, ping mdmon, repeat. ++ Meanwhile mdmon::read_and_act(): records checkpoints. ++ Specifically. ++ ++ 9a/ if the 'next' stripe to be reshaped will over-write ++ itself during reshape then: ++ 9a.1/ increase suspend_hi to cover a suitable number of ++ stripes. ++ 9a.2/ backup those stripes safely. ++ 9a.3/ advance sync_max to allow those stripes to be backed up ++ 9a.4/ when sync_completed indicates that those stripes have ++ been reshaped, manage_reshape must ping_manager ++ 9a.5/ when mdmon notices that sync_completed has been updated, ++ it records the new checkpoint in the metadata ++ 9a.6/ after the ping_manager, manage_reshape will increase ++ suspend_lo to allow access to those stripes again ++ ++ 9b/ if the 'next' stripe to be reshaped will over-write unused ++ space during reshape then we apply same process as above, ++ except that there is no need to back anything up. ++ Note that we *do* need to keep suspend_hi progressing as ++ it is not safe to write to the area-under-reshape. For ++ kernel-managed-metadata this protection is provided by ++ ->reshape_safe, but that does not protect us in the case ++ of user-space-managed-metadata. ++ ++ 10/ mdadm::->manage_reshape(): Once reshape completes changes the raid ++ level back to the nominal raid level (if necessary) ++ ++ FIXME: native metadata does not have the capability to record the original ++ raid level in reshape-restart case because the kernel always records current ++ raid level to the metadata, whereas external metadata can masquerade at an ++ alternate level based on the reshape state. ++ ++2.6 Reshape raid disks (shrink) ++ ++3 Interaction with metadata handle. ++ ++ The following calls are made into the metadata handler to assist ++ with initiating and monitoring a 'reshape'. ++ ++ 1/ ->reshape_super is called quite early (after only minimial ++ checks) to make sure that the metadata can record the new shape ++ and any necessary transitions. It may be passed a 'container' ++ or an individual array within a container, and it should notice ++ the difference and act accordingly. ++ When a reshape is requested against a container it is expected ++ that it should be applied to every array in the container, ++ however it is up to the metadata handler to determine final ++ policy. ++ ++ If the reshape is supportable, the internal copy of the metadata ++ should be updated, and a metadata update suitable for sending ++ to mdmon should be queued. ++ ++ If the reshape will involve converting spares into array members, ++ this must be recorded in the metadata too. ++ ++ 2/ ->container_content will be called to find out the new state ++ of all the array, or all arrays in the container. Any newly ++ added devices (with state==0 and raid_disk >= 0) will be added ++ to the array as spares with the relevant slot number. ++ ++ It is likely that the info returned by ->container_content will ++ have ->reshape_active set, ->reshape_progress set to e.g. 0, and ++ new_* set appropriately. mdadm will use this information to ++ cause the correct reshape to start at an appropriate time. ++ ++ 3/ ->set_array_state will be called by mdmon when reshape has ++ started and again periodically as it progresses. This should ++ record the ->last_checkpoint as the point where reshape has ++ progressed to. When the reshape finished this will be called ++ again and it should notice that ->curr_action is no longer ++ 'reshape' and so should record that the reshape has finished ++ providing 'last_checkpoint' has progressed suitably. ++ ++ 4/ ->manage_reshape will be called once the reshape has been set ++ up in the kernel but before sync_max has been moved from 0, so ++ no actual reshape will have happened. ++ ++ ->manage_reshape should call progress_reshape() to allow the ++ reshape to progress, and should back-up any data as indicated ++ by the return value. See the documentation of that function ++ for more details. ++ ->manage_reshape will be called multiple times when a ++ container is being reshaped, once for each member array in ++ the container. ++ ++ ++ The progress of the metadata is as follows: ++ 1/ mdadm sends a metadata update to mdmon which marks the array ++ as undergoing a reshape. This is set up by ++ ->reshape_super and applied by ->process_update ++ For container-wide reshape, this happens once for the whole ++ container. ++ 2/ mdmon notices progress via the sysfs files and calls ++ ->set_array_state to update the state periodically ++ For container-wide reshape, this happens repeatedly for ++ one array, then repeatedly for the next, etc. ++ 3/ mdmon notices when reshape has finished and call ++ ->set_array_state to record the the reshape is complete. ++ For container-wide reshape, this happens once for each ++ member array. ++ ++ ++ ++... ++ ++[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/ +diff --git a/documentation/mdadm.conf-example b/documentation/mdadm.conf-example +new file mode 100644 +index 00000000..35a75d12 +--- /dev/null ++++ b/documentation/mdadm.conf-example +@@ -0,0 +1,65 @@ ++# mdadm configuration file ++# ++# mdadm will function properly without the use of a configuration file, ++# but this file is useful for keeping track of arrays and member disks. ++# In general, a mdadm.conf file is created, and updated, after arrays ++# are created. This is the opposite behavior of /etc/raidtab which is ++# created prior to array construction. ++# ++# ++# the config file takes two types of lines: ++# ++# DEVICE lines specify a list of devices of where to look for ++# potential member disks ++# ++# ARRAY lines specify information about how to identify arrays so ++# so that they can be activated ++# ++# You can have more than one device line and use wild cards. The first ++# example includes SCSI the first partition of SCSI disks /dev/sdb, ++# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second ++# line looks for array slices on IDE disks. ++# ++#DEVICE /dev/sd[bcdjkl]1 ++#DEVICE /dev/hda1 /dev/hdb1 ++# ++# If you mount devfs on /dev, then a suitable way to list all devices is: ++#DEVICE /dev/discs/*/* ++# ++# ++# The AUTO line can control which arrays get assembled by auto-assembly, ++# meaing either "mdadm -As" when there are no 'ARRAY' lines in this file, ++# or "mdadm --incremental" when the array found is not listed in this file. ++# By default, all arrays that are found are assembled. ++# If you want to ignore all DDF arrays (maybe they are managed by dmraid), ++# and only assemble 1.x arrays if which are marked for 'this' homehost, ++# but assemble all others, then use ++#AUTO -ddf homehost -1.x +all ++# ++# ARRAY lines specify an array to assemble and a method of identification. ++# Arrays can currently be identified by using a UUID, superblock minor number, ++# or a listing of devices. ++# ++# super-minor is usually the minor number of the metadevice ++# UUID is the Universally Unique Identifier for the array ++# Each can be obtained using ++# ++# mdadm -D ++# ++#ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 ++#ARRAY /dev/md1 super-minor=1 ++#ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 ++# ++# ARRAY lines can also specify a "spare-group" for each array. mdadm --monitor ++# will then move a spare between arrays in a spare-group if one array has a failed ++# drive but no spare ++#ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df spare-group=group1 ++#ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 spare-group=group1 ++# ++# When used in --follow (aka --monitor) mode, mdadm needs a ++# mail address and/or a program. This can be given with "mailaddr" ++# and "program" lines to that monitoring can be started using ++# mdadm --follow --scan & echo $! > /run/mdadm/mon.pid ++# If the lines are not found, mdadm will exit quietly ++#MAILADDR root@mydomain.tld ++#PROGRAM /usr/sbin/handle-mdadm-events +diff --git a/documentation/mdmon-design.txt b/documentation/mdmon-design.txt +new file mode 100644 +index 00000000..f09184a9 +--- /dev/null ++++ b/documentation/mdmon-design.txt +@@ -0,0 +1,146 @@ ++ ++When managing a RAID1 array which uses metadata other than the ++"native" metadata understood by the kernel, mdadm makes use of a ++partner program named 'mdmon' to manage some aspects of updating ++that metadata and synchronising the metadata with the array state. ++ ++This document provides some details on how mdmon works. ++ ++Containers ++---------- ++ ++As background: mdadm makes a distinction between an 'array' and a ++'container'. Other sources sometimes use the term 'volume' or ++'device' for an 'array', and may use the term 'array' for a ++'container'. ++ ++For our purposes: ++ - a 'container' is a collection of devices which are described by a ++ single set of metadata. The metadata may be stored equally ++ on all devices, or different devices may have quite different ++ subsets of the total metadata. But there is conceptually one set ++ of metadata that unifies the devices. ++ ++ - an 'array' is a set of datablock from various devices which ++ together are used to present the abstraction of a single linear ++ sequence of block, which may provide data redundancy or enhanced ++ performance. ++ ++So a container has some metadata and provides a number of arrays which ++are described by that metadata. ++ ++Sometimes this model doesn't work perfectly. For example, global ++spares may have their own metadata which is quite different from the ++metadata from any device that participates in one or more arrays. ++Such a global spare might still need to belong to some container so ++that it is available to be used should a failure arise. In that case ++we consider the 'metadata' to be the union of the metadata on the ++active devices which describes the arrays, and the metadata on the ++global spares which only describes the spares. In this case different ++devices in the one container will have quite different metadata. ++ ++ ++Purpose ++------- ++ ++The main purpose of mdmon is to update the metadata in response to ++changes to the array which need to be reflected in the metadata before ++futures writes to the array can safely be performed. ++These include: ++ - transitions from 'clean' to 'dirty'. ++ - recording the devices have failed. ++ - recording the progress of a 'reshape' ++ ++This requires mdmon to be running at any time that the array is ++writable (a read-only array does not require mdmon to be running). ++ ++Because mdmon must be able to process these metadata updates at any ++time, it must (when running) have exclusive write access to the ++metadata. Any other changes (e.g. reconfiguration of the array) must ++go through mdmon. ++ ++A secondary role for mdmon is to activate spares when a device fails. ++This role is much less time-critical than the other metadata updates, ++so it could be performed by a separate process, possibly ++"mdadm --monitor" which has a related role of moving devices between ++arrays. A main reason for including this functionality in mdmon is ++that in the native-metadata case this function is handled in the ++kernel, and mdmon's reason for existence to provide functionality ++which is otherwise handled by the kernel. ++ ++ ++Design overview ++--------------- ++ ++mdmon is structured as two threads with a common address space and ++common data structures. These threads are know as the 'monitor' and ++the 'manager'. ++ ++The 'monitor' has the primary role of monitoring the array for ++important state changes and updating the metadata accordingly. As ++writes to the array can be blocked until 'monitor' completes and ++acknowledges the update, it much be very careful not to block itself. ++In particular it must not block waiting for any write to complete else ++it could deadlock. This means that it must not allocate memory as ++doing this can require dirty memory to be written out and if the ++system choose to write to the array that mdmon is monitoring, the ++memory allocation could deadlock. ++ ++So 'monitor' must never allocate memory and must limit the number of ++other system call it performs. It may: ++ - use select (or poll) to wait for activity on a file descriptor ++ - read from a sysfs file descriptor ++ - write to a sysfs file descriptor ++ - write the metadata out to the block devices using O_DIRECT ++ - send a signal (kill) to the manager thread ++ ++It must not e.g. open files or do anything similar that might allocate ++resources. ++ ++The 'manager' thread does everything else that is needed. If any ++files are to be opened (e.g. because a device has been added to the ++array), the manager does that. If any memory needs to be allocated ++(e.g. to hold data about a new array as can happen when one set of ++metadata describes several arrays), the manager performs that ++allocation. ++ ++The 'manager' is also responsible for communicating with mdadm and ++assigning spares to replace failed devices. ++ ++ ++Handling metadata updates ++------------------------- ++ ++There are a number of cases in which mdadm needs to update the ++metdata which mdmon is managing. These include: ++ - creating a new array in an active container ++ - adding a device to a container ++ - reconfiguring an array ++etc. ++ ++To complete these updates, mdadm must send a message to mdmon which ++will merge the update into the metadata as it is at that moment. ++ ++To achieve this, mdmon creates a Unix Domain Socket which the manager ++thread listens on. mdadm sends a message over this socket. The ++manager thread examines the message to see if it will require ++allocating any memory and allocates it. This is done in the ++'prepare_update' metadata method. ++ ++The update message is then queued for handling by the monitor thread ++which it will do when convenient. The monitor thread calls ++->process_update which should atomically make the required changes to ++the metadata, making use of the pre-allocate memory as required. Any ++memory the is no-longer needed can be placed back in the request and ++the manager thread will free it. ++ ++The exact format of a metadata update is up to the implementer of the ++metadata handlers. It will simply describe a change that needs to be ++made. It will sometimes contain fragments of the metadata to be ++copied in to place. However the ->process_update routine must make ++sure not to over-write any field that the monitor thread might have ++updated, such as a 'device failed' or 'array is dirty' state. ++ ++When the monitor thread has completed the update and written it to the ++devices, an acknowledgement message is sent back over the socket so ++that mdadm knows it is complete. +diff --git a/external-reshape-design.txt b/external-reshape-design.txt +deleted file mode 100644 +index e4cf4e16..00000000 +--- a/external-reshape-design.txt ++++ /dev/null +@@ -1,280 +0,0 @@ +-External Reshape +- +-1 Problem statement +- +-External (third-party metadata) reshape differs from native-metadata +-reshape in three key ways: +- +-1.1 Format specific constraints +- +-In the native case reshape is limited by what is implemented in the +-generic reshape routine (Grow_reshape()) and what is supported by the +-kernel. There are exceptional cases where Grow_reshape() may block +-operations when it knows that the kernel implementation is broken, but +-otherwise the kernel is relied upon to be the final arbiter of what +-reshape operations are supported. +- +-In the external case the kernel, and the generic checks in +-Grow_reshape(), become the super-set of what reshapes are possible. The +-metadata format may not support, or have yet to implement a given +-reshape type. The implication for Grow_reshape() is that it must query +-the metadata handler and effect changes in the metadata before the new +-geometry is posted to the kernel. The ->reshape_super method allows +-Grow_reshape() to validate the requested operation and post the metadata +-update. +- +-1.2 Scope of reshape +- +-Native metadata reshape is always performed at the array scope (no +-metadata relationship with sibling arrays on the same disks). External +-reshape, depending on the format, may not allow the number of member +-disks to be changed in a subarray unless the change is simultaneously +-applied to all subarrays in the container. For example the imsm format +-requires all member disks to be a member of all subarrays, so a 4-disk +-raid5 in a container that also houses a 4-disk raid10 array could not be +-reshaped to 5 disks as the imsm format does not support a 5-disk raid10 +-representation. This requires the ->reshape_super method to check the +-contents of the array and ask the user to run the reshape at container +-scope (if all subarrays are agreeable to the change), or report an +-error in the case where one subarray cannot support the change. +- +-1.3 Monitoring / checkpointing +- +-Reshape, unlike rebuild/resync, requires strict checkpointing to survive +-interrupted reshape operations. For example when expanding a raid5 +-array the first few stripes of the array will be overwritten in a +-destructive manner. When restarting the reshape process we need to know +-the exact location of the last successfully written stripe, and we need +-to restore the data in any partially overwritten stripe. Native +-metadata stores this backup data in the unused portion of spares that +-are being promoted to array members, or in an external backup file +-(located on a non-involved block device). +- +-The kernel is in charge of recording checkpoints of reshape progress, +-but mdadm is delegated the task of managing the backup space which +-involves: +-1/ Identifying what data will be overwritten in the next unit of reshape +- operation +-2/ Suspending access to that region so that a snapshot of the data can +- be transferred to the backup space. +-3/ Allowing the kernel to reshape the saved region and setting the +- boundary for the next backup. +- +-In the external reshape case we want to preserve this mdadm +-'reshape-manager' arrangement, but have a third actor, mdmon, to +-consider. It is tempting to give the role of managing reshape to mdmon, +-but that is counter to its role as a monitor, and conflicts with the +-existing capabilities and role of mdadm to manage the progress of +-reshape. For clarity the external reshape implementation maintains the +-role of mdmon as a (mostly) passive recorder of raid events, and mdadm +-treats it as it would the kernel in the native reshape case (modulo +-needing to send explicit metadata update messages and checking that +-mdmon took the expected action). +- +-External reshape can use the generic md backup file as a fallback, but in the +-optimal/firmware-compatible case the reshape-manager will use the metadata +-specific areas for managing reshape. The implementation also needs to spawn a +-reshape-manager per subarray when the reshape is being carried out at the +-container level. For these two reasons the ->manage_reshape() method is +-introduced. This method in addition to base tasks mentioned above: +-1/ Processed each subarray one at a time in series - where appropriate. +-2/ Uses either generic routines in Grow.c for md-style backup file +- support, or uses the metadata-format specific location for storing +- recovery data. +-This aims to avoid a "midlayer mistake"[1] and lets the metadata handler +-optionally take advantage of generic infrastructure in Grow.c +- +-2 Details for specific reshape requests +- +-There are quite a few moving pieces spread out across md, mdadm, and mdmon for +-the support of external reshape, and there are several different types of +-reshape that need to be comprehended by the implementation. A rundown of +-these details follows. +- +-2.0 General provisions: +- +-Obtain an exclusive open on the container to make sure we are not +-running concurrently with a Create() event. +- +-2.1 Freezing sync_action +- +- Before making any attempt at a reshape we 'freeze' every array in +- the container to ensure no spare assignment or recovery happens. +- This involves writing 'frozen' to sync_action and changing the '/' +- after 'external:' in metadata_version to a '-'. mdmon knows that +- this means not to perform any management. +- +- Before doing this we check that all sync_actions are 'idle', which +- is racy but still useful. +- Afterwards we check that all member arrays have no spares +- or partial spares (recovery_start != 'none') which would indicate a +- race. If they do, we unfreeze again. +- +- Once this completes we know all the arrays are stable. They may +- still have failed devices as devices can fail at any time. However +- we treat those like failures that happen during the reshape. +- +-2.2 Reshape size +- +- 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally +- initializes st->update_tail +- 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the size change +- is allowed (being performed at subarray scope / enough room) prepares a +- metadata update +- 3/ mdadm::Grow_reshape(): flushes the metadata update (via +- flush_metadata_update(), or ->sync_metadata()) +- 4/ mdadm::Grow_reshape(): post the new size to the kernel +- +- +-2.3 Reshape level (simple-takeover) +- +-"simple-takeover" implies the level change can be satisfied without touching +-sync_action +- +- 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally +- initializes st->update_tail +- 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the level change +- is allowed (being performed at subarray scope) prepares a +- metadata update +- 2a/ raid10 --> raid0: degrade all mirror legs prior to calling +- ->reshape_super +- 3/ mdadm::Grow_reshape(): flushes the metadata update (via +- flush_metadata_update(), or ->sync_metadata()) +- 4/ mdadm::Grow_reshape(): post the new level to the kernel +- +-2.4 Reshape chunk, layout +- +-2.5 Reshape raid disks (grow) +- +- 1/ mdadm::Grow_reshape(): unconditionally initializes st->update_tail +- because only redundant raid levels can modify the number of raid disks +- 2/ mdadm::Grow_reshape(): calls ->reshape_super() to check that the level +- change is allowed (being performed at proper scope / permissible +- geometry / proper spares available in the container), chooses +- the spares to use, and prepares a metadata update. +- 3/ mdadm::Grow_reshape(): Converts each subarray in the container to the +- raid level that can perform the reshape and starts mdmon. +- 4/ mdadm::Grow_reshape(): Pushes the update to mdmon. +- 5/ mdadm::Grow_reshape(): uses container_content to find details of +- the spares and passes them to the kernel. +- 6/ mdadm::Grow_reshape(): gives raid_disks update to the kernel, +- sets sync_max, sync_min, suspend_lo, suspend_hi all to zero, +- and starts the reshape by writing 'reshape' to sync_action. +- 7/ mdmon::monitor notices the sync_action change and tells +- managemon to check for new devices. managemon notices the new +- devices, opens relevant sysfs file, and passes them all to +- monitor. +- 8/ mdadm::Grow_reshape() calls ->manage_reshape to oversee the +- rest of the reshape. +- +- 9/ mdadm::->manage_reshape(): saves data that will be overwritten by +- the kernel to either the backup file or the metadata specific location, +- advances sync_max, waits for reshape, ping mdmon, repeat. +- Meanwhile mdmon::read_and_act(): records checkpoints. +- Specifically. +- +- 9a/ if the 'next' stripe to be reshaped will over-write +- itself during reshape then: +- 9a.1/ increase suspend_hi to cover a suitable number of +- stripes. +- 9a.2/ backup those stripes safely. +- 9a.3/ advance sync_max to allow those stripes to be backed up +- 9a.4/ when sync_completed indicates that those stripes have +- been reshaped, manage_reshape must ping_manager +- 9a.5/ when mdmon notices that sync_completed has been updated, +- it records the new checkpoint in the metadata +- 9a.6/ after the ping_manager, manage_reshape will increase +- suspend_lo to allow access to those stripes again +- +- 9b/ if the 'next' stripe to be reshaped will over-write unused +- space during reshape then we apply same process as above, +- except that there is no need to back anything up. +- Note that we *do* need to keep suspend_hi progressing as +- it is not safe to write to the area-under-reshape. For +- kernel-managed-metadata this protection is provided by +- ->reshape_safe, but that does not protect us in the case +- of user-space-managed-metadata. +- +- 10/ mdadm::->manage_reshape(): Once reshape completes changes the raid +- level back to the nominal raid level (if necessary) +- +- FIXME: native metadata does not have the capability to record the original +- raid level in reshape-restart case because the kernel always records current +- raid level to the metadata, whereas external metadata can masquerade at an +- alternate level based on the reshape state. +- +-2.6 Reshape raid disks (shrink) +- +-3 Interaction with metadata handle. +- +- The following calls are made into the metadata handler to assist +- with initiating and monitoring a 'reshape'. +- +- 1/ ->reshape_super is called quite early (after only minimial +- checks) to make sure that the metadata can record the new shape +- and any necessary transitions. It may be passed a 'container' +- or an individual array within a container, and it should notice +- the difference and act accordingly. +- When a reshape is requested against a container it is expected +- that it should be applied to every array in the container, +- however it is up to the metadata handler to determine final +- policy. +- +- If the reshape is supportable, the internal copy of the metadata +- should be updated, and a metadata update suitable for sending +- to mdmon should be queued. +- +- If the reshape will involve converting spares into array members, +- this must be recorded in the metadata too. +- +- 2/ ->container_content will be called to find out the new state +- of all the array, or all arrays in the container. Any newly +- added devices (with state==0 and raid_disk >= 0) will be added +- to the array as spares with the relevant slot number. +- +- It is likely that the info returned by ->container_content will +- have ->reshape_active set, ->reshape_progress set to e.g. 0, and +- new_* set appropriately. mdadm will use this information to +- cause the correct reshape to start at an appropriate time. +- +- 3/ ->set_array_state will be called by mdmon when reshape has +- started and again periodically as it progresses. This should +- record the ->last_checkpoint as the point where reshape has +- progressed to. When the reshape finished this will be called +- again and it should notice that ->curr_action is no longer +- 'reshape' and so should record that the reshape has finished +- providing 'last_checkpoint' has progressed suitably. +- +- 4/ ->manage_reshape will be called once the reshape has been set +- up in the kernel but before sync_max has been moved from 0, so +- no actual reshape will have happened. +- +- ->manage_reshape should call progress_reshape() to allow the +- reshape to progress, and should back-up any data as indicated +- by the return value. See the documentation of that function +- for more details. +- ->manage_reshape will be called multiple times when a +- container is being reshaped, once for each member array in +- the container. +- +- +- The progress of the metadata is as follows: +- 1/ mdadm sends a metadata update to mdmon which marks the array +- as undergoing a reshape. This is set up by +- ->reshape_super and applied by ->process_update +- For container-wide reshape, this happens once for the whole +- container. +- 2/ mdmon notices progress via the sysfs files and calls +- ->set_array_state to update the state periodically +- For container-wide reshape, this happens repeatedly for +- one array, then repeatedly for the next, etc. +- 3/ mdmon notices when reshape has finished and call +- ->set_array_state to record the the reshape is complete. +- For container-wide reshape, this happens once for each +- member array. +- +- +- +-... +- +-[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/ +diff --git a/mdadm.conf-example b/mdadm.conf-example +deleted file mode 100644 +index 35a75d12..00000000 +--- a/mdadm.conf-example ++++ /dev/null +@@ -1,65 +0,0 @@ +-# mdadm configuration file +-# +-# mdadm will function properly without the use of a configuration file, +-# but this file is useful for keeping track of arrays and member disks. +-# In general, a mdadm.conf file is created, and updated, after arrays +-# are created. This is the opposite behavior of /etc/raidtab which is +-# created prior to array construction. +-# +-# +-# the config file takes two types of lines: +-# +-# DEVICE lines specify a list of devices of where to look for +-# potential member disks +-# +-# ARRAY lines specify information about how to identify arrays so +-# so that they can be activated +-# +-# You can have more than one device line and use wild cards. The first +-# example includes SCSI the first partition of SCSI disks /dev/sdb, +-# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second +-# line looks for array slices on IDE disks. +-# +-#DEVICE /dev/sd[bcdjkl]1 +-#DEVICE /dev/hda1 /dev/hdb1 +-# +-# If you mount devfs on /dev, then a suitable way to list all devices is: +-#DEVICE /dev/discs/*/* +-# +-# +-# The AUTO line can control which arrays get assembled by auto-assembly, +-# meaing either "mdadm -As" when there are no 'ARRAY' lines in this file, +-# or "mdadm --incremental" when the array found is not listed in this file. +-# By default, all arrays that are found are assembled. +-# If you want to ignore all DDF arrays (maybe they are managed by dmraid), +-# and only assemble 1.x arrays if which are marked for 'this' homehost, +-# but assemble all others, then use +-#AUTO -ddf homehost -1.x +all +-# +-# ARRAY lines specify an array to assemble and a method of identification. +-# Arrays can currently be identified by using a UUID, superblock minor number, +-# or a listing of devices. +-# +-# super-minor is usually the minor number of the metadevice +-# UUID is the Universally Unique Identifier for the array +-# Each can be obtained using +-# +-# mdadm -D +-# +-#ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 +-#ARRAY /dev/md1 super-minor=1 +-#ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 +-# +-# ARRAY lines can also specify a "spare-group" for each array. mdadm --monitor +-# will then move a spare between arrays in a spare-group if one array has a failed +-# drive but no spare +-#ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df spare-group=group1 +-#ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 spare-group=group1 +-# +-# When used in --follow (aka --monitor) mode, mdadm needs a +-# mail address and/or a program. This can be given with "mailaddr" +-# and "program" lines to that monitoring can be started using +-# mdadm --follow --scan & echo $! > /run/mdadm/mon.pid +-# If the lines are not found, mdadm will exit quietly +-#MAILADDR root@mydomain.tld +-#PROGRAM /usr/sbin/handle-mdadm-events +diff --git a/mdmon-design.txt b/mdmon-design.txt +deleted file mode 100644 +index f09184a9..00000000 +--- a/mdmon-design.txt ++++ /dev/null +@@ -1,146 +0,0 @@ +- +-When managing a RAID1 array which uses metadata other than the +-"native" metadata understood by the kernel, mdadm makes use of a +-partner program named 'mdmon' to manage some aspects of updating +-that metadata and synchronising the metadata with the array state. +- +-This document provides some details on how mdmon works. +- +-Containers +----------- +- +-As background: mdadm makes a distinction between an 'array' and a +-'container'. Other sources sometimes use the term 'volume' or +-'device' for an 'array', and may use the term 'array' for a +-'container'. +- +-For our purposes: +- - a 'container' is a collection of devices which are described by a +- single set of metadata. The metadata may be stored equally +- on all devices, or different devices may have quite different +- subsets of the total metadata. But there is conceptually one set +- of metadata that unifies the devices. +- +- - an 'array' is a set of datablock from various devices which +- together are used to present the abstraction of a single linear +- sequence of block, which may provide data redundancy or enhanced +- performance. +- +-So a container has some metadata and provides a number of arrays which +-are described by that metadata. +- +-Sometimes this model doesn't work perfectly. For example, global +-spares may have their own metadata which is quite different from the +-metadata from any device that participates in one or more arrays. +-Such a global spare might still need to belong to some container so +-that it is available to be used should a failure arise. In that case +-we consider the 'metadata' to be the union of the metadata on the +-active devices which describes the arrays, and the metadata on the +-global spares which only describes the spares. In this case different +-devices in the one container will have quite different metadata. +- +- +-Purpose +-------- +- +-The main purpose of mdmon is to update the metadata in response to +-changes to the array which need to be reflected in the metadata before +-futures writes to the array can safely be performed. +-These include: +- - transitions from 'clean' to 'dirty'. +- - recording the devices have failed. +- - recording the progress of a 'reshape' +- +-This requires mdmon to be running at any time that the array is +-writable (a read-only array does not require mdmon to be running). +- +-Because mdmon must be able to process these metadata updates at any +-time, it must (when running) have exclusive write access to the +-metadata. Any other changes (e.g. reconfiguration of the array) must +-go through mdmon. +- +-A secondary role for mdmon is to activate spares when a device fails. +-This role is much less time-critical than the other metadata updates, +-so it could be performed by a separate process, possibly +-"mdadm --monitor" which has a related role of moving devices between +-arrays. A main reason for including this functionality in mdmon is +-that in the native-metadata case this function is handled in the +-kernel, and mdmon's reason for existence to provide functionality +-which is otherwise handled by the kernel. +- +- +-Design overview +---------------- +- +-mdmon is structured as two threads with a common address space and +-common data structures. These threads are know as the 'monitor' and +-the 'manager'. +- +-The 'monitor' has the primary role of monitoring the array for +-important state changes and updating the metadata accordingly. As +-writes to the array can be blocked until 'monitor' completes and +-acknowledges the update, it much be very careful not to block itself. +-In particular it must not block waiting for any write to complete else +-it could deadlock. This means that it must not allocate memory as +-doing this can require dirty memory to be written out and if the +-system choose to write to the array that mdmon is monitoring, the +-memory allocation could deadlock. +- +-So 'monitor' must never allocate memory and must limit the number of +-other system call it performs. It may: +- - use select (or poll) to wait for activity on a file descriptor +- - read from a sysfs file descriptor +- - write to a sysfs file descriptor +- - write the metadata out to the block devices using O_DIRECT +- - send a signal (kill) to the manager thread +- +-It must not e.g. open files or do anything similar that might allocate +-resources. +- +-The 'manager' thread does everything else that is needed. If any +-files are to be opened (e.g. because a device has been added to the +-array), the manager does that. If any memory needs to be allocated +-(e.g. to hold data about a new array as can happen when one set of +-metadata describes several arrays), the manager performs that +-allocation. +- +-The 'manager' is also responsible for communicating with mdadm and +-assigning spares to replace failed devices. +- +- +-Handling metadata updates +-------------------------- +- +-There are a number of cases in which mdadm needs to update the +-metdata which mdmon is managing. These include: +- - creating a new array in an active container +- - adding a device to a container +- - reconfiguring an array +-etc. +- +-To complete these updates, mdadm must send a message to mdmon which +-will merge the update into the metadata as it is at that moment. +- +-To achieve this, mdmon creates a Unix Domain Socket which the manager +-thread listens on. mdadm sends a message over this socket. The +-manager thread examines the message to see if it will require +-allocating any memory and allocates it. This is done in the +-'prepare_update' metadata method. +- +-The update message is then queued for handling by the monitor thread +-which it will do when convenient. The monitor thread calls +-->process_update which should atomically make the required changes to +-the metadata, making use of the pre-allocate memory as required. Any +-memory the is no-longer needed can be placed back in the request and +-the manager thread will free it. +- +-The exact format of a metadata update is up to the implementer of the +-metadata handlers. It will simply describe a change that needs to be +-made. It will sometimes contain fragments of the metadata to be +-copied in to place. However the ->process_update routine must make +-sure not to over-write any field that the monitor thread might have +-updated, such as a 'device failed' or 'array is dirty' state. +- +-When the monitor thread has completed the update and written it to the +-devices, an acknowledgement message is sent back over the socket so +-that mdadm knows it is complete. +-- +2.40.1 + diff --git a/SOURCES/0020-Detail-remove-duplicated-code.patch b/SOURCES/0020-Detail-remove-duplicated-code.patch new file mode 100644 index 0000000..17db9ae --- /dev/null +++ b/SOURCES/0020-Detail-remove-duplicated-code.patch @@ -0,0 +1,75 @@ +From 60c19530dd7cc6b38a75695a0a3d004bbe60d430 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Feb 2024 03:36:14 +0100 +Subject: [PATCH 20/41] Detail: remove duplicated code + +Remove duplicated code from Detail(), where MD_UUID and MD_DEVNAME +are being set. Superblock is no longer required to print system +properties. Now it tries to obtain map in two ways. + +Signed-off-by: Kinga Tanska +Signed-off-by: Mariusz Tkaczyk +--- + Detail.c | 33 +++++++++++++-------------------- + 1 file changed, 13 insertions(+), 20 deletions(-) + +diff --git a/Detail.c b/Detail.c +index aaa3dd6e..f23ec16f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -226,6 +226,9 @@ int Detail(char *dev, struct context *c) + str = map_num(pers, array.level); + + if (c->export) { ++ char nbuf[64]; ++ struct map_ent *mp = NULL, *map = NULL; ++ + if (array.raid_disks) { + if (str) + printf("MD_LEVEL=%s\n", str); +@@ -247,32 +250,22 @@ int Detail(char *dev, struct context *c) + array.minor_version); + } + +- if (st && st->sb && info) { +- char nbuf[64]; +- struct map_ent *mp, *map = NULL; +- +- fname_from_uuid(st, info, nbuf, ':'); +- printf("MD_UUID=%s\n", nbuf + 5); ++ if (info) + mp = map_by_uuid(&map, info->uuid); ++ if (!mp) ++ mp = map_by_devnm(&map, fd2devnm(fd)); + +- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) ++ if (mp) { ++ __fname_from_uuid(mp->uuid, 0, nbuf, ':'); ++ printf("MD_UUID=%s\n", nbuf + 5); ++ if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) + printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); ++ } + ++ map_free(map); ++ if (st && st->sb) { + if (st->ss->export_detail_super) + st->ss->export_detail_super(st); +- map_free(map); +- } else { +- struct map_ent *mp, *map = NULL; +- char nbuf[64]; +- mp = map_by_devnm(&map, fd2devnm(fd)); +- if (mp) { +- __fname_from_uuid(mp->uuid, 0, nbuf, ':'); +- printf("MD_UUID=%s\n", nbuf+5); +- } +- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) +- printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); +- +- map_free(map); + } + if (!c->no_devices && sra) { + struct mdinfo *mdi; +-- +2.40.1 + diff --git a/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch b/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch new file mode 100644 index 0000000..97f8115 --- /dev/null +++ b/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch @@ -0,0 +1,286 @@ +From 0c0f09cb035b6a27a1d11c54836742a9945a5014 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:05 +0100 +Subject: [PATCH 21/41] mdadm: Add functions for spare criteria verification + +It is done similar way in few places. As a result, two almost identical +functions (dev_size_from_id() and dev_sector_size_from_id()) are +removed. Now, it uses same file descriptor to send two ioctls. + +Two extern functions are added, in next patches +disk_fd_matches_criteria() is used. + +Next optimization is inline zeroing struct spare_criteria. With that, +we don't need to reset values in get_spare_criteria_imsm(). + +Dedicated boolean field for checking if criteria are filled is added. +We don't need to execute the code if it is not set. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 2 +- + Monitor.c | 14 +------ + mdadm.h | 6 ++- + super-intel.c | 4 +- + util.c | 112 ++++++++++++++++++++++++++------------------------ + 5 files changed, 67 insertions(+), 71 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 30c07c03..2b5a5859 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -874,7 +874,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct domainlist *dl = NULL; + struct mdinfo *sra; + unsigned long long devsize, freesize = 0; +- struct spare_criteria sc = {0, 0}; ++ struct spare_criteria sc = {0}; + + if (is_subarray(mp->metadata)) + continue; +diff --git a/Monitor.c b/Monitor.c +index 9be2b528..1ece8712 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1070,22 +1070,12 @@ static dev_t choose_spare(struct state *from, struct state *to, + for (d = from->raid; !dev && d < MAX_DISKS; d++) { + if (from->devid[d] > 0 && from->devstate[d] == 0) { + struct dev_policy *pol; +- unsigned long long dev_size; +- unsigned int dev_sector_size; + + if (to->metadata->ss->external && + test_partition_from_id(from->devid[d])) + continue; + +- if (sc->min_size && +- dev_size_from_id(from->devid[d], &dev_size) && +- dev_size < sc->min_size) +- continue; +- +- if (sc->sector_size && +- dev_sector_size_from_id(from->devid[d], +- &dev_sector_size) && +- sc->sector_size != dev_sector_size) ++ if (devid_matches_criteria(from->devid[d], sc) == false) + continue; + + pol = devid_policy(from->devid[d]); +@@ -1170,12 +1160,12 @@ static void try_spare_migration(struct state *statelist) + { + struct state *from; + struct state *st; +- struct spare_criteria sc; + + link_containers_with_subarrays(statelist); + for (st = statelist; st; st = st->next) + if (st->active < st->raid && st->spare == 0 && !st->err) { + struct domainlist *domlist = NULL; ++ struct spare_criteria sc = {0}; + int d; + struct state *to = st; + +diff --git a/mdadm.h b/mdadm.h +index 75c887e4..e8abd730 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -430,6 +430,7 @@ struct createinfo { + }; + + struct spare_criteria { ++ bool criteria_set; + unsigned long long min_size; + unsigned int sector_size; + }; +@@ -1368,8 +1369,6 @@ extern struct supertype *dup_super(struct supertype *st); + extern int get_dev_size(int fd, char *dname, unsigned long long *sizep); + extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep); + extern int must_be_container(int fd); +-extern int dev_size_from_id(dev_t id, unsigned long long *size); +-extern int dev_sector_size_from_id(dev_t id, unsigned int *size); + void wait_for(char *dev, int fd); + + /* +@@ -1708,6 +1707,9 @@ extern int assemble_container_content(struct supertype *st, int mdfd, + #define INCR_UNSAFE 2 + #define INCR_ALREADY 4 + #define INCR_YES 8 ++ ++extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc); ++extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc); + extern struct mdinfo *container_choose_spares(struct supertype *st, + struct spare_criteria *criteria, + struct domainlist *domlist, +diff --git a/super-intel.c b/super-intel.c +index 4babec9f..39ec4754 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1748,9 +1748,6 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) + int i; + unsigned long long size = 0; + +- c->min_size = 0; +- c->sector_size = 0; +- + if (!super) + return -EINVAL; + /* find first active disk in array */ +@@ -1774,6 +1771,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) + + c->min_size = size * 512; + c->sector_size = super->sector_size; ++ c->criteria_set = true; + + return 0; + } +diff --git a/util.c b/util.c +index b1454473..041e78cf 100644 +--- a/util.c ++++ b/util.c +@@ -1266,40 +1266,6 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + return st; + } + +-int dev_size_from_id(dev_t id, unsigned long long *size) +-{ +- char buf[20]; +- int fd; +- +- sprintf(buf, "%d:%d", major(id), minor(id)); +- fd = dev_open(buf, O_RDONLY); +- if (fd < 0) +- return 0; +- if (get_dev_size(fd, NULL, size)) { +- close(fd); +- return 1; +- } +- close(fd); +- return 0; +-} +- +-int dev_sector_size_from_id(dev_t id, unsigned int *size) +-{ +- char buf[20]; +- int fd; +- +- sprintf(buf, "%d:%d", major(id), minor(id)); +- fd = dev_open(buf, O_RDONLY); +- if (fd < 0) +- return 0; +- if (get_dev_sector_size(fd, NULL, size)) { +- close(fd); +- return 1; +- } +- close(fd); +- return 0; +-} +- + struct supertype *dup_super(struct supertype *orig) + { + struct supertype *st; +@@ -2088,6 +2054,60 @@ void append_metadata_update(struct supertype *st, void *buf, int len) + unsigned int __invalid_size_argument_for_IOC = 0; + #endif + ++/** ++ * disk_fd_matches_criteria() - check if device matches spare criteria. ++ * @disk_fd: file descriptor of the disk. ++ * @sc: criteria to test. ++ * ++ * Return: true if disk matches criteria, false otherwise. ++ */ ++bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) ++{ ++ unsigned int dev_sector_size = 0; ++ unsigned long long dev_size = 0; ++ ++ if (!sc->criteria_set) ++ return true; ++ ++ if (!get_dev_size(disk_fd, NULL, &dev_size) || dev_size < sc->min_size) ++ return false; ++ ++ if (!get_dev_sector_size(disk_fd, NULL, &dev_sector_size) || ++ sc->sector_size != dev_sector_size) ++ return false; ++ ++ return true; ++} ++ ++/** ++ * devid_matches_criteria() - check if device referenced by devid matches spare criteria. ++ * @devid: devid of the device to check. ++ * @sc: criteria to test. ++ * ++ * Return: true if disk matches criteria, false otherwise. ++ */ ++bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) ++{ ++ char buf[NAME_MAX]; ++ bool ret; ++ int fd; ++ ++ if (!sc->criteria_set) ++ return true; ++ ++ snprintf(buf, NAME_MAX, "%d:%d", major(devid), minor(devid)); ++ ++ fd = dev_open(buf, O_RDONLY); ++ if (!is_fd_valid(fd)) ++ return false; ++ ++ /* Error code inherited */ ++ ret = disk_fd_matches_criteria(fd, sc); ++ ++ close(fd); ++ return ret; ++} ++ + /* Pick all spares matching given criteria from a container + * if min_size == 0 do not check size + * if domlist == NULL do not check domains +@@ -2111,28 +2131,13 @@ struct mdinfo *container_choose_spares(struct supertype *st, + dp = &disks->devs; + disks->array.spare_disks = 0; + while (*dp) { +- int found = 0; ++ bool found = false; ++ + d = *dp; + if (d->disk.state == 0) { +- /* check if size is acceptable */ +- unsigned long long dev_size; +- unsigned int dev_sector_size; +- int size_valid = 0; +- int sector_size_valid = 0; +- + dev_t dev = makedev(d->disk.major,d->disk.minor); + +- if (!criteria->min_size || +- (dev_size_from_id(dev, &dev_size) && +- dev_size >= criteria->min_size)) +- size_valid = 1; +- +- if (!criteria->sector_size || +- (dev_sector_size_from_id(dev, &dev_sector_size) && +- criteria->sector_size == dev_sector_size)) +- sector_size_valid = 1; +- +- found = size_valid && sector_size_valid; ++ found = devid_matches_criteria(dev, criteria); + + /* check if domain matches */ + if (found && domlist) { +@@ -2141,7 +2146,8 @@ struct mdinfo *container_choose_spares(struct supertype *st, + pol_add(&pol, pol_domain, + spare_group, NULL); + if (domain_test(domlist, pol, metadata) != 1) +- found = 0; ++ found = false; ++ + dev_policy_free(pol); + } + } +-- +2.40.1 + diff --git a/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch b/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch new file mode 100644 index 0000000..b3ebb67 --- /dev/null +++ b/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch @@ -0,0 +1,357 @@ +From f656201188d73cdc2726265f1348f8ffbf7587be Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:06 +0100 +Subject: [PATCH 22/41] mdadm: drop get_required_spare_criteria() + +Only IMSM implements get_spare_criteria, so load_super() in +get_required_spare_criteria() is dead code. It is moved inside +metadata handler, because only IMSM implements it. + +Give possibility to provide devnode to be opened. With that we can hide +load_container() used only to fill spare criteria inside handler +and simplify implementation in generic code. + +Add helper function for testing spare criteria in Incremental and +error messages. + +File descriptor in get_spare_criteria_imsm() is always opened on purpose. +New functionality added in next patches will require it. For the same +reason, function is moved to other place. + +No functional changes. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 77 ++++++++++++++++++++++---------- + Monitor.c | 35 +++------------ + mdadm.h | 5 +-- + super-intel.c | 120 +++++++++++++++++++++++++++++++++----------------- + 4 files changed, 140 insertions(+), 97 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 2b5a5859..66c2cc86 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -833,6 +833,53 @@ container_members_max_degradation(struct map_ent *map, struct map_ent *me) + return max_degraded; + } + ++/** ++ * incremental_external_test_spare_criteria() - helper to test spare criteria. ++ * @st: supertype, must be not NULL, it is duplicated here. ++ * @container_devnm: devnm of the container. ++ * @disk_fd: file descriptor of device to tested. ++ * @verbose: verbose flag. ++ * ++ * The function is used on new drive verification path to check if it can be added to external ++ * container. To test spare criteria, metadata must be loaded. It duplicates super to not mess in ++ * original one. ++ * Function is executed if superblock supports get_spare_criteria(), otherwise success is returned. ++ */ ++mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, char *container_devnm, ++ int disk_fd, int verbose) ++{ ++ mdadm_status_t rv = MDADM_STATUS_ERROR; ++ char container_devname[PATH_MAX]; ++ struct spare_criteria sc = {0}; ++ struct supertype *dup; ++ ++ if (!st->ss->get_spare_criteria) ++ return MDADM_STATUS_SUCCESS; ++ ++ dup = dup_super(st); ++ snprintf(container_devname, PATH_MAX, "/dev/%s", container_devnm); ++ ++ if (dup->ss->get_spare_criteria(dup, container_devname, &sc) != 0) { ++ if (verbose > 1) ++ pr_err("Failed to get spare criteria for %s\n", container_devname); ++ goto out; ++ } ++ ++ if (!disk_fd_matches_criteria(disk_fd, &sc)) { ++ if (verbose > 1) ++ pr_err("Disk does not match spare criteria for %s\n", container_devname); ++ goto out; ++ } ++ ++ rv = MDADM_STATUS_SUCCESS; ++ ++out: ++ dup->ss->free_super(dup); ++ free(dup); ++ ++ return rv; ++} ++ + static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct map_ent *target, int bare, + struct supertype *st, int verbose) +@@ -873,8 +920,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct supertype *st2; + struct domainlist *dl = NULL; + struct mdinfo *sra; +- unsigned long long devsize, freesize = 0; +- struct spare_criteria sc = {0}; ++ unsigned long long freesize = 0; + + if (is_subarray(mp->metadata)) + continue; +@@ -925,34 +971,19 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + if (sra->array.failed_disks == -1) + sra->array.failed_disks = container_members_max_degradation(map, mp); + +- get_dev_size(dfd, NULL, &devsize); + if (sra->component_size == 0) { +- /* true for containers, here we must read superblock +- * to obtain minimum spare size */ +- struct supertype *st3 = dup_super(st2); +- int mdfd = open_dev(mp->devnm); +- if (mdfd < 0) { +- free(st3); ++ /* true for containers */ ++ if (incremental_external_test_spare_criteria(st2, mp->devnm, dfd, verbose)) + goto next; +- } +- if (st3->ss->load_container && +- !st3->ss->load_container(st3, mdfd, mp->path)) { +- if (st3->ss->get_spare_criteria) +- st3->ss->get_spare_criteria(st3, &sc); +- st3->ss->free_super(st3); +- } +- free(st3); +- close(mdfd); + } +- if ((sra->component_size > 0 && +- st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout, ++ ++ if (sra->component_size > 0 && ++ st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout, + sra->array.raid_disks, &sra->array.chunk_size, + sra->component_size, + sra->devs ? sra->devs->data_offset : INVALID_SECTORS, + devname, &freesize, sra->consistency_policy, +- 0) && +- freesize < sra->component_size) || +- (sra->component_size == 0 && devsize < sc.min_size)) { ++ 0) && freesize < sra->component_size) { + if (verbose > 1) + pr_err("not adding %s to %s as it is too small\n", + devname, mp->path); +diff --git a/Monitor.c b/Monitor.c +index 1ece8712..6b4560ae 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1008,34 +1008,6 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + return new_found; + } + +-static int get_required_spare_criteria(struct state *st, +- struct spare_criteria *sc) +-{ +- int fd; +- +- if (!st->metadata || !st->metadata->ss->get_spare_criteria) { +- sc->min_size = 0; +- sc->sector_size = 0; +- return 0; +- } +- +- fd = open(st->devname, O_RDONLY); +- if (fd < 0) +- return 1; +- if (st->metadata->ss->external) +- st->metadata->ss->load_container(st->metadata, fd, st->devname); +- else +- st->metadata->ss->load_super(st->metadata, fd, st->devname); +- close(fd); +- if (!st->metadata->sb) +- return 1; +- +- st->metadata->ss->get_spare_criteria(st->metadata, sc); +- st->metadata->ss->free_super(st->metadata); +- +- return 0; +-} +- + static int check_donor(struct state *from, struct state *to) + { + struct state *sub; +@@ -1178,8 +1150,11 @@ static void try_spare_migration(struct state *statelist) + /* member of a container */ + to = to->parent; + +- if (get_required_spare_criteria(to, &sc)) +- continue; ++ if (to->metadata->ss->get_spare_criteria) ++ if (to->metadata->ss->get_spare_criteria(to->metadata, to->devname, ++ &sc)) ++ continue; ++ + if (to->metadata->ss->external) { + /* We must make sure there is + * no suitable spare in container already. +diff --git a/mdadm.h b/mdadm.h +index e8abd730..cbc586f5 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1116,10 +1116,9 @@ extern struct superswitch { + * Return spare criteria for array: + * - minimum disk size can be used in array; + * - sector size can be used in array. +- * Return values: 0 - for success and -EINVAL on error. + */ +- int (*get_spare_criteria)(struct supertype *st, +- struct spare_criteria *sc); ++ mdadm_status_t (*get_spare_criteria)(struct supertype *st, char *mddev_path, ++ struct spare_criteria *sc); + /* Find somewhere to put a bitmap - possibly auto-size it - and + * update the metadata to record this. The array may be newly + * created, in which case data_size may be updated, or it might +diff --git a/super-intel.c b/super-intel.c +index 39ec4754..7ad391ac 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1736,46 +1736,6 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super) + return (remainder < rv) ? remainder : rv; + } + +-/* +- * Return minimum size of a spare and sector size +- * that can be used in this array +- */ +-int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) +-{ +- struct intel_super *super = st->sb; +- struct dl *dl; +- struct extent *e; +- int i; +- unsigned long long size = 0; +- +- if (!super) +- return -EINVAL; +- /* find first active disk in array */ +- dl = super->disks; +- while (dl && (is_failed(&dl->disk) || dl->index == -1)) +- dl = dl->next; +- if (!dl) +- return -EINVAL; +- /* find last lba used by subarrays */ +- e = get_extents(super, dl, 0); +- if (!e) +- return -EINVAL; +- for (i = 0; e[i].size; i++) +- continue; +- if (i > 0) +- size = e[i-1].start + e[i-1].size; +- free(e); +- +- /* add the amount of space needed for metadata */ +- size += imsm_min_reserved_sectors(super); +- +- c->min_size = size * 512; +- c->sector_size = super->sector_size; +- c->criteria_set = true; +- +- return 0; +-} +- + static bool is_gen_migration(struct imsm_dev *dev); + + #define IMSM_4K_DIV 8 +@@ -11295,6 +11255,84 @@ static const char *imsm_get_disk_controller_domain(const char *path) + return drv; + } + ++/** ++ * get_spare_criteria_imsm() - set spare criteria. ++ * @st: supertype. ++ * @mddev_path: path to md device devnode, it must be container. ++ * @c: spare_criteria struct to fill, not NULL. ++ * ++ * If superblock is not loaded, use mddev_path to load_container. It must be given in this case. ++ * Filles size and sector size accordingly to superblock. ++ */ ++mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, ++ struct spare_criteria *c) ++{ ++ mdadm_status_t ret = MDADM_STATUS_ERROR; ++ bool free_superblock = false; ++ unsigned long long size = 0; ++ struct intel_super *super; ++ struct extent *e; ++ struct dl *dl; ++ int i; ++ ++ /* If no superblock and no mddev_path, we cannot load superblock. */ ++ assert(st->sb || mddev_path); ++ ++ if (mddev_path) { ++ int fd = open(mddev_path, O_RDONLY); ++ ++ if (!is_fd_valid(fd)) ++ return MDADM_STATUS_ERROR; ++ ++ if (!st->sb) { ++ if (load_container_imsm(st, fd, st->devnm)) { ++ close(fd); ++ return MDADM_STATUS_ERROR; ++ } ++ free_superblock = true; ++ } ++ close(fd); ++ } ++ ++ super = st->sb; ++ ++ /* find first active disk in array */ ++ dl = super->disks; ++ while (dl && (is_failed(&dl->disk) || dl->index == -1)) ++ dl = dl->next; ++ ++ if (!dl) ++ goto out; ++ ++ /* find last lba used by subarrays */ ++ e = get_extents(super, dl, 0); ++ if (!e) ++ goto out; ++ ++ for (i = 0; e[i].size; i++) ++ continue; ++ if (i > 0) ++ size = e[i - 1].start + e[i - 1].size; ++ free(e); ++ ++ /* add the amount of space needed for metadata */ ++ size += imsm_min_reserved_sectors(super); ++ ++ c->min_size = size * 512; ++ c->sector_size = super->sector_size; ++ c->criteria_set = true; ++ ret = MDADM_STATUS_SUCCESS; ++ ++out: ++ if (free_superblock) ++ free_super_imsm(st); ++ ++ if (ret != MDADM_STATUS_SUCCESS) ++ c->criteria_set = false; ++ ++ return ret; ++} ++ + static char *imsm_find_array_devnm_by_subdev(int subdev, char *container) + { + static char devnm[32]; +@@ -11425,7 +11463,7 @@ static struct mdinfo *get_spares_for_grow(struct supertype *st) + { + struct spare_criteria sc; + +- get_spare_criteria_imsm(st, &sc); ++ get_spare_criteria_imsm(st, NULL, &sc); + return container_choose_spares(st, &sc, NULL, NULL, NULL, 0); + } + +-- +2.40.1 + diff --git a/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch b/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch new file mode 100644 index 0000000..eec558c --- /dev/null +++ b/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch @@ -0,0 +1,64 @@ +From e97ca3583c96591af0e4863c12c394074a51c84d Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:07 +0100 +Subject: [PATCH 23/41] Manage: fix check after dereference issue + +The code dereferences dev_st earlier without checking, it gives SAST +problem. + +dev_st is needed for attempt_re_add(), but it is executed only if +dv->disposition != 'S', so move disposition check up. + +tst is a must to reach this place, dup_super() have to return valid +pointer, all it needs to check is if load_super() returns superblock. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 30302ac8..77b79cf5 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -794,25 +794,23 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + * simply re-add it. + */ + +- if (array->not_persistent == 0) { ++ if (array->not_persistent == 0 && dv->disposition != 'S') { ++ int rv = 0; ++ + dev_st = dup_super(tst); + dev_st->ss->load_super(dev_st, tfd, NULL); +- if (dev_st->sb && dv->disposition != 'S') { +- int rv; + +- rv = attempt_re_add(fd, tfd, dv, dev_st, tst, +- rdev, update, devname, +- verbose, array); +- dev_st->ss->free_super(dev_st); +- if (rv) { +- free(dev_st); +- return rv; +- } +- } +- if (dev_st) { ++ if (dev_st->sb) { ++ rv = attempt_re_add(fd, tfd, dv, dev_st, tst, rdev, update, ++ devname, verbose, array); ++ + dev_st->ss->free_super(dev_st); +- free(dev_st); + } ++ ++ free(dev_st); ++ ++ if (rv) ++ return rv; + } + if (dv->disposition == 'M') { + if (verbose > 0) +-- +2.40.1 + diff --git a/SOURCES/0024-Manage-implement-manage_add_external.patch b/SOURCES/0024-Manage-implement-manage_add_external.patch new file mode 100644 index 0000000..9aa3d68 --- /dev/null +++ b/SOURCES/0024-Manage-implement-manage_add_external.patch @@ -0,0 +1,184 @@ +From 29273f606542d915a3ddf37bb084f4eff54fcc3b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:08 +0100 +Subject: [PATCH 24/41] Manage: implement manage_add_external() + +Move external add code to separate function. It is easier to control +error path now. Error messages are adjusted. + +No functional changes. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 147 ++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 86 insertions(+), 61 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 77b79cf5..b3e216cb 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -695,6 +695,91 @@ skip_re_add: + return 0; + } + ++/** ++ * manage_add_external() - Add disk to external container. ++ * @st: external supertype pointer, must not be NULL, superblock is released here. ++ * @fd: container file descriptor, must not have O_EXCL mode. ++ * @disk_fd: device to add file descriptor. ++ * @disk_name: name of the device to add. ++ * @disc: disk info. ++ * ++ * Superblock is released here because any open fd with O_EXCL will block sysfs_add_disk(). ++ */ ++mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name, ++ mdu_disk_info_t *disc) ++{ ++ mdadm_status_t rv = MDADM_STATUS_ERROR; ++ char container_devpath[MD_NAME_MAX]; ++ struct mdinfo new_mdi; ++ struct mdinfo *sra = NULL; ++ int container_fd; ++ int disk_fd = -1; ++ ++ snprintf(container_devpath, MD_NAME_MAX, "%s", fd2devnm(fd)); ++ ++ container_fd = open_dev_excl(container_devpath); ++ if (!is_fd_valid(container_fd)) { ++ pr_err("Failed to get exclusive access to container %s\n", container_devpath); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* Check if metadata handler is able to accept the drive */ ++ if (!st->ss->validate_geometry(st, LEVEL_CONTAINER, 0, 1, NULL, 0, 0, disk_name, NULL, ++ 0, 1)) ++ goto out; ++ ++ Kill(disk_name, NULL, 0, -1, 0); ++ ++ disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT); ++ if (!is_fd_valid(disk_fd)) { ++ pr_err("Failed to exclusively open %s\n", disk_name); ++ goto out; ++ } ++ ++ if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS)) ++ goto out; ++ ++ if (!mdmon_running(st->container_devnm)) ++ st->ss->sync_metadata(st); ++ ++ sra = sysfs_read(container_fd, NULL, 0); ++ if (!sra) { ++ pr_err("Failed to read sysfs for %s\n", disk_name); ++ goto out; ++ } ++ ++ sra->array.level = LEVEL_CONTAINER; ++ /* Need to set data_offset and component_size */ ++ st->ss->getinfo_super(st, &new_mdi, NULL); ++ new_mdi.disk.major = disc->major; ++ new_mdi.disk.minor = disc->minor; ++ new_mdi.recovery_start = 0; ++ ++ st->ss->free_super(st); ++ ++ if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { ++ pr_err("Failed to add %s to container %s\n", disk_name, container_devpath); ++ goto out; ++ } ++ ping_monitor(container_devpath); ++ rv = MDADM_STATUS_SUCCESS; ++ ++out: ++ close(container_fd); ++ ++ if (sra) ++ sysfs_free(sra); ++ ++ if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd)) ++ /* Metadata handler records this descriptor, so release it only on failure. */ ++ close(disk_fd); ++ ++ if (st->sb) ++ st->ss->free_super(st); ++ ++ return rv; ++} ++ + int Manage_add(int fd, int tfd, struct mddev_dev *dv, + struct supertype *tst, mdu_array_info_t *array, + int force, int verbose, char *devname, +@@ -966,68 +1051,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + if (dv->failfast == FlagSet) + disc.state |= (1 << MD_DISK_FAILFAST); + if (tst->ss->external) { +- /* add a disk +- * to an external metadata container */ +- struct mdinfo new_mdi; +- struct mdinfo *sra; +- int container_fd; +- char devnm[32]; +- int dfd; +- +- strcpy(devnm, fd2devnm(fd)); +- +- container_fd = open_dev_excl(devnm); +- if (container_fd < 0) { +- pr_err("add failed for %s: could not get exclusive access to container\n", +- dv->devname); +- tst->ss->free_super(tst); ++ if (manage_add_external(tst, fd, dv->devname, &disc) != MDADM_STATUS_SUCCESS) + goto unlock; +- } +- +- /* Check if metadata handler is able to accept the drive */ +- if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL, +- 0, 0, dv->devname, NULL, 0, 1)) { +- close(container_fd); +- goto unlock; +- } +- +- Kill(dv->devname, NULL, 0, -1, 0); +- dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); +- if (tst->ss->add_to_super(tst, &disc, dfd, +- dv->devname, INVALID_SECTORS)) { +- close(dfd); +- close(container_fd); +- goto unlock; +- } +- if (!mdmon_running(tst->container_devnm)) +- tst->ss->sync_metadata(tst); +- +- sra = sysfs_read(container_fd, NULL, 0); +- if (!sra) { +- pr_err("add failed for %s: sysfs_read failed\n", +- dv->devname); +- close(container_fd); +- tst->ss->free_super(tst); +- goto unlock; +- } +- sra->array.level = LEVEL_CONTAINER; +- /* Need to set data_offset and component_size */ +- tst->ss->getinfo_super(tst, &new_mdi, NULL); +- new_mdi.disk.major = disc.major; +- new_mdi.disk.minor = disc.minor; +- new_mdi.recovery_start = 0; +- /* Make sure fds are closed as they are O_EXCL which +- * would block add_disk */ +- tst->ss->free_super(tst); +- if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { +- pr_err("add new device to external metadata failed for %s\n", dv->devname); +- close(container_fd); +- sysfs_free(sra); +- goto unlock; +- } +- ping_monitor(devnm); +- sysfs_free(sra); +- close(container_fd); + } else { + tst->ss->free_super(tst); + if (ioctl(fd, ADD_NEW_DISK, &disc)) { +-- +2.40.1 + diff --git a/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch b/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch new file mode 100644 index 0000000..acd0f84 --- /dev/null +++ b/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch @@ -0,0 +1,138 @@ +From 14a8657940be34a781222b4b715bd09eb80d1057 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:09 +0100 +Subject: [PATCH 25/41] mdadm: introduce sysfs_get_container_devnm() + +There at least two places where it is done directly, so replace them +with function. Print message about creating external array, add "/dev/" +prefix to refer directly to devnode. + +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 21 ++++++++++----------- + Manage.c | 14 ++++---------- + mdadm.h | 2 ++ + sysfs.c | 23 +++++++++++++++++++++++ + 4 files changed, 39 insertions(+), 21 deletions(-) + +diff --git a/Create.c b/Create.c +index 7e9170b6..0b776266 100644 +--- a/Create.c ++++ b/Create.c +@@ -1142,24 +1142,23 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (did_default && c->verbose >= 0) { + if (is_subarray(info.text_version)) { +- char devnm[32]; +- char *ep; ++ char devnm[MD_NAME_MAX]; + struct mdinfo *mdi; + +- strncpy(devnm, info.text_version+1, 32); +- devnm[31] = 0; +- ep = strchr(devnm, '/'); +- if (ep) +- *ep = 0; ++ sysfs_get_container_devnm(&info, devnm); + + mdi = sysfs_read(-1, devnm, GET_VERSION); ++ if (!mdi) { ++ pr_err("Cannot open sysfs for container %s\n", devnm); ++ goto abort_locked; ++ } ++ ++ pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version, ++ devnm); + +- pr_info("Creating array inside %s container %s\n", +- mdi?mdi->text_version:"managed", devnm); + sysfs_free(mdi); + } else +- pr_info("Defaulting to version %s metadata\n", +- info.text_version); ++ pr_info("Defaulting to version %s metadata\n", info.text_version); + } + + map_update(&map, fd2devnm(mdfd), info.text_version, +diff --git a/Manage.c b/Manage.c +index b3e216cb..969d0ea9 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -178,7 +178,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + struct map_ent *map = NULL; + struct mdinfo *mdi; + char devnm[32]; +- char container[32]; ++ char container[MD_NAME_MAX] = {0}; + int err; + int count; + char buf[SYSFS_MAX_BUF_SIZE]; +@@ -192,15 +192,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + * to stop is probably a bad idea. + */ + mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_COMPONENT|GET_VERSION); +- if (mdi && is_subarray(mdi->text_version)) { +- char *sl; +- strncpy(container, mdi->text_version+1, sizeof(container)); +- container[sizeof(container)-1] = 0; +- sl = strchr(container, '/'); +- if (sl) +- *sl = 0; +- } else +- container[0] = 0; ++ if (mdi && is_subarray(mdi->text_version)) ++ sysfs_get_container_devnm(mdi, container); ++ + close(fd); + count = 5; + while (((fd = ((devname[0] == '/') +diff --git a/mdadm.h b/mdadm.h +index cbc586f5..39b86bd0 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -777,6 +777,8 @@ enum sysfs_read_flags { + + #define SYSFS_MAX_BUF_SIZE 64 + ++extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf); ++ + /* If fd >= 0, get the array it is open on, + * else use devnm. + */ +diff --git a/sysfs.c b/sysfs.c +index f95ef701..230b842e 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -74,6 +74,29 @@ void sysfs_free(struct mdinfo *sra) + } + } + ++/** ++ * sysfs_get_container_devnm() - extract container device name. ++ * @mdi: md_info describes member array, with GET_VERSION option. ++ * @buf: buf to fill, must be MD_NAME_MAX. ++ * ++ * External array version is in format {/,-}/ ++ * Extract container_devnm from it and safe it in @buf. ++ */ ++void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf) ++{ ++ char *p; ++ ++ assert(is_subarray(mdi->text_version)); ++ ++ /* Skip first special sign */ ++ snprintf(buf, MD_NAME_MAX, "%s", mdi->text_version + 1); ++ ++ /* Remove array index */ ++ p = strchr(buf, '/'); ++ if (p) ++ *p = 0; ++} ++ + int sysfs_open(char *devnm, char *devname, char *attr) + { + char fname[MAX_SYSFS_PATH_LEN]; +-- +2.40.1 + diff --git a/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch b/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch new file mode 100644 index 0000000..ed4caee --- /dev/null +++ b/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch @@ -0,0 +1,115 @@ +From 1fef0c6ff54c2710f75a239dd8a5e0ffb0068e86 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:10 +0100 +Subject: [PATCH 26/41] mdadm.h: Introduce custom device policies + +The approach proposed here is to test drive policies outside +validate_geometry() separately per every drive and add determined +policies to list. The implementation reuses dev_policy we have in +mdadm. + +This concept addresses following problems: +- test drives if they fit together to criteria required by metadata + handler, +- test all drives assigned to the container even if some of them are not + target of the request, mdmon is free to use any drive in the same + container, +- extensibility, new policies can be added to handler easy, +- fix issues related to imsm controller domain verifying. + +Add superswitch function. It is used in next patches. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 54 ++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 36 insertions(+), 18 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 39b86bd0..889f4a0f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -940,6 +940,23 @@ struct reshape { + unsigned long long new_size; /* New size of array in sectors */ + }; + ++/** ++ * struct dev_policy - Data structure for policy management. ++ * @next: pointer to next dev_policy. ++ * @name: policy name, category. ++ * @metadata: the metadata type it affects. ++ * @value: value of the policy. ++ * ++ * The functions to manipulate dev_policy lists do not free elements, so they must be statically ++ * allocated. @name and @metadata can be compared by address. ++ */ ++typedef struct dev_policy { ++ struct dev_policy *next; ++ char *name; ++ const char *metadata; ++ const char *value; ++} dev_policy_t; ++ + /* A superswitch provides entry point to a metadata handler. + * + * The superswitch primarily operates on some "metadata" that +@@ -1168,6 +1185,25 @@ extern struct superswitch { + char *subdev, unsigned long long *freesize, + int consistency_policy, int verbose); + ++ /** ++ * test_and_add_drive_policies() - test new and add custom policies from metadata handler. ++ * @pols: list of currently recorded policies. ++ * @disk_fd: file descriptor of the device to check. ++ * @verbose: verbose flag. ++ * ++ * Used by IMSM to verify all drives in container/array, against requirements not recored ++ * in superblock, like controller type for IMSM. It should check all drives even if ++ * they are not actually used, because mdmon or kernel are free to use any drive assigned to ++ * container automatically. ++ * ++ * Generating and comparison methods belong to metadata handler. It is not mandatory to be ++ * implemented. ++ * ++ * Return: MDADM_STATUS_SUCCESS is expected on success. ++ */ ++ mdadm_status_t (*test_and_add_drive_policies)(dev_policy_t **pols, int disk_fd, ++ const int verbose); ++ + /* Return a linked list of 'mdinfo' structures for all arrays + * in the container. For non-containers, it is like + * getinfo_super with an allocated mdinfo.*/ +@@ -1372,23 +1408,6 @@ extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep); + extern int must_be_container(int fd); + void wait_for(char *dev, int fd); + +-/* +- * Data structures for policy management. +- * Each device can have a policy structure that lists +- * various name/value pairs each possibly with a metadata associated. +- * The policy list is sorted by name/value/metadata +- */ +-struct dev_policy { +- struct dev_policy *next; +- char *name; /* None of these strings are allocated. They are +- * all just references to strings which are known +- * to exist elsewhere. +- * name and metadata can be compared by address equality. +- */ +- const char *metadata; +- const char *value; +-}; +- + extern char pol_act[], pol_domain[], pol_metadata[], pol_auto[]; + + /* iterate over the sublist starting at list, having the same +@@ -1430,7 +1449,6 @@ extern struct dev_policy *disk_policy(struct mdinfo *disk); + extern struct dev_policy *devid_policy(int devid); + extern void dev_policy_free(struct dev_policy *p); + +-//extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata); + extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata); + extern struct dev_policy *pol_find(struct dev_policy *pol, char *name); + +-- +2.40.1 + diff --git a/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch b/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch new file mode 100644 index 0000000..b7bc9ce --- /dev/null +++ b/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch @@ -0,0 +1,144 @@ +From 5a2e194cb31569880a26356b8594ddca6e3b3828 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:11 +0100 +Subject: [PATCH 27/41] mdadm: test_and_add device policies implementation + +Add support for three scenarios: +- obtaining array wide policies via fd, +- obtaining array wide policies via struct mdinfo, +- getting policies for particular drive from the request. + +Add proper functions and make them extern. These functions are used +in next patches. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 7 +++++ + policy.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 100 insertions(+) + +diff --git a/mdadm.h b/mdadm.h +index 889f4a0f..af2bc714 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1452,6 +1452,13 @@ extern void dev_policy_free(struct dev_policy *p); + extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata); + extern struct dev_policy *pol_find(struct dev_policy *pol, char *name); + ++extern mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, ++ int fd, const int verbose); ++extern mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ struct mdinfo *mdi, const int verbose); ++extern mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ int array_fd, const int verbose); ++ + enum policy_action { + act_default, + act_include, +diff --git a/policy.c b/policy.c +index eee9ef63..4b85f62d 100644 +--- a/policy.c ++++ b/policy.c +@@ -397,6 +397,99 @@ struct dev_policy *path_policy(char **paths, char *type) + return pol; + } + ++/** ++ * drive_test_and_add_policies() - get policies for drive and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @fd: device descriptor. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. Use metadata handler to get ++ * policies. ++ */ ++mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, int fd, ++ const int verbose) ++{ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (st->ss->test_and_add_drive_policies(pols, fd, verbose) == MDADM_STATUS_SUCCESS) { ++ /* After successful call list cannot be empty */ ++ assert(*pols); ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ return MDADM_STATUS_ERROR; ++} ++ ++/** ++ * sysfs_test_and_add_policies() - get policies for mddev and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @mdi: mdinfo describes the MD array, must have GET_DISKS option. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. To get policies, all disks ++ * connected to mddev are analyzed. ++ */ ++mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ struct mdinfo *mdi, const int verbose) ++{ ++ struct mdinfo *sd; ++ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ for (sd = mdi->devs; sd; sd = sd->next) { ++ char *devpath = map_dev(sd->disk.major, sd->disk.minor, 0); ++ int fd = dev_open(devpath, O_RDONLY); ++ int rv; ++ ++ if (!is_fd_valid(fd)) { ++ pr_err("Cannot open fd for %s\n", devpath); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ rv = drive_test_and_add_policies(st, pols, fd, verbose); ++ close(fd); ++ ++ if (rv) ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * mddev_test_and_add_policies() - get policies for mddev and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @array_fd: MD device descriptor. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. Use fd to extract disks. ++ */ ++mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ int array_fd, const int verbose) ++{ ++ struct mdinfo *sra; ++ int ret; ++ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ sra = sysfs_read(array_fd, NULL, GET_DEVS); ++ if (!sra) { ++ pr_err("Cannot load sysfs for %s\n", fd2devnm(array_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ ret = sysfs_test_and_add_drive_policies(st, pols, sra, verbose); ++ ++ sysfs_free(sra); ++ return ret; ++} ++ + void pol_add(struct dev_policy **pol, + char *name, char *val, + char *metadata) +-- +2.40.1 + diff --git a/SOURCES/0028-Create-Use-device-policies.patch b/SOURCES/0028-Create-Use-device-policies.patch new file mode 100644 index 0000000..e49fea9 --- /dev/null +++ b/SOURCES/0028-Create-Use-device-policies.patch @@ -0,0 +1,124 @@ +From f5a39b66f794322f30828389ddd488d17f578ad5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:12 +0100 +Subject: [PATCH 28/41] Create: Use device policies + +Generate and compare policies, abort if policies do not match. +It is tested for both create modes, with container and disk list +specified directly. It is used if supertype supports it. + +For a case when disk list is specified, container may contain more +devices, so additional check on container is done to analyze all disks. + +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/Create.c b/Create.c +index 0b776266..4397ff49 100644 +--- a/Create.c ++++ b/Create.c +@@ -497,6 +497,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + */ + int mdfd; + unsigned long long minsize = 0, maxsize = 0; ++ dev_policy_t *custom_pols = NULL; + char *mindisc = NULL; + char *maxdisc = NULL; + char *name = ident->name; +@@ -588,6 +589,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + first_missing = subdevs * 2; + second_missing = subdevs * 2; + insert_point = subdevs * 2; ++ ++ if (mddev_test_and_add_drive_policies(st, &custom_pols, fd, 1)) ++ exit(1); + } + } + if (fd >= 0) +@@ -739,7 +743,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + close(dfd); + exit(2); + } +- close(dfd); ++ + info.array.working_disks++; + if (dnum < s->raiddisks && dv->disposition != 'j') + info.array.active_disks++; +@@ -812,6 +816,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + } + } + ++ if (drive_test_and_add_policies(st, &custom_pols, dfd, 1)) ++ exit(1); ++ ++ close(dfd); ++ + if (dv->disposition == 'j') + goto skip_size_check; /* skip write journal for size check */ + +@@ -886,6 +895,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + close(fd); + } + } ++ + if (missing_disks == dnum && !have_container) { + pr_err("Subdevs can't be all missing\n"); + return 1; +@@ -1140,25 +1150,30 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + goto abort_locked; + } + +- if (did_default && c->verbose >= 0) { ++ if (did_default) { + if (is_subarray(info.text_version)) { + char devnm[MD_NAME_MAX]; + struct mdinfo *mdi; + + sysfs_get_container_devnm(&info, devnm); + +- mdi = sysfs_read(-1, devnm, GET_VERSION); ++ mdi = sysfs_read(-1, devnm, GET_VERSION | GET_DEVS); + if (!mdi) { + pr_err("Cannot open sysfs for container %s\n", devnm); + goto abort_locked; + } + +- pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version, +- devnm); ++ if (sysfs_test_and_add_drive_policies(st, &custom_pols, mdi, 1)) ++ goto abort_locked; ++ ++ if (c->verbose >= 0) ++ pr_info("Creating array inside %s container /dev/%s\n", ++ mdi->text_version, devnm); + + sysfs_free(mdi); +- } else ++ } else if (c->verbose >= 0) { + pr_info("Defaulting to version %s metadata\n", info.text_version); ++ } + } + + map_update(&map, fd2devnm(mdfd), info.text_version, +@@ -1328,6 +1343,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + udev_unblock(); + close(mdfd); + sysfs_uevent(&info, "change"); ++ dev_policy_free(custom_pols); ++ + return 0; + + abort: +@@ -1339,5 +1356,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (mdfd >= 0) + close(mdfd); ++ ++ dev_policy_free(custom_pols); + return 1; + } +-- +2.40.1 + diff --git a/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch b/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch new file mode 100644 index 0000000..061f77c --- /dev/null +++ b/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch @@ -0,0 +1,60 @@ +From 1251db34616bf4890d86664abc5186e9106e9073 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:13 +0100 +Subject: [PATCH 29/41] Manage: check device policies in manage_add_external() + +Only IMSM is going to use device policies so it is added to +manage_add_external(). Test policies before adding the drive to +container. + +The change blocks adding new device to the container which already +contains not matching devices + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/Manage.c b/Manage.c +index 969d0ea9..96e5ee54 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -704,6 +704,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + { + mdadm_status_t rv = MDADM_STATUS_ERROR; + char container_devpath[MD_NAME_MAX]; ++ struct dev_policy *pols = NULL; + struct mdinfo new_mdi; + struct mdinfo *sra = NULL; + int container_fd; +@@ -722,6 +723,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + 0, 1)) + goto out; + ++ if (mddev_test_and_add_drive_policies(st, &pols, container_fd, 1)) ++ goto out; ++ + Kill(disk_name, NULL, 0, -1, 0); + + disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT); +@@ -730,6 +734,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + goto out; + } + ++ if (drive_test_and_add_policies(st, &pols, disk_fd, 1)) ++ goto out; ++ + if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS)) + goto out; + +@@ -760,6 +767,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + + out: + close(container_fd); ++ dev_policy_free(pols); + + if (sra) + sysfs_free(sra); +-- +2.40.1 + diff --git a/SOURCES/0030-Monitor-Incremental-use-device-policies.patch b/SOURCES/0030-Monitor-Incremental-use-device-policies.patch new file mode 100644 index 0000000..753ee8f --- /dev/null +++ b/SOURCES/0030-Monitor-Incremental-use-device-policies.patch @@ -0,0 +1,142 @@ +From 51a9f2fc5e982f3bcbf88fe1bf30c0bf55bfd49c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:14 +0100 +Subject: [PATCH 30/41] Monitor, Incremental: use device policies + +spare_criteria is expanded to contain policies which will be generated +by handler's get_spare_criteria() function. It provides a way to +test device for metadata specific policies earlier than during +add_do_super(), when device is already removed from previous +array/container for Monitor. + +For Incremental, it ensures that all criteria are tested when trying +spare. It is not tested when device contains valid metadata. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 2 +- + Monitor.c | 3 ++- + mdadm.h | 5 +++-- + util.c | 13 +++++++++---- + 4 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 66c2cc86..958ba9ba 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -865,7 +865,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch + goto out; + } + +- if (!disk_fd_matches_criteria(disk_fd, &sc)) { ++ if (!disk_fd_matches_criteria(dup, disk_fd, &sc)) { + if (verbose > 1) + pr_err("Disk does not match spare criteria for %s\n", container_devname); + goto out; +diff --git a/Monitor.c b/Monitor.c +index 6b4560ae..9b016bc3 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1047,7 +1047,7 @@ static dev_t choose_spare(struct state *from, struct state *to, + test_partition_from_id(from->devid[d])) + continue; + +- if (devid_matches_criteria(from->devid[d], sc) == false) ++ if (devid_matches_criteria(to->metadata, from->devid[d], sc) == false) + continue; + + pol = devid_policy(from->devid[d]); +@@ -1195,6 +1195,7 @@ static void try_spare_migration(struct state *statelist) + } + } + domain_free(domlist); ++ dev_policy_free(sc.pols); + } + } + +diff --git a/mdadm.h b/mdadm.h +index af2bc714..cfa11391 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -433,6 +433,7 @@ struct spare_criteria { + bool criteria_set; + unsigned long long min_size; + unsigned int sector_size; ++ struct dev_policy *pols; + }; + + typedef enum mdadm_status { +@@ -1734,8 +1735,8 @@ extern int assemble_container_content(struct supertype *st, int mdfd, + #define INCR_ALREADY 4 + #define INCR_YES 8 + +-extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc); +-extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc); ++extern bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc); ++extern bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc); + extern struct mdinfo *container_choose_spares(struct supertype *st, + struct spare_criteria *criteria, + struct domainlist *domlist, +diff --git a/util.c b/util.c +index 041e78cf..05ad3343 100644 +--- a/util.c ++++ b/util.c +@@ -2056,12 +2056,13 @@ unsigned int __invalid_size_argument_for_IOC = 0; + + /** + * disk_fd_matches_criteria() - check if device matches spare criteria. ++ * @st: supertype, not NULL. + * @disk_fd: file descriptor of the disk. + * @sc: criteria to test. + * + * Return: true if disk matches criteria, false otherwise. + */ +-bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) ++bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc) + { + unsigned int dev_sector_size = 0; + unsigned long long dev_size = 0; +@@ -2076,17 +2077,21 @@ bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) + sc->sector_size != dev_sector_size) + return false; + ++ if (drive_test_and_add_policies(st, &sc->pols, disk_fd, 0)) ++ return false; ++ + return true; + } + + /** + * devid_matches_criteria() - check if device referenced by devid matches spare criteria. ++ * @st: supertype, not NULL. + * @devid: devid of the device to check. + * @sc: criteria to test. + * + * Return: true if disk matches criteria, false otherwise. + */ +-bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) ++bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc) + { + char buf[NAME_MAX]; + bool ret; +@@ -2102,7 +2107,7 @@ bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) + return false; + + /* Error code inherited */ +- ret = disk_fd_matches_criteria(fd, sc); ++ ret = disk_fd_matches_criteria(st, fd, sc); + + close(fd); + return ret; +@@ -2137,7 +2142,7 @@ struct mdinfo *container_choose_spares(struct supertype *st, + if (d->disk.state == 0) { + dev_t dev = makedev(d->disk.major,d->disk.minor); + +- found = devid_matches_criteria(dev, criteria); ++ found = devid_matches_criteria(st, dev, criteria); + + /* check if domain matches */ + if (found && domlist) { +-- +2.40.1 + diff --git a/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch b/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch new file mode 100644 index 0000000..86161d4 --- /dev/null +++ b/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch @@ -0,0 +1,187 @@ +From e21aea08eb706939a38f7dc5cf9509a9afd45f8a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:15 +0100 +Subject: [PATCH 31/41] imsm: test_and_add_device_policies() implementation + +This patch removes get_disk_controller_domain_imsm() in favour of +test_and_add_device_policies_imsm(). It is used by +create, add and mdmonitor. + +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.h | 1 - + super-intel.c | 123 ++++++++++++++++++++++++++++++++++------------- + 2 files changed, 90 insertions(+), 34 deletions(-) + +diff --git a/platform-intel.h b/platform-intel.h +index ce29d3da..3c2bc595 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -262,7 +262,6 @@ int disk_attached_to_hba(int fd, const char *hba_path); + int devt_attached_to_hba(dev_t dev, const char *hba_path); + char *devt_to_devpath(dev_t dev, int dev_level, char *buf); + int path_attached_to_hba(const char *disk_path, const char *hba_path); +-const char *get_sys_dev_type(enum sys_dev_type); + const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id); + const struct imsm_orom *get_orom_by_device_id(__u16 device_id); + struct sys_dev *device_by_id(__u16 device_id); +diff --git a/super-intel.c b/super-intel.c +index 7ad391ac..77140455 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11220,39 +11220,90 @@ abort: + return retval; + } + +-static char disk_by_path[] = "/dev/disk/by-path/"; +- +-static const char *imsm_get_disk_controller_domain(const char *path) +-{ +- char disk_path[PATH_MAX]; +- char *drv=NULL; +- struct stat st; +- +- strncpy(disk_path, disk_by_path, PATH_MAX); +- strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1); +- if (stat(disk_path, &st) == 0) { +- struct sys_dev* hba; +- char *path; +- +- path = devt_to_devpath(st.st_rdev, 1, NULL); +- if (path == NULL) +- return "unknown"; +- hba = find_disk_attached_hba(-1, path); +- if (hba && hba->type == SYS_DEV_SAS) +- drv = "isci"; +- else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD)) +- drv = "ahci"; +- else if (hba && hba->type == SYS_DEV_VMD) +- drv = "vmd"; +- else if (hba && hba->type == SYS_DEV_NVME) +- drv = "nvme"; +- else +- drv = "unknown"; +- dprintf("path: %s hba: %s attached: %s\n", +- path, (hba) ? hba->path : "NULL", drv); +- free(path); ++/** ++ * test_and_add_drive_controller_policy_imsm() - add disk controller to policies list. ++ * @type: Policy type to search on list. ++ * @pols: List of currently recorded policies. ++ * @disk_fd: File descriptor of the device to check. ++ * @hba: The hba disk is attached, could be NULL if verification is disabled. ++ * @verbose: verbose flag. ++ * ++ * IMSM cares about drive physical placement. If @hba is not set, it adds unknown policy. ++ * If there is no controller policy on pols we are free to add first one. If there is a policy then, ++ * new must be the same - no controller mixing allowed. ++ */ ++static mdadm_status_t ++test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose) ++{ ++ const char *controller_policy = get_sys_dev_type(SYS_DEV_UNKNOWN); ++ struct dev_policy *pol = pol_find(*pols, (char *)type); ++ char devname[MAX_RAID_SERIAL_LEN]; ++ ++ if (hba) ++ controller_policy = get_sys_dev_type(hba->type); ++ ++ if (!pol) { ++ pol_add(pols, (char *)type, (char *)controller_policy, "imsm"); ++ return MDADM_STATUS_SUCCESS; + } +- return drv; ++ ++ if (strcmp(pol->value, controller_policy) == 0) ++ return MDADM_STATUS_SUCCESS; ++ ++ fd2devname(disk_fd, devname); ++ pr_vrb("Intel(R) raid controller \"%s\" found for %s, but \"%s\" was detected earlier\n", ++ controller_policy, devname, pol->value); ++ pr_vrb("Disks under different controllers cannot be used, aborting\n"); ++ ++ return MDADM_STATUS_ERROR; ++} ++ ++struct imsm_drive_policy { ++ char *type; ++ mdadm_status_t (*test_and_add_drive_policy)(const char * const type, ++ struct dev_policy **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose); ++}; ++ ++struct imsm_drive_policy imsm_policies[] = { ++ {"controller", test_and_add_drive_controller_policy_imsm}, ++}; ++ ++mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd, ++ const int verbose) ++{ ++ struct imsm_drive_policy *imsm_pol; ++ struct sys_dev *hba = NULL; ++ char path[PATH_MAX]; ++ mdadm_status_t ret; ++ unsigned int i; ++ ++ /* If imsm platform verification is disabled, do not search for hba. */ ++ if (check_no_platform() != 1) { ++ if (!diskfd_to_devpath(disk_fd, 1, path)) { ++ pr_vrb("IMSM: Failed to retrieve device path by file descriptor.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ hba = find_disk_attached_hba(disk_fd, path); ++ if (!hba) { ++ pr_vrb("IMSM: Failed to find hba for %s\n", path); ++ return MDADM_STATUS_ERROR; ++ } ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(imsm_policies); i++) { ++ imsm_pol = &imsm_policies[i]; ++ ++ ret = imsm_pol->test_and_add_drive_policy(imsm_pol->type, pols, disk_fd, hba, ++ verbose); ++ if (ret != MDADM_STATUS_SUCCESS) ++ /* Inherit error code */ ++ return ret; ++ } ++ ++ return MDADM_STATUS_SUCCESS; + } + + /** +@@ -11280,6 +11331,7 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, + + if (mddev_path) { + int fd = open(mddev_path, O_RDONLY); ++ mdadm_status_t rv; + + if (!is_fd_valid(fd)) + return MDADM_STATUS_ERROR; +@@ -11291,7 +11343,12 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, + } + free_superblock = true; + } ++ ++ rv = mddev_test_and_add_drive_policies(st, &c->pols, fd, 0); + close(fd); ++ ++ if (rv != MDADM_STATUS_SUCCESS) ++ goto out; + } + + super = st->sb; +@@ -13026,7 +13083,7 @@ struct superswitch super_imsm = { + .update_subarray = update_subarray_imsm, + .load_container = load_container_imsm, + .default_geometry = default_geometry_imsm, +- .get_disk_controller_domain = imsm_get_disk_controller_domain, ++ .test_and_add_drive_policies = test_and_add_drive_policies_imsm, + .reshape_super = imsm_reshape_super, + .manage_reshape = imsm_manage_reshape, + .recover_backup = recover_backup_imsm, +-- +2.40.1 + diff --git a/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch b/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch new file mode 100644 index 0000000..be22fdf --- /dev/null +++ b/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch @@ -0,0 +1,75 @@ +From e492d2ac143e7f02d6c262130d42a4422e8295d5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:16 +0100 +Subject: [PATCH 32/41] mdadm: drop get_disk_controller_domain() + +This function is unused now. Drop it. +Controller for IMSM is a device policy and is separated from user defined +domains. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 15 --------------- + policy.c | 13 ------------- + 2 files changed, 28 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index cfa11391..3fedca48 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1286,21 +1286,6 @@ extern struct superswitch { + */ + struct mdinfo *(*activate_spare)(struct active_array *a, + struct metadata_update **updates); +- /* +- * Return statically allocated string that represents metadata specific +- * controller domain of the disk. The domain is used in disk domain +- * matching functions. Disks belong to the same domain if the they have +- * the same domain from mdadm.conf and belong the same metadata domain. +- * Returning NULL or not providing this handler means that metadata +- * does not distinguish the differences between disks that belong to +- * different controllers. They are in the domain specified by +- * configuration file (mdadm.conf). +- * In case when the metadata has the notion of domains based on disk +- * it shall return NULL for disks that do not belong to the controller +- * the supported domains. Such disks will form another domain and won't +- * be mixed with supported ones. +- */ +- const char *(*get_disk_controller_domain)(const char *path); + + /* for external backup area */ + int (*recover_backup)(struct supertype *st, struct mdinfo *info); +diff --git a/policy.c b/policy.c +index 4b85f62d..404f9b5d 100644 +--- a/policy.c ++++ b/policy.c +@@ -365,7 +365,6 @@ struct dev_policy *path_policy(char **paths, char *type) + { + struct pol_rule *rules; + struct dev_policy *pol = NULL; +- int i; + + rules = config_rules; + +@@ -380,18 +379,6 @@ struct dev_policy *path_policy(char **paths, char *type) + rules = rules->next; + } + +- /* Now add any metadata-specific internal knowledge +- * about this path +- */ +- for (i=0; paths && paths[0] && superlist[i]; i++) +- if (superlist[i]->get_disk_controller_domain) { +- const char *d = +- superlist[i]->get_disk_controller_domain( +- paths[0]); +- if (d) +- pol_new(&pol, pol_domain, d, superlist[i]->name); +- } +- + pol_sort(&pol); + pol_dedup(pol); + return pol; +-- +2.40.1 + diff --git a/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch b/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch new file mode 100644 index 0000000..b38a1da --- /dev/null +++ b/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch @@ -0,0 +1,42 @@ +From 933bb500b80cca6f4e9237382f7d8ac852978471 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:17 +0100 +Subject: [PATCH 33/41] Revert "policy.c: Avoid to take spare without defined + domain by imsm" + +This reverts commit 3bf9495270d7 ("policy.c: Avoid to take spare without +defined domain by imsm"). + +IMSM does not require to be special now because it doesn't create disk +controller domain. + +Signed-off-by: Mariusz Tkaczyk +--- + policy.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/policy.c b/policy.c +index 404f9b5d..dfaafdc0 100644 +--- a/policy.c ++++ b/policy.c +@@ -759,7 +759,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + * 1: has domains, all match + */ + int found_any = -1; +- int has_one_domain = 1; + struct dev_policy *p; + + pol = pol_find(pol, pol_domain); +@@ -769,9 +768,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + dom = dom->next; + if (!dom || strcmp(dom->dom, p->value) != 0) + return 0; +- if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0) +- found_any = -1; +- has_one_domain = 0; + } + return found_any; + } +-- +2.40.1 + diff --git a/SOURCES/0034-mdadm-remove-inventory-file.patch b/SOURCES/0034-mdadm-remove-inventory-file.patch new file mode 100644 index 0000000..ee9bb97 --- /dev/null +++ b/SOURCES/0034-mdadm-remove-inventory-file.patch @@ -0,0 +1,307 @@ +From 9c63130e8974033969569fb9d0b373d1d1478cf7 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 6 Mar 2024 13:45:53 +0100 +Subject: [PATCH 34/41] mdadm: remove inventory file + +It is a file with repo content list. It is outdated already. +Remove it. + +Signed-off-by: Mariusz Tkaczyk +--- + inventory | 284 ------------------------------------------------------ + 1 file changed, 284 deletions(-) + delete mode 100755 inventory + +diff --git a/inventory b/inventory +deleted file mode 100755 +index c4801b49..00000000 +--- a/inventory ++++ /dev/null +@@ -1,284 +0,0 @@ +- +-.gitignore +-ANNOUNCE-3.0 +-ANNOUNCE-3.0.1 +-ANNOUNCE-3.0.2 +-ANNOUNCE-3.0.3 +-ANNOUNCE-3.1 +-ANNOUNCE-3.1.1 +-ANNOUNCE-3.1.2 +-ANNOUNCE-3.1.3 +-ANNOUNCE-3.1.4 +-ANNOUNCE-3.1.5 +-ANNOUNCE-3.2 +-ANNOUNCE-3.2.1 +-ANNOUNCE-3.2.2 +-ANNOUNCE-3.2.3 +-ANNOUNCE-3.2.4 +-ANNOUNCE-3.2.5 +-ANNOUNCE-3.2.6 +-ANNOUNCE-3.3 +-ANNOUNCE-3.3.1 +-ANNOUNCE-3.3.2 +-ANNOUNCE-3.3.3 +-ANNOUNCE-3.3.4 +-ANNOUNCE-3.4 +-ANNOUNCE-4.0 +-ANNOUNCE-4.1 +-ANNOUNCE-4.2 +-Assemble.c +-Build.c +-COPYING +-ChangeLog +-Create.c +-Detail.c +-Dump.c +-Examine.c +-Grow.c +-INSTALL +-Incremental.c +-Kill.c +-Makefile +-Manage.c +-Monitor.c +-Query.c +-README.initramfs +-ReadMe.c +-TODO +-bitmap.c +-bitmap.h +-clustermd_tests/ +-clustermd_tests/00r10_Create +-clustermd_tests/00r1_Create +-clustermd_tests/01r10_Grow_bitmap-switch +-clustermd_tests/01r10_Grow_resize +-clustermd_tests/01r1_Grow_add +-clustermd_tests/01r1_Grow_bitmap-switch +-clustermd_tests/01r1_Grow_resize +-clustermd_tests/02r10_Manage_add +-clustermd_tests/02r10_Manage_add-spare +-clustermd_tests/02r10_Manage_re-add +-clustermd_tests/02r1_Manage_add +-clustermd_tests/02r1_Manage_add-spare +-clustermd_tests/02r1_Manage_re-add +-clustermd_tests/03r10_switch-recovery +-clustermd_tests/03r10_switch-resync +-clustermd_tests/03r1_switch-recovery +-clustermd_tests/03r1_switch-resync +-clustermd_tests/cluster_conf +-clustermd_tests/func.sh +-config.c +-coverity-gcc-hack.h +-crc32.c +-crc32.h +-crc32c.c +-dlink.c +-dlink.h +-external-reshape-design.txt +-inventory +-lib.c +-makedist +-managemon.c +-mapfile.c +-maps.c +-md.4 +-md5.h +-md_p.h +-md_u.h +-mdadm.8.in +-mdadm.c +-mdadm.conf-example +-mdadm.conf.5 +-mdadm.h +-mdadm.spec +-mdmon-design.txt +-mdmon.8 +-mdmon.c +-mdmon.h +-mdopen.c +-mdstat.c +-misc/ +-misc/mdcheck +-misc/syslog-events +-mkinitramfs +-monitor.c +-msg.c +-msg.h +-part.h +-platform-intel.c +-platform-intel.h +-policy.c +-probe_roms.c +-probe_roms.h +-pwgr.c +-raid5extend.c +-raid6check.8 +-raid6check.c +-restripe.c +-sg_io.c +-sha1.c +-sha1.h +-super-ddf.c +-super-gpt.c +-super-intel.c +-super-mbr.c +-super0.c +-super1.c +-swap_super.c +-sysfs.c +-systemd/ +-systemd/SUSE-mdadm_env.sh +-systemd/mdadm-grow-continue@.service +-systemd/mdadm-last-resort@.service +-systemd/mdadm-last-resort@.timer +-systemd/mdadm.shutdown +-systemd/mdcheck_continue.service +-systemd/mdcheck_continue.timer +-systemd/mdcheck_start.service +-systemd/mdcheck_start.timer +-systemd/mdmon@.service +-systemd/mdmonitor-oneshot.service +-systemd/mdmonitor-oneshot.timer +-systemd/mdmonitor.service +-test +-tests/ +-tests/00linear +-tests/00multipath +-tests/00names +-tests/00raid0 +-tests/00raid1 +-tests/00raid10 +-tests/00raid4 +-tests/00raid5 +-tests/00raid6 +-tests/00readonly +-tests/01r1fail +-tests/01r5fail +-tests/01r5integ +-tests/01raid6integ +-tests/01replace +-tests/02lineargrow +-tests/02r1add +-tests/02r1grow +-tests/02r5grow +-tests/02r6grow +-tests/03assem-incr +-tests/03r0assem +-tests/03r5assem +-tests/03r5assem-failed +-tests/03r5assemV1 +-tests/04r0update +-tests/04r1update +-tests/04r5swap +-tests/04update-metadata +-tests/04update-uuid +-tests/05r1-add-internalbitmap +-tests/05r1-add-internalbitmap-v1a +-tests/05r1-add-internalbitmap-v1b +-tests/05r1-add-internalbitmap-v1c +-tests/05r1-bitmapfile +-tests/05r1-failfast +-tests/05r1-grow-external +-tests/05r1-grow-internal +-tests/05r1-grow-internal-1 +-tests/05r1-internalbitmap +-tests/05r1-internalbitmap-v1a +-tests/05r1-internalbitmap-v1b +-tests/05r1-internalbitmap-v1c +-tests/05r1-n3-bitmapfile +-tests/05r1-re-add +-tests/05r1-re-add-nosuper +-tests/05r1-remove-internalbitmap +-tests/05r1-remove-internalbitmap-v1a +-tests/05r1-remove-internalbitmap-v1b +-tests/05r1-remove-internalbitmap-v1c +-tests/05r5-bitmapfile +-tests/05r5-internalbitmap +-tests/05r6-bitmapfile +-tests/05r6tor0 +-tests/06name +-tests/06sysfs +-tests/06wrmostly +-tests/07autoassemble +-tests/07autodetect +-tests/07changelevelintr +-tests/07changelevels +-tests/07layouts +-tests/07reshape5intr +-tests/07revert-grow +-tests/07revert-inplace +-tests/07revert-shrink +-tests/07testreshape5 +-tests/09imsm-assemble +-tests/09imsm-create-fail-rebuild +-tests/09imsm-overlap +-tests/10ddf-assemble-missing +-tests/10ddf-create +-tests/10ddf-create-fail-rebuild +-tests/10ddf-fail-create-race +-tests/10ddf-fail-readd +-tests/10ddf-fail-readd-readonly +-tests/10ddf-fail-spare +-tests/10ddf-fail-stop-readd +-tests/10ddf-fail-twice +-tests/10ddf-fail-two-spares +-tests/10ddf-geometry +-tests/10ddf-incremental-wrong-order +-tests/10ddf-sudden-degraded +-tests/11spare-migration +-tests/12imsm-r0_2d-grow-r0_3d +-tests/12imsm-r0_2d-grow-r0_4d +-tests/12imsm-r0_2d-grow-r0_5d +-tests/12imsm-r0_3d-grow-r0_4d +-tests/12imsm-r5_3d-grow-r5_4d +-tests/12imsm-r5_3d-grow-r5_5d +-tests/13imsm-r0_r0_2d-grow-r0_r0_4d +-tests/13imsm-r0_r0_2d-grow-r0_r0_5d +-tests/13imsm-r0_r0_3d-grow-r0_r0_4d +-tests/13imsm-r0_r5_3d-grow-r0_r5_4d +-tests/13imsm-r0_r5_3d-grow-r0_r5_5d +-tests/13imsm-r5_r0_3d-grow-r5_r0_4d +-tests/13imsm-r5_r0_3d-grow-r5_r0_5d +-tests/14imsm-r0_3d-r5_3d-migrate-r5_4d-r5_4d +-tests/14imsm-r0_3d_no_spares-migrate-r5_3d +-tests/14imsm-r0_r0_2d-takeover-r10_4d +-tests/14imsm-r10_4d-grow-r10_5d +-tests/14imsm-r10_r5_4d-takeover-r0_2d +-tests/14imsm-r1_2d-grow-r1_3d +-tests/14imsm-r1_2d-takeover-r0_2d +-tests/14imsm-r5_3d-grow-r5_5d-no-spares +-tests/14imsm-r5_3d-migrate-r4_3d +-tests/15imsm-r0_3d_64k-migrate-r0_3d_256k +-tests/15imsm-r5_3d_4k-migrate-r5_3d_256k +-tests/15imsm-r5_3d_64k-migrate-r5_3d_256k +-tests/15imsm-r5_6d_4k-migrate-r5_6d_256k +-tests/15imsm-r5_r0_3d_64k-migrate-r5_r0_3d_256k +-tests/16imsm-r0_3d-migrate-r5_4d +-tests/16imsm-r0_5d-migrate-r5_6d +-tests/16imsm-r5_3d-migrate-r0_3d +-tests/16imsm-r5_5d-migrate-r0_5d +-tests/18imsm-1d-takeover-r0_1d +-tests/18imsm-1d-takeover-r1_2d +-tests/18imsm-r0_2d-takeover-r10_4d +-tests/18imsm-r10_4d-takeover-r0_2d +-tests/18imsm-r1_2d-takeover-r0_1d +-tests/19raid6auto-repair +-tests/19raid6check +-tests/19raid6repair +-tests/19repair-does-not-destroy +-tests/20raid5journal +-tests/21raid5cache +-tests/ToTest +-tests/env-ddf-template +-tests/env-imsm-template +-tests/func.sh +-tests/imsm-grow-template +-tests/utils +-udev-md-clustered-confirm-device.rules +-udev-md-raid-arrays.rules +-udev-md-raid-assembly.rules +-udev-md-raid-creating.rules +-udev-md-raid-safe-timeouts.rules +-util.c +-uuid.c +-xmalloc.c +-- +2.40.1 + diff --git a/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch b/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch new file mode 100644 index 0000000..084bbc4 --- /dev/null +++ b/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch @@ -0,0 +1,31 @@ +From 1750758c7ff526e3560433f6235e5cfa35cf646a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 6 Mar 2024 15:50:55 +0100 +Subject: [PATCH 35/41] udev.c: Do not require libudev.h if DNO_LIBUDEV + +libudev may not be presented at all, do not require it. + +Reported-by: Boian Bonev +Signed-off-by: Mariusz Tkaczyk +--- + udev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/udev.c b/udev.c +index bc4722b0..066e6ab1 100644 +--- a/udev.c ++++ b/udev.c +@@ -26,7 +26,10 @@ + #include + #include + #include ++ ++#ifndef NO_LIBUDEV + #include ++#endif + + static char *unblock_path; + +-- +2.40.1 + diff --git a/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch b/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch new file mode 100644 index 0000000..c3c0ced --- /dev/null +++ b/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch @@ -0,0 +1,29 @@ +From 8bda86099089b44129ef6206764f9de47a45f0db Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin +Date: Tue, 12 Mar 2024 11:01:50 +0100 +Subject: [PATCH 36/41] util.c: add limits.h include for NAME_MAX definition + +Add limits.h include for NAME_MAX definition. + +Signed-off-by: Alexander Kanavin +Signed-off-by: Mariusz Tkaczyk +--- + util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util.c b/util.c +index 05ad3343..49a9c6e2 100644 +--- a/util.c ++++ b/util.c +@@ -36,7 +36,7 @@ + #include + #include + #include +- ++#include + + /* + * following taken from linux/blkpg.h because they aren't +-- +2.40.1 + diff --git a/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch b/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch new file mode 100644 index 0000000..b8c77e8 --- /dev/null +++ b/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch @@ -0,0 +1,59 @@ +From 1c8327950566449e206e613c11c8232032f26787 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 16:19:29 +0100 +Subject: [PATCH 37/41] mdadm: set swapuuid in all handlers + +It is not set, so it should be 0 but it may vary on compilation +settings. Set it always to 0. + +metadata should care to set UUID and read in proper endianness so it +doesn't follow super1 concept of swapuuid to depend on endianness. + +It is not an attempt to fix endianness issues. + +Signed-off-by: Mariusz Tkaczyk +--- + super-ddf.c | 1 + + super-intel.c | 1 + + super0.c | 2 ++ + 3 files changed, 4 insertions(+) + +diff --git a/super-ddf.c b/super-ddf.c +index 7571e3b7..94ac5ff3 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -5162,6 +5162,7 @@ struct superswitch super_ddf = { + .default_geometry = default_geometry_ddf, + + .external = 1, ++ .swapuuid = 0, + + /* for mdmon */ + .open_new = ddf_open_new, +diff --git a/super-intel.c b/super-intel.c +index 77140455..e1754f29 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -13116,6 +13116,7 @@ struct superswitch super_imsm = { + .validate_ppl = validate_ppl_imsm, + + .external = 1, ++ .swapuuid = 0, + .name = "imsm", + + /* for mdmon */ +diff --git a/super0.c b/super0.c +index a7c5f813..9b8a1bd6 100644 +--- a/super0.c ++++ b/super0.c +@@ -1369,5 +1369,7 @@ struct superswitch super0 = { + .locate_bitmap = locate_bitmap0, + .write_bitmap = write_bitmap0, + .free_super = free_super0, ++ ++ .swapuuid = 0, + .name = "0.90", + }; +-- +2.40.1 + diff --git a/SOURCES/0038-mdadm-Fix-native-detail-export.patch b/SOURCES/0038-mdadm-Fix-native-detail-export.patch new file mode 100644 index 0000000..74d7084 --- /dev/null +++ b/SOURCES/0038-mdadm-Fix-native-detail-export.patch @@ -0,0 +1,247 @@ +From ba65d917d121dfb9876053e6f62dbd4ebf2e028c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 16:19:30 +0100 +Subject: [PATCH 38/41] mdadm: Fix native --detail --export + +Mentioned commit (see Fixes) causes that UUID is not swapped as expected +for native superblock. Fix this problem. + +For detail, we should avoid superblock calls, we can have information +about supertype from map, use that. + +Simplify fname_from_uuid() by removing dependencies to metadata +handler, it is not needed. Decision is taken at compile time, expect +super1 but this function is not used by super1. Add warning about that. +Remove separator, it is always ':'. + +Fixes: 60c19530dd7c ("Detail: remove duplicated code") +Signed-off-by: Mariusz Tkaczyk +--- + Detail.c | 26 +++++++++++++++++++++++++- + mdadm.h | 3 +-- + super-ddf.c | 10 +++++----- + super-intel.c | 16 ++++++++-------- + util.c | 24 +++++++++++++----------- + 5 files changed, 52 insertions(+), 27 deletions(-) + +diff --git a/Detail.c b/Detail.c +index f23ec16f..55a086d3 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -49,6 +49,30 @@ static int add_device(const char *dev, char ***p_devices, + return n_devices + 1; + } + ++/** ++ * detail_fname_from_uuid() - generate uuid string with special super1 handling. ++ * @mp: map entry to parse. ++ * @buf: buf to write. ++ * ++ * Hack to workaround an issue with super1 superblocks. It swapuuid set in order for assembly ++ * to work, but can't have it set if we want this printout to match all the other uuid printouts ++ * in super1.c, so we force swapuuid to 1 to make our printout match the rest of super1. ++ * ++ * Always convert uuid if host is big endian. ++ */ ++char *detail_fname_from_uuid(struct map_ent *mp, char *buf) ++{ ++#if __BYTE_ORDER == BIG_ENDIAN ++ bool swap = true; ++#else ++ bool swap = false; ++#endif ++ if (strncmp(mp->metadata, "1.", 2) == 0) ++ swap = true; ++ ++ return __fname_from_uuid(mp->uuid, swap, buf, ':'); ++} ++ + int Detail(char *dev, struct context *c) + { + /* +@@ -256,7 +280,7 @@ int Detail(char *dev, struct context *c) + mp = map_by_devnm(&map, fd2devnm(fd)); + + if (mp) { +- __fname_from_uuid(mp->uuid, 0, nbuf, ':'); ++ detail_fname_from_uuid(mp, nbuf); + printf("MD_UUID=%s\n", nbuf + 5); + if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) + printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); +diff --git a/mdadm.h b/mdadm.h +index 3fedca48..a363708a 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1696,8 +1696,7 @@ extern const int uuid_zero[4]; + extern int same_uuid(int a[4], int b[4], int swapuuid); + extern void copy_uuid(void *a, int b[4], int swapuuid); + extern char *__fname_from_uuid(int id[4], int swap, char *buf, char sep); +-extern char *fname_from_uuid(struct supertype *st, +- struct mdinfo *info, char *buf, char sep); ++extern char *fname_from_uuid(struct mdinfo *info, char *buf); + extern unsigned long calc_csum(void *super, int bytes); + extern int enough(int level, int raid_disks, int layout, int clean, + char *avail); +diff --git a/super-ddf.c b/super-ddf.c +index 94ac5ff3..21426c75 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1617,7 +1617,7 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose) + struct mdinfo info; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + + printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5); + } +@@ -1632,7 +1632,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + unsigned int i; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + + for (i = 0; i < be16_to_cpu(ddf->virt->max_vdes); i++) { + struct virtual_entry *ve = &ddf->virt->entries[i]; +@@ -1645,7 +1645,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + ddf->currentconf =&vcl; + vcl.vcnum = i; + uuid_from_super_ddf(st, info.uuid); +- fname_from_uuid(st, &info, nbuf1, ':'); ++ fname_from_uuid(&info, nbuf1); + _ddf_array_name(namebuf, ddf, i); + printf("ARRAY%s%s container=%s member=%d UUID=%s\n", + namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf, +@@ -1658,7 +1658,7 @@ static void export_examine_super_ddf(struct supertype *st) + struct mdinfo info; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("MD_METADATA=ddf\n"); + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); +@@ -1798,7 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st, char *subarray) + return; + else + uuid_of_ddf_subarray(ddf, vcnum, info.uuid); +- fname_from_uuid(st, &info, nbuf,':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID=%s", nbuf + 5); + } + +diff --git a/super-intel.c b/super-intel.c +index e1754f29..ff2590fe 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2217,7 +2217,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + else + printf("not supported\n"); + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID : %s\n", nbuf + 5); + sum = __le32_to_cpu(mpb->check_sum); + printf(" Checksum : %08x %s\n", sum, +@@ -2242,7 +2242,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + + super->current_vol = i; + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + print_imsm_dev(super, dev, nbuf + 5, super->disks->index); + } + for (i = 0; i < mpb->num_disks; i++) { +@@ -2267,7 +2267,7 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose) + char nbuf[64]; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("ARRAY metadata=imsm UUID=%s\n", nbuf + 5); + } + +@@ -2284,13 +2284,13 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose) + return; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + for (i = 0; i < super->anchor->num_raid_devs; i++) { + struct imsm_dev *dev = get_imsm_dev(super, i); + + super->current_vol = i; + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf1, ':'); ++ fname_from_uuid(&info, nbuf1); + printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n", + dev->volume, nbuf + 5, i, nbuf1 + 5); + } +@@ -2304,7 +2304,7 @@ static void export_examine_super_imsm(struct supertype *st) + char nbuf[64]; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("MD_METADATA=imsm\n"); + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); +@@ -2324,7 +2324,7 @@ static void detail_super_imsm(struct supertype *st, char *homehost, + super->current_vol = strtoul(subarray, NULL, 10); + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("\n UUID : %s\n", nbuf + 5); + + super->current_vol = temp_vol; +@@ -2341,7 +2341,7 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray) + super->current_vol = strtoul(subarray, NULL, 10); + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID=%s", nbuf + 5); + + super->current_vol = temp_vol; +diff --git a/util.c b/util.c +index 49a9c6e2..03336d6f 100644 +--- a/util.c ++++ b/util.c +@@ -589,19 +589,21 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep) + + } + +-char *fname_from_uuid(struct supertype *st, struct mdinfo *info, +- char *buf, char sep) +-{ +- // dirty hack to work around an issue with super1 superblocks... +- // super1 superblocks need swapuuid set in order for assembly to +- // work, but can't have it set if we want this printout to match +- // all the other uuid printouts in super1.c, so we force swapuuid +- // to 1 to make our printout match the rest of super1 ++/** ++ * fname_from_uuid() - generate uuid string. Should not be used with super1. ++ * @info: info with uuid ++ * @buf: buf to fill. ++ * ++ * This routine should not be used with super1. See detail_fname_from_uuid() for details. It does ++ * not use superswitch swapuuid as it should be 0 but it has to do UUID conversion if host is big ++ * endian- left for backward compatibility. ++ */ ++char *fname_from_uuid(struct mdinfo *info, char *buf) ++{ + #if __BYTE_ORDER == BIG_ENDIAN +- return __fname_from_uuid(info->uuid, 1, buf, sep); ++ return __fname_from_uuid(info->uuid, true, buf, ':'); + #else +- return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : +- st->ss->swapuuid, buf, sep); ++ return __fname_from_uuid(info->uuid, false, buf, ':'); + #endif + } + +-- +2.40.1 + diff --git a/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch b/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch new file mode 100644 index 0000000..c84146e --- /dev/null +++ b/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch @@ -0,0 +1,87 @@ +From de23e12a39cfc94575e1173293fe9e15337ee999 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 18 Mar 2024 16:53:31 +0100 +Subject: [PATCH 39/41] sysfs: remove vers parameter from sysfs_set_array + +9003 was passed directly to sysfs_set_array() since md_get_version() +always returned this value. md_get_version() was removed long ago. + +Remove dead version check from sysfs_set_array(). +Remove "vers" argument and fix function calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 2 +- + mdadm.h | 2 +- + sysfs.c | 6 ++---- + util.c | 3 +-- + 4 files changed, 5 insertions(+), 8 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9d042055..f6c5b99e 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1988,7 +1988,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + * and ignoring special character on the first place. + */ + if (strcmp(sra->text_version + 1, content->text_version + 1) != 0) { +- if (sysfs_set_array(content, 9003) != 0) { ++ if (sysfs_set_array(content) != 0) { + sysfs_free(sra); + return 1; + } +diff --git a/mdadm.h b/mdadm.h +index a363708a..ae2106a2 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -811,7 +811,7 @@ extern int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev, + extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev, + char *name, char *val, int size); + extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms); +-extern int sysfs_set_array(struct mdinfo *info, int vers); ++extern int sysfs_set_array(struct mdinfo *info); + extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume); + extern int sysfs_disk_to_scsi_id(int fd, __u32 *id); + extern int sysfs_unique_holder(char *devnm, long rdev); +diff --git a/sysfs.c b/sysfs.c +index 230b842e..4ded1672 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -678,7 +678,7 @@ int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms) + return sysfs_set_str(sra, NULL, "safe_mode_delay", delay); + } + +-int sysfs_set_array(struct mdinfo *info, int vers) ++int sysfs_set_array(struct mdinfo *info) + { + int rv = 0; + char ver[100]; +@@ -702,9 +702,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) + if (strlen(buf) >= 9 && buf[9] == '-') + ver[9] = '-'; + +- if ((vers % 100) < 2 || +- sysfs_set_str(info, NULL, "metadata_version", +- ver) < 0) { ++ if (sysfs_set_str(info, NULL, "metadata_version", ver) < 0) { + pr_err("This kernel does not support external metadata.\n"); + return 1; + } +diff --git a/util.c b/util.c +index 03336d6f..9e837045 100644 +--- a/util.c ++++ b/util.c +@@ -1867,8 +1867,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + int rv; + + if (st->ss->external) +- return sysfs_set_array(info, 9003); +- ++ return sysfs_set_array(info); + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; + inf.minor_version = info->array.minor_version; +-- +2.40.1 + diff --git a/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch b/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch new file mode 100644 index 0000000..80df278 --- /dev/null +++ b/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch @@ -0,0 +1,55 @@ +From ae996e81232b8ba991e763dfa15577a0af358358 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 17:28:42 +0100 +Subject: [PATCH 40/41] mdadm: fix grow segfault for IMSM + +If sc is not initialized, there is possibility that sc.pols is not zeroed +and it causes segfault. + +Add missing initialization. +Add missing dev_policy_free() in two places. + +Fixes: f656201188d7 ("mdadm: drop get_required_spare_criteria()") +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 1 + + super-intel.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 958ba9ba..83db0712 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -874,6 +874,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch + rv = MDADM_STATUS_SUCCESS; + + out: ++ dev_policy_free(sc.pols); + dup->ss->free_super(dup); + free(dup); + +diff --git a/super-intel.c b/super-intel.c +index ff2590fe..70f3c4ef 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11518,10 +11518,15 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, + */ + static struct mdinfo *get_spares_for_grow(struct supertype *st) + { +- struct spare_criteria sc; ++ struct spare_criteria sc = {0}; ++ struct mdinfo *spares; + + get_spare_criteria_imsm(st, NULL, &sc); +- return container_choose_spares(st, &sc, NULL, NULL, NULL, 0); ++ spares = container_choose_spares(st, &sc, NULL, NULL, NULL, 0); ++ ++ dev_policy_free(sc.pols); ++ ++ return spares; + } + + /****************************************************************************** +-- +2.40.1 + diff --git a/SOURCES/0041-Remove-all-if-zeros-pt.2.patch b/SOURCES/0041-Remove-all-if-zeros-pt.2.patch new file mode 100644 index 0000000..8fc44e8 --- /dev/null +++ b/SOURCES/0041-Remove-all-if-zeros-pt.2.patch @@ -0,0 +1,85 @@ +From da4d58b6d01ed8b0149b777eba7818861fde8c80 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 19 Mar 2024 11:15:29 +0100 +Subject: [PATCH 41/41] Remove all "if zeros" pt.2 + +Commit e15e8b00cbce ("Remove all "if zeros"") did not remove all "if 0" +code blocks. + +This commit is cleanup for that commit. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Build.c | 6 ------ + Grow.c | 13 +------------ + super1.c | 11 ----------- + 3 files changed, 1 insertion(+), 29 deletions(-) + +diff --git a/Build.c b/Build.c +index 1fbf8596..1be90e41 100644 +--- a/Build.c ++++ b/Build.c +@@ -156,12 +156,6 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, + bitmap_fd = open(s->bitmap_file, O_RDWR); + if (bitmap_fd < 0) { + int major = BITMAP_MAJOR_HI; +-#if 0 +- if (s->bitmap_chunk == UnSet) { +- pr_err("%s cannot be opened.\n", s->bitmap_file); +- goto abort; +- } +-#endif + bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */ + if (CreateBitmap(s->bitmap_file, 1, NULL, + s->bitmap_chunk, c->delay, +diff --git a/Grow.c b/Grow.c +index c69a342d..074f1995 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -4413,19 +4413,8 @@ static void validate(int afd, int bfd, unsigned long long offset) + lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0); + if ((unsigned long long)read(afd, abuf, len) != len) + fail("read first from array failed"); +- if (memcmp(bbuf, abuf, len) != 0) { +-#if 0 +- int i; +- printf("offset=%llu len=%llu\n", +- (unsigned long long)__le64_to_cpu(bsb2.arraystart)*512, len); +- for (i=0; imax_dev); i++) { +- int role = __le16_to_cpu(sb->dev_roles[i]); +- if (role == MD_DISK_ROLE_FAULTY) +- faulty++; +- } +- if (faulty) +- printf(" %d failed", faulty); +-#endif + printf(" ('A' == active, '.' == missing, 'R' == replacing)"); + printf("\n"); + for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) { +-- +2.40.1 + diff --git a/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch b/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch new file mode 100644 index 0000000..0741be2 --- /dev/null +++ b/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch @@ -0,0 +1,44 @@ +From cc75b0faaa016e54d569486c9a7abe6c39cb883a Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:15 +0100 +Subject: [PATCH 42/66] mdadm: Move pr_vrb define to mdadm.h + +Move pr_vrb define from super-intel.c to mdadm.h to make it widely +available. This change will be used in the next patches. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 2 ++ + super-intel.c | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index ae2106a2..fbb161ba 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1911,6 +1911,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { + + #define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) + ++#define pr_vrb(fmt, arg...) ((void)(verbose && pr_err(fmt, ##arg))) ++ + void *xmalloc(size_t len); + void *xrealloc(void *ptr, size_t len); + void *xcalloc(size_t num, size_t size); +diff --git a/super-intel.c b/super-intel.c +index 70f3c4ef..212387ec 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -393,8 +393,6 @@ struct md_list { + struct md_list *next; + }; + +-#define pr_vrb(fmt, arg...) (void) (verbose && pr_err(fmt, ##arg)) +- + static __u8 migr_type(struct imsm_dev *dev) + { + if (dev->vol.migr_type == MIGR_VERIFY && +-- +2.41.0 + diff --git a/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch b/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch new file mode 100644 index 0000000..140c620 --- /dev/null +++ b/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch @@ -0,0 +1,463 @@ +From cc48406887b3bc439e3462e8e4d20f992e81b87e Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:16 +0100 +Subject: [PATCH 43/66] Add reading Opal NVMe encryption information + +For NVMe devices with Opal support, encryption information, status and +ability are determined based on Opal Level 0 discovery response. Technical +documentation used is given in the implementation. + +Ability in general describes what type of encryption is supported, Status +describes in what state the disk with encryption support is. The current +patch includes only the implementation of reading encryption information, +functions will be used in one of the next patches. + +Motivation for adding this functionality is to block mixing of disks in +IMSM arrays with encryption enabled and disabled. The main goal is to not +allow stealing data by rebuilding array to not encrypted drive which can be +read elsewhere. + +Value ENA_OTHER from enum encryption_ability will be used in the next +patch. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + Makefile | 4 +- + drive_encryption.c | 362 +++++++++++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 32 ++++ + 3 files changed, 396 insertions(+), 2 deletions(-) + create mode 100644 drive_encryption.c + create mode 100644 drive_encryption.h + +diff --git a/Makefile b/Makefile +index cbdba49a..7c221a89 100644 +--- a/Makefile ++++ b/Makefile +@@ -170,7 +170,7 @@ OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o u + mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \ + super-mbr.o super-gpt.o \ + restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \ +- platform-intel.o probe_roms.o crc32c.o ++ platform-intel.o probe_roms.o crc32c.o drive_encryption.o + + CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o + +@@ -183,7 +183,7 @@ MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o c + Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ + super-mbr.o super-gpt.o \ + super-ddf.o sha1.o crc32.o msg.o bitmap.o xmalloc.o \ +- platform-intel.o probe_roms.o crc32c.o ++ platform-intel.o probe_roms.o crc32c.o drive_encryption.o + + MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS)) + +diff --git a/drive_encryption.c b/drive_encryption.c +new file mode 100644 +index 00000000..b44585a7 +--- /dev/null ++++ b/drive_encryption.c +@@ -0,0 +1,362 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Read encryption information for Opal and ATA devices. ++ * ++ * Copyright (C) 2024 Intel Corporation ++ * Author: Blazej Kucman ++ */ ++ ++#include "mdadm.h" ++ ++#include ++#include ++#include "drive_encryption.h" ++ ++/* ++ * Opal defines ++ * TCG Storage Opal SSC 2.01 chapter 3.3.3 ++ * NVM ExpressTM Revision 1.4c, chapter 5 ++ */ ++#define TCG_SECP_01 (0x01) ++#define TCG_SECP_00 (0x00) ++#define OPAL_DISCOVERY_COMID (0x0001) ++#define OPAL_LOCKING_FEATURE (0x0002) ++#define OPAL_IO_BUFFER_LEN 2048 ++#define OPAL_DISCOVERY_FEATURE_HEADER_LEN (4) ++ ++/* ++ * NVMe defines ++ * NVM ExpressTM Revision 1.4c, chapter 5 ++ */ ++#define NVME_SECURITY_RECV (0x82) ++#define NVME_IDENTIFY (0x06) ++#define NVME_IDENTIFY_RESPONSE_LEN 4096 ++#define NVME_OACS_BYTE_POSITION (256) ++#define NVME_IDENTIFY_CONTROLLER_DATA (1) ++ ++typedef enum drive_feature_support_status { ++ /* Drive feature is supported. */ ++ DRIVE_FEAT_SUP_ST = 0, ++ /* Drive feature is not supported. */ ++ DRIVE_FEAT_NOT_SUP_ST, ++ /* Drive feature support check failed. */ ++ DRIVE_FEAT_CHECK_FAILED_ST ++} drive_feat_sup_st; ++ ++/* TCG Storage Opal SSC 2.01 chapter 3.1.1.3 */ ++typedef struct opal_locking_feature { ++ /* feature header */ ++ __u16 feature_code; ++ __u8 reserved : 4; ++ __u8 version : 4; ++ __u8 description_length; ++ /* feature description */ ++ __u8 locking_supported : 1; ++ __u8 locking_enabled : 1; ++ __u8 locked : 1; ++ __u8 media_encryption : 1; ++ __u8 mbr_enabled : 1; ++ __u8 mbr_done : 1; ++ __u8 mbr_shadowing_not_supported : 1; ++ __u8 hw_reset_for_dor_supported : 1; ++ __u8 reserved1[11]; ++} __attribute__((__packed__)) opal_locking_feature_t; ++ ++/* TCG Storage Opal SSC 2.01 chapter 3.1.1.1 */ ++typedef struct opal_level0_header { ++ __u32 length; ++ __u32 version; ++ __u64 reserved; ++ __u8 vendor_specific[32]; ++} opal_level0_header_t; ++ ++/** ++ * NVM ExpressTM Revision 1.4c, Figure 249 ++ * Structure specifies only OACS filed, which is needed in the current use case. ++ */ ++typedef struct nvme_identify_ctrl { ++ __u8 reserved[255]; ++ __u16 oacs; ++ __u8 reserved2[3839]; ++} nvme_identify_ctrl_t; ++ ++/* SCSI Primary Commands - 4 (SPC-4), Table 512 */ ++typedef struct supported_security_protocols { ++ __u8 reserved[6]; ++ __u16 list_length; ++ __u8 list[504]; ++} supported_security_protocols_t; ++ ++/** ++ * get_opal_locking_feature_description() - get opal locking feature description. ++ * @response: response from Opal Discovery Level 0. ++ * ++ * Based on the documentation TCG Storage Opal SSC 2.01 chapter 3.1.1, ++ * a Locking feature is searched for in Opal Level 0 Discovery response. ++ * ++ * Return: if locking feature is found, pointer to struct %opal_locking_feature_t, NULL otherwise. ++ */ ++static opal_locking_feature_t *get_opal_locking_feature_description(__u8 *response) ++{ ++ opal_level0_header_t *response_header = (opal_level0_header_t *)response; ++ int features_length = __be32_to_cpu(response_header->length); ++ int current_position = sizeof(*response_header); ++ ++ while (current_position < features_length) { ++ opal_locking_feature_t *feature; ++ ++ feature = (opal_locking_feature_t *)(response + current_position); ++ ++ if (__be16_to_cpu(feature->feature_code) == OPAL_LOCKING_FEATURE) ++ return feature; ++ ++ current_position += feature->description_length + OPAL_DISCOVERY_FEATURE_HEADER_LEN; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * nvme_security_recv_ioctl() - nvme security receive ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @sec_protocol: security protocol. ++ * @comm_id: command id. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and ++ * NVM ExpressTM Revision 1.4c, chapter 5.25, ++ * read security receive command via ioctl(). ++ * On success, @response_buffer is completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t ++nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *response_buffer, ++ size_t buf_size, const int verbose) ++{ ++ struct nvme_admin_cmd nvme_cmd = {0}; ++ int status; ++ ++ nvme_cmd.opcode = NVME_SECURITY_RECV; ++ nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8; ++ nvme_cmd.cdw11 = buf_size; ++ nvme_cmd.data_len = buf_size; ++ nvme_cmd.addr = (__u64)response_buffer; ++ ++ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); ++ if (status != 0) { ++ pr_vrb("Failed to read NVMe security receive ioctl() for device /dev/%s, status: %d\n", ++ fd2kname(disk_fd), status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * nvme_identify_ioctl() - NVMe identify ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and ++ * NVM ExpressTM Revision 1.4c, chapter 5.25, ++ * read NVMe identify via ioctl(). ++ * On success, @response_buffer will be completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t ++nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const int verbose) ++{ ++ struct nvme_admin_cmd nvme_cmd = {0}; ++ int status; ++ ++ nvme_cmd.opcode = NVME_IDENTIFY; ++ nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA; ++ nvme_cmd.data_len = buf_size; ++ nvme_cmd.addr = (__u64)response_buffer; ++ ++ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); ++ if (status != 0) { ++ pr_vrb("Failed to read NVMe identify ioctl() for device /dev/%s, status: %d\n", ++ fd2kname(disk_fd), status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_sec_prot_01h_supported() - check if security protocol 01h supported. ++ * @security_protocols: struct with response from disk (NVMe, SATA) describing supported ++ * security protocols. ++ * ++ * Return: true if TCG_SECP_01 found, false otherwise. ++ */ ++static bool is_sec_prot_01h_supported(supported_security_protocols_t *security_protocols) ++{ ++ int list_length = be16toh(security_protocols->list_length); ++ int index; ++ ++ for (index = 0 ; index < list_length; index++) { ++ if (security_protocols->list[index] == TCG_SECP_01) ++ return true; ++ } ++ ++ return false; ++} ++ ++/** ++ * is_sec_prot_01h_supported_nvme() - check if security protocol 01h supported for given NVMe disk. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check. ++ */ ++static drive_feat_sup_st is_sec_prot_01h_supported_nvme(int disk_fd, const int verbose) ++{ ++ supported_security_protocols_t security_protocols = {0}; ++ ++ /* security_protocol: TCG_SECP_00, comm_id: not applicable */ ++ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_00, 0x0, &security_protocols, ++ sizeof(security_protocols), verbose)) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if (is_sec_prot_01h_supported(&security_protocols)) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * is_nvme_sec_send_recv_supported() - check if Security Send and Security Receive is supported. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Check if "Optional Admin Command Support" bit 0 is set in NVMe identify. ++ * Bit 0 set to 1 means controller supports the Security Send and Security Receive commands. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if security send/receive supported, ++ * %DRIVE_FEAT_NOT_SUP_ST if not supported, %DRIVE_FEAT_CHECK_FAILED_ST if check failed. ++ */ ++static drive_feat_sup_st is_nvme_sec_send_recv_supported(int disk_fd, const int verbose) ++{ ++ nvme_identify_ctrl_t nvme_identify = {0}; ++ int status = 0; ++ ++ status = nvme_identify_ioctl(disk_fd, &nvme_identify, sizeof(nvme_identify), verbose); ++ if (status) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if ((__le16_to_cpu(nvme_identify.oacs) & 0x1) == 0x1) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * get_opal_encryption_information() - get Opal encryption information. ++ * @buffer: buffer with Opal Level 0 Discovery response. ++ * @information: struct to fill out, describing encryption status of disk. ++ * ++ * If Locking feature frame is in response from Opal Level 0 discovery, &encryption_information_t ++ * structure is completed with status and ability otherwise the status is set to &None. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t get_opal_encryption_information(__u8 *buffer, ++ encryption_information_t *information) ++{ ++ opal_locking_feature_t *opal_locking_feature = ++ get_opal_locking_feature_description(buffer); ++ ++ if (!opal_locking_feature) ++ return MDADM_STATUS_ERROR; ++ ++ if (opal_locking_feature->locking_supported == 1) { ++ information->ability = ENC_ABILITY_SED; ++ ++ if (opal_locking_feature->locking_enabled == 0) ++ information->status = ENC_STATUS_UNENCRYPTED; ++ else if (opal_locking_feature->locked == 1) ++ information->status = ENC_STATUS_LOCKED; ++ else ++ information->status = ENC_STATUS_UNLOCKED; ++ } else { ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * get_nvme_opal_encryption_information() - get NVMe Opal encryption information. ++ * @disk_fd: a disk file descriptor. ++ * @information: struct to fill out, describing encryption status of disk. ++ * @verbose: verbose flag. ++ * ++ * In case the disk supports Opal Level 0 discovery, &encryption_information_t structure ++ * is completed with status and ability based on ioctl response, ++ * otherwise the ability is set to %ENC_ABILITY_NONE and &status to %ENC_STATUS_UNENCRYPTED. ++ * As the current use case does not need the knowledge of Opal support, if there is no support, ++ * %MDADM_STATUS_SUCCESS will be returned, with the values described above. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++mdadm_status_t ++get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *information, ++ const int verbose) ++{ ++ __u8 buffer[OPAL_IO_BUFFER_LEN]; ++ int sec_send_recv_supported = 0; ++ int protocol_01h_supported = 0; ++ mdadm_status_t status; ++ ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ ++ sec_send_recv_supported = is_nvme_sec_send_recv_supported(disk_fd, verbose); ++ if (sec_send_recv_supported == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ /* Opal not supported */ ++ if (sec_send_recv_supported == DRIVE_FEAT_NOT_SUP_ST) ++ return MDADM_STATUS_SUCCESS; ++ ++ /** ++ * sec_send_recv_supported determine that it should be possible to read ++ * supported sec protocols ++ */ ++ protocol_01h_supported = is_sec_prot_01h_supported_nvme(disk_fd, verbose); ++ if (protocol_01h_supported == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ /* Opal not supported */ ++ if (sec_send_recv_supported == DRIVE_FEAT_SUP_ST && ++ protocol_01h_supported == DRIVE_FEAT_NOT_SUP_ST) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_01, OPAL_DISCOVERY_COMID, (void *)&buffer, ++ OPAL_IO_BUFFER_LEN, verbose)) ++ return MDADM_STATUS_ERROR; ++ ++ status = get_opal_encryption_information((__u8 *)&buffer, information); ++ if (status) ++ pr_vrb("Locking feature description not found in Level 0 discovery response. Device /dev/%s.\n", ++ fd2kname(disk_fd)); ++ ++ if (information->ability == ENC_ABILITY_NONE) ++ assert(information->status == ENC_STATUS_UNENCRYPTED); ++ ++ return status; ++} +diff --git a/drive_encryption.h b/drive_encryption.h +new file mode 100644 +index 00000000..82c2c624 +--- /dev/null ++++ b/drive_encryption.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Read encryption information for Opal and ATA devices. ++ * ++ * Copyright (C) 2024 Intel Corporation ++ * Author: Blazej Kucman ++ */ ++ ++typedef enum encryption_status { ++ /* The drive is not currently encrypted. */ ++ ENC_STATUS_UNENCRYPTED = 0, ++ /* The drive is encrypted and the data is not accessible. */ ++ ENC_STATUS_LOCKED, ++ /* The drive is encrypted but the data is accessible in unencrypted form. */ ++ ENC_STATUS_UNLOCKED ++} encryption_status_t; ++ ++typedef enum encryption_ability { ++ ENC_ABILITY_NONE = 0, ++ ENC_ABILITY_OTHER, ++ /* Self encrypted drive */ ++ ENC_ABILITY_SED ++} encryption_ability_t; ++ ++typedef struct encryption_information { ++ encryption_ability_t ability; ++ encryption_status_t status; ++} encryption_information_t; ++ ++mdadm_status_t ++get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose); +-- +2.41.0 + diff --git a/SOURCES/0044-Add-reading-SATA-encryption-information.patch b/SOURCES/0044-Add-reading-SATA-encryption-information.patch new file mode 100644 index 0000000..607f6af --- /dev/null +++ b/SOURCES/0044-Add-reading-SATA-encryption-information.patch @@ -0,0 +1,459 @@ +From df38df3052c3386c0fd076e0d534b4f688b5c8a4 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:17 +0100 +Subject: [PATCH 44/66] Add reading SATA encryption information + +Functionality reads information about SATA disk encryption. Technical +documentation used is given in the implementation. + +The implementation is able to recognized two encryption standards for SATA +drives, OPAL and ATA security. + +If the SATA drive supports OPAL, encryption status and ability are +determined based on Opal Level 0 discovery response, for ATA security, +based on ATA identify response. If SATA supports OPAL, ability is set to +"SED", for ATA security to "Other". + +SED(Self-Encrypting Drive) is commonly used to describe drive which using +OPAL or Enterprise standards developed by Trusted Computing Group. Ability +"Other" is used for ATA security because we rely only on information from +ATA identify which describe the overall state of encryption. + +It is allowed to mix disks with different encryption ability such as "SED" +and "Other" and it is not security gap. + +Motivation for adding this functionality is to block mixing of disks in +IMSM arrays with encryption enabled and disabled. The main goal is to not +allow stealing data by rebuilding array to not encrypted drive which can be +read elsewhere. + +For SATA Opal drives, libata allow_tmp parameter enabled is required, which +is necessary for Opal Security commands to work, therefore, if the +parameter is not enabled, SATA Opal disk cannot be used in case the +encryption will be checked by metadata. + +Implemented functions will be used in one of the next patches. In one of +the next patches, a flag will be added to enable disabling SATA Opal +encryption checking due to allow_tpm kernel setting dependency. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + drive_encryption.c | 318 +++++++++++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 3 + + mdadm.h | 1 + + sysfs.c | 29 +++++ + 4 files changed, 351 insertions(+) + +diff --git a/drive_encryption.c b/drive_encryption.c +index b44585a7..d520f0c7 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -10,8 +10,12 @@ + + #include + #include ++#include ++#include + #include "drive_encryption.h" + ++#define DEFAULT_SECTOR_SIZE (512) ++ + /* + * Opal defines + * TCG Storage Opal SSC 2.01 chapter 3.3.3 +@@ -34,6 +38,35 @@ + #define NVME_OACS_BYTE_POSITION (256) + #define NVME_IDENTIFY_CONTROLLER_DATA (1) + ++/* ++ * ATA defines ++ * ATA/ATAPI Command Set ATA8-ACS ++ * SCSI / ATA Translation - 3 (SAT-3) ++ * SCSI Primary Commands - 4 (SPC-4) ++ * AT Attachment-8 - ATA Serial Transport (ATA8-AST) ++ * ATA Command Pass-Through ++ */ ++#define ATA_IDENTIFY (0xec) ++#define ATA_TRUSTED_RECEIVE (0x5c) ++#define ATA_SECURITY_WORD_POSITION (128) ++#define HDIO_DRIVE_CMD (0x031f) ++#define ATA_TRUSTED_COMPUTING_POS (48) ++#define ATA_PASS_THROUGH_12 (0xa1) ++#define ATA_IDENTIFY_RESPONSE_LEN (512) ++#define ATA_PIO_DATA_IN (4) ++#define SG_CHECK_CONDITION (0x02) ++#define ATA_STATUS_RETURN_DESCRIPTOR (0x09) ++#define ATA_PT_INFORMATION_AVAILABLE_ASCQ (0x1d) ++#define ATA_PT_INFORMATION_AVAILABLE_ASC (0x00) ++#define ATA_INQUIRY_LENGTH (0x0c) ++#define SG_INTERFACE_ID 'S' ++#define SG_IO_TIMEOUT (60000) ++#define SG_SENSE_SIZE (32) ++#define SENSE_DATA_CURRENT_FIXED (0x70) ++#define SENSE_DATA_CURRENT_DESC (0x72) ++#define SENSE_CURRENT_RES_DESC_POS (8) ++#define SG_DRIVER_SENSE (0x08) ++ + typedef enum drive_feature_support_status { + /* Drive feature is supported. */ + DRIVE_FEAT_SUP_ST = 0, +@@ -87,6 +120,27 @@ typedef struct supported_security_protocols { + __u8 list[504]; + } supported_security_protocols_t; + ++/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */ ++typedef struct ata_security_status { ++ __u16 security_supported : 1; ++ __u16 security_enabled : 1; ++ __u16 security_locked : 1; ++ __u16 security_frozen : 1; ++ __u16 security_count_expired : 1; ++ __u16 enhanced_security_erase_supported : 1; ++ __u16 reserved1 : 2; ++ __u16 security_level : 1; ++ __u16 reserved2 : 7; ++} __attribute__((__packed__)) ata_security_status_t; ++ ++/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */ ++typedef struct ata_trusted_computing { ++ __u16 tc_feature :1; ++ __u16 reserved : 13; ++ __u16 var1 : 1; ++ __u16 var2 : 1; ++} __attribute__((__packed__)) ata_trusted_computing_t; ++ + /** + * get_opal_locking_feature_description() - get opal locking feature description. + * @response: response from Opal Discovery Level 0. +@@ -360,3 +414,267 @@ get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *info + + return status; + } ++ ++/** ++ * ata_pass_through12_ioctl() - ata pass through12 ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @ata_command: ata command. ++ * @sec_protocol: security protocol. ++ * @comm_id: additional command id. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations ATA Command Pass-Through, chapter 13.2.2 and ++ * ATA Translation - 3 (SAT-3), send read ata pass through 12 command via ioctl(). ++ * On success, @response_buffer will be completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++static mdadm_status_t ++ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u16 comm_id, ++ void *response_buffer, size_t buf_size, const int verbose) ++{ ++ __u8 cdb[ATA_INQUIRY_LENGTH] = {0}; ++ __u8 sense[SG_SENSE_SIZE] = {0}; ++ __u8 *sense_desc = NULL; ++ sg_io_hdr_t sg = {0}; ++ ++ /* ++ * ATA Command Pass-Through, chapter 13.2.2 ++ * SCSI Primary Commands - 4 (SPC-4) ++ * ATA Translation - 3 (SAT-3) ++ */ ++ cdb[0] = ATA_PASS_THROUGH_12; ++ /* protocol, bits 1-4 */ ++ cdb[1] = ATA_PIO_DATA_IN << 1; ++ /* Bytes: CK_COND=1, T_DIR = 1, BYTE_BLOCK = 1, Length in Sector Count = 2 */ ++ cdb[2] = 0x2E; ++ cdb[3] = sec_protocol; ++ /* Sector count */ ++ cdb[4] = buf_size / DEFAULT_SECTOR_SIZE; ++ cdb[6] = (comm_id) & 0xFF; ++ cdb[7] = (comm_id >> 8) & 0xFF; ++ cdb[9] = ata_command; ++ ++ sg.interface_id = SG_INTERFACE_ID; ++ sg.cmd_len = sizeof(cdb); ++ sg.mx_sb_len = sizeof(sense); ++ sg.dxfer_direction = SG_DXFER_FROM_DEV; ++ sg.dxfer_len = buf_size; ++ sg.dxferp = response_buffer; ++ sg.cmdp = cdb; ++ sg.sbp = sense; ++ sg.timeout = SG_IO_TIMEOUT; ++ sg.usr_ptr = NULL; ++ ++ if (ioctl(disk_fd, SG_IO, &sg) < 0) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if ((sg.status && sg.status != SG_CHECK_CONDITION) || sg.host_status || ++ (sg.driver_status && sg.driver_status != SG_DRIVER_SENSE)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ pr_vrb("SG_IO error: ATA_12 Status: %d Host Status: %d, Driver Status: %d\n", ++ sg.status, sg.host_status, sg.driver_status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* verify expected sense response code */ ++ if (!(sense[0] == SENSE_DATA_CURRENT_DESC || sense[0] == SENSE_DATA_CURRENT_FIXED)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ sense_desc = sense + SENSE_CURRENT_RES_DESC_POS; ++ /* verify sense data current response with descriptor format */ ++ if (sense[0] == SENSE_DATA_CURRENT_DESC && ++ !(sense_desc[0] == ATA_STATUS_RETURN_DESCRIPTOR && ++ sense_desc[1] == ATA_INQUIRY_LENGTH)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", ++ fd2kname(disk_fd), sense[2], sense[3]); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* verify sense data current response with fixed format */ ++ if (sense[0] == SENSE_DATA_CURRENT_FIXED && ++ !(sense[12] == ATA_PT_INFORMATION_AVAILABLE_ASC && ++ sense[13] == ATA_PT_INFORMATION_AVAILABLE_ASCQ)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", ++ fd2kname(disk_fd), sense[12], sense[13]); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_sec_prot_01h_supported_ata() - check if security protocol 01h supported for given SATA disk. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed. ++ */ ++static drive_feat_sup_st is_sec_prot_01h_supported_ata(int disk_fd, const int verbose) ++{ ++ supported_security_protocols_t security_protocols; ++ ++ mdadm_status_t result = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_00, ++ 0x0, &security_protocols, ++ sizeof(security_protocols), verbose); ++ if (result) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if (is_sec_prot_01h_supported(&security_protocols)) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * is_ata_trusted_computing_supported() - check if ata trusted computing supported. ++ * @buffer: buffer with ATA identify response, not NULL. ++ * ++ * Return: true if trusted computing bit set, false otherwise. ++ */ ++bool is_ata_trusted_computing_supported(__u16 *buffer) ++{ ++ /* Added due to warnings from the compiler about a possible uninitialized variable below. */ ++ assert(buffer); ++ ++ __u16 security_tc_frame = __le16_to_cpu(buffer[ATA_TRUSTED_COMPUTING_POS]); ++ ata_trusted_computing_t *security_tc = (ata_trusted_computing_t *)&security_tc_frame; ++ ++ if (security_tc->tc_feature == 1) ++ return true; ++ ++ return false; ++} ++ ++/** ++ * get_ata_standard_security_status() - get ATA disk encryption information from ATA identify. ++ * @buffer: buffer with response from ATA identify, not NULL. ++ * @information: struct to fill out, describing encryption status of disk. ++ * ++ * The function based on the Security status frame from ATA identify, ++ * completed encryption information. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++static mdadm_status_t get_ata_standard_security_status(__u16 *buffer, ++ struct encryption_information *information) ++{ ++ /* Added due to warnings from the compiler about a possible uninitialized variable below. */ ++ assert(buffer); ++ ++ __u16 security_status_frame = __le16_to_cpu(buffer[ATA_SECURITY_WORD_POSITION]); ++ ata_security_status_t *security_status = (ata_security_status_t *)&security_status_frame; ++ ++ if (!security_status->security_supported) { ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ information->ability = ENC_ABILITY_OTHER; ++ ++ if (security_status->security_enabled == 0) ++ information->status = ENC_STATUS_UNENCRYPTED; ++ else if (security_status->security_locked == 1) ++ information->status = ENC_STATUS_LOCKED; ++ else ++ information->status = ENC_STATUS_UNLOCKED; ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_ata_opal() - check if SATA disk support Opal. ++ * @disk_fd: a disk file descriptor. ++ * @buffer: buffer with ATA identify response. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check. ++ */ ++static drive_feat_sup_st is_ata_opal(int disk_fd, __u16 *buffer_identify, const int verbose) ++{ ++ bool tc_status = is_ata_trusted_computing_supported(buffer_identify); ++ drive_feat_sup_st tcg_sec_prot_status; ++ ++ if (!tc_status) ++ return DRIVE_FEAT_NOT_SUP_ST; ++ ++ tcg_sec_prot_status = is_sec_prot_01h_supported_ata(disk_fd, verbose); ++ ++ if (tcg_sec_prot_status == DRIVE_FEAT_CHECK_FAILED_ST) { ++ pr_vrb("Failed to verify if security protocol 01h supported. Device /dev/%s.\n", ++ fd2kname(disk_fd)); ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ } ++ ++ if (tc_status && tcg_sec_prot_status == DRIVE_FEAT_SUP_ST) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * get_ata_encryption_information() - get ATA disk encryption information. ++ * @disk_fd: a disk file descriptor. ++ * @information: struct to fill out, describing encryption status of disk. ++ * @verbose: verbose flag. ++ * ++ * The function reads information about encryption, if the disk supports Opal, ++ * the information is completed based on Opal Level 0 discovery, otherwise, ++ * based on ATA security status frame from ATA identification response. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Based on the documentations ATA/ATAPI Command Set ATA8-ACS and ++ * AT Attachment-8 - ATA Serial Transport (ATA8-AST). ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++mdadm_status_t ++get_ata_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose) ++{ ++ __u8 buffer_opal_level0_discovery[OPAL_IO_BUFFER_LEN] = {0}; ++ __u16 buffer_identify[ATA_IDENTIFY_RESPONSE_LEN] = {0}; ++ drive_feat_sup_st ata_opal_status; ++ mdadm_status_t status; ++ ++ /* Get disk ATA identification */ ++ status = ata_pass_through12_ioctl(disk_fd, ATA_IDENTIFY, 0x0, 0x0, buffer_identify, ++ sizeof(buffer_identify), verbose); ++ if (status == MDADM_STATUS_ERROR) ++ return MDADM_STATUS_ERROR; ++ ++ if (is_ata_trusted_computing_supported(buffer_identify) && ++ !sysfs_is_libata_allow_tpm_enabled(verbose)) { ++ pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose); ++ if (ata_opal_status == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ if (ata_opal_status == DRIVE_FEAT_NOT_SUP_ST) ++ return get_ata_standard_security_status(buffer_identify, information); ++ ++ /* SATA Opal */ ++ status = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_01, ++ OPAL_DISCOVERY_COMID, buffer_opal_level0_discovery, ++ OPAL_IO_BUFFER_LEN, verbose); ++ if (status != MDADM_STATUS_SUCCESS) ++ return MDADM_STATUS_ERROR; ++ ++ return get_opal_encryption_information(buffer_opal_level0_discovery, information); ++} +diff --git a/drive_encryption.h b/drive_encryption.h +index 82c2c624..77c7f10f 100644 +--- a/drive_encryption.h ++++ b/drive_encryption.h +@@ -30,3 +30,6 @@ typedef struct encryption_information { + mdadm_status_t + get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information, + const int verbose); ++mdadm_status_t ++get_ata_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose); +diff --git a/mdadm.h b/mdadm.h +index fbb161ba..52a66b9a 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -853,6 +853,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, + int source, unsigned long long read_offset, + unsigned long long start, unsigned long long length, + char *src_buf); ++extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose); + + #ifndef Sendmail + #define Sendmail "/usr/lib/sendmail -t" +diff --git a/sysfs.c b/sysfs.c +index 4ded1672..20fe1e9e 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -1121,3 +1121,32 @@ void sysfsline(char *line) + sr->next = sysfs_rules; + sysfs_rules = sr; + } ++ ++/** ++ * sysfs_is_libata_allow_tpm_enabled() - check if libata allow_tmp is enabled. ++ * @verbose: verbose flag. ++ * ++ * Check if libata allow_tmp flag is set, this is required for SATA Opal Security commands to work. ++ * ++ * Return: true if allow_tpm enable, false otherwise. ++ */ ++bool sysfs_is_libata_allow_tpm_enabled(const int verbose) ++{ ++ const char *path = "/sys/module/libata/parameters/allow_tpm"; ++ const char *expected_value = "1"; ++ int fd = open(path, O_RDONLY); ++ char buf[3]; ++ ++ if (!is_fd_valid(fd)) { ++ pr_vrb("Failed open file descriptor to %s. Cannot check libata allow_tpm param.\n", ++ path); ++ return false; ++ } ++ ++ sysfs_fd_get_str(fd, buf, sizeof(buf)); ++ close(fd); ++ ++ if (strncmp(buf, expected_value, 1) == 0) ++ return true; ++ return false; ++} +-- +2.41.0 + diff --git a/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch b/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch new file mode 100644 index 0000000..d9009c4 --- /dev/null +++ b/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch @@ -0,0 +1,163 @@ +From 336e13fc5ef43bc5b4633a9dadac5f7208e6c241 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:18 +0100 +Subject: [PATCH 45/66] Add key ENCRYPTION_NO_VERIFY to conf + +Add ENCRYPTION_NO_VERIFY config key and allow to disable checking +encryption status for given type of drives. + +The key is introduced because of SATA Opal disks for which TPM commands +must be enabled in libata kernel module, (libata.allow_tpm=1), otherwise +it is impossible to verify encryption status. TPM commands are disabled by +default. + +Currently the key only supports the "sata_opal" value, if necessary, +the functionality is ready to support more types of disks. This +functionality will be used in the next patches. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + config.c | 25 ++++++++++++++++++++++++- + drive_encryption.c | 16 ++++++++++++---- + mdadm.conf.5.in | 13 +++++++++++++ + mdadm.h | 1 + + 4 files changed, 50 insertions(+), 5 deletions(-) + +diff --git a/config.c b/config.c +index 44f7dd2f..b46d71cb 100644 +--- a/config.c ++++ b/config.c +@@ -81,7 +81,7 @@ char DefaultAltConfDir[] = CONFFILE2 ".d"; + + enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev, + Homehost, HomeCluster, AutoMode, Policy, PartPolicy, Sysfs, +- MonitorDelay, LTEnd }; ++ MonitorDelay, EncryptionNoVerify, LTEnd }; + char *keywords[] = { + [Devices] = "devices", + [Array] = "array", +@@ -96,6 +96,7 @@ char *keywords[] = { + [PartPolicy]="part-policy", + [Sysfs] = "sysfs", + [MonitorDelay] = "monitordelay", ++ [EncryptionNoVerify] = "ENCRYPTION_NO_VERIFY", + [LTEnd] = NULL + }; + +@@ -729,6 +730,19 @@ void monitordelayline(char *line) + } + } + ++static bool sata_opal_encryption_no_verify; ++void encryption_no_verify_line(char *line) ++{ ++ char *word; ++ ++ for (word = dl_next(line); word != line; word = dl_next(word)) { ++ if (strcasecmp(word, "sata_opal") == 0) ++ sata_opal_encryption_no_verify = true; ++ else ++ pr_err("unrecognised word on ENCRYPTION_NO_VERIFY line: %s\n", word); ++ } ++} ++ + char auto_yes[] = "yes"; + char auto_no[] = "no"; + char auto_homehost[] = "homehost"; +@@ -913,6 +927,9 @@ void conf_file(FILE *f) + case MonitorDelay: + monitordelayline(line); + break; ++ case EncryptionNoVerify: ++ encryption_no_verify_line(line); ++ break; + default: + pr_err("Unknown keyword %s\n", line); + } +@@ -1075,6 +1092,12 @@ int conf_get_monitor_delay(void) + return monitor_delay; + } + ++bool conf_get_sata_opal_encryption_no_verify(void) ++{ ++ load_conffile(); ++ return sata_opal_encryption_no_verify; ++} ++ + struct createinfo *conf_get_create_info(void) + { + load_conffile(); +diff --git a/drive_encryption.c b/drive_encryption.c +index d520f0c7..6b2bd358 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -656,10 +656,18 @@ get_ata_encryption_information(int disk_fd, struct encryption_information *infor + if (status == MDADM_STATUS_ERROR) + return MDADM_STATUS_ERROR; + +- if (is_ata_trusted_computing_supported(buffer_identify) && +- !sysfs_is_libata_allow_tpm_enabled(verbose)) { +- pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n"); +- return MDADM_STATUS_ERROR; ++ /* Possible OPAL support, further checks require tpm_enabled.*/ ++ if (is_ata_trusted_computing_supported(buffer_identify)) { ++ /* OPAL SATA encryption checking disabled. */ ++ if (conf_get_sata_opal_encryption_no_verify()) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (!sysfs_is_libata_allow_tpm_enabled(verbose)) { ++ pr_vrb("Detected SATA drive /dev/%s with Trusted Computing support.\n", ++ fd2kname(disk_fd)); ++ pr_vrb("Cannot verify encryption state. Requires libata.tpm_enabled=1.\n"); ++ return MDADM_STATUS_ERROR; ++ } + } + + ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose); +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index 787e51e9..afb0a296 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -636,6 +636,17 @@ If multiple + .B MINITORDELAY + lines are provided, only first non-zero value is considered. + ++.TP ++.B ENCRYPTION_NO_VERIFY ++The ++.B ENCRYPTION_NO_VERIFY ++disables encryption verification for devices with particular encryption support detected. ++Currently, only verification of SATA OPAL encryption can be disabled. ++It does not disable ATA security encryption verification. ++Available parameter ++.I "sata_opal". ++ ++ + .SH FILES + + .SS {CONFFILE} +@@ -744,6 +755,8 @@ SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 + sync_speed_max=1000000 + .br + MONITORDELAY 60 ++.br ++ENCRYPTION_NO_VERIFY sata_opal + + .SH SEE ALSO + .BR mdadm (8), +diff --git a/mdadm.h b/mdadm.h +index 52a66b9a..2640b396 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1673,6 +1673,7 @@ extern char *conf_get_program(void); + extern char *conf_get_homehost(int *require_homehostp); + extern char *conf_get_homecluster(void); + extern int conf_get_monitor_delay(void); ++extern bool conf_get_sata_opal_encryption_no_verify(void); + extern char *conf_line(FILE *file); + extern char *conf_word(FILE *file, int allow_key); + extern void print_quoted(char *str); +-- +2.41.0 + diff --git a/SOURCES/0046-imsm-print-disk-encryption-information.patch b/SOURCES/0046-imsm-print-disk-encryption-information.patch new file mode 100644 index 0000000..0208e72 --- /dev/null +++ b/SOURCES/0046-imsm-print-disk-encryption-information.patch @@ -0,0 +1,217 @@ +From bf62ed5d9642aa60abf4ac2d1d89f173bd66ae48 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:19 +0100 +Subject: [PATCH 46/66] imsm: print disk encryption information + +Print SATA/NVMe disk encryption information in --detail-platform. +Encryption Ability and Status will be printed for each disk. + +There is one exception, Opal SATA drives encryption is not checked when +ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this +reason such drives are treated as without encryption support. + +To test this feature, drives SATA/NVMe with Opal support or SATA drives +with encryption support have to be used. + +Example outputs of --detail-platform: + +Non Opal, encryption enabled, SATA drive: +Port0 : /dev/sdc (CVPR050600G3120LGN) + Encryption(Ability|Status): Other|Unlocked + +NVMe drive without Opal support: +NVMe under VMD : /dev/nvme2n1 (PHLF737302GB1P0GGN) + Encryption(Ability|Status): None|Unencrypted + +Unencrypted SATA drive with OPAL support: + +- default allow_tpm, we will get an error from mdadm: + Port6 : /dev/sdi (CVTS4246015V180IGN) +mdadm: Detected SATA drive /dev/sdi with Trusted Computing support. +mdadm: Cannot verify encryption state. Requires libata.tpm_enabled=1. +mdadm: Failed to get drive encrytpion information. + +- default "allow_tpm" and config entry "ENCRYPTION_NO_VERIFY sata_opal": +Port6 : /dev/sdi (CVTS4246015V180IGN) + Encryption(Ability|Status): None|Unencrypted + +- added "libata.allow_tpm=1" to boot parameters(requires reboot), +the status will be read correctly: +Port6 : /dev/sdi (CVTS4246015V180IGN) + Encryption(Ability|Status): SED|Unencrypted + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + drive_encryption.c | 36 ++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 2 ++ + mdadm.conf.5.in | 3 +++ + super-intel.c | 42 ++++++++++++++++++++++++++++++++++++++---- + 4 files changed, 79 insertions(+), 4 deletions(-) + +diff --git a/drive_encryption.c b/drive_encryption.c +index 6b2bd358..27da9621 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -141,6 +141,42 @@ typedef struct ata_trusted_computing { + __u16 var2 : 1; + } __attribute__((__packed__)) ata_trusted_computing_t; + ++mapping_t encryption_ability_map[] = { ++ { "None", ENC_ABILITY_NONE }, ++ { "Other", ENC_ABILITY_OTHER }, ++ { "SED", ENC_ABILITY_SED }, ++ { NULL, UnSet } ++}; ++ ++mapping_t encryption_status_map[] = { ++ { "Unencrypted", ENC_STATUS_UNENCRYPTED }, ++ { "Locked", ENC_STATUS_LOCKED }, ++ { "Unlocked", ENC_STATUS_UNLOCKED }, ++ { NULL, UnSet } ++}; ++ ++/** ++ * get_encryption_ability_string() - get encryption ability name string. ++ * @ability: encryption ability enum. ++ * ++ * Return: encryption ability string. ++ */ ++const char *get_encryption_ability_string(enum encryption_ability ability) ++{ ++ return map_num_s(encryption_ability_map, ability); ++} ++ ++/** ++ * get_encryption_status_string() - get encryption status name string. ++ * @ability: encryption status enum. ++ * ++ * Return: encryption status string. ++ */ ++const char *get_encryption_status_string(enum encryption_status status) ++{ ++ return map_num_s(encryption_status_map, status); ++} ++ + /** + * get_opal_locking_feature_description() - get opal locking feature description. + * @response: response from Opal Discovery Level 0. +diff --git a/drive_encryption.h b/drive_encryption.h +index 77c7f10f..0cb8ff1b 100644 +--- a/drive_encryption.h ++++ b/drive_encryption.h +@@ -33,3 +33,5 @@ get_nvme_opal_encryption_information(int disk_fd, struct encryption_information + mdadm_status_t + get_ata_encryption_information(int disk_fd, struct encryption_information *information, + const int verbose); ++const char *get_encryption_ability_string(enum encryption_ability ability); ++const char *get_encryption_status_string(enum encryption_status status); +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index afb0a296..14302a91 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -643,6 +643,9 @@ The + disables encryption verification for devices with particular encryption support detected. + Currently, only verification of SATA OPAL encryption can be disabled. + It does not disable ATA security encryption verification. ++Currently effective only for ++.I IMSM ++metadata. + Available parameter + .I "sata_opal". + +diff --git a/super-intel.c b/super-intel.c +index 212387ec..fbd1c11f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include "drive_encryption.h" + + /* MPB == Metadata Parameter Block */ + #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " +@@ -2349,12 +2350,41 @@ static int imsm_read_serial(int fd, char *devname, __u8 *serial, + size_t serial_buf_len); + static void fd2devname(int fd, char *name); + +-static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose) ++void print_encryption_information(int disk_fd, enum sys_dev_type hba_type) ++{ ++ struct encryption_information information = {0}; ++ mdadm_status_t status = MDADM_STATUS_SUCCESS; ++ const char *indent = " "; ++ ++ switch (hba_type) { ++ case SYS_DEV_VMD: ++ case SYS_DEV_NVME: ++ status = get_nvme_opal_encryption_information(disk_fd, &information, 1); ++ break; ++ case SYS_DEV_SATA: ++ case SYS_DEV_SATA_VMD: ++ status = get_ata_encryption_information(disk_fd, &information, 1); ++ break; ++ default: ++ return; ++ } ++ ++ if (status) { ++ pr_err("Failed to get drive encryption information.\n"); ++ return; ++ } ++ ++ printf("%sEncryption(Ability|Status): %s|%s\n", indent, ++ get_encryption_ability_string(information.ability), ++ get_encryption_status_string(information.status)); ++} ++ ++static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_base, int verbose) + { + /* dump an unsorted list of devices attached to AHCI Intel storage + * controller, as well as non-connected ports + */ +- int hba_len = strlen(hba_path) + 1; ++ int hba_len = strlen(hba->path) + 1; + struct dirent *ent; + DIR *dir; + char *path = NULL; +@@ -2390,7 +2420,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + path = devt_to_devpath(makedev(major, minor), 1, NULL); + if (!path) + continue; +- if (!path_attached_to_hba(path, hba_path)) { ++ if (!path_attached_to_hba(path, hba->path)) { + free(path); + path = NULL; + continue; +@@ -2493,6 +2523,8 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + printf(" (%s)\n", buf); + else + printf(" ()\n"); ++ ++ print_encryption_information(fd, hba->type); + close(fd); + } + free(path); +@@ -2557,6 +2589,8 @@ static int print_nvme_info(struct sys_dev *hba) + else + printf("()\n"); + ++ print_encryption_information(fd, hba->type); ++ + skip: + close_fd(&fd); + } +@@ -2812,7 +2846,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle + hba->path, get_sys_dev_type(hba->type)); + if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) { + host_base = ahci_get_port_count(hba->path, &port_count); +- if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { ++ if (ahci_enumerate_ports(hba, port_count, host_base, verbose)) { + if (verbose > 0) + pr_err("failed to enumerate ports on %s controller at %s.\n", + get_sys_dev_type(hba->type), hba->pci_id); +-- +2.41.0 + diff --git a/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch b/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch new file mode 100644 index 0000000..c4b9d0a --- /dev/null +++ b/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch @@ -0,0 +1,114 @@ +From acb8f13be88c224eb1e01f72c1e1fda955bc80ba Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:20 +0100 +Subject: [PATCH 47/66] imsm: drive encryption policy implementation + +IMSM cares about drive encryption state. It is not allowed to mix disks +with different encryption state within one md device. This policy will +verify that attempt to use disks with different encryption states will +fail. Verification is performed for devices NVMe/SATA Opal and SATA. + +There is one exception, Opal SATA drives encryption is not checked when +ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this +reason such drives are treated as without encryption support. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index fbd1c11f..1faab607 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11291,6 +11291,78 @@ test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t + return MDADM_STATUS_ERROR; + } + ++/** ++ * test_and_add_drive_encryption_policy_imsm() - add disk encryption to policies list. ++ * @type: policy type to search in the list. ++ * @pols: list of currently recorded policies. ++ * @disk_fd: file descriptor of the device to check. ++ * @hba: The hba to which the drive is attached, could be NULL if verification is disabled. ++ * @verbose: verbose flag. ++ * ++ * IMSM cares about drive encryption state. It is not allowed to mix disks with different ++ * encryption state within one md device. ++ * If there is no encryption policy on pols we are free to add first one. ++ * If there is a policy then, new must be the same. ++ */ ++static mdadm_status_t ++test_and_add_drive_encryption_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose) ++{ ++ struct dev_policy *expected_policy = pol_find(*pols, (char *)type); ++ struct encryption_information information = {0}; ++ char *encryption_state = "Unknown"; ++ int status = MDADM_STATUS_SUCCESS; ++ bool encryption_checked = true; ++ char devname[PATH_MAX]; ++ ++ if (!hba) ++ goto check_policy; ++ ++ switch (hba->type) { ++ case SYS_DEV_NVME: ++ case SYS_DEV_VMD: ++ status = get_nvme_opal_encryption_information(disk_fd, &information, verbose); ++ break; ++ case SYS_DEV_SATA: ++ case SYS_DEV_SATA_VMD: ++ status = get_ata_encryption_information(disk_fd, &information, verbose); ++ break; ++ default: ++ encryption_checked = false; ++ } ++ ++ if (status) { ++ fd2devname(disk_fd, devname); ++ pr_vrb("Failed to read encryption information of device %s\n", devname); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if (encryption_checked) { ++ if (information.status == ENC_STATUS_LOCKED) { ++ fd2devname(disk_fd, devname); ++ pr_vrb("Device %s is in Locked state, cannot use. Aborting.\n", devname); ++ return MDADM_STATUS_ERROR; ++ } ++ encryption_state = (char *)get_encryption_status_string(information.status); ++ } ++ ++check_policy: ++ if (expected_policy) { ++ if (strcmp(expected_policy->value, encryption_state) == 0) ++ return MDADM_STATUS_SUCCESS; ++ ++ fd2devname(disk_fd, devname); ++ pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected eariler.\n", ++ encryption_state, devname, expected_policy->value); ++ pr_vrb("Disks with different encryption status cannot be used.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ pol_add(pols, (char *)type, encryption_state, "imsm"); ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ + struct imsm_drive_policy { + char *type; + mdadm_status_t (*test_and_add_drive_policy)(const char * const type, +@@ -11300,6 +11372,7 @@ struct imsm_drive_policy { + + struct imsm_drive_policy imsm_policies[] = { + {"controller", test_and_add_drive_controller_policy_imsm}, ++ {"encryption", test_and_add_drive_encryption_policy_imsm} + }; + + mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd, +-- +2.41.0 + diff --git a/SOURCES/0048-mdadm-add-CHANGELOG.md.patch b/SOURCES/0048-mdadm-add-CHANGELOG.md.patch new file mode 100644 index 0000000..4923820 --- /dev/null +++ b/SOURCES/0048-mdadm-add-CHANGELOG.md.patch @@ -0,0 +1,2010 @@ +From 275e5d2fe316202cce5cb1319a83c3cd8fb22dd3 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:10 +0100 +Subject: [PATCH 48/66] mdadm: add CHANGELOG.md + +Bring changelog back to life. Remove ANNOUCEs. It will use markdown +format, to have one style. All releases are migrated to new +changelog. It was a exercise I have taken, to familiarize with the +mdadm history. + +Signed-off-by: Mariusz Tkaczyk +--- + ANNOUNCE-3.0 | 98 ------------- + ANNOUNCE-3.0.1 | 22 --- + ANNOUNCE-3.0.2 | 21 --- + ANNOUNCE-3.0.3 | 29 ---- + ANNOUNCE-3.1 | 33 ----- + ANNOUNCE-3.1.1 | 39 ------ + ANNOUNCE-3.1.2 | 46 ------- + ANNOUNCE-3.1.3 | 46 ------- + ANNOUNCE-3.1.4 | 37 ----- + ANNOUNCE-3.1.5 | 42 ------ + ANNOUNCE-3.2 | 77 ----------- + ANNOUNCE-3.2.1 | 75 ---------- + ANNOUNCE-3.2.2 | 36 ----- + ANNOUNCE-3.2.3 | 24 ---- + ANNOUNCE-3.2.4 | 144 ------------------- + ANNOUNCE-3.2.5 | 31 ----- + ANNOUNCE-3.2.6 | 57 -------- + ANNOUNCE-3.3 | 63 --------- + ANNOUNCE-3.3.1 | 23 ---- + ANNOUNCE-3.3.2 | 16 --- + ANNOUNCE-3.3.3 | 18 --- + ANNOUNCE-3.3.4 | 37 ----- + ANNOUNCE-3.4 | 24 ---- + ANNOUNCE-4.0 | 22 --- + ANNOUNCE-4.1 | 16 --- + ANNOUNCE-4.2 | 19 --- + CHANGELOG.md | 368 +++++++++++++++++++++++++++++++++++++++++++++++++ + ChangeLog | 306 ---------------------------------------- + 28 files changed, 368 insertions(+), 1401 deletions(-) + delete mode 100644 ANNOUNCE-3.0 + delete mode 100644 ANNOUNCE-3.0.1 + delete mode 100644 ANNOUNCE-3.0.2 + delete mode 100644 ANNOUNCE-3.0.3 + delete mode 100644 ANNOUNCE-3.1 + delete mode 100644 ANNOUNCE-3.1.1 + delete mode 100644 ANNOUNCE-3.1.2 + delete mode 100644 ANNOUNCE-3.1.3 + delete mode 100644 ANNOUNCE-3.1.4 + delete mode 100644 ANNOUNCE-3.1.5 + delete mode 100644 ANNOUNCE-3.2 + delete mode 100644 ANNOUNCE-3.2.1 + delete mode 100644 ANNOUNCE-3.2.2 + delete mode 100644 ANNOUNCE-3.2.3 + delete mode 100644 ANNOUNCE-3.2.4 + delete mode 100644 ANNOUNCE-3.2.5 + delete mode 100644 ANNOUNCE-3.2.6 + delete mode 100644 ANNOUNCE-3.3 + delete mode 100644 ANNOUNCE-3.3.1 + delete mode 100644 ANNOUNCE-3.3.2 + delete mode 100644 ANNOUNCE-3.3.3 + delete mode 100644 ANNOUNCE-3.3.4 + delete mode 100644 ANNOUNCE-3.4 + delete mode 100644 ANNOUNCE-4.0 + delete mode 100644 ANNOUNCE-4.1 + delete mode 100644 ANNOUNCE-4.2 + create mode 100644 CHANGELOG.md + delete mode 100644 ChangeLog + +diff --git a/ANNOUNCE-3.0 b/ANNOUNCE-3.0 +deleted file mode 100644 +index f2d4f847..00000000 +--- a/ANNOUNCE-3.0 ++++ /dev/null +@@ -1,98 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0 - A tool for managing Soft RAID under Linux +- +-I am pleased to (finally) announce the availability of +- mdadm version 3.0 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This is a major new version and as such should be treated with some +-caution. However it has seen substantial testing and is considerred +-to be ready for wide use. +- +- +-The significant change which justifies the new major version number is +-that mdadm can now handle metadata updates entirely in userspace. +-This allows mdadm to support metadata formats that the kernel knows +-nothing about. +- +-Currently two such metadata formats are supported: +- - DDF - The SNIA standard format +- - Intel Matrix - The metadata used by recent Intel ICH controlers. +- +-Also the approach to device names has changed significantly. +- +-If udev is installed on the system, mdadm will not create any devices +-in /dev. Rather it allows udev to manage those devices. For this to work +-as expected, the included udev rules file should be installed. +- +-If udev is not installed, mdadm will still create devices and symlinks +-as required, and will also remove them when the array is stopped. +- +-mdadm now requires all devices which do not have a standard name (mdX +-or md_dX) to live in the directory /dev/md/. Names in this directory +-will always be created as symlinks back to the standard name in /dev. +- +-The man pages contain some information about the new externally managed +-metadata. However see below for a more condensed overview. +- +-Externally managed metadata introduces the concept of a 'container'. +-A container is a collection of (normally) physical devices which have +-a common set of metadata. A container is assembled as an md array, but +-is left 'inactive'. +- +-A container can contain one or more data arrays. These are composed from +-slices (partitions?) of various devices in the container. +- +-For example, a 5 devices DDF set can container a RAID1 using the first +-half of two devices, a RAID0 using the first half of the remain 3 devices, +-and a RAID5 over thte second half of all 5 devices. +- +-A container can be created with +- +- mdadm --create /dev/md0 -e ddf -n5 /dev/sd[abcde] +- +-or "-e imsm" to use the Intel Matrix Storage Manager. +- +-An array can be created within a container either by giving the +-container name and the only member: +- +- mdadm -C /dev/md1 --level raid1 -n 2 /dev/md0 +- +-or by listing the component devices +- +- mdadm -C /dev/md2 --level raid0 -n 3 /dev/sd[cde] +- +-To assemble a container, it is easiest just to pass each device in turn to +-mdadm -I +- +- for i in /dev/sd[abcde] +- do mdadm -I $i +- done +- +-This will assemble the container and the components. +- +-Alternately the container can be assembled explicitly +- +- mdadm -A /dev/md0 /dev/sd[abcde] +- +-Then the components can all be assembled with +- +- mdadm -I /dev/md0 +- +-For each container, mdadm will start a program called "mdmon" which will +-monitor the array and effect any metadata updates needed. The array is +-initially assembled readonly. It is up to "mdmon" to mark the metadata +-as 'dirty' and which the array to 'read-write'. +- +-The version 0.90 and 1.x metadata formats supported by previous +-versions for mdadm are still supported and the kernel still performs +-the same updates it use to. The new 'mdmon' approach is only used for +-newly introduced metadata types. +- +-NeilBrown 2nd June 2009 +diff --git a/ANNOUNCE-3.0.1 b/ANNOUNCE-3.0.1 +deleted file mode 100644 +index 91b44284..00000000 +--- a/ANNOUNCE-3.0.1 ++++ /dev/null +@@ -1,22 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.1 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This contains only minor bug fixes over 3.0. If you are using +-3.0, you could consider upgrading. +- +-The brief change log is: +- - Fix various segfaults +- - Fixed for --examine with containers +- - Lots of other little fixes. +- +-NeilBrown 25th September 2009 +diff --git a/ANNOUNCE-3.0.2 b/ANNOUNCE-3.0.2 +deleted file mode 100644 +index 93643d17..00000000 +--- a/ANNOUNCE-3.0.2 ++++ /dev/null +@@ -1,21 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This just contains one bugfix over 3.0.1 - I was obviously a bit hasty +-in releasing that one. +- +-The brief change log is: +- - Fix crash when hosthost is not set, as often happens in +- early boot. +- +-NeilBrown 25th September 2009 +diff --git a/ANNOUNCE-3.0.3 b/ANNOUNCE-3.0.3 +deleted file mode 100644 +index d6117a1d..00000000 +--- a/ANNOUNCE-3.0.3 ++++ /dev/null +@@ -1,29 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This contains a collection of bug fixes and minor enhancements over +-3.0.1. +- +-The brief change log is: +- - Improvements for creating arrays giving just a name, like 'foo', +- rather than the full '/dev/md/foo'. +- - Improvements for assembling member arrays of containers. +- - Improvements to test suite +- - Add option to change increment for RebuildNN messages reported +- by "mdadm --monitor" +- - Improvements to mdmon 'hand-over' from initrd to final root. +- - Handle merging of devices that have left an IMSM array and are +- being re-incorporated. +- - Add missing space in "--detail --brief" output. +- +-NeilBrown 22nd October 2009 +diff --git a/ANNOUNCE-3.1 b/ANNOUNCE-3.1 +deleted file mode 100644 +index 343b85da..00000000 +--- a/ANNOUNCE-3.1 ++++ /dev/null +@@ -1,33 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1 - A tool for managing Soft RAID under Linux +- +-Hot on the heals of 3.0.3 I am pleased to announce the availability of +- mdadm version 3.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-It contains significant feature enhancements over 3.0.x +- +-The brief change log is: +- - Support --grow to change the layout of RAID4/5/6 +- - Support --grow to change the chunksize of raid 4/5/6 +- - Support --grow to change level from RAID1 -> RAID5 -> RAID6 and +- back. +- - Support --grow to reduce the number of devices in RAID4/5/6. +- - Support restart of these grow options which assembling an array +- which is partially grown. +- - Assorted tests of this code, and of different RAID6 layouts. +- +-Note that a 2.6.31 or later is needed to have access to these. +-Reducing devices in a RAID4/5/6 requires 2.6.32. +-Changing RAID5 to RAID1 requires 2.6.33. +- +-You should only upgrade if you need to use, or which to test, these +-features. +- +-NeilBrown 22nd October 2009 +diff --git a/ANNOUNCE-3.1.1 b/ANNOUNCE-3.1.1 +deleted file mode 100644 +index 9e480dc0..00000000 +--- a/ANNOUNCE-3.1.1 ++++ /dev/null +@@ -1,39 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.1 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix release over 3.1, which was withdrawn due to serious +-bugs. So it might be best to ignore 3.1 and say that this is a significant +-feature release over 3.0.x +- +-Significant changes are: +- - RAID level conversion between RAID1, RAID5, and RAID6 are +- possible were the kernel supports it (2.6.32 at least) +- - online chunksize and layout changing for RAID5 and RAID6 +- where the kernel supports it. +- - reduce the number of devices in a RAID4/5/6 array. +- +- - The default metadata is not v1.1. This metadata is stored at the +- start of the device so is safer in many ways but could interfere with +- boot loaded. The old default (0.90) is still available and fully +- supported. +- +- - The default chunksize is now 512K rather than 64K. This seems more +- appropriate for modern devices. +- +- - The default bitmap chunksize for internal bitmaps is now at least +- 64Meg as fine grained bitmaps tend to impact performance more for +- little extra gain. +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.1. +- +-NeilBrown 19th November 2009 +diff --git a/ANNOUNCE-3.1.2 b/ANNOUNCE-3.1.2 +deleted file mode 100644 +index 321b8bef..00000000 +--- a/ANNOUNCE-3.1.2 ++++ /dev/null +@@ -1,46 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.1. +- +-Significant changes are: +- - The default metadata has change again (sorry about that). +- It is now v1.2 and will hopefully stay that way. It turned +- out there with boot-block issues with v1.1 which make it +- unsuitable for a default, though in many cases it is still +- suitable to use. +- - Stopping a container is not permitted when members are still +- active +- - Add 'homehost' to the valid words for the "AUTO" config file +- line. When followed by "-all", this causes mdadm to +- auto-assemble any array belonging to this host, but not +- auto-assemble anything else. +- - Fix some bugs with "--grow --chunksize=" for changing chunksize. +- - VAR_RUN can be easily changed at compile time just like ALT_RUN. +- This gives distros more flexability in how to manage the +- pid and sock files that mdmon needs. +- - Various mdmon fixes +- - Alway make bitmap 4K-aligned if at all possible. +- - If mdadm.conf lists arrays which have inter-dependencies, +- the previously had to be listed in the "right" order. Now +- any order should work. +- - Fix --force assembly of v1.x arrays which are in the process +- of recovering. +- - Add section on 'scrubbing' to 'md' man page. +- - Various command-line-option parsing improvements. +- - ... and lots of other bug fixes. +- +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.2 +- +-NeilBrown 10th March 2010 +diff --git a/ANNOUNCE-3.1.3 b/ANNOUNCE-3.1.3 +deleted file mode 100644 +index 95b2b6c1..00000000 +--- a/ANNOUNCE-3.1.3 ++++ /dev/null +@@ -1,46 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.2 +- +-Significant changes are: +- - mapfile now lives in a fixed location which default to +- /dev/.mdadm/map but can be changed at compile time. This +- location is choses and most distros provide it during early +- boot and preserve it through. As long a /dev exists and is +- writable, /dev/.mdadm will be created. +- Other files file communication with mdmon live here too. +- This fixes a bug reported by Debian and Gentoo users where +- udev would spin in early-boot. +- - IMSM and DDF metadata will not be recognised on partitions +- as they should only be used on whole-disks. +- - Various overflows causes by 2G drives have been addressed. +- - A subarray of an IMSM contain can now be killed with +- --kill-subarray. Also subarrays can be renamed with +- --update-subarray +- - -If (or --incremental --fail) can be used from udev to +- fail and remove from all arrays a device which has been +- unplugged from the system. i.e. hot-unplug-support. +- - "mdadm /dev/mdX --re-add missing" will look for any device +- that looks like it should be a member of /dev/mdX but isn't +- and will automatically --re-add it +- - Now compile with -Wextra to get extra warnings. +- - Lots of minor bug fixes, documentation improvements, etcc +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.3 +- +-It is expected that the next release will be 3.2 with a number of new +-features. 3.1.4 will only happen if important bugs show up before 3.2 +-is stable. +- +-NeilBrown 6th August 2010 +diff --git a/ANNOUNCE-3.1.4 b/ANNOUNCE-3.1.4 +deleted file mode 100644 +index c157a36a..00000000 +--- a/ANNOUNCE-3.1.4 ++++ /dev/null +@@ -1,37 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.4 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.4 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.3. +-3.1.3 had a couple of embarrasing regressions and a couple of other +-issues surfaces which had easy fixes so I decided to make a 3.1.4 +-release after all. +- +-Two fixes related to configs that aren't using udev: +- - Don't remove md devices which 'standard' names on --stop +- - Allow dev_open to work on read-only /dev +-And fixed regressions: +- - Allow --incremental to add spares to an array +- - Accept --no-degraded as a deprecated option rather than +- throwing an error +- - Return correct success status when --incrmental assembling +- a container which does not yet have enough devices. +- - Don't link mdadm with pthreads, only mdmon needs it. +- - Fix compiler warning due to bad use of snprintf +- - Fix spare migration +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.4 +- +-It is expected that the next release will be 3.2 with a number of new +-features. +- +-NeilBrown 31st August 2010 +diff --git a/ANNOUNCE-3.1.5 b/ANNOUNCE-3.1.5 +deleted file mode 100644 +index baa1f921..00000000 +--- a/ANNOUNCE-3.1.5 ++++ /dev/null +@@ -1,42 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.5 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.5 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.4. It contains all the +-important bugfixes found while working on 3.2 and 3.2.1. It will be +-the last 3.1.x release - 3.2.1 is expected to be released in a few days. +- +-Changes include: +- - Fixes for v1.x metadata on big-endian machines. +- - man page improvements +- - Improve '--detail --export' when run on partitions of an md array. +- - Fix regression with removing 'failed' or 'detached' devices. +- - Fixes for "--assemble --force" in various unusual cases. +- - Allow '-Y' to mean --export. This was documented but not implemented. +- - Various fixed for handling 'ddf' metadata. This is now more reliable +- but could benefit from more interoperability testing. +- - Correctly list subarrays of a container in "--detail" output. +- - Improve checks on whether the requested number of devices is supported +- by the metadata - both for --create and --grow. +- - Don't remove partitions from a device that is being included in an +- array until we are fully committed to including it. +- - Allow "--assemble --update=no-bitmap" so an array with a corrupt +- bitmap can still be assembled. +- - Don't allow --add to succeed if it looks like a "--re-add" is probably +- wanted, but cannot succeed. This avoids inadvertently turning +- devices into spares when an array is failed. +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.5 +- +- +-NeilBrown 23rd March 2011 +- +diff --git a/ANNOUNCE-3.2 b/ANNOUNCE-3.2 +deleted file mode 100644 +index 9e282bc6..00000000 +--- a/ANNOUNCE-3.2 ++++ /dev/null +@@ -1,77 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2 - A tool for managing Soft RAID under Linux (DEVEL ONLY) +- +-I am pleased to announce the availability of +- mdadm version 3.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm devel-3.2 +- http://neil.brown.name/git?p=mdadm +- +-This is a "Developers only" release. Please don't consider using it +-or making it available to others without reading the following. +- +- +-By far the most significant change in this release related to the +-management of reshaping arrays. This code has been substantially +-re-written so that it can work with 'externally managed metadata' - +-Intel's IMSM in particular. We now support level migration and +-OnLine Capacity Expansion on these arrays. +- +-However, while the code largely works it has not been tested +-exhaustively so there are likely to be problems. As the reshape code +-for native metadata arrays was changed as part of this rewrite these +-problems could also result in regressions for reshape of native +-metadata. +- +-It is partly to encourage greater testing that this release is being +-made. Any reports of problem - particular reproducible recipes for +-triggering the problems - will be gratefully received. +- +-It is hopped that a "3.2.1" release will be available in early March +-which will be a bugfix release over this and can be considered +-suitable for general use. +- +-Other changes of note: +- +- - Policy framework. +- Various policy statements can be made in the mdadm.conf to guide +- the behaviour of mdadm, particular with regards to how new devices +- are treated by "mdadm -I". +- Depending on the 'action' associated with a device (identified by +- its 'path') such need devices can be automatically re-added to and +- existing array that they previously fell out off, or automatically +- added as a spare if they appear to contain no data. +- +- - mdadm now has a limited understanding of partition tables. This +- allows the policy framework to make decisions about partitioned +- devices as well. +- +- - --incremental --remove can be told what --path the device was on, +- and this info will be recorded so that another device appearing at +- the same physical location can be preferentially added to the same +- array (provides the spare-same-slot action policy applied to the +- path). +- +- - A new flags "--invalid-backup" flag is available in --assemble +- mode. This can be used to re-assemble an array which was stopping +- in the middle of a reshape, and for which the 'backup file' is no +- longer available or is corrupted. The array may have some +- corruption in it at the point where reshape was up to, but at least +- the rest of the array will become available. +- +- +- - Various internal restructuring - more is needed. +- +- +-Any feed back and bug reports are always welcomed at: +- linux-raid@vger.kernel.org +- +-And please: don't use this in production - particularly not the +---grow functionality. +- +-NeilBrown 1st February 2011 +- +- +diff --git a/ANNOUNCE-3.2.1 b/ANNOUNCE-3.2.1 +deleted file mode 100644 +index 0e7826ca..00000000 +--- a/ANNOUNCE-3.2.1 ++++ /dev/null +@@ -1,75 +0,0 @@ +- +- +-I am pleased to announce the availability of +- mdadm version 3.2.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-Many of the changes in this release are of internal interest only, +-restructuring and refactoring code and so forth. +- +-Most of the bugs found and fixed during development for 3.2.1 have been +-back-ported for the recently-release 3.1.5 so this release primarily +-provides a few new features over 3.1.5. +- +-They include: +- - policy framework +- Policy can be expressed for moving spare devices between arrays, and +- for how to handle hot-plugged devices. This policy can be different +- for devices plugged in to different controllers etc. +- This, for example, allows a configuration where when a device is plugged +- in it is immediately included in an md array as a hot spare and +- possibly starts recovery immediately if an array is degraded. +- +- - some understanding of mbr and gpt paritition tables +- This is primarly to support the new hot-plug support. If a +- device is plugged in and policy suggests it should have a partition table, +- the partition table will be copied from a suitably similar device, and +- then the partitions will hot-plug and can then be added to md arrays. +- +- - "--incremental --remove" can remember where a device was removed from +- so if a device gets plugged back in the same place, special policy applies +- to it, allowing it to be included in an array even if a general hotplug +- will not be included. +- +- - enhanced reshape options, including growing a RAID0 by converting to RAID4, +- restriping, and converting back. Also convertions between RAID0 and +- RAID10 and between RAID1 and RAID10 are possible (with a suitably recent +- kernel). +- +- - spare migration for IMSM arrays. +- Spare migration can now work across 'containers' using non-native metadata +- and specifically Intel's IMSM arrays support spare migrations. +- +- - OLCE and level migration for Intel IMSM arrays. +- OnLine Capacity Expansion and level migration (e.g. RAID0 -> RAID5) is +- supported for Intel Matrix Storage Manager arrays. +- This support is currently 'experimental' for technical reasons. It can +- be enabled with "export MDADM_EXPERIMENTAL=1" +- +- - avoid including wayward devices +- If you split a RAID1, mount the two halves as two separate degraded RAID1s, +- and then later bring the two back together, it is possible that the md +- metadata won't properly show that one must over-ride the other. +- mdadm now does extra checking to detect this possibilty and avoid +- potentially corrupting data. +- +- - remove any possible confusion between similar options. +- e.g. --brief and --bitmap were mapped to 'b' and mdadm wouldn't +- notice if one was used where the other was expected. +- +- - allow K,M,G suffixes on chunk sizes +- +- +-While mdadm-3.2.1 is considered to be reasonably stable, you should +-only use it if you want to try out the new features, or if you +-generally like to be on the bleeding edge. If the new features are not +-important to you, then 3.1.5 is probably the appropriate version to be using +-until 3.2.2 comes out. +- +-NeilBrown 28th March 2011 +diff --git a/ANNOUNCE-3.2.2 b/ANNOUNCE-3.2.2 +deleted file mode 100644 +index b70d18b9..00000000 +--- a/ANNOUNCE-3.2.2 ++++ /dev/null +@@ -1,36 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a stablising release for the 3.2 series. +-Many of the changes just fix bugs introduces in 3.2 or 3.2.1. +- +-There are some new features. They are: +- - reshaping IMSM (Intel metadata) arrays is no longer 'experimental', +- it should work properly and be largely compatible with IMSM drivers in +- other platforms. +- - --assume-clean can be used with --grow --size to avoid resyncing the +- new part of the array. This is only support with very new kernels. +- - RAID0 arrays can have chunksize which is not a power of 2. This has been +- supported in the kernel for a while but is only now supprted by +- mdadm. +- +- - A new tool 'raid6check' is available which can check a RAID6 array, +- or part of it, and report which device is most inconsistent with the +- others if any stripe is inconsistent. This is still under development +- and does not have a man page yet. If anyone tries it out and has any +- questions or experience to report, they would be most welcome on +- linux-raid@vger.kernel.org. +- +-Future releases in the 3.2 series will only be made if bugfixes are needed. +-The next release to add features is expected to be 3.3. +- +-NeilBrown 17th June 2011 +diff --git a/ANNOUNCE-3.2.3 b/ANNOUNCE-3.2.3 +deleted file mode 100644 +index 8a8dba46..00000000 +--- a/ANNOUNCE-3.2.3 ++++ /dev/null +@@ -1,24 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a bugfix release for the 3.2 series with many +-minor fixes with little or no impact. +- +-The largest single area of change is support for reshape of Intel +-IMSM arrays (OnLine Capacity Explansion and Level Migtration). +-Among other fixes, this now has a better chance of surviving if a +-device fails during reshape. +- +-Upgrading is recommended - particularly if you use mdadm for IMSM +-arrays - but not essential. +- +-NeilBrown 23rd December 2011 +diff --git a/ANNOUNCE-3.2.4 b/ANNOUNCE-3.2.4 +deleted file mode 100644 +index e3216786..00000000 +--- a/ANNOUNCE-3.2.4 ++++ /dev/null +@@ -1,144 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.4 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.4 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a bugfix release for the 3.2 series with many +-minor fixes with little or no impact. +- +-"--oneline" log of changes is below. Some notable ones are: +- +- - --offroot argument to improve interactions between mdmon and initrd +- - --prefer argument to select which /dev names to display in some +- circumstances. +- - relax restructions on when "--add" will be allowed +- - Fix bug with adding write-intent-bitmap to active array +- - Now defaults to "/run/mdadm" for storing run-time files. +- +-Upgrading is encouraged. +- +-The next mdadm release is expected to be 3.3 with a number of new +-features. +- +-NeilBrown 9th May 2012 +- +-77b3ac8 monitor: make return from read_and_act more symbolic. +-68226a8 monitor: ensure we retry soon when 'remove' fails. +-8453f8d fix: Monitor sometimes crashes +-90fa1a2 Work around gcc-4.7's strict aliasing checks +-0c4304c fix: container creation with --incremental used. +-5d1c7cd FIX: External metadata sometimes is not updated +-3c20f98 FIX: mdmon check in reshape_container() can cause a problem +-59ab9f5 FIX: Typo error in fprint command +-9587c37 imsm: load_super_imsm_all function refactoring +-ec50f7b imsm: load_imsm_super_all supports loading metadata from the device list +-ca9de18 imsm: validate the number of imsm volumes per controller +-30602f5 imsm: display fd in error trace when when store_imsm_mpb failes +-eb155f6 mdmon: Use getopt_long() to parse command line options +-08ca2ad Add --offroot argument to mdadm +-da82751 Add --offroot argument to mdmon +-a0963a8 Spawn mdmon with --offroot if mdadm was launched with --offroot +-f878b24 imsm: fix, the second array need to have the whole available space on devices +-d597705 getinfo_super1: Use MaxSector in place of sb->size +-6ef8905 super1: make aread/awrite always use an aligned buffer. +-de5a472 Remove avail_disks arg from 'enough'. +-da8fe5a Assemble: fix --force assemble during reshape. +-b10c663 config: fix handing of 'homehost' in AUTO line. +-92d49ec FIX: NULL pointer to strdup() can be passed +-d2bde6d imsm: FIX: No new missing disks are allowed during general migration +-111e9fd FIX: Array is not run when expansion disks are added +-bf5cf7c imsm: FIX: imsm_get_allowed_degradation() doesn't count degradation for raid1 +-50927b1 Fix: Sometimes mdmon throws core dump during reshape +-78340e2 Flush mdmon before next reshape step during container operation +-e174219 imsm: FIX: Chunk size migration problem +-f93346e FIX: use md position to reshape restart +-6a75c8c imsm: FIX: use md position to reshape restart +-51d83f5 imsm: FIX: Clear migration record when migration switches to next volume. +-e1dd332 FIX: restart reshape when reshape process is stopped just between 2 reshapes +-1ca90aa FIX: Do not try to (continue) reshape using inactive array +-9f1b0f0 config: conf_match should ignore devname when not set. +-d669228 Use posix_memalign() for memory used to write bitmaps +-178950e FIX: Changes in '0' case for reshape position verification +-9200d41 avoid double-free upon "old buggy kernel" sysfs_read failure +-4011421 Print error message if failing to write super for 1.x metadata +-0011874 Use MDMON_DIR for pid files created in Monitor.c +-56d1885 Assemble: don't use O_EXCL until we have checked device content. +-b720636 Assemble: support assembling of a RAID0 being reshaped. +-c69ffac Manage: allow --re-add to failed array. +-52f07f5 Reset bad flag on map update +-911cead super1: support superblocks up to 4K. +-ad6db3c Create: reduce the verbosity of 'default_layout'. +-b2bfdfa super1.c don't keep recalculating bitmap pointer +-4122675 Define and use SUPER1_SIZE for allocations +-1afa930 init_super1() memset full buffer allocated for superblock +-2de0b8a match_metadata_desc1(): Use calloc instead of malloc+memset +-3c0bcd4 Use 4K buffer alignment for superblock allocations +-308340a Use struct align_fd to cache fd's block size for aligned reads/writes +-65ed615 match_metadata_desc0(): Use calloc instead of malloc+memset +-de89706 Generalize ROUND_UP() macro and introduce matching ROUND_UP_PTR() +-0a2f189 super1.c: use ROUND_UP/ROUND_UP_PTR +-654a381 super-intel.c: Use ROUND_UP() instead of manually coding it +-42d5dfd __write_init_super_ddf(): Use posix_memalign() instead of static aligned buffer +-d4633e0 Examine: fix array size calculation for RAID10. +-e62b778 Assemble: improve verbose logging when including old devices. +-0073a6e Remove possible crash during RAID6 -> RAID5 reshape. +-69fe207 Incremental: fix adding devices with --incremental +-bcbb311 Manage: replace 'return 1' with 'goto abort'. +-9f58469 Manage: freeze recovery while adding multiple devices. +-ae6c05a Create: round off size for RAID1 arrays. +-5ca3a90 Grow: print useful error when converting RAID1->RAID5 will fail. +-c07d640 Fix tests/05r1-re-add-nosupper +-2d762ad Fix the new ROUND_UP macro. +-fd324b0 sysfs: fixed sysfs_freeze_array array to work properly with Manage_subdevs. +-5551b11 imsm: avoid overflows for disks over 1TB +-97f81ee clear hi bits if not used after loading metadata from disk +-e03640b simplify calculating array_blocks +-29cd082 show 2TB volumes/disks support in --detail-platform +-2cc699a check volume size in validate_geometry_imsm_orom +-9126b9a check that no disk over 2TB is used to create container when no support +-027c374 imsm: set 2tb disk attribute for spare +-3556c2f Fix typo: wan -> want +-15632a9 parse_size: distinguish between 0 and error. +-fbdef49 Bitmap_offset is a signed number +-508a7f1 super1: leave more space in front of data by default. +-40110b9 Fix two typos in fprintf messages +-342460c mdadm man page: fix typo +-0e7f69a imsm: display maximum volumes per controller and array +-36fd8cc imsm: FIX: Update function imsm_num_data_members() for Raid1/10 +-7abc987 imsm: FIX: Add volume size expand support to imsm_analyze_change() +-f3871fd imsm: Add new metadata update for volume size expansion +-54397ed imsm: Execute size change for external metatdata +-016e00f FIX: Support metadata changes rollback +-fbf3d20 imsm: FIX: Support metadata changes rollback +-44f6f18 FIX: Extend size of raid0 array +-7e7e9a4 FIX: Respect metadata size limitations +-65a9798 FIX: Detect error and rollback metadata +-13bcac9 imsm: Add function imsm_get_free_size() +-b130333 imsm: Support setting max size for size change operation +-c41e00b imsm: FIX: Component size alignment check +-58d26a2 FIX: Size change is possible as standalone change only +-4aecb54 FIX: Assembled second array is in read only state during reshape +-ae2416e FIX: resolve make everything compilation error +-480f356 Raid limit of 1024 when scanning for devices. +-c2ecf5f Add --prefer option for --detail and --monitor +-0a99975 Relax restrictions on when --add is permitted. +-7ce0570 imsm: fix: rebuild does not continue after reboot +-b51702b fix: correct extending size of raid0 array +-34a1395 Fix sign extension of bitmap_offset in super1.c +-012a864 Introduce sysfs_set_num_signed() and use it to set bitmap/offset +-5d7b407 imsm: fix: thunderdome may drop 2tb attribute +-5ffdc2d Update test for "is udev active". +-96fd06e Adjust to new standard of /run +-974e039 test: don't worry too much about array size. +-b0a658f Grow: failing the set the per-device size is not an error. +-36614e9 super-intel.c: Don't try to close negative fd +-562aa10 super-intel.c: Fix resource leak from opendir() +- +diff --git a/ANNOUNCE-3.2.5 b/ANNOUNCE-3.2.5 +deleted file mode 100644 +index 396da12a..00000000 +--- a/ANNOUNCE-3.2.5 ++++ /dev/null +@@ -1,31 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.5 - A tool for managing Soft RAID under Linux +- +-I am somewhat disappointed to have to announce the availability of +- mdadm version 3.2.5 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release primarily fixes a serious regression in 3.2.4. +-This regression does *not* cause any risk to data. It simply +-means that adding a device with "--add" would sometime fail +-when it should not. +- +-The fix also includes a couple of minor fixes such as making +-the "--layout=preserve" option to "--grow" work again. +- +-A reminder that the default location for runtime files is now +-"/run/mdadm". If you compile this for a distro that does not +-have "/run", you will need to compile with an alternate setting for +-MAP_DIR. e.g. +- make MAP_DIR=/var/run/mdadm +-or +- make MAP_DIR=/dev/.mdadm +- +-NeilBrown 18th May 2012 +- +diff --git a/ANNOUNCE-3.2.6 b/ANNOUNCE-3.2.6 +deleted file mode 100644 +index f5cfd492..00000000 +--- a/ANNOUNCE-3.2.6 ++++ /dev/null +@@ -1,57 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.6 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.6 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This is a stablity release which adds a number of bugfixs to 3.2.5. +-There are no real stand-out fixes, just lots of little bits and pieces. +- +-Below is the "git log --oneline --reverse" list of changes since +-3.2.5. +- +-NeilBrown 25th October 2012 +- +-b7e05d2 udev-rules: prevent systemd from mount devices before they are ready. +-0d478e2 mdadm: Fix Segmentation fault. +-42f0ca1 imsm: fix: correct checking volume's degradation +-fcf2195 Monitor: fix inconsistencies in values for ->percent +-5f862fb Monitor: Report NewArray when an array the disappeared, reappears. +-6f51b1c Monitor: fix reporting for Fail vs FailSpare etc. +-68ad53b mdmon: fix arg parsing. +-517f135 Assemble: don't leak memory with fdlist. +-090900c udev-rules: prevent systemd from mount devices before they are ready. +-446e000 sha1.h: remove ansidecl.h header inclusion +-ec894f5 Manage: zero metadata before adding to 'external' array. +-3a84db5 ddf: allow a non-spare to be used to recovery a missing device. +-c5d61ca ddf: hack to fix container recognition. +-23084aa mdmon: fix arg processing for -a +-c4e96a3 mdmon: allow --takeover when original was started with --offroot +-80841df find_free_devnum: avoid auto-using names in /etc/mdadm.conf +-c5c56d6 mapfile: fix mapfile rebuild for containers +-aec89f6 fix segfaults in Detail() +-2117ad1 Fix 'enough' function for RAID10. +-0bc300d Use --offroot flag when assembling md arrays via --incrmental +-ac78f24 Grow: make warning about old metadata more explicit. +-14026ab Replace sha1.h with slightly older version. +-6f6809f Add zlib license to crc32.c +-5267ba0 Handles spaces in array names better. +-c51f288 imsm: allow --assume-clean to work. +-acf7076 Grow: allow --grow --continue to work for native metadata. +-335d2a6 Grow: fix a couple of typos with --assume-clean usage +-9ff1427 Fix open_container +-3713633 mdadm: super0: do not override uuid with homehost +-31bff58 Trivial bugfix and spelling fixes. +-e1e539f Detail: don't report a faulty device as 'spare' or 'rebuilding'. +-22a6461 super0: allow creation of array on 2TB+ devices. +-a5d47a2 Create new md devices consistently +-eb48676 Monitor: don't complain about non-monitorable arrays in mdadm.conf +-ecdf2d7 Query: don't be confused by partition tables. +-f7b75c1 Query: allow member of non-0.90 arrays to be better reported. +diff --git a/ANNOUNCE-3.3 b/ANNOUNCE-3.3 +deleted file mode 100644 +index f770aa13..00000000 +--- a/ANNOUNCE-3.3 ++++ /dev/null +@@ -1,63 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3 - A tools for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm +- +-This is a major new release so don't be too surprised if there are a +-few issues. If I hear about them they will be fixed in 3.3.1. +-git log reports nearly 500 changes since 3.2.6 so I won't list them +-all. +- +-Some highlights are: +- +-- Some array reshapes can proceed without needing backup file. +- This is done by changing the 'data_offset' so we never need to write +- any data back over where it was before. If there is no "head space" +- or "tail space" to allow data_offset to change, the old mechanism +- with a backup file can still be used. +-- RAID10 arrays can be reshaped to change the number of devices, +- change the chunk size, or change the layout between 'near' +- and 'offset'. +- This will always change data_offset, and will fail if there is no +- room for data_offset to be moved. +-- "--assemble --update=metadata" can convert a 0.90 array to a 1.0 array. +-- bad-block-logs are supported (but not heavily tested yet) +-- "--assemble --update=revert-reshape" can be used to undo a reshape +- that has just been started but isn't really wanted. This is very +- new and while it passes basic tests it cannot be guaranteed. +-- improved locking between --incremental and --assemble +-- uses systemd to run "mdmon" if systemd is configured to do that. +-- kernel names of md devices can be non-numeric. e.g. "md_home" rather than +- "md0". This will probably confuse lots of other tools, so you need to +- echo CREATE names=yes >> /etc/mdadm.conf +- or the feature will not be used. (you also need a reasonably new kernel). +-- "--stop" can be given a kernel name instead of a device name. i.e +- mdadm --stop md4 +- will work even if /dev/md4 doesn't exist. +-- "--detail --export" has some information about the devices in the array +-- --dump and --restore can be used to backup and restore the metadata on an +- array. +-- Hot-replace is supported with +- mdadm /dev/mdX --replace /dev/foo +- and +- mdadm /dev/mdX --replace /dev/foo --with /dev/bar +-- Config file can be a directory in which case all "*.conf" files are +- read in lexical order. +- Default is to read /etc/mdadm.conf and then /etc/mdadm.conf.d +- Thus +- echo CREATE name=yes > /etc/mdadm.conf.d/names.conf +- will also enable the use of named md devices. +- +-- Lots of improvements to DDF support including adding support for +- RAID10 (thanks Martin Wilck). +- +-and lots of bugfixes and other little changes. +- +-NeilBrown 3rd September 2013 +diff --git a/ANNOUNCE-3.3.1 b/ANNOUNCE-3.3.1 +deleted file mode 100644 +index 7d5e666e..00000000 +--- a/ANNOUNCE-3.3.1 ++++ /dev/null +@@ -1,23 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.1 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.1 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-The main changes are: +- - lots of work on "DDF" support. Hopefully it will be more stable +- now. Bug reports are always welcome. +- - improved interactions with 'systemd'. Where possible, background +- tasks are run from systemd (if it is present) rather then forking +- disassociationg from the session. This is important because udev +- doesn't really let you disassociate. +- +-though there are a number of other little bug fixes too. +- +-NeilBrown 5th June 2014 +diff --git a/ANNOUNCE-3.3.2 b/ANNOUNCE-3.3.2 +deleted file mode 100644 +index 6b549611..00000000 +--- a/ANNOUNCE-3.3.2 ++++ /dev/null +@@ -1,16 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.2 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.2 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-Changes since 3.3.1 are mostly little bugfixes and some man-page +-updates. +- +-NeilBrown 21st August 2014 +diff --git a/ANNOUNCE-3.3.3 b/ANNOUNCE-3.3.3 +deleted file mode 100644 +index ac1b2173..00000000 +--- a/ANNOUNCE-3.3.3 ++++ /dev/null +@@ -1,18 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.3 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.3 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-The 100 changes since 3.3.3 are mostly little bugfixes and some improvements +-to the selftests. +-raid6check now handle all RAID6 layouts including DDF correctly. +-See git log for the rest. +- +-NeilBrown 24th July 2015 +diff --git a/ANNOUNCE-3.3.4 b/ANNOUNCE-3.3.4 +deleted file mode 100644 +index 52b94562..00000000 +--- a/ANNOUNCE-3.3.4 ++++ /dev/null +@@ -1,37 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.4 - A tool for managing md Soft RAID under Linux +- +-I am somewhat disappointed to have to announce the availability of +- mdadm version 3.3.4 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-In mdadm-3.3 a change was made to how IMSM (Intel Matrix Storage +-Manager) metadata was handled. Previously an IMSM array would only +-be assembled if it was attached to an IMSM controller. +- +-In 3.3 this was relaxed as there are circumstances where the +-controller is not properly detected. Unfortunately this has negative +-consequences which have only just come to light. +- +-If you have an IMSM RAID1 configured and then disable RAID in the +-BIOS, the metadata will remain on the devices. If you then install +-some other OS on one device and then install Linux on the other, Linux +-might eventually start noticing the IMSM metadata (depending a bit on whether +-mdadm is included in the initramfs) and might start up the RAID1. This could +-copy one device over the other, thus trashing one of the installations. +- +-Not good. +- +-So with this release IMSM arrays will only be assembled if attached to +-an IMSM controller, or if "--force" is given to --assemble, or if the +-environment variable IMSM_NO_PLATFORM is set (used primarily for +-testing). +- +-I strongly recommend upgrading to 3.3.4 if you are using 3.3 or later. +- +-NeilBrown 3rd August 2015. +diff --git a/ANNOUNCE-3.4 b/ANNOUNCE-3.4 +deleted file mode 100644 +index 2689732d..00000000 +--- a/ANNOUNCE-3.4 ++++ /dev/null +@@ -1,24 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.4 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.4 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm +- +-The new second-level version number reflects significant new +-functionality, particular support for journalled RAID5/6 and clustered +-RAID1. This new support is probably still buggy. Please report bugs. +- +-There are also a number of fixes for Intel's IMSM metadata support, +-and an assortment of minor bug fixes. +- +-I plan for this to be the last release of mdadm that I provide as I am +-retiring from MD and mdadm maintenance. Jes Sorensen has volunteered +-to oversee mdadm for the next while. Thanks Jes! +- +-NeilBrown 28th January 2016 +diff --git a/ANNOUNCE-4.0 b/ANNOUNCE-4.0 +deleted file mode 100644 +index f79c5408..00000000 +--- a/ANNOUNCE-4.0 ++++ /dev/null +@@ -1,22 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.0 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 4.0 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The update in major version number primarily indicates this is a +-release by it's new maintainer. In addition it contains a large number +-of fixes in particular for IMSM RAID and clustered RAID support. In +-addition this release includes support for IMSM 4k sector drives, +-failfast and better documentation for journaled RAID. +- +-This is my first release of mdadm. Please thank Neil Brown for his +-previous work as maintainer and blame me for all the bugs I caused +-since taking over. +- +-Jes Sorensen, 2017-01-09 +diff --git a/ANNOUNCE-4.1 b/ANNOUNCE-4.1 +deleted file mode 100644 +index a273b9a0..00000000 +--- a/ANNOUNCE-4.1 ++++ /dev/null +@@ -1,16 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.1 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 4.1 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The update constitutes more than one year of enhancements and bug fixes +-including for IMSM RAID, Partial Parity Log, clustered RAID support, +-improved testing, and gcc-8 support. +- +-Jes Sorensen, 2018-10-01 +diff --git a/ANNOUNCE-4.2 b/ANNOUNCE-4.2 +deleted file mode 100644 +index 8b22d09f..00000000 +--- a/ANNOUNCE-4.2 ++++ /dev/null +@@ -1,19 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.2 - A tool for managing md Soft RAID under Linux +- +-I am pleased to finally announce the availability of mdadm-4.2. +-get 4.2 out the door soon. +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The release includes more than two years of development and bugfixes, +-so it is difficult to remember everything. Highlights include +-enhancements and bug fixes including for IMSM RAID, Partial Parity +-Log, clustered RAID support, improved testing, and gcc-9 support. +- +-Thank you everyone who contributed to this release! +- +-Jes Sorensen, 2021-12-30 +diff --git a/CHANGELOG.md b/CHANGELOG.md +new file mode 100644 +index 00000000..c1997ba7 +--- /dev/null ++++ b/CHANGELOG.md +@@ -0,0 +1,368 @@ ++# Release [mdadm-4.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.3) ++ ++Features: ++- **IMSM_NO_PLATFORM** boot parameter support from Neil Brown. ++- **--write-zeros** option support by Logan Gunthorpe. ++- **IMSM** monetization by VMD register from Mateusz Grzonka. ++- RST SATA under VMD support from Kevin Friedberg. ++- Strong name rules from Mariusz Tkaczyk. ++ ++Fixes: ++- Unify failed raid behavior from Coly Li. ++- Rework of **--update** options from Mateusz Kusiak. ++- **mdmon-initrd** service from Neil Brown. ++- **IMSM** expand functionality rework from Mariusz Tkaczyk. ++- Mdmonitor improvements from Mateusz Grzonka. ++- Failed state verification from Mateusz Kusiak and Kinga Tanska. ++ ++# Release [mdadm-4.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.2) ++ ++The release includes more than two years of development and bugfixes, so it is difficult to ++remember everything. Highlights include enhancements and bug fixes including for **IMSM** RAID, ++Partial Parity Log, clustered RAID support, improved testing, and gcc-9 support. ++ ++# Release [mdadm-4.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.1) ++ ++The update constitutes more than one year of enhancements and bug fixes including for **IMSM** ++RAID, Partial Parity Log, clustered RAID support, improved testing, and gcc-8 support. ++ ++# Release [mdadm-4.0](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.0) ++ ++The update in major version number primarily indicates this is a release by it's new maintainer. ++In addition it contains a large number of fixes in particular for IMSM RAID and clustered RAID ++support. In addition, this release includes support for IMSM 4k sector drives, failfast and better ++documentation for journaled RAID. ++ ++This is my first release of mdadm. Please thank Neil Brown for his previous work as maintainer and ++blame me for all the bugs I caused since taking over. ++ ++# Release [mdadm-3.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.4) ++ ++- Support for journalled RAID5/6 and clustered RAID1. This new support is probably still buggy. ++ Please report bugs. ++ ++- There are also a number of fixes for **IMSM** support and an assortment of minor bug fixes. ++ ++- I plan for this to be the last release of mdadm that I provide as I am retiring from MD and mdadm ++ maintenance. Jes Sorensen has volunteered to oversee mdadm for the next while. Thanks Jes! ++ ++# Release [mdadm-3.3.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.4) ++ ++**I strongly recommend upgrading to 3.3.4 if you are using 3.3 or later with IMSM.** ++ ++- **IMSM** metadata assemble fixes. ++ ++ In mdadm-3.3 a change was made to how **IMSM** metadata was handled. Previously an **IMSM** array ++ would only be assembled if it was attached to an **IMSM** controller. In 3.3 this was relaxed as ++ there are circumstances where the controller is not properly detected. Unfortunately, this has ++ negative consequences which have only just come to light. ++ ++ If you have an IMSM RAID1 configured and then disable RAID in the BIOS, the metadata will remain ++ on the devices. If you then install some other OS on one device and then install Linux on the ++ other, Linux might eventually start noticing the IMSM metadata (depending a bit on whether ++ mdadm is included in the initramfs) and might start up the RAID1. This could copy one device over ++ the other, thus trashing one of the installations. ++ ++ So, with this release IMSM arrays will only be assembled if attached to an **IMSM** controller, ++ or if **--force** is given to **--assemble**, or if the environment variable ++ **IMSM_NO_PLATFORM=1** is set (used primarily for testing). ++ ++# Release [mdadm-3.3.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.3) ++ ++- The 100 changes since 3.3.3 are mostly little bugfixes and some improvements to the self-tests. ++- raid6check now handle all RAID6 layouts including **DDF** correctly. See git log for the rest. ++ ++# Release [mdadm-3.3.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.2) ++ ++- Little bugfixes and some man-page updates. ++ ++# Release [mdadm-3.3.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.1) ++ ++- lots of work on **DDF** support. ++- Improved interactions with **systemd**. Where possible, background tasks are run from systemd ++ rather than forking. ++- Number of other little bug fixes too. ++ ++# Release [mdadm-3.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3) ++ ++- Some array reshapes can proceed without needing backup file. This is done by changing the ++ data_offset* so we never need to write any data back over where it was before. If there is no ++ 'head space' or 'tail space' to allow *data_offset* to change, the old mechanism with a backup ++ file can still be used. ++ ++- RAID10 arrays can be reshaped to change the number of devices, change the chunk size, or change ++ the layout between *near* and *offset*. ++ This will always change *data_offset*, and will fail if there is no room for *data_offset* to be ++ moved. ++ ++- **--assemble --update=metadata** can convert a **0.90** array to a **1.0** array. ++ ++- **bad-block-logs** are supported (but not heavily tested yet). ++ ++- **--assemble --update=revert-reshape** can be used to undo a reshape that has just been started ++ but isn't really wanted. This is very new and while it passes basic tests it cannot be ++ guaranteed. ++ ++- improved locking between **--incremental** and **--assemble**. ++ ++- uses systemd to run **mdmon** if systemd is configured to do that. ++- kernel names of md devices can be non-numeric. e.g. "md_home" rather than ++ "md0". This will probably confuse lots of other tools, so you need to ++ **echo CREATE names=yes >> /etc/mdadm.conf** or the feature will not be used (you also need a ++ reasonably new kernel). ++ ++- **--stop** can be given a kernel name instead of a device name. i.e. **mdadm --stop md4** will ++ work even if /dev/md4 doesn't exist. ++ ++- **--detail --export** has some information about the devices in the array. ++- **--dump** and **--restore** can be used to backup and restore the metadata on an array. ++- Hot-replace is supported with **mdadm /dev/mdX --replace /dev/foo** and ++ **mdadm /dev/mdX --replace /dev/foo --with /dev/bar**. ++ ++- Config file can be a directory in which case all "*.conf" files are read in lexical order. ++ Default is to read **/etc/mdadm.conf** and then **/etc/mdadm.conf.d**. Thus ++ **echo CREATE name=yes > /etc/mdadm.conf.d/names.conf** will also enable the use of named md ++ devices. ++ ++- Lots of improvements to **DDF** support including adding support for RAID10 (thanks Martin Wilck). ++ ++# Release [mdadm-3.2.6](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.6) ++ ++- There are no real stand-out fixes, just lots of little bits and pieces. ++ ++# Release [mdadm-3.2.5](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.5) ++ ++- This release primarily fixes a serious regression in 3.2.4. This regression does *not* cause ++ any risk to data. It simply means that adding a device with **--add** would sometime fail ++ when it should not. ++- The fix also includes a couple of minor fixes such as making the **--layout=preserve** option to ++ **--grow** work again. ++ ++# Release [mdadm-3.2.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.4) ++ ++ - **--offroot** argument to improve interactions between mdmon and initrd. ++ - **--prefer** argument to select which */dev* names to display in some circumstances. ++ - relax restrictions on when **--add** will be allowed. ++ - Fix bug with adding write-intent-bitmap to active array. ++ - Now defaults to */run/mdadm* for storing run-time files. ++ ++# Release [mdadm-3.2.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.3) ++ ++- The largest single area of change is support for reshape of Intel IMSM arrays (OnLine Capacity ++ Expansion and Level Migration). ++- Among other fixes, this now has a better chance of surviving if a device fails during reshape. ++ ++# Release [mdadm-3.2.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.2) ++ ++- reshaping IMSM (Intel metadata) arrays is no longer 'experimental', it should work properly and be ++ largely compatible with IMSM drivers in other platforms. ++- **--assume-clean** can be used with **--grow --size** to avoid resyncing the new part of the ++ array. This is only support with very new kernels. ++- RAID0 arrays can have chunksize which is not a power of 2. This has been supported in the kernel ++ for a while but is only now supported by mdadm. ++ ++- A new tool **raid6check** is available, which can check a RAID6 array, or part of it and report ++ which device is most inconsistent with the others if any stripe is inconsistent. This is still ++ under development and does not have a man page yet. If anyone tries it out and has any questions ++ or experience to report, they would be most welcome on linux-raid@vger.kernel.org. ++ ++# Release [mdadm-3.2.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.1) ++ ++- Policy framework ++ ++ Policy can be expressed for moving spare devices between arrays, and for how to handle hot-plugged ++ devices. This policy can be different for devices plugged in to different controllers etc. This, ++ for example, allows a configuration where when a device is plugged in it is immediately included ++ in an md array as a hot spare and possibly starts recovery immediately if an array is degraded. ++ ++- Some understanding of mbr and gpt paritition tables. This is primarily to support the new ++ hot-plug support. If a device is plugged in and policy suggests it should have a partition table, ++ the partition table will be copied from a suitably similar device, and then the partitions will ++ hot-plug and can then be added to md arrays. ++ ++- **--incremental --remove** can remember where a device was removed from so if a device gets ++ plugged back in the same place, special policy applies to it, allowing it to be included in an ++ array even if a general hotplug will not be included. ++ ++- Enhanced reshape options, including growing a RAID0 by converting to RAID4, restriping, and ++ converting back. Also convertions between RAID0 and RAID10 and between RAID1 and RAID10 are ++ possible (with a suitably recent kernel). ++ ++- Spare migration for IMSM arrays. Spare migration can now work across 'containers' using ++ non-native metadata and specifically Intel's IMSM arrays support spare migrations. ++ ++- OLCE and level migration for Intel IMSM arrays. OnLine Capacity Expansion and level migration ++ (e.g. RAID0 -> RAID5) is supported for Intel Matrix Storage Manager arrays. This support is ++ currently *experimental* for technical reasons. It can be enabled with ++ **export MDADM_EXPERIMENTAL=1**. ++ ++- avoid including wayward devices. ++ ++ If you split a RAID1, mount the two halves as two separate degraded RAID1s, and then later bring ++ the two back together, it is possible that the md metadata won't properly show that one must ++ over-ride the other. Mdadm now does extra checking to detect this possibility and avoid ++ potentially corrupting data. ++ ++- Remove any possible confusion between similar options. e.g. **--brief** and **--bitmap** were ++ mapped to 'b' and mdadm wouldn't notice if one was used where the other was expected. ++ ++- Allow K,M,G suffixes on chunk sizes. ++ ++# Release [mdadm-3.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2) ++ ++- By far the most significant change in this release related to the management of reshaping arrays. ++ This code has been substantially re-written so that it can work with **externally managed ++ metadata** -Intel's IMSM in particular. We now support level migration and OnLine Capacity ++ Expansion on these arrays. ++ ++- Various policy statements can be made in the *mdadm.conf* to guide the behavior of mdadm, ++ particular with regards to how new devices are treated by **--incremental**. Depending on the ++ *action* associated with a device (identified by its *path*) such need devices can be ++ automatically re-added to and existing array that they previously fell out off, or automatically ++ added as a spare if they appear to contain no data. ++ ++- mdadm now has a limited understanding of partition tables. This allows the policy framework to ++ make decisions about partitioned devices as well. ++ ++- **--incremental --remove** can be told what **--path** the device was on, and this info will be ++ recorded so that another device appearing at the same physical location can be preferentially ++ added to the same array (provides the spare-same-slot action policy applied to the path). ++ ++- A new flags **--invalid-backup** flag is available in **--assemble** mode. This can be used to ++ re-assemble an array which was stopping in the middle of a reshape, and for which the ++ *backup file* is no longer available or is corrupted. The array may have some corruption in it ++ at the point where reshape was up to, but at least the rest of the array will become available. ++ ++- Policy framework. ++- Various internal restructuring - more is needed. ++ ++# Release [mdadm-3.1.5](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.5) ++ ++- Fixes for **v1.x** metadata on big-endian machines. ++- man page improvements. ++- Improve **--detail --export** when run on partitions of an md array. ++- Fix regression with removing *failed* or *detached* devices. ++- Fixes for **--assemble --force** in various unusual cases. ++- Allow **-Y** to mean **--export**. This was documented but not implemented. ++- Various fixes for handling **ddf** metadata. This is now more reliable but could benefit from ++ more interoperability testing. ++- Correctly list subarrays of a container in **--detail** output. ++- Improve checks on whether the requested number of devices is supported by the metadata, both for ++ **--create** and **--grow**. ++- Don't remove partitions from a device that is being included in an array until we are fully ++ committed to including it. ++- Allow **--assemble --update=no-bitmap** so an array with a corrupt bitmap can still be assembled. ++- Don't allow **--add** to succeed if it looks like a **--re-add** is probably wanted, but cannot ++ succeed. This avoids inadvertently turning devices into spares when an array is failed. ++ ++# Release [mdadm-3.1.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.4) ++ ++Two fixes related to configs that aren't using udev: ++- Don't remove md devices which 'standard' names on **--stop**. ++- Allow dev_open to work on read-only */dev*. ++ ++And fixed regressions: ++- Allow **--incremental** to add spares to an array. ++- Accept **--no-degraded** as a deprecated option rather than throwing an error. ++- Return correct success status when **--incremental** assembling a container which does not yet ++ have enough devices. ++- Don't link mdadm with pthreads, only mdmon needs it. ++- Fix compiler warning due to bad use of snprintf. ++ ++# Release [mdadm-3.1.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.3) ++ ++- mapfile now lives in a fixed location which default to */dev/.mdadm/map*, but can be changed at ++ compile time. This location is chosen and most distros provide it during early boot and preserve ++ it through. As long a */dev* exists and is writable, */dev/.mdadm* will be created. Other files ++ communication with mdmon live here too. This fixes a bug reported by Debian and Gentoo users where ++ udev would spin in early-boot. ++ ++- IMSM and DDF metadata will not be recognized on partitions as they should only be used on ++ whole-disks. ++ ++- Various overflows causes by 2G drives have been addressed. ++ ++- A subarray of an IMSM contain can now be killed with **--kill-subarray**. Also, subarrays can be ++ renamed with **--update-subarray --update=name**. ++ ++- **-If** (or **--incremental --fail**) can be used from udev to fail and remove from all arrays ++ a device which has been unplugged from the system i.e. hot-unplug-support. ++ ++- **/dev/mdX --re-add missing** will look for any device that looks like it should be a member of ++ */dev/mdX* but isn't and will automatically **--re-add** it. ++ ++- Now compile with *-Wextra* to get extra warnings. ++- Lots of minor bug fixes, documentation improvements, etc. ++ ++# Release [mdadm-3.1.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.2) ++ ++- The default metadata has change again (sorry about that). It is now **v1.2** and will hopefully ++ stay that way. It turned out there with boot-block issues with **v1.1** which make it unsuitable ++ for a default, though in many cases it is still suitable to use. ++ ++- Add *homehost* to the valid words for the **AUTO** config file line. When followed by *-all*, ++ this causes mdadm to auto-assemble any array belonging to this host, but not auto-assemble ++ anything else. ++ ++- VAR_RUN can be easily changed at compile time just like ALT_RUN. This gives distros more ++ flexibility in how to manage the pid and sock files that mdmon needs. ++ ++- If mdadm.conf lists arrays which have inter-dependencies, the previously had to be listed in the ++ "right" order. Now, any order should work. ++ ++- Fix some bugs with **--grow --chunksize=**. ++- Stopping a container is not permitted when members are still active. ++- Various mdmon fixes. ++- Alway make bitmap 4K-aligned if at all possible. ++- Fix **--force** assembly of **v1.x** arrays which are in the process of recovering. ++- Add section on 'scrubbing' to 'md' man page. ++- Various command-line-option parsing improvements. ++- ... and lots of other bug fixes. ++ ++# Release [mdadm-3.1.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.1) ++ ++- Multiple fixes for new **--grow** levels including fixes for serious data corruption ++ problems. ++- Change default metadata to **v1.1**. ++- Change default chunk size to 512K. ++- Change default bitmap chunk size to 64MB. ++- When **--re-add** is used, don't fall back to **--add** as this can destroy data. ++ ++# Release [mdadm-3.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1) ++ ++- Support **--grow** to change the layout of RAID 4/5/6. ++- Support **--grow** to change the chunk size of RAID 4/5/6. ++- Support **--grow** to change level from RAID1 -> RAID5 -> RAID6 and back. ++- Support **--grow** to reduce the number of devices in RAID 4/5/6. ++- Support restart of these grow options which assembling an array which is partially grown. ++- Assorted tests of this code, and of different RAID6 layouts. ++ ++# Release [mdadm-3.0.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.3) ++ ++- Improvements for creating arrays giving just a name, like *foo*, rather than the full ++ */dev/md/foo*. ++- Improvements for assembling member arrays of containers. ++- Improvements to test suite. ++- Add option to change increment for *RebuildNN* messages reported by **--monitor**. ++- Improvements to **mdmon** hand-over from initrd to final root. ++- Handle merging of devices that have left an IMSM array and are being re-incorporated. ++- Add missing space in **--detail --brief** output. ++ ++# Release [mdadm-3.0.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.2) ++ ++- Fix crash when **homehost** is not set, as often happens in early boot. ++ ++# Release [mdadm-3.0.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.1) ++ ++- Fix various segfaults. ++- Fixed for **--examine** with containers. ++- Lots of other little fixes. ++ ++# Release [mdadm-3.0](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0) ++ ++- Support for **externally managed metadata**, specifically DDF and IMSM. ++- Depend on udev to create entries in */dev*, rather than creating them ourselves. ++- Remove **--auto-update-home-hosts**. ++- New config file line **auto**. ++- New *ignore* and *any* options for **homehost**. ++- Numerous bug fixes and minor enhancements. +diff --git a/ChangeLog b/ChangeLog +deleted file mode 100644 +index a3bf7007..00000000 +--- a/ChangeLog ++++ /dev/null +@@ -1,306 +0,0 @@ +-Please see git logs for detailed change log. +-This file just contains highlight. +- +-Changes Prior to release 3.3 +-- Some array reshapes can proceed without needing backup file. +- This is done by changing the 'data_offset' so we never need to write +- any data back over where it was before. If there is no "head space" +- or "tail space" to allow data_offset to change, the old mechanism +- with a backup file can still be used. +-- RAID10 arrays can be reshaped to change the number of devices, +- change the chunk size, or change the layout between 'near' +- and 'offset'. +- This will always change data_offset, and will fail if there is no +- room for data_offset to be moved. +-- "--assemble --update=metadata" can convert a 0.90 array to a 1.0 array. +-- bad-block-logs are supported (but not heavily tested yet) +-- "--assemble --update=revert-reshape" can be used to undo a reshape +- that has just been started but isn't really wanted. This is very +- new and while it passes basic tests it cannot be guaranteed. +-- improved locking between --incremental and --assemble +-- uses systemd to run "mdmon" if systemd is configured to do that. +-- kernel names of md devices can be non-numeric. e.g. "md_home" rather than +- "md0". This will probably confuse lots of other tools, so you need to +- echo CREATE names=yes >> /etc/mdadm.conf +- or the feature will not be used. (you also need a reasonably new kernel). +-- "--stop" can be given a kernel name instead of a device name. i.e +- mdadm --stop md4 +- will work even if /dev/md4 doesn't exist. +-- "--detail --export" has some information about the devices in the array +-- --dump and --restore can be used to backup and restore the metadata on an +- array. +-- Hot-replace is supported with +- mdadm /dev/mdX --replace /dev/foo +- and +- mdadm /dev/mdX --replace /dev/foo --with /dev/bar +-- Config file can be a directory in which case all "*.conf" files are +- read in lexical order. +- Default is to read /etc/mdadm.conf and then /etc/mdadm.conf.d +- Thus +- echo CREATE name=yes > /etc/mdadm.conf.d/names.conf +- will also enable the use of named md devices. +- +-- Lots of improvements to DDF support including adding support for +- RAID10 (thanks Martin Wilck). +- +-Changes Prior to release 3.2.6 +- - There are no real stand-out fixes, just lots of little bits and pieces. +- +-Changes Prior to release 3.2.5 +- - This release primarily fixes a serious regression in 3.2.4. +- This regression does *not* cause any risk to data. It simply +- means that adding a device with "--add" would sometime fail +- when it should not. +- +- - The fix also includes a couple of minor fixes such as making +- the "--layout=preserve" option to "--grow" work again. +- +- +-Changes Prior to release 3.2.4 +-"--oneline" log of changes is below. Some notable ones are: +- +- - --offroot argument to improve interactions between mdmon and initrd +- - --prefer argument to select which /dev names to display in some +- circumstances. +- - relax restructions on when "--add" will be allowed +- - Fix bug with adding write-intent-bitmap to active array +- - Now defaults to "/run/mdadm" for storing run-time files. +- +-Changes Prior to release 3.2.3 +- - The largest single area of change is support for reshape of Intel +- IMSM arrays (OnLine Capacity Explansion and Level Migration). +- - Among other fixes, this now has a better chance of surviving if a +- device fails during reshape. +- +-Changes Prior to release 3.2.2 +- - reshaping IMSM (Intel metadata) arrays is no longer 'experimental', +- it should work properly and be largely compatible with IMSM drivers in +- other platforms. +- - --assume-clean can be used with --grow --size to avoid resyncing the +- new part of the array. This is only support with very new kernels. +- - RAID0 arrays can have chunksize which is not a power of 2. This has been +- supported in the kernel for a while but is only now supprted by +- mdadm. +- +- - A new tool 'raid6check' is available which can check a RAID6 array, +- or part of it, and report which device is most inconsistent with the +- others if any stripe is inconsistent. This is still under development +- and does not have a man page yet. If anyone tries it out and has any +- questions or experience to report, they would be most welcome on +- linux-raid@vger.kernel.org. +- +-Changes Prior to release 3.2.1 +- - policy framework +- Policy can be expressed for moving spare devices between arrays, and +- for how to handle hot-plugged devices. This policy can be different +- for devices plugged in to different controllers etc. +- This, for example, allows a configuration where when a device is plugged +- in it is immediately included in an md array as a hot spare and +- possibly starts recovery immediately if an array is degraded. +- +- - some understanding of mbr and gpt paritition tables +- This is primarly to support the new hot-plug support. If a +- device is plugged in and policy suggests it should have a partition table, +- the partition table will be copied from a suitably similar device, and +- then the partitions will hot-plug and can then be added to md arrays. +- +- - "--incremental --remove" can remember where a device was removed from +- so if a device gets plugged back in the same place, special policy applies +- to it, allowing it to be included in an array even if a general hotplug +- will not be included. +- +- - enhanced reshape options, including growing a RAID0 by converting to RAID4, +- restriping, and converting back. Also convertions between RAID0 and +- RAID10 and between RAID1 and RAID10 are possible (with a suitably recent +- kernel). +- +- - spare migration for IMSM arrays. +- Spare migration can now work across 'containers' using non-native metadata +- and specifically Intel's IMSM arrays support spare migrations. +- +- - OLCE and level migration for Intel IMSM arrays. +- OnLine Capacity Expansion and level migration (e.g. RAID0 -> RAID5) is +- supported for Intel Matrix Storage Manager arrays. +- This support is currently 'experimental' for technical reasons. It can +- be enabled with "export MDADM_EXPERIMENTAL=1" +- +- - avoid including wayward devices +- If you split a RAID1, mount the two halves as two separate degraded RAID1s, +- and then later bring the two back together, it is possible that the md +- metadata won't properly show that one must over-ride the other. +- mdadm now does extra checking to detect this possibilty and avoid +- potentially corrupting data. +- +- - remove any possible confusion between similar options. +- e.g. --brief and --bitmap were mapped to 'b' and mdadm wouldn't +- notice if one was used where the other was expected. +- +- - allow K,M,G suffixes on chunk sizes +- +-Changes Prior to release 3.2 +- - By far the most significant change in this release related to the +- management of reshaping arrays. This code has been substantially +- re-written so that it can work with 'externally managed metadata' - +- Intel's IMSM in particular. We now support level migration and +- OnLine Capacity Expansion on these arrays. +- - Policy framework. +- Various policy statements can be made in the mdadm.conf to guide +- the behaviour of mdadm, particular with regards to how new devices +- are treated by "mdadm -I". +- Depending on the 'action' associated with a device (identified by +- its 'path') such need devices can be automatically re-added to and +- existing array that they previously fell out off, or automatically +- added as a spare if they appear to contain no data. +- +- - mdadm now has a limited understanding of partition tables. This +- allows the policy framework to make decisions about partitioned +- devices as well. +- +- - --incremental --remove can be told what --path the device was on, +- and this info will be recorded so that another device appearing at +- the same physical location can be preferentially added to the same +- array (provides the spare-same-slot action policy applied to the +- path). +- +- - A new flags "--invalid-backup" flag is available in --assemble +- mode. This can be used to re-assemble an array which was stopping +- in the middle of a reshape, and for which the 'backup file' is no +- longer available or is corrupted. The array may have some +- corruption in it at the point where reshape was up to, but at least +- the rest of the array will become available. +- +- +- - Various internal restructuring - more is needed. +- +-Changes Prior to release 3.1.5 +- - Fixes for v1.x metadata on big-endian machines. +- - man page improvements +- - Improve '--detail --export' when run on partitions of an md array. +- - Fix regression with removing 'failed' or 'detached' devices. +- - Fixes for "--assemble --force" in various unusual cases. +- - Allow '-Y' to mean --export. This was documented but not implemented. +- - Various fixed for handling 'ddf' metadata. This is now more reliable +- but could benefit from more interoperability testing. +- - Correctly list subarrays of a container in "--detail" output. +- - Improve checks on whether the requested number of devices is supported +- by the metadata - both for --create and --grow. +- - Don't remove partitions from a device that is being included in an +- array until we are fully committed to including it. +- - Allow "--assemble --update=no-bitmap" so an array with a corrupt +- bitmap can still be assembled. +- - Don't allow --add to succeed if it looks like a "--re-add" is probably +- wanted, but cannot succeed. This avoids inadvertently turning +- devices into spares when an array is failed. +- +-Changes Prior to release 3.1.4 +- Two fixes related to configs that aren't using udev: +- - Don't remove md devices which 'standard' names on --stop +- - Allow dev_open to work on read-only /dev +- And fixed regressions: +- - Allow --incremental to add spares to an array +- - Accept --no-degraded as a deprecated option rather than +- throwing an error +- - Return correct success status when --incrmental assembling +- a container which does not yet have enough devices. +- - Don't link mdadm with pthreads, only mdmon needs it. +- - Fix compiler warning due to bad use of snprintf +- +-Changes Prior to release 3.1.3 +- - mapfile now lives in a fixed location which default to +- /dev/.mdadm/map but can be changed at compile time. This +- location is choses and most distros provide it during early +- boot and preserve it through. As long a /dev exists and is +- writable, /dev/.mdadm will be created. +- Other files file communication with mdmon live here too. +- This fixes a bug reported by Debian and Gentoo users where +- udev would spin in early-boot. +- - IMSM and DDF metadata will not be recognised on partitions +- as they should only be used on whole-disks. +- - Various overflows causes by 2G drives have been addressed. +- - A subarray of an IMSM contain can now be killed with +- --kill-subarray. Also subarrays can be renamed with +- --update-subarray +- - -If (or --incremental --fail) can be used from udev to +- fail and remove from all arrays a device which has been +- unplugged from the system. i.e. hot-unplug-support. +- - "mdadm /dev/mdX --re-add missing" will look for any device +- that looks like it should be a member of /dev/mdX but isn't +- and will automatically --re-add it +- - Now compile with -Wextra to get extra warnings. +- - Lots of minor bug fixes, documentation improvements, etcc +- +-Changes Prior to release 3.1.2 +- - The default metadata has change again (sorry about that). +- It is now v1.2 and will hopefully stay that way. It turned +- out there with boot-block issues with v1.1 which make it +- unsuitable for a default, though in many cases it is still +- suitable to use. +- - Stopping a container is not permitted when members are still +- active +- - Add 'homehost' to the valid words for the "AUTO" config file +- line. When followed by "-all", this causes mdadm to +- auto-assemble any array belonging to this host, but not +- auto-assemble anything else. +- - Fix some bugs with "--grow --chunksize=" for changing chunksize. +- - VAR_RUN can be easily changed at compile time just like ALT_RUN. +- This gives distros more flexability in how to manage the +- pid and sock files that mdmon needs. +- - Various mdmon fixes +- - Alway make bitmap 4K-aligned if at all possible. +- - If mdadm.conf lists arrays which have inter-dependencies, +- the previously had to be listed in the "right" order. Now +- any order should work. +- - Fix --force assembly of v1.x arrays which are in the process +- of recovering. +- - Add section on 'scrubbing' to 'md' man page. +- - Various command-line-option parsing improvements. +- - ... and lots of other bug fixes. +- +-Changes Prior to release 3.1.1 +- - Multiple fixes for new --grow levels including fixes for +- serious data corruption problems. +- - Change default metadata to v1.1 +- - Change default chunk size to 512K +- - Change default bitmap chunk size to 64Meg +- - When --re-add is used, don't fall back to +- --add if --re-add fails as this can destroy data. +- +-Changes Prior to release 3.1 +- - Support --grow to change the layout of RAID4/5/6 +- - Support --grow to change the chunksize of raid 4/5/6 +- - Support --grow to change level from RAID1 -> RAID5 -> RAID6 and +- back. +- - Support --grow to reduce the number of devices in RAID4/5/6. +- - Support restart of these grow options which assembling an array +- which is partially grown. +- - Assorted tests of this code, and of different RAID6 layouts. +- +-Changes Prior to release 3.0.3 +- - Improvements for creating arrays giving just a name, like 'foo', +- rather than the full '/dev/md/foo'. +- - Improvements for assembling member arrays of containers. +- - Improvements to test suite +- - Add option to change increment for RebuildNN messages reported +- by "mdadm --monitor" +- - Improvements to mdmon 'hand-over' from initrd to final root. +- - Handle merging of devices that have left an IMSM array and are +- being re-incorporated. +- - Add missing space in "--detail --brief" output. +- +-Changes Prior to release 3.0.2 +- - Fix crash when hosthost is not set, as often happens in +- early boot. +- +-Changes Prior to release 3.0.1 +- - Fix various segfaults +- - Fixed for --examine with containers +- - Lots of other little fixes. +- +-Changes Prior to release 3.0 +- - Support for externally managed metadata, specifically DDF and IMSM. +- - Depend on udev to create entries in /dev, rather than creating them +- ourselves. +- - remove --auto-update-home-hosts +- - new config file line "auto" +- - new "" and "any" options for "homehost" +- - numerous bug fixes and minor enhancements. +-- +2.41.0 + diff --git a/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch b/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch new file mode 100644 index 0000000..c5ff1f5 --- /dev/null +++ b/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch @@ -0,0 +1,66 @@ +From 21d6c5d96a5a467b5877ba1d38106b3746005bcc Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:11 +0100 +Subject: [PATCH 49/66] mdadm: Add MAINTAINERS.md + +Describe rules maintainer should follow. + +Signed-off-by: Mariusz Tkaczyk +--- + MAINTAINERS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + create mode 100644 MAINTAINERS.md + +diff --git a/MAINTAINERS.md b/MAINTAINERS.md +new file mode 100644 +index 00000000..9c79ba87 +--- /dev/null ++++ b/MAINTAINERS.md +@@ -0,0 +1,44 @@ ++# Maintainer tools ++ ++Useful tools used in daily routines: ++- [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) ++- [kup](https://korg.docs.kernel.org/kup.html) ++- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer) ++- [b4](https://b4.docs.kernel.org/en/latest/) ++ ++# Checklist before applying patch ++ ++We don't have CI testing yet, so all those steps must be performed manually: ++- Style check with [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html): ++ ++ This is the current code style follows. We are not strict to all rules. It must be run ++ by **checkpatch --no-tree**, see README.md. ++ ++- [Commit style](https://www.kernel.org/doc/html/v4.10/process/submitting-patches.html): ++ ++ It doesn't need to be followed as strictly as is in kernel but changes should be logically ++ separated. Submitter should care at least to mention "It is used in next patches" if unused ++ externs/files are added in patch. We love: *Reported-by:*, *Suggested-by:*, *Fixes:* tags. ++ ++- Compilation, ideally on various gcc versions. ++- Mdadm test suite execution. ++- Consider requesting new tests from submitter, especially for new functionalities. ++- Ensure that maintainer *sign-off* is added, before pushing. ++ ++# Making a release ++ ++Assuming that maintainer is certain that release is safe, following steps must be done: ++ ++- Update versions strings in release commit, please refer to previous releases for examples. ++ ++- Create GPG signed tag and push it to repo. Use same format as was used previously, prefixed by ++ **mdadm-**, e.g. **mdadm-3.1.2**, **mdadm-4.1**. ++ ++- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer): ++ ++ Adopt script to our release tag model. When ready, push signed note to repository. If it is done ++ correctly, then *(sig)* is added to the package automatically generated by kernel.org automation. ++ There is no need to upload archive manually. ++ ++- Update CHANGELOG.md. ++- Write "ANNOUNCE" mail to linux-raid@kernel.org to notify community. +-- +2.41.0 + diff --git a/SOURCES/0050-mdadm-Add-README.md.patch b/SOURCES/0050-mdadm-Add-README.md.patch new file mode 100644 index 0000000..18a5340 --- /dev/null +++ b/SOURCES/0050-mdadm-Add-README.md.patch @@ -0,0 +1,106 @@ +From 256edaef3d43a112356762aaea4a48f021f45aec Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:12 +0100 +Subject: [PATCH 50/66] mdadm: Add README.md + +Describe supported metadata types, add step-by-step patch sending +instruction, mention minimally supported kernel version and licensing. + +Signed-off-by: Mariusz Tkaczyk +--- + README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 83 insertions(+) + create mode 100644 README.md + +diff --git a/README.md b/README.md +new file mode 100644 +index 00000000..64f2ecec +--- /dev/null ++++ b/README.md +@@ -0,0 +1,83 @@ ++**mdadm** is a utility used to create and manage **software RAID** devices implemented through ++**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats: ++ ++* [Linux native RAID](https://raid.wiki.kernel.org/index.php/RAID_superblock_formats): ++ ++ Known as **native** or **native RAID**. First and default metadata format. Metadata management ++ is implemented in **MD driver**. ++ ++* Matrix Storage Manager Support (no reference, metadata format documentation is proprietary). ++ ++ Known as **IMSM**. Metadata format developed and maintained by **Intel®** as a part of **VROC** ++ solution. There are some functional differences between **native** and **imsm**. The most ++ important difference is that the metadata is managed from userspace. ++ ++ **CAUTION:** **imsm** is compatible with **Intel RST**, however it is not officially supported. ++ You are using it on your own risk. ++ ++* [Common RAID DDF Specification Revision](https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf) ++ ++ **IMPORTANT:** DDF is in **maintenance only** mode. There is no active development around it. ++ Please do not use it in new solutions. ++ ++# How to Contribute ++ ++ **mdadm** is hosted on [kernel.org](https://kernel.org/). You can access repository ++[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git). ++ ++It is maintained similarly to kernel, using *mailing list*. Patches must be send through email. ++Please familiarize with general kernel ++[submitting patches](https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html) ++documentation. Formatting, tags and commit message guidelines applies to **mdadm**. ++ ++## Sending patches step-by-step ++ ++To maximize change of patches being taken, follow this instruction when submitting: ++ ++1. Create possibly logically separated commits and generate patches: ++ ++ Use ``git format-patch --cover-letter --signoff -v `` to create patches: ++ * ``--cover-letter`` can be skipped if it is only one patch; ++ * ``--signoff`` adds sign-off tag; ++ * ``-v `` indicates review revision number, sender should increment it before resending. ++ ++2. Check style of every patch with kernel ++ [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) script: ++ ++ It is important to keep same coding style that is why in **mdadm** ++ [kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html) ++ is preferred. ``checkpath --no-tree `` can be used to verify patches. ++ Following checkpatch issues can be ignored: ++ - New typedefs. ++ - comparing with *True/False*. ++ - kernel *MAINTAINERS* file warning. ++ - *extern* keyword in headers. ++ ++3. Send patches using ``git send-mail --to=linux-raid@vger.kernel.org (...)`` ++ ++# Maintainers ++ ++It is good practice to add **mdadm maintainers** to recipients for patches: ++ ++- Jes Sorensen ; ++- Mariusz Tkaczyk ; ++ ++Adding **MD maintainers** could be reasonable, especially if patches may affect MD driver: ++ ++- Song Liu ; ++- Yu Kuai ; ++ ++# Reviewers ++ ++**mdadm** utility is not part of kernel tree, so there is no certificated *Reviewers* list. Everyone ++can comment on mailing list, last decision (and merging) belongs to maintainers. ++ ++# Minimal supported kernel version ++ ++We do not support kernel versions below **v3.10**. Please be aware that maintainers may remove ++workarounds and fixes for legacy issues. ++ ++# License ++ ++It is released under the terms of the **GNU General Public License version 2** as published ++by the **Free Software Foundation**. +-- +2.41.0 + diff --git a/SOURCES/0051-Create.c-fix-uclibc-build.patch b/SOURCES/0051-Create.c-fix-uclibc-build.patch new file mode 100644 index 0000000..96c9c4d --- /dev/null +++ b/SOURCES/0051-Create.c-fix-uclibc-build.patch @@ -0,0 +1,41 @@ +From 52bead95d2957437c691891fcdc49bd6afccdd49 Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Fri, 12 Apr 2024 18:45:13 +0200 +Subject: [PATCH 51/66] Create.c: fix uclibc build + +Define FALLOC_FL_ZERO_RANGE if needed as FALLOC_FL_ZERO_RANGE is only +defined for aarch64 on uclibc-ng resulting in the following or1k build +failure since commit 577fd10486d8d1472a6b559066f344ac30a3a391: + +Create.c: In function 'write_zeroes_fork': +Create.c:155:35: error: 'FALLOC_FL_ZERO_RANGE' undeclared (first use in this function) + 155 | if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, + | ^~~~~~~~~~~~~~~~~~~~ + +Fixes: + - http://autobuild.buildroot.org/results/0e04bcdb591ca5642053e1f7e31384f06581e989 + +Signed-off-by: Fabrice Fontaine +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Create.c b/Create.c +index 4397ff49..d94253b1 100644 +--- a/Create.c ++++ b/Create.c +@@ -32,6 +32,10 @@ + #include + #include + ++#ifndef FALLOC_FL_ZERO_RANGE ++#define FALLOC_FL_ZERO_RANGE 16 ++#endif ++ + static int round_size_and_verify(unsigned long long *size, int chunk) + { + if (*size == 0) +-- +2.41.0 + diff --git a/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch b/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch new file mode 100644 index 0000000..7c92cdc --- /dev/null +++ b/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch @@ -0,0 +1,309 @@ +From bdc2c56998abf76141294b04facf20217cfd1911 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:13 +0200 +Subject: [PATCH 52/66] mdadm: pass struct context for external reshapes + +This patch alters mutiple functions calls so the context is passed to +external reshape functions. + +There are two main reasons behind it: +- reduces number of arguments passed and unifies them, +- imsm code will make use of context in incoming patches. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 7 ++---- + Grow.c | 68 +++++++++++++++++++++------------------------------ + mdadm.c | 2 +- + mdadm.h | 11 +++------ + super-intel.c | 6 ++--- + 5 files changed, 37 insertions(+), 57 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index f6c5b99e..f5e9ab1f 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1197,9 +1197,7 @@ static int start_array(int mdfd, + rv = sysfs_set_str(content, NULL, + "array_state", "readonly"); + if (rv == 0) +- rv = Grow_continue(mdfd, st, content, +- c->backup_file, 0, +- c->freeze_reshape); ++ rv = Grow_continue(mdfd, st, content, 0, c); + } else if (c->readonly && + sysfs_attribute_available(content, NULL, + "array_state")) { +@@ -2180,8 +2178,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + st->update_tail = &st->updates; + } + +- err = Grow_continue(mdfd, st, content, c->backup_file, +- 0, c->freeze_reshape); ++ err = Grow_continue(mdfd, st, content, 0, c); + } else switch(content->array.level) { + case LEVEL_LINEAR: + case LEVEL_MULTIPATH: +diff --git a/Grow.c b/Grow.c +index 074f1995..f477b438 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -864,8 +864,7 @@ static void wait_reshape(struct mdinfo *sra) + + static int reshape_super(struct supertype *st, unsigned long long size, + int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup_file, char *dev, +- int direction, int verbose) ++ int delta_disks, char *dev, int direction, struct context *c) + { + /* nothing extra to check in the native case */ + if (!st->ss->external) +@@ -876,9 +875,8 @@ static int reshape_super(struct supertype *st, unsigned long long size, + return 1; + } + +- return st->ss->reshape_super(st, size, level, layout, chunksize, +- raid_disks, delta_disks, backup_file, dev, +- direction, verbose); ++ return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks, ++ delta_disks, dev, direction, c); + } + + static void sync_metadata(struct supertype *st) +@@ -1764,9 +1762,8 @@ static int reshape_container(char *container, char *devname, + int mdfd, + struct supertype *st, + struct mdinfo *info, +- int force, +- char *backup_file, int verbose, +- int forked, int restart, int freeze_reshape); ++ struct context *c, ++ int forked, int restart); + + /** + * prepare_external_reshape() - prepares update on external metadata if supported. +@@ -2004,9 +2001,8 @@ int Grow_reshape(char *devname, int fd, + goto release; + } + +- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, +- devname, APPLY_METADATA_CHANGES, +- c->verbose > 0)) { ++ if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, ++ devname, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -2124,10 +2120,8 @@ size_change_error: + int err = errno; + + /* restore metadata */ +- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, +- UnSet, NULL, devname, +- ROLLBACK_METADATA_CHANGES, +- c->verbose) == 0) ++ if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet, ++ devname, ROLLBACK_METADATA_CHANGES, c) == 0) + sync_metadata(st); + pr_err("Cannot set device size for %s: %s\n", + devname, strerror(err)); +@@ -2338,8 +2332,7 @@ size_change_error: + */ + close_fd(&fd); + rv = reshape_container(container, devname, -1, st, &info, +- c->force, c->backup_file, c->verbose, +- 0, 0, 0); ++ c, 0, 0); + frozen = 0; + } else { + /* get spare devices from external metadata +@@ -2356,13 +2349,13 @@ size_change_error: + } + + /* Impose these changes on a single array. First +- * check that the metadata is OK with the change. */ ++ * check that the metadata is OK with the change. ++ */ + + if (reshape_super(st, 0, info.new_level, + info.new_layout, info.new_chunk, + info.array.raid_disks, info.delta_disks, +- c->backup_file, devname, +- APPLY_METADATA_CHANGES, c->verbose)) { ++ devname, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -3668,9 +3661,8 @@ int reshape_container(char *container, char *devname, + int mdfd, + struct supertype *st, + struct mdinfo *info, +- int force, +- char *backup_file, int verbose, +- int forked, int restart, int freeze_reshape) ++ struct context *c, ++ int forked, int restart) + { + struct mdinfo *cc = NULL; + int rv = restart; +@@ -3683,8 +3675,7 @@ int reshape_container(char *container, char *devname, + reshape_super(st, 0, info->new_level, + info->new_layout, info->new_chunk, + info->array.raid_disks, info->delta_disks, +- backup_file, devname, APPLY_METADATA_CHANGES, +- verbose)) { ++ devname, APPLY_METADATA_CHANGES, c)) { + unfreeze(st); + return 1; + } +@@ -3695,7 +3686,7 @@ int reshape_container(char *container, char *devname, + */ + ping_monitor(container); + +- if (!forked && !freeze_reshape) ++ if (!forked && !c->freeze_reshape) + if (continue_via_systemd(container, GROW_SERVICE, NULL)) + return 0; + +@@ -3705,7 +3696,7 @@ int reshape_container(char *container, char *devname, + unfreeze(st); + return 1; + default: /* parent */ +- if (!freeze_reshape) ++ if (!c->freeze_reshape) + printf("%s: multi-array reshape continues in background\n", Name); + return 0; + case 0: /* child */ +@@ -3802,12 +3793,12 @@ int reshape_container(char *container, char *devname, + flush_mdmon(container); + + rv = reshape_array(container, fd, adev, st, +- content, force, NULL, INVALID_SECTORS, +- backup_file, verbose, 1, restart, +- freeze_reshape); ++ content, c->force, NULL, INVALID_SECTORS, ++ c->backup_file, c->verbose, 1, restart, ++ c->freeze_reshape); + close(fd); + +- if (freeze_reshape) { ++ if (c->freeze_reshape) { + sysfs_free(cc); + exit(0); + } +@@ -4970,8 +4961,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, + return 1; + } + +-int Grow_continue_command(char *devname, int fd, +- char *backup_file, int verbose) ++int Grow_continue_command(char *devname, int fd, struct context *c) + { + int ret_val = 0; + struct supertype *st = NULL; +@@ -5157,7 +5147,7 @@ int Grow_continue_command(char *devname, int fd, + + /* continue reshape + */ +- ret_val = Grow_continue(fd, st, content, backup_file, 1, 0); ++ ret_val = Grow_continue(fd, st, content, 1, c); + + Grow_continue_command_exit: + if (cfd > -1) +@@ -5171,7 +5161,7 @@ Grow_continue_command_exit: + } + + int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, +- char *backup_file, int forked, int freeze_reshape) ++ int forked, struct context *c) + { + int ret_val = 2; + +@@ -5187,14 +5177,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, + st->ss->load_container(st, cfd, st->container_devnm); + close(cfd); + ret_val = reshape_container(st->container_devnm, NULL, mdfd, +- st, info, 0, backup_file, 0, +- forked, 1 | info->reshape_active, +- freeze_reshape); ++ st, info, c, forked, 1 | info->reshape_active); + } else + ret_val = reshape_array(NULL, mdfd, "array", st, info, 1, +- NULL, INVALID_SECTORS, backup_file, ++ NULL, INVALID_SECTORS, c->backup_file, + 0, forked, 1 | info->reshape_active, +- freeze_reshape); ++ c->freeze_reshape); + + return ret_val; + } +diff --git a/mdadm.c b/mdadm.c +index 3f191288..d18619db 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1636,7 +1636,7 @@ int main(int argc, char *argv[]) + c.delay = DEFAULT_BITMAP_DELAY; + rv = Grow_addbitmap(ident.devname, mdfd, &c, &s); + } else if (grow_continue) +- rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose); ++ rv = Grow_continue_command(ident.devname, mdfd, &c); + else if (s.size > 0 || s.raiddisks || s.layout_str || + s.chunk != 0 || s.level != UnSet || + s.data_offset != INVALID_SECTORS) { +diff --git a/mdadm.h b/mdadm.h +index 2640b396..0ade4beb 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1235,9 +1235,8 @@ extern struct superswitch { + int (*reshape_super)(struct supertype *st, + unsigned long long size, int level, + int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup, char *dev, +- int direction, +- int verbose); /* optional */ ++ int delta_disks, char *dev, int direction, ++ struct context *c); + int (*manage_reshape)( /* optional */ + int afd, struct mdinfo *sra, struct reshape *reshape, + struct supertype *st, unsigned long blocks, +@@ -1541,8 +1540,7 @@ extern int Grow_reshape(char *devname, int fd, + extern int Grow_restart(struct supertype *st, struct mdinfo *info, + int *fdlist, int cnt, char *backup_file, int verbose); + extern int Grow_continue(int mdfd, struct supertype *st, +- struct mdinfo *info, char *backup_file, +- int forked, int freeze_reshape); ++ struct mdinfo *info, int forked, struct context *c); + extern int Grow_consistency_policy(char *devname, int fd, + struct context *c, struct shape *s); + +@@ -1552,8 +1550,7 @@ extern int restore_backup(struct supertype *st, + int spares, + char **backup_filep, + int verbose); +-extern int Grow_continue_command(char *devname, int fd, +- char *backup_file, int verbose); ++extern int Grow_continue_command(char *devname, int fd, struct context *c); + + extern int Assemble(struct supertype *st, char *mddev, + struct mddev_ident *ident, +diff --git a/super-intel.c b/super-intel.c +index 1faab607..417da267 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -12153,10 +12153,8 @@ exit: + } + + static int imsm_reshape_super(struct supertype *st, unsigned long long size, +- int level, +- int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup, char *dev, +- int direction, int verbose) ++ int level, int layout, int chunksize, int raid_disks, ++ int delta_disks, char *dev, int direction, struct context *c) + { + int ret_val = 1; + struct geo_params geo; +-- +2.41.0 + diff --git a/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch b/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch new file mode 100644 index 0000000..ebe0810 --- /dev/null +++ b/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch @@ -0,0 +1,296 @@ +From 0acda7053df653022e46fa3b7caf1f4d4ba31a66 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:14 +0200 +Subject: [PATCH 53/66] mdadm: use struct context in reshape_super() + +reshape_super() takes too many arguments. Change passing params in +favor of single struct. + +Add devname pointer and change direction members to struct shape +and use it for reshape_super(). + +Create reshape_array_size() and reshape_array_non_size() to handle +reshape_super() calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 93 +++++++++++++++++++++++++++++++++++++-------------- + mdadm.h | 18 +++++----- + super-intel.c | 43 +++++++++++++++--------- + 3 files changed, 105 insertions(+), 49 deletions(-) + +diff --git a/Grow.c b/Grow.c +index f477b438..87ed9214 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -862,9 +862,7 @@ static void wait_reshape(struct mdinfo *sra) + close(fd); + } + +-static int reshape_super(struct supertype *st, unsigned long long size, +- int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, struct context *c) ++static int reshape_super(struct supertype *st, struct shape *shape, struct context *c) + { + /* nothing extra to check in the native case */ + if (!st->ss->external) +@@ -875,8 +873,65 @@ static int reshape_super(struct supertype *st, unsigned long long size, + return 1; + } + +- return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks, +- delta_disks, dev, direction, c); ++ return st->ss->reshape_super(st, shape, c); ++} ++ ++/** ++ * reshape_super_size() - Reshape array, size only. ++ * ++ * @st: supertype. ++ * @devname: device name. ++ * @size: component size. ++ * @dir metadata changes direction ++ * Returns: 0 on success, 1 otherwise. ++ * ++ * This function is solely used to change size of the volume. ++ * Setting size is not valid for container. ++ * Size is only change that can be rolled back, thus the @dir param. ++ */ ++static int reshape_super_size(struct supertype *st, char *devname, ++ unsigned long long size, change_dir_t direction, ++ struct context *c) ++{ ++ struct shape shape = {0}; ++ ++ shape.level = UnSet; ++ shape.layout = UnSet; ++ shape.delta_disks = UnSet; ++ shape.dev = devname; ++ shape.size = size; ++ shape.direction = direction; ++ ++ return reshape_super(st, &shape, c); ++} ++ ++/** ++ * reshape_super_non_size() - Reshape array, non size changes. ++ * ++ * @st: supertype. ++ * @devname: device name. ++ * @info: superblock info. ++ * Returns: 0 on success, 1 otherwise. ++ * ++ * This function is used for any external array changes but size. ++ * It handles both volumes and containers. ++ * For changes other than size, rollback is not possible. ++ */ ++static int reshape_super_non_size(struct supertype *st, char *devname, ++ struct mdinfo *info, struct context *c) ++{ ++ struct shape shape = {0}; ++ /* Size already set to zero, not updating size */ ++ shape.level = info->new_level; ++ shape.layout = info->new_layout; ++ shape.chunk = info->new_chunk; ++ shape.raiddisks = info->array.raid_disks; ++ shape.delta_disks = info->delta_disks; ++ shape.dev = devname; ++ /* Rollback not possible for non size changes */ ++ shape.direction = APPLY_METADATA_CHANGES; ++ ++ return reshape_super(st, &shape, c); + } + + static void sync_metadata(struct supertype *st) +@@ -1979,9 +2034,8 @@ int Grow_reshape(char *devname, int fd, + } + + /* ========= set size =============== */ +- if (s->size > 0 && +- (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { +- unsigned long long orig_size = get_component_size(fd)/2; ++ if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { ++ unsigned long long orig_size = get_component_size(fd) / 2; + unsigned long long min_csize; + struct mdinfo *mdi; + int raid0_takeover = 0; +@@ -2001,8 +2055,7 @@ int Grow_reshape(char *devname, int fd, + goto release; + } + +- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, +- devname, APPLY_METADATA_CHANGES, c)) { ++ if (reshape_super_size(st, devname, s->size, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -2120,8 +2173,8 @@ size_change_error: + int err = errno; + + /* restore metadata */ +- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet, +- devname, ROLLBACK_METADATA_CHANGES, c) == 0) ++ if (reshape_super_size(st, devname, orig_size, ++ ROLLBACK_METADATA_CHANGES, c) == 0) + sync_metadata(st); + pr_err("Cannot set device size for %s: %s\n", + devname, strerror(err)); +@@ -2351,11 +2404,7 @@ size_change_error: + /* Impose these changes on a single array. First + * check that the metadata is OK with the change. + */ +- +- if (reshape_super(st, 0, info.new_level, +- info.new_layout, info.new_chunk, +- info.array.raid_disks, info.delta_disks, +- devname, APPLY_METADATA_CHANGES, c)) { ++ if (reshape_super_non_size(st, devname, &info, c)) { + rv = 1; + goto release; + } +@@ -3668,14 +3717,8 @@ int reshape_container(char *container, char *devname, + int rv = restart; + char last_devnm[32] = ""; + +- /* component_size is not meaningful for a container, +- * so pass '0' meaning 'no change' +- */ +- if (!restart && +- reshape_super(st, 0, info->new_level, +- info->new_layout, info->new_chunk, +- info->array.raid_disks, info->delta_disks, +- devname, APPLY_METADATA_CHANGES, c)) { ++ /* component_size is not meaningful for a container */ ++ if (!restart && reshape_super_non_size(st, devname, info, c)) { + unfreeze(st); + return 1; + } +diff --git a/mdadm.h b/mdadm.h +index 0ade4beb..2ff3e463 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -594,6 +594,11 @@ enum flag_mode { + FlagDefault, FlagSet, FlagClear, + }; + ++typedef enum { ++ ROLLBACK_METADATA_CHANGES, ++ APPLY_METADATA_CHANGES ++} change_dir_t; ++ + /* structures read from config file */ + /* List of mddevice names and identifiers + * Identifiers can be: +@@ -667,7 +672,9 @@ struct context { + }; + + struct shape { ++ char *dev; + int raiddisks; ++ int delta_disks; + int sparedisks; + int journaldisks; + int level; +@@ -682,6 +689,7 @@ struct shape { + unsigned long long size; + unsigned long long data_offset; + int consistency_policy; ++ change_dir_t direction; + }; + + /* List of device names - wildcards expanded */ +@@ -1229,14 +1237,8 @@ extern struct superswitch { + * initialized to indicate if reshape is being performed at the + * container or subarray level + */ +-#define APPLY_METADATA_CHANGES 1 +-#define ROLLBACK_METADATA_CHANGES 0 +- +- int (*reshape_super)(struct supertype *st, +- unsigned long long size, int level, +- int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, +- struct context *c); ++ ++ int (*reshape_super)(struct supertype *st, struct shape *shape, struct context *c); + int (*manage_reshape)( /* optional */ + int afd, struct mdinfo *sra, struct reshape *reshape, + struct supertype *st, unsigned long blocks, +diff --git a/super-intel.c b/super-intel.c +index 417da267..1a8a7b12 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -12152,26 +12152,37 @@ exit: + return ret_val; + } + +-static int imsm_reshape_super(struct supertype *st, unsigned long long size, +- int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, struct context *c) ++/** ++ * shape_to_geo() - fill geo_params from shape. ++ * ++ * @shape: array details. ++ * @geo: new geometry params. ++ * Returns: 0 on success, 1 otherwise. ++ */ ++static void shape_to_geo(struct shape *shape, struct geo_params *geo) ++{ ++ assert(shape); ++ assert(geo); ++ ++ geo->dev_name = shape->dev; ++ geo->size = shape->size; ++ geo->level = shape->level; ++ geo->layout = shape->layout; ++ geo->chunksize = shape->chunk; ++ geo->raid_disks = shape->raiddisks; ++} ++ ++static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct context *c) + { + int ret_val = 1; +- struct geo_params geo; ++ struct geo_params geo = {0}; + + dprintf("(enter)\n"); + +- memset(&geo, 0, sizeof(struct geo_params)); +- +- geo.dev_name = dev; ++ shape_to_geo(shape, &geo); + strcpy(geo.devnm, st->devnm); +- geo.size = size; +- geo.level = level; +- geo.layout = layout; +- geo.chunksize = chunksize; +- geo.raid_disks = raid_disks; +- if (delta_disks != UnSet) +- geo.raid_disks += delta_disks; ++ if (shape->delta_disks != UnSet) ++ geo.raid_disks += shape->delta_disks; + + dprintf("for level : %i\n", geo.level); + dprintf("for raid_disks : %i\n", geo.raid_disks); +@@ -12182,7 +12193,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, + int old_raid_disks = 0; + + if (imsm_reshape_is_allowed_on_container( +- st, &geo, &old_raid_disks, direction)) { ++ st, &geo, &old_raid_disks, shape->direction)) { + struct imsm_update_reshape *u = NULL; + int len; + +@@ -12236,7 +12247,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, + goto exit_imsm_reshape_super; + } + super->current_vol = dev->index; +- change = imsm_analyze_change(st, &geo, direction); ++ change = imsm_analyze_change(st, &geo, shape->direction); + switch (change) { + case CH_TAKEOVER: + ret_val = imsm_takeover(st, &geo); +-- +2.41.0 + diff --git a/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch b/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch new file mode 100644 index 0000000..f611b7c --- /dev/null +++ b/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch @@ -0,0 +1,184 @@ +From 27550b13297adbdefe42fe4eb785b7fde1c0ed91 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:15 +0200 +Subject: [PATCH 54/66] imsm: add support for literal RAID 10 + +As for now, IMSM supports only 4 drive RAID 1+0. This patch is first in +series to add support for literal RAID 10 (with more than 4 drives) to +imsm. + +Allow setting RAID 10 as raid level for imsm arrays. + +Add update_imsm_raid_level() to handle raid level updates. Set RAID10 as +default level for imsm R0 to R10 migrations. Replace magic numbers with +defined values for RAID level checks/assigns. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 67 ++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 48 insertions(+), 19 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 1a8a7b12..a7efc8df 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -166,7 +166,8 @@ struct imsm_map { + __u8 raid_level; + #define IMSM_T_RAID0 0 + #define IMSM_T_RAID1 1 +-#define IMSM_T_RAID5 5 /* since metadata version 1.2.02 ? */ ++#define IMSM_T_RAID5 5 ++#define IMSM_T_RAID10 10 + __u8 num_members; /* number of member disks */ + __u8 num_domains; /* number of parity domains */ + __u8 failed_disk_num; /* valid only when state is degraded */ +@@ -1259,14 +1260,42 @@ static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) + + return IMSM_STATUS_ERROR; + } ++/** ++ * update_imsm_raid_level() - update raid level appropriately in &imsm_map. ++ * @map: &imsm_map pointer. ++ * @new_level: MD style level. ++ * ++ * For backward compatibility reasons we need to differentiate RAID10. ++ * In the past IMSM RAID10 was presented as RAID1. ++ * Keep compatibility unless it is not explicitly updated by UEFI driver. ++ * ++ * Routine needs num_members to be set and (optionally) raid_level. ++ */ ++static void update_imsm_raid_level(struct imsm_map *map, int new_level) ++{ ++ if (new_level != IMSM_T_RAID10) { ++ map->raid_level = new_level; ++ return; ++ } ++ ++ if (map->num_members == 4) { ++ if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1) ++ return; ++ ++ map->raid_level = IMSM_T_RAID1; ++ return; ++ } ++ ++ map->raid_level = IMSM_T_RAID10; ++} + + static int get_imsm_raid_level(struct imsm_map *map) + { +- if (map->raid_level == 1) { ++ if (map->raid_level == IMSM_T_RAID1) { + if (map->num_members == 2) +- return 1; ++ return IMSM_T_RAID1; + else +- return 10; ++ return IMSM_T_RAID10; + } + + return map->raid_level; +@@ -5678,7 +5707,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + set_pba_of_lba0(map, super->create_offset); + map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info)); + map->failed_disk_num = ~0; +- if (info->level > 0) ++ if (info->level > IMSM_T_RAID0) + map->map_state = (info->state ? IMSM_T_STATE_NORMAL + : IMSM_T_STATE_UNINITIALIZED); + else +@@ -5686,16 +5715,15 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + IMSM_T_STATE_NORMAL; + map->ddf = 1; + +- if (info->level == 1 && info->raid_disks > 2) { ++ if (info->level == IMSM_T_RAID1 && info->raid_disks > 2) { + free(dev); + free(dv); +- pr_err("imsm does not support more than 2 disksin a raid1 volume\n"); ++ pr_err("imsm does not support more than 2 disks in a raid1 volume\n"); + return 0; + } ++ map->num_members = info->raid_disks; + +- map->raid_level = info->level; +- if (info->level == 10) +- map->raid_level = 1; ++ update_imsm_raid_level(map, info->level); + set_num_domains(map); + + size_per_member += NUM_BLOCKS_DIRTY_STRIPE_REGION; +@@ -5703,7 +5731,6 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + size_per_member / + BLOCKS_PER_KB)); + +- map->num_members = info->raid_disks; + update_num_data_stripes(map, array_blocks); + for (i = 0; i < map->num_members; i++) { + /* initialized in add_to_super */ +@@ -8275,7 +8302,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + info_d->data_offset = pba_of_lba0(map); + info_d->component_size = calc_component_size(map, dev); + +- if (map->raid_level == 5) { ++ if (map->raid_level == IMSM_T_RAID5) { + info_d->ppl_sector = this->ppl_sector; + info_d->ppl_size = this->ppl_size; + if (this->consistency_policy == CONSISTENCY_POLICY_PPL && +@@ -9533,7 +9560,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + } + + to_state = map->map_state; +- if ((u->new_level == 5) && (map->raid_level == 0)) { ++ if ((u->new_level == IMSM_T_RAID5) && (map->raid_level == IMSM_T_RAID0)) { + map->num_members++; + /* this should not happen */ + if (u->new_disks[0] < 0) { +@@ -9544,11 +9571,13 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + to_state = IMSM_T_STATE_NORMAL; + } + migrate(new_dev, super, to_state, MIGR_GEN_MIGR); ++ + if (u->new_level > -1) +- map->raid_level = u->new_level; ++ update_imsm_raid_level(map, u->new_level); ++ + migr_map = get_imsm_map(new_dev, MAP_1); +- if ((u->new_level == 5) && +- (migr_map->raid_level == 0)) { ++ if ((u->new_level == IMSM_T_RAID5) && ++ (migr_map->raid_level == IMSM_T_RAID0)) { + int ord = map->num_members - 1; + migr_map->num_members--; + if (u->new_disks[0] < 0) +@@ -9584,7 +9613,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + + /* add disk + */ +- if (u->new_level != 5 || migr_map->raid_level != 0 || ++ if (u->new_level != IMSM_T_RAID5 || migr_map->raid_level != IMSM_T_RAID0 || + migr_map->raid_level == map->raid_level) + goto skip_disk_add; + +@@ -9963,7 +9992,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u, + /* update map */ + map->num_members /= map->num_domains; + map->map_state = IMSM_T_STATE_NORMAL; +- map->raid_level = 0; ++ update_imsm_raid_level(map, IMSM_T_RAID0); + set_num_domains(map); + update_num_data_stripes(map, imsm_dev_size(dev)); + map->failed_disk_num = -1; +@@ -10007,7 +10036,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u, + map = get_imsm_map(dev_new, MAP_0); + + map->map_state = IMSM_T_STATE_DEGRADED; +- map->raid_level = 1; ++ update_imsm_raid_level(map, IMSM_T_RAID10); + set_num_domains(map); + map->num_members = map->num_members * map->num_domains; + update_num_data_stripes(map, imsm_dev_size(dev)); +-- +2.41.0 + diff --git a/SOURCES/0055-imsm-refactor-RAID-level-handling.patch b/SOURCES/0055-imsm-refactor-RAID-level-handling.patch new file mode 100644 index 0000000..8b1689a --- /dev/null +++ b/SOURCES/0055-imsm-refactor-RAID-level-handling.patch @@ -0,0 +1,345 @@ +From 191e6ddb1388236c5c54baf5020a87c996be941f Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:16 +0200 +Subject: [PATCH 55/66] imsm: refactor RAID level handling + +Add imsm_level_ops struct for better handling and unifying raid level +support. Add helper methods and move "orom_has_raid[...]" methods from +header to source file. + +RAID 1e is not supported under Linux, remove RAID 1e associated code. + +Refactor imsm_analyze_change() and is_raid_level_supported(). +Remove hardcoded check for 4 drives and make devNumChange a multiplier +for RAID 10. + +Refactor printing supported raid levels. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 57 ++++++++++++++++++++++++ + platform-intel.h | 32 ++++++-------- + super-intel.c | 111 ++++++++++++++++++++++++++++------------------- + 3 files changed, 138 insertions(+), 62 deletions(-) + +diff --git a/platform-intel.c b/platform-intel.c +index ac282bc5..40e8fb82 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -32,6 +32,63 @@ + + #define NVME_SUBSYS_PATH "/sys/devices/virtual/nvme-subsystem/" + ++static bool imsm_orom_has_raid0(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID0); ++} ++ ++static bool imsm_orom_has_raid1(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID1); ++} ++ ++static bool imsm_orom_has_raid10(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID10); ++} ++ ++static bool imsm_orom_has_raid5(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID5); ++} ++ ++/* IMSM platforms do not define how many disks are allowed for each level, ++ * but there are some global limitations we need to follow. ++ */ ++static bool imsm_orom_support_raid_disks_count_raid0(const int raid_disks) ++{ ++ return true; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid1(const int raid_disks) ++{ ++ if (raid_disks == 2) ++ return true; ++ return false; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks) ++{ ++ if (raid_disks > 2) ++ return true; ++ return false; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks) ++{ ++ if (raid_disks == 4) ++ return true; ++ return false; ++} ++ ++struct imsm_level_ops imsm_level_ops[] = { ++ {0, imsm_orom_has_raid0, imsm_orom_support_raid_disks_count_raid0, "raid0"}, ++ {1, imsm_orom_has_raid1, imsm_orom_support_raid_disks_count_raid1, "raid1"}, ++ {5, imsm_orom_has_raid5, imsm_orom_support_raid_disks_count_raid5, "raid5"}, ++ {10, imsm_orom_has_raid10, imsm_orom_support_raid_disks_count_raid10, "raid10"}, ++ {-1, NULL, NULL, NULL} ++}; ++ + static int devpath_to_ll(const char *dev_path, const char *entry, + unsigned long long *val); + +diff --git a/platform-intel.h b/platform-intel.h +index 3c2bc595..dcc5aaa7 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -109,25 +109,21 @@ struct imsm_orom { + #define IMSM_OROM_CAPABILITIES_TPV (1 << 10) + } __attribute__((packed)); + +-static inline int imsm_orom_has_raid0(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID0); +-} +-static inline int imsm_orom_has_raid1(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID1); +-} +-static inline int imsm_orom_has_raid1e(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID1E); +-} +-static inline int imsm_orom_has_raid10(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID10); +-} +-static inline int imsm_orom_has_raid5(const struct imsm_orom *orom) ++/* IMSM metadata requirements for each level */ ++struct imsm_level_ops { ++ int level; ++ bool (*is_level_supported)(const struct imsm_orom *); ++ bool (*is_raiddisks_count_supported)(const int); ++ char *name; ++}; ++ ++extern struct imsm_level_ops imsm_level_ops[]; ++ ++static inline bool imsm_rlc_has_bit(const struct imsm_orom *orom, const unsigned short bit) + { +- return !!(orom->rlc & IMSM_OROM_RLC_RAID5); ++ if (orom->rlc & bit) ++ return true; ++ return false; + } + + /** +diff --git a/super-intel.c b/super-intel.c +index a7efc8df..da17265d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2681,6 +2681,15 @@ static int ahci_get_port_count(const char *hba_path, int *port_count) + return host_base; + } + ++static void print_imsm_level_capability(const struct imsm_orom *orom) ++{ ++ int idx; ++ ++ for (idx = 0; imsm_level_ops[idx].name; idx++) ++ if (imsm_level_ops[idx].is_level_supported(orom)) ++ printf("%s ", imsm_level_ops[idx].name); ++} ++ + static void print_imsm_capability(const struct imsm_orom *orom) + { + printf(" Platform : Intel(R) "); +@@ -2699,12 +2708,11 @@ static void print_imsm_capability(const struct imsm_orom *orom) + printf(" Version : %d.%d.%d.%d\n", orom->major_ver, + orom->minor_ver, orom->hotfix_ver, orom->build); + } +- printf(" RAID Levels :%s%s%s%s%s\n", +- imsm_orom_has_raid0(orom) ? " raid0" : "", +- imsm_orom_has_raid1(orom) ? " raid1" : "", +- imsm_orom_has_raid1e(orom) ? " raid1e" : "", +- imsm_orom_has_raid10(orom) ? " raid10" : "", +- imsm_orom_has_raid5(orom) ? " raid5" : ""); ++ ++ printf(" RAID Levels : "); ++ print_imsm_level_capability(orom); ++ printf("\n"); ++ + printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + imsm_orom_has_chunk(orom, 2) ? " 2k" : "", + imsm_orom_has_chunk(orom, 4) ? " 4k" : "", +@@ -2739,12 +2747,11 @@ static void print_imsm_capability_export(const struct imsm_orom *orom) + if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) + printf("IMSM_VERSION=%d.%d.%d.%d\n", orom->major_ver, orom->minor_ver, + orom->hotfix_ver, orom->build); +- printf("IMSM_SUPPORTED_RAID_LEVELS=%s%s%s%s%s\n", +- imsm_orom_has_raid0(orom) ? "raid0 " : "", +- imsm_orom_has_raid1(orom) ? "raid1 " : "", +- imsm_orom_has_raid1e(orom) ? "raid1e " : "", +- imsm_orom_has_raid5(orom) ? "raid10 " : "", +- imsm_orom_has_raid10(orom) ? "raid5 " : ""); ++ ++ printf("IMSM_SUPPORTED_RAID_LEVELS="); ++ print_imsm_level_capability(orom); ++ printf("\n"); ++ + printf("IMSM_SUPPORTED_CHUNK_SIZES=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + imsm_orom_has_chunk(orom, 2) ? "2k " : "", + imsm_orom_has_chunk(orom, 4) ? "4k " : "", +@@ -6992,26 +6999,41 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex + return free_size - reservation_size; + } + +-static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) ++/** ++ * is_raid_level_supported() - check if this count of drives and level is supported by platform. ++ * @orom: hardware properties, could be NULL. ++ * @level: requested raid level. ++ * @raiddisks: requested disk count. ++ * ++ * IMSM UEFI/OROM does not provide information about supported count of raid disks ++ * for particular level. That is why it is hardcoded. ++ * It is recommended to not allow of usage other levels than supported, ++ * IMSM code is not tested against different level implementations. ++ * ++ * Return: true if supported, false otherwise. ++ */ ++static bool is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) + { +- if (level < 0 || level == 6 || level == 4) +- return 0; ++ int idx; + +- /* if we have an orom prevent invalid raid levels */ +- if (orom) +- switch (level) { +- case 0: return imsm_orom_has_raid0(orom); +- case 1: +- if (raiddisks > 2) +- return imsm_orom_has_raid1e(orom); +- return imsm_orom_has_raid1(orom) && raiddisks == 2; +- case 10: return imsm_orom_has_raid10(orom) && raiddisks == 4; +- case 5: return imsm_orom_has_raid5(orom) && raiddisks > 2; +- } +- else +- return 1; /* not on an Intel RAID platform so anything goes */ ++ for (idx = 0; imsm_level_ops[idx].name; idx++) { ++ if (imsm_level_ops[idx].level == level) ++ break; ++ } + +- return 0; ++ if (!imsm_level_ops[idx].name) ++ return false; ++ ++ if (!imsm_level_ops[idx].is_raiddisks_count_supported(raiddisks)) ++ return false; ++ ++ if (!orom) ++ return true; ++ ++ if (imsm_level_ops[idx].is_level_supported(orom)) ++ return true; ++ ++ return false; + } + + static int +@@ -11962,18 +11984,17 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + int change = -1; + int check_devs = 0; + int chunk; +- /* number of added/removed disks in operation result */ +- int devNumChange = 0; + /* imsm compatible layout value for array geometry verification */ + int imsm_layout = -1; ++ int raid_disks = geo->raid_disks; + imsm_status_t rv; + + getinfo_super_imsm_volume(st, &info, NULL); +- if (geo->level != info.array.level && geo->level >= 0 && ++ if (geo->level != info.array.level && geo->level >= IMSM_T_RAID0 && + geo->level != UnSet) { + switch (info.array.level) { +- case 0: +- if (geo->level == 5) { ++ case IMSM_T_RAID0: ++ if (geo->level == IMSM_T_RAID5) { + change = CH_MIGRATION; + if (geo->layout != ALGORITHM_LEFT_ASYMMETRIC) { + pr_err("Error. Requested Layout not supported (left-asymmetric layout is supported only)!\n"); +@@ -11982,20 +12003,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + } + imsm_layout = geo->layout; + check_devs = 1; +- devNumChange = 1; /* parity disk added */ +- } else if (geo->level == 10) { ++ raid_disks += 1; /* parity disk added */ ++ } else if (geo->level == IMSM_T_RAID10) { + change = CH_TAKEOVER; + check_devs = 1; +- devNumChange = 2; /* two mirrors added */ ++ raid_disks *= 2; /* mirrors added */ + imsm_layout = 0x102; /* imsm supported layout */ + } + break; +- case 1: +- case 10: ++ case IMSM_T_RAID1: ++ case IMSM_T_RAID10: + if (geo->level == 0) { + change = CH_TAKEOVER; + check_devs = 1; +- devNumChange = -(geo->raid_disks/2); ++ raid_disks /= 2; + imsm_layout = 0; /* imsm raid0 layout */ + } + break; +@@ -12011,10 +12032,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + if (geo->layout != info.array.layout && + (geo->layout != UnSet && geo->layout != -1)) { + change = CH_MIGRATION; +- if (info.array.layout == 0 && info.array.level == 5 && ++ if (info.array.layout == 0 && info.array.level == IMSM_T_RAID5 && + geo->layout == 5) { + /* reshape 5 -> 4 */ +- } else if (info.array.layout == 5 && info.array.level == 5 && ++ } else if (info.array.layout == 5 && info.array.level == IMSM_T_RAID5 && + geo->layout == 0) { + /* reshape 4 -> 5 */ + geo->layout = 0; +@@ -12033,7 +12054,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + + if (geo->chunksize > 0 && geo->chunksize != UnSet && + geo->chunksize != info.array.chunk_size) { +- if (info.array.level == 10) { ++ if (info.array.level == IMSM_T_RAID10) { + pr_err("Error. Chunk size change for RAID 10 is not supported.\n"); + change = -1; + goto analyse_change_exit; +@@ -12058,14 +12079,16 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + rv = imsm_analyze_expand(st, geo, &info, direction); + if (rv != IMSM_STATUS_OK) + goto analyse_change_exit; ++ raid_disks = geo->raid_disks; + change = CH_ARRAY_SIZE; + } + + chunk = geo->chunksize / 1024; ++ + if (!validate_geometry_imsm(st, + geo->level, + imsm_layout, +- geo->raid_disks + devNumChange, ++ raid_disks, + &chunk, + geo->size, INVALID_SECTORS, + 0, 0, info.consistency_policy, 1)) +-- +2.41.0 + diff --git a/SOURCES/0056-imsm-bump-minimal-version.patch b/SOURCES/0056-imsm-bump-minimal-version.patch new file mode 100644 index 0000000..fe78a92 --- /dev/null +++ b/SOURCES/0056-imsm-bump-minimal-version.patch @@ -0,0 +1,180 @@ +From ec7e873ba6643a9e5e74311b00ede66a3d2e36c9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:17 +0200 +Subject: [PATCH 56/66] imsm: bump minimal version + +IMSM version 1.3 (called ATTRIBS) brought attributes used to define array +properties which require support in driver. The goal of this change was +to avoid changing version when adding new features. + +For some reasons migration has never been completed and currently (after +10 years of implementing) IMSM can use older versions. + +It is right time to finally switch it. There is no point in using old +versions, use 1.3.00 as minimal one. + +Define JD_VERSION used by Windows driver. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 87 ++++++++++++++++++++++----------------------------- + 1 file changed, 38 insertions(+), 49 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index da17265d..4b168add 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -32,14 +32,19 @@ + /* MPB == Metadata Parameter Block */ + #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " + #define MPB_SIG_LEN (strlen(MPB_SIGNATURE)) +-#define MPB_VERSION_RAID0 "1.0.00" +-#define MPB_VERSION_RAID1 "1.1.00" +-#define MPB_VERSION_MANY_VOLUMES_PER_ARRAY "1.2.00" +-#define MPB_VERSION_3OR4_DISK_ARRAY "1.2.01" +-#define MPB_VERSION_RAID5 "1.2.02" +-#define MPB_VERSION_5OR6_DISK_ARRAY "1.2.04" +-#define MPB_VERSION_CNG "1.2.06" ++ ++/* Legacy IMSM versions: ++ * MPB_VERSION_RAID0 1.0.00 ++ * MPB_VERSION_RAID1 1.1.00 ++ * MPB_VERSION_MANY_VOLUMES_PER_ARRAY 1.2.00 ++ * MPB_VERSION_3OR4_DISK_ARRAY 1.2.01 ++ * MPB_VERSION_RAID5 1.2.02 ++ * MPB_VERSION_5OR6_DISK_ARRAY 1.2.04 ++ * MPB_VERSION_CNG 1.2.06 ++ */ ++ + #define MPB_VERSION_ATTRIBS "1.3.00" ++#define MPB_VERSION_ATTRIBS_JD "2.0.00" + #define MAX_SIGNATURE_LENGTH 32 + #define MAX_RAID_SERIAL_LEN 16 + +@@ -5512,51 +5517,46 @@ static unsigned long long info_to_blocks_per_member(mdu_array_info_t *info, + return (size * 2) & ~(info_to_blocks_per_strip(info) - 1); + } + ++static void imsm_write_signature(struct imsm_super *mpb) ++{ ++ /* It is safer to eventually truncate version rather than left it not NULL ended */ ++ snprintf((char *) mpb->sig, MAX_SIGNATURE_LENGTH, MPB_SIGNATURE MPB_VERSION_ATTRIBS); ++} ++ + static void imsm_update_version_info(struct intel_super *super) + { + /* update the version and attributes */ + struct imsm_super *mpb = super->anchor; +- char *version; + struct imsm_dev *dev; + struct imsm_map *map; + int i; + ++ mpb->attributes |= MPB_ATTRIB_CHECKSUM_VERIFY; ++ + for (i = 0; i < mpb->num_raid_devs; i++) { + dev = get_imsm_dev(super, i); + map = get_imsm_map(dev, MAP_0); ++ + if (__le32_to_cpu(dev->size_high) > 0) + mpb->attributes |= MPB_ATTRIB_2TB; + +- /* FIXME detect when an array spans a port multiplier */ +- #if 0 +- mpb->attributes |= MPB_ATTRIB_PM; +- #endif +- +- if (mpb->num_raid_devs > 1 || +- mpb->attributes != MPB_ATTRIB_CHECKSUM_VERIFY) { +- version = MPB_VERSION_ATTRIBS; +- switch (get_imsm_raid_level(map)) { +- case 0: mpb->attributes |= MPB_ATTRIB_RAID0; break; +- case 1: mpb->attributes |= MPB_ATTRIB_RAID1; break; +- case 10: mpb->attributes |= MPB_ATTRIB_RAID10; break; +- case 5: mpb->attributes |= MPB_ATTRIB_RAID5; break; +- } +- } else { +- if (map->num_members >= 5) +- version = MPB_VERSION_5OR6_DISK_ARRAY; +- else if (dev->status == DEV_CLONE_N_GO) +- version = MPB_VERSION_CNG; +- else if (get_imsm_raid_level(map) == 5) +- version = MPB_VERSION_RAID5; +- else if (map->num_members >= 3) +- version = MPB_VERSION_3OR4_DISK_ARRAY; +- else if (get_imsm_raid_level(map) == 1) +- version = MPB_VERSION_RAID1; +- else +- version = MPB_VERSION_RAID0; ++ switch (get_imsm_raid_level(map)) { ++ case IMSM_T_RAID0: ++ mpb->attributes |= MPB_ATTRIB_RAID0; ++ break; ++ case IMSM_T_RAID1: ++ mpb->attributes |= MPB_ATTRIB_RAID1; ++ break; ++ case IMSM_T_RAID5: ++ mpb->attributes |= MPB_ATTRIB_RAID5; ++ break; ++ case IMSM_T_RAID10: ++ mpb->attributes |= MPB_ATTRIB_RAID10; ++ break; + } +- strcpy(((char *) mpb->sig) + strlen(MPB_SIGNATURE), version); + } ++ ++ imsm_write_signature(mpb); + } + + /** +@@ -5785,7 +5785,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + struct intel_super *super; + struct imsm_super *mpb; + size_t mpb_size; +- char *version; + + if (data_offset != INVALID_SECTORS) { + pr_err("data-offset not supported by imsm\n"); +@@ -5828,13 +5827,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + return 0; + } + +- mpb->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; +- +- version = (char *) mpb->sig; +- strcpy(version, MPB_SIGNATURE); +- version += strlen(MPB_SIGNATURE); +- strcpy(version, MPB_VERSION_RAID0); +- ++ imsm_update_version_info(super); + return 1; + } + +@@ -6208,7 +6201,6 @@ static union { + + static int write_super_imsm_spare(struct intel_super *super, struct dl *d) + { +- struct imsm_super *mpb = super->anchor; + struct imsm_super *spare = &spare_record.anchor; + __u32 sum; + +@@ -6217,14 +6209,11 @@ static int write_super_imsm_spare(struct intel_super *super, struct dl *d) + + spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)); + spare->generation_num = __cpu_to_le32(1UL); +- spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; + spare->num_disks = 1; + spare->num_raid_devs = 0; +- spare->cache_size = mpb->cache_size; + spare->pwr_cycle_count = __cpu_to_le32(1); + +- snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH, +- MPB_SIGNATURE MPB_VERSION_RAID0); ++ imsm_write_signature(spare); + + spare->disk[0] = d->disk; + if (__le32_to_cpu(d->disk.total_blocks_hi) > 0) +-- +2.41.0 + diff --git a/SOURCES/0057-imsm-define-RAID_10-attribute.patch b/SOURCES/0057-imsm-define-RAID_10-attribute.patch new file mode 100644 index 0000000..edb1c8e --- /dev/null +++ b/SOURCES/0057-imsm-define-RAID_10-attribute.patch @@ -0,0 +1,67 @@ +From 610fc2ee6fc09e828b14e8fa221b3f4f70fc7b2b Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:18 +0200 +Subject: [PATCH 57/66] imsm: define RAID_10 attribute + +Add MPB_ATTRIB_RAID10_EXT attribute to support RAID 10 +with more than 4 drives. + +Allow more than 4 drives in imsm_orom_support_raid_disks_raid10(). + +This is one of last patches for introducing R10D4+ to imsm. +Only small adjustments in reshape behaviours are needed. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 3 ++- + super-intel.c | 5 +++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 40e8fb82..15a9fa5a 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -76,7 +76,8 @@ static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks) + + static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks) + { +- if (raid_disks == 4) ++ /* raid_disks count must be higher than 4 and even */ ++ if (raid_disks >= 4 && (raid_disks & 1) == 0) + return true; + return false; + } +diff --git a/super-intel.c b/super-intel.c +index 4b168add..2d309316 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -62,6 +62,8 @@ + #define MPB_ATTRIB_RAIDCNG __cpu_to_le32(0x00000020) + /* supports expanded stripe sizes of 256K, 512K and 1MB */ + #define MPB_ATTRIB_EXP_STRIPE_SIZE __cpu_to_le32(0x00000040) ++/* supports RAID10 with more than 4 drives */ ++#define MPB_ATTRIB_RAID10_EXT __cpu_to_le32(0x00000080) + + /* The OROM Support RST Caching of Volumes */ + #define MPB_ATTRIB_NVM __cpu_to_le32(0x02000000) +@@ -89,6 +91,7 @@ + MPB_ATTRIB_RAID10 | \ + MPB_ATTRIB_RAID5 | \ + MPB_ATTRIB_EXP_STRIPE_SIZE | \ ++ MPB_ATTRIB_RAID10_EXT | \ + MPB_ATTRIB_BBM) + + /* Define attributes that are unused but not harmful */ +@@ -5552,6 +5555,8 @@ static void imsm_update_version_info(struct intel_super *super) + break; + case IMSM_T_RAID10: + mpb->attributes |= MPB_ATTRIB_RAID10; ++ if (map->num_members > 4) ++ mpb->attributes |= MPB_ATTRIB_RAID10_EXT; + break; + } + } +-- +2.41.0 + diff --git a/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch b/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch new file mode 100644 index 0000000..8c1754c --- /dev/null +++ b/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch @@ -0,0 +1,153 @@ +From e0e56f4b2ed514f5049eb96b4ff8f7fdf30a4c49 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:19 +0200 +Subject: [PATCH 58/66] imsm: simplify imsm_check_attributes() + +imsm_check_attributes() is too complex for that it really does. + +Remove repeating code and simplify the function. +Fix function calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 106 ++++++++------------------------------------------ + 1 file changed, 16 insertions(+), 90 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 2d309316..d60915e8 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2135,91 +2135,18 @@ void convert_from_4k(struct intel_super *super) + mpb->check_sum = __gen_imsm_checksum(mpb); + } + +-/******************************************************************************* +- * function: imsm_check_attributes +- * Description: Function checks if features represented by attributes flags +- * are supported by mdadm. +- * Parameters: +- * attributes - Attributes read from metadata +- * Returns: +- * 0 - passed attributes contains unsupported features flags +- * 1 - all features are supported +- ******************************************************************************/ +-static int imsm_check_attributes(__u32 attributes) ++/** ++ * imsm_check_attributes() - Check if features represented by attributes flags are supported. ++ * ++ * @attributes: attributes read from metadata. ++ * Returns: true if all features are supported, false otherwise. ++ */ ++static bool imsm_check_attributes(__u32 attributes) + { +- int ret_val = 1; +- __u32 not_supported = MPB_ATTRIB_SUPPORTED^0xffffffff; +- +- not_supported &= ~MPB_ATTRIB_IGNORED; +- +- not_supported &= attributes; +- if (not_supported) { +- pr_err("(IMSM): Unsupported attributes : %x\n", +- (unsigned)__le32_to_cpu(not_supported)); +- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) { +- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY \n"); +- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY; +- } +- if (not_supported & MPB_ATTRIB_2TB) { +- dprintf("\t\tMPB_ATTRIB_2TB\n"); +- not_supported ^= MPB_ATTRIB_2TB; +- } +- if (not_supported & MPB_ATTRIB_RAID0) { +- dprintf("\t\tMPB_ATTRIB_RAID0\n"); +- not_supported ^= MPB_ATTRIB_RAID0; +- } +- if (not_supported & MPB_ATTRIB_RAID1) { +- dprintf("\t\tMPB_ATTRIB_RAID1\n"); +- not_supported ^= MPB_ATTRIB_RAID1; +- } +- if (not_supported & MPB_ATTRIB_RAID10) { +- dprintf("\t\tMPB_ATTRIB_RAID10\n"); +- not_supported ^= MPB_ATTRIB_RAID10; +- } +- if (not_supported & MPB_ATTRIB_RAID1E) { +- dprintf("\t\tMPB_ATTRIB_RAID1E\n"); +- not_supported ^= MPB_ATTRIB_RAID1E; +- } +- if (not_supported & MPB_ATTRIB_RAID5) { +- dprintf("\t\tMPB_ATTRIB_RAID5\n"); +- not_supported ^= MPB_ATTRIB_RAID5; +- } +- if (not_supported & MPB_ATTRIB_RAIDCNG) { +- dprintf("\t\tMPB_ATTRIB_RAIDCNG\n"); +- not_supported ^= MPB_ATTRIB_RAIDCNG; +- } +- if (not_supported & MPB_ATTRIB_BBM) { +- dprintf("\t\tMPB_ATTRIB_BBM\n"); +- not_supported ^= MPB_ATTRIB_BBM; +- } +- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) { +- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY (== MPB_ATTRIB_LEGACY)\n"); +- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY; +- } +- if (not_supported & MPB_ATTRIB_EXP_STRIPE_SIZE) { +- dprintf("\t\tMPB_ATTRIB_EXP_STRIP_SIZE\n"); +- not_supported ^= MPB_ATTRIB_EXP_STRIPE_SIZE; +- } +- if (not_supported & MPB_ATTRIB_2TB_DISK) { +- dprintf("\t\tMPB_ATTRIB_2TB_DISK\n"); +- not_supported ^= MPB_ATTRIB_2TB_DISK; +- } +- if (not_supported & MPB_ATTRIB_NEVER_USE2) { +- dprintf("\t\tMPB_ATTRIB_NEVER_USE2\n"); +- not_supported ^= MPB_ATTRIB_NEVER_USE2; +- } +- if (not_supported & MPB_ATTRIB_NEVER_USE) { +- dprintf("\t\tMPB_ATTRIB_NEVER_USE\n"); +- not_supported ^= MPB_ATTRIB_NEVER_USE; +- } +- +- if (not_supported) +- dprintf("(IMSM): Unknown attributes : %x\n", not_supported); +- +- ret_val = 0; +- } ++ if ((attributes & (MPB_ATTRIB_SUPPORTED | MPB_ATTRIB_IGNORED)) == attributes) ++ return true; + +- return ret_val; ++ return false; + } + + static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map); +@@ -2247,11 +2174,10 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + creation_time = __le64_to_cpu(mpb->creation_time); + printf(" Creation Time : %.24s\n", + creation_time ? ctime(&creation_time) : "Unknown"); +- printf(" Attributes : "); +- if (imsm_check_attributes(mpb->attributes)) +- printf("All supported\n"); +- else +- printf("not supported\n"); ++ ++ printf(" Attributes : %08x (%s)\n", mpb->attributes, ++ imsm_check_attributes(mpb->attributes) ? "supported" : "not supported"); ++ + getinfo_super_imsm(st, &info, NULL); + fname_from_uuid(&info, nbuf); + printf(" UUID : %s\n", nbuf + 5); +@@ -8182,9 +8108,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + int current_vol = super->current_vol; + + /* do not assemble arrays when not all attributes are supported */ +- if (imsm_check_attributes(mpb->attributes) == 0) { ++ if (imsm_check_attributes(mpb->attributes) == false) { + sb_errors = 1; +- pr_err("Unsupported attributes in IMSM metadata.Arrays activation is blocked.\n"); ++ pr_err("Unsupported attributes in IMSM metadata. Arrays activation is blocked.\n"); + } + + /* count spare devices, not used in maps +-- +2.41.0 + diff --git a/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch b/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch new file mode 100644 index 0000000..6d6d245 --- /dev/null +++ b/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch @@ -0,0 +1,168 @@ +From 44463edeb303a464c4a44fcea184b267aeb53302 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:20 +0200 +Subject: [PATCH 59/66] imsm: support RAID 10 with more than 4 drives + +VROC UEFI driver does not support RAID 10 with more than 4 drives. +Add user prompts if such layout is being created and for R0->R10 +reshapes. + +Refactor ask() function: +- simplify the code, +- remove dialog reattempts, +- do no pass '?' sign on function calls, +- highlight default option on output. + +This patch completes adding support for R10D4+ to IMSM. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 9 ++++++++- + super-intel.c | 14 ++++++++++++-- + util.c | 39 +++++++++++++++++++++++++-------------- + 3 files changed, 45 insertions(+), 17 deletions(-) + +diff --git a/Create.c b/Create.c +index d94253b1..d033eb68 100644 +--- a/Create.c ++++ b/Create.c +@@ -965,6 +965,13 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + return 1; + } + ++ if (st->ss == &super_imsm && s->level == 10 && s->raiddisks > 4) { ++ /* Print no matter runstop was specifed */ ++ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n"); ++ pr_err("Array won't be suitable as boot device.\n"); ++ warn = 1; ++ } ++ + if (!have_container && s->level > 0 && ((maxsize-s->size)*100 > maxsize)) { + if (c->runstop != 1 || c->verbose >= 0) + pr_err("largest drive (%s) exceeds size (%lluK) by more than 1%%\n", +@@ -984,7 +991,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (warn) { + if (c->runstop!= 1) { +- if (!ask("Continue creating array? ")) { ++ if (!ask("Continue creating array")) { + pr_err("create aborted.\n"); + return 1; + } +diff --git a/super-intel.c b/super-intel.c +index d60915e8..2b8b6fda 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -523,6 +523,7 @@ enum imsm_reshape_type { + CH_TAKEOVER, + CH_MIGRATION, + CH_ARRAY_SIZE, ++ CH_ABORT + }; + + /* definition of messages passed to imsm_process_update */ +@@ -11898,7 +11899,7 @@ success: + ****************************************************************************/ + enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + struct geo_params *geo, +- int direction) ++ int direction, struct context *c) + { + struct mdinfo info; + int change = -1; +@@ -11925,6 +11926,14 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + check_devs = 1; + raid_disks += 1; /* parity disk added */ + } else if (geo->level == IMSM_T_RAID10) { ++ if (geo->level == IMSM_T_RAID10 && geo->raid_disks > 2 && ++ !c->force) { ++ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n"); ++ pr_err("Array won't be suitable as boot device.\n"); ++ pr_err("Note: You can omit this check with \"--force\"\n"); ++ if (ask("Do you want to continue") < 1) ++ return CH_ABORT; ++ } + change = CH_TAKEOVER; + check_devs = 1; + raid_disks *= 2; /* mirrors added */ +@@ -12219,7 +12228,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct + goto exit_imsm_reshape_super; + } + super->current_vol = dev->index; +- change = imsm_analyze_change(st, &geo, shape->direction); ++ change = imsm_analyze_change(st, &geo, shape->direction, c); + switch (change) { + case CH_TAKEOVER: + ret_val = imsm_takeover(st, &geo); +@@ -12262,6 +12271,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct + free(u); + } + break; ++ case CH_ABORT: + default: + ret_val = 1; + } +diff --git a/util.c b/util.c +index 9e837045..4fbf11c4 100644 +--- a/util.c ++++ b/util.c +@@ -725,23 +725,33 @@ int stat_is_blkdev(char *devname, dev_t *rdev) + return 1; + } + ++/** ++ * ask() - prompt user for "yes/no" dialog. ++ * @mesg: message to be printed, without '?' sign. ++ * Returns: 1 if 'Y/y', 0 otherwise. ++ * ++ * The default value is 'N/n', thus the caps on "N" on prompt. ++ */ + int ask(char *mesg) + { +- char *add = ""; +- int i; +- for (i = 0; i < 5; i++) { +- char buf[100]; +- fprintf(stderr, "%s%s", mesg, add); +- fflush(stderr); +- if (fgets(buf, 100, stdin)==NULL) +- return 0; +- if (buf[0]=='y' || buf[0]=='Y') +- return 1; +- if (buf[0]=='n' || buf[0]=='N') +- return 0; +- add = "(y/n) "; ++ char buf[3] = {0}; ++ ++ fprintf(stderr, "%s [y/N]? ", mesg); ++ fflush(stderr); ++ if (fgets(buf, 3, stdin) == NULL) ++ return 0; ++ if (strlen(buf) == 1) { ++ pr_err("assuming no.\n"); ++ return 0; + } +- pr_err("assuming 'no'\n"); ++ if (buf[1] != '\n') ++ goto bad_option; ++ if (toupper(buf[0]) == 'Y') ++ return 1; ++ if (toupper(buf[0]) == 'N') ++ return 0; ++bad_option: ++ pr_err("bad option.\n"); + return 0; + } + +@@ -1868,6 +1878,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + + if (st->ss->external) + return sysfs_set_array(info); ++ + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; + inf.minor_version = info->array.minor_version; +-- +2.41.0 + diff --git a/SOURCES/0060-tests-01r5fail-enhance.patch b/SOURCES/0060-tests-01r5fail-enhance.patch new file mode 100644 index 0000000..32c06d6 --- /dev/null +++ b/SOURCES/0060-tests-01r5fail-enhance.patch @@ -0,0 +1,41 @@ +From d399c494c6364a6b6d0f965c08443fdc79d1e248 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:19 +0800 +Subject: [PATCH 60/66] tests/01r5fail enhance + +After removing dev0, the recovery starts because it already has a spare +disk. It's good to check recovery. But it's not right to check recovery +after adding dev3. Because the recovery may finish. It depends on the +recovery performance of the testing machine. If the recovery finishes, +it will fail. But dev3 is only added as a spare disk, we can't expect +there is a recovery happens. + +So remove the codes about adding dev3. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01r5fail | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/tests/01r5fail b/tests/01r5fail +index 873dba58..c210d6e7 100644 +--- a/tests/01r5fail ++++ b/tests/01r5fail +@@ -17,11 +17,7 @@ check wait + mdadm $md0 --fail $dev0 + mdadm $md0 --remove $dev3 $dev0 + check recovery +-check state _UUU +- +-mdadm $md0 -a $dev3 +-check recovery + check wait + check state UUUU + +-mdadm -S $md0 +\ No newline at end of file ++mdadm -S $md0 +-- +2.41.0 + diff --git a/SOURCES/0061-tests-01r5integ.broken.patch b/SOURCES/0061-tests-01r5integ.broken.patch new file mode 100644 index 0000000..c662238 --- /dev/null +++ b/SOURCES/0061-tests-01r5integ.broken.patch @@ -0,0 +1,32 @@ +From a20cb3872c02241e4f0f7cc26933a43bac7d1cbb Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:20 +0800 +Subject: [PATCH 61/66] tests/01r5integ.broken + +01r5integ can be run successfully 152 times without error with +kernel 6.9.0-rc4 and mdadm - v4.3-51-g52bead95. So remove this +one broken case. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01r5integ.broken | 7 ------- + 1 file changed, 7 deletions(-) + delete mode 100644 tests/01r5integ.broken + +diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken +deleted file mode 100644 +index 20737637..00000000 +--- a/tests/01r5integ.broken ++++ /dev/null +@@ -1,7 +0,0 @@ +-fails rarely +- +-Fails about 1 in every 30 runs with a sha mismatch error: +- +- c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match +- 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3 +- missing +-- +2.41.0 + diff --git a/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch b/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch new file mode 100644 index 0000000..9becf86 --- /dev/null +++ b/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch @@ -0,0 +1,31 @@ +From 896948b14ad26f15590269dce50ac4896284dc29 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:21 +0800 +Subject: [PATCH 62/66] tests/01raid6integ.broken can be removed + +01raid6integ can be run successfully with kernel 6.9.0-rc3. +So remove 01raid6integ.broken. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01raid6integ.broken | 7 ------- + 1 file changed, 7 deletions(-) + delete mode 100644 tests/01raid6integ.broken + +diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken +deleted file mode 100644 +index 1df735f0..00000000 +--- a/tests/01raid6integ.broken ++++ /dev/null +@@ -1,7 +0,0 @@ +-fails infrequently +- +-Fails about 1 in 5 with a sha mismatch: +- +- 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match +- a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and +- /dev/loop3 missing +-- +2.41.0 + diff --git a/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch b/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch new file mode 100644 index 0000000..7065fe7 --- /dev/null +++ b/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch @@ -0,0 +1,38 @@ +From 893a55831e5abbcd15b171db66fa1f389fb61506 Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Tue, 7 May 2024 19:32:16 +0200 +Subject: [PATCH 63/66] Makefile: Move -pie to LDFLAGS + +Move -pie from LDLIBS to LDFLAGS and make LDFLAGS configurable to allow +the user to drop it by setting their own LDFLAGS (e.g. PIE could be +enabled or disabled by the buildsystem such as buildroot). + +Suggested-by: Mariusz Tkaczyk +Signed-off-by: Fabrice Fontaine +Signed-off-by: Mariusz Tkaczyk +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 7c221a89..adac7905 100644 +--- a/Makefile ++++ b/Makefile +@@ -132,12 +132,12 @@ CFLAGS += -DUSE_PTHREADS + MON_LDFLAGS += -pthread + endif + +-LDFLAGS = -Wl,-z,now,-z,noexecstack ++LDFLAGS ?= -pie -Wl,-z,now,-z,noexecstack + + # If you want a static binary, you might uncomment these + # LDFLAGS += -static + # STRIP = -s +-LDLIBS = -ldl -pie ++LDLIBS = -ldl + + # To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS + ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS))) +-- +2.41.0 + diff --git a/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch b/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch new file mode 100644 index 0000000..5c1b196 --- /dev/null +++ b/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch @@ -0,0 +1,30 @@ +From a0174749426f49a04f11ae0e728cb0a681bfa465 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Thu, 9 May 2024 09:10:59 +0800 +Subject: [PATCH 64/66] tests/23rdev-lifetime: fix a typo + +"pill" was wrong, while it should be "kill", test will still pass while +test thread will not be cleaned up. + +Signed-off-by: Yu Kuai +Signed-off-by: Mariusz Tkaczyk +--- + tests/23rdev-lifetime | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime +index 1750b0db..03b61de4 100644 +--- a/tests/23rdev-lifetime ++++ b/tests/23rdev-lifetime +@@ -4,7 +4,7 @@ pid="" + runtime=2 + + clean_up_test() { +- pill -9 $pid ++ kill -9 $pid + echo clear > /sys/block/md0/md/array_state + } + +-- +2.41.0 + diff --git a/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch b/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch new file mode 100644 index 0000000..6de3318 --- /dev/null +++ b/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch @@ -0,0 +1,55 @@ +From b0f4e8e30f38d83f7e3f53d01d72d4cb3b4d42d7 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 7 May 2024 05:38:55 +0200 +Subject: [PATCH 65/66] util.c: change devnm to const in mdmon functions + +Devnm shall not be changed inside mdmon_running() +and mdmon_pid() functions, change this parameter to const. + +Signed-off-by: Kinga Stefaniuk +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 4 ++-- + util.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 2ff3e463..1ba541fc 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1768,8 +1768,8 @@ extern int is_subarray_active(char *subarray, char *devname); + extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet); + extern struct superswitch *version_to_superswitch(char *vers); + +-extern int mdmon_running(char *devnm); +-extern int mdmon_pid(char *devnm); ++extern int mdmon_running(const char *devnm); ++extern int mdmon_pid(const char *devnm); + extern int check_env(char *name); + extern __u32 random32(void); + extern void random_uuid(__u8 *buf); +diff --git a/util.c b/util.c +index 4fbf11c4..e2b490e1 100644 +--- a/util.c ++++ b/util.c +@@ -1902,7 +1902,7 @@ unsigned long long min_recovery_start(struct mdinfo *array) + return recovery_start; + } + +-int mdmon_pid(char *devnm) ++int mdmon_pid(const char *devnm) + { + char path[100]; + char pid[10]; +@@ -1922,7 +1922,7 @@ int mdmon_pid(char *devnm) + return atoi(pid); + } + +-int mdmon_running(char *devnm) ++int mdmon_running(const char *devnm) + { + int pid = mdmon_pid(devnm); + if (pid <= 0) +-- +2.41.0 + diff --git a/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch b/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch new file mode 100644 index 0000000..6cd30b2 --- /dev/null +++ b/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch @@ -0,0 +1,121 @@ +From aa1cc5815d2b14a8b47add18cfaa8264e19c10ce Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 7 May 2024 05:38:56 +0200 +Subject: [PATCH 66/66] Wait for mdmon when it is stared via systemd + +When mdmon is being started it may need few seconds to start. +For now, we didn't wait for it. Introduce wait_for_mdmon() +function, which waits up to 5 seconds for mdmon to start completely. + +Signed-off-by: Kinga Stefaniuk +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 4 ++-- + Grow.c | 7 ++++--- + mdadm.h | 2 ++ + util.c | 29 +++++++++++++++++++++++++++++ + 4 files changed, 37 insertions(+), 5 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index f5e9ab1f..83dced19 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -2173,8 +2173,8 @@ int assemble_container_content(struct supertype *st, int mdfd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(st->container_devnm); +- if (mdmon_running(st->container_devnm) && +- st->update_tail == NULL) ++ if (wait_for_mdmon(st->container_devnm) == MDADM_STATUS_SUCCESS && ++ !st->update_tail) + st->update_tail = &st->updates; + } + +diff --git a/Grow.c b/Grow.c +index 87ed9214..1923c27c 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2134,7 +2134,7 @@ int Grow_reshape(char *devname, int fd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(container); +- if (mdmon_running(st->container_devnm) == false) { ++ if (wait_for_mdmon(st->container_devnm) != MDADM_STATUS_SUCCESS) { + pr_err("No mdmon found. Grow cannot continue.\n"); + goto release; + } +@@ -3218,7 +3218,8 @@ static int reshape_array(char *container, int fd, char *devname, + if (!mdmon_running(container)) + start_mdmon(container); + ping_monitor(container); +- if (mdmon_running(container) && st->update_tail == NULL) ++ if (wait_for_mdmon(container) == MDADM_STATUS_SUCCESS && ++ !st->update_tail) + st->update_tail = &st->updates; + } + } +@@ -5173,7 +5174,7 @@ int Grow_continue_command(char *devname, int fd, struct context *c) + start_mdmon(container); + ping_monitor(container); + +- if (mdmon_running(container) == false) { ++ if (wait_for_mdmon(container) != MDADM_STATUS_SUCCESS) { + pr_err("No mdmon found. Grow cannot continue.\n"); + ret_val = 1; + goto Grow_continue_command_exit; +diff --git a/mdadm.h b/mdadm.h +index 1ba541fc..b71d7b32 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1770,6 +1770,8 @@ extern struct superswitch *version_to_superswitch(char *vers); + + extern int mdmon_running(const char *devnm); + extern int mdmon_pid(const char *devnm); ++extern mdadm_status_t wait_for_mdmon(const char *devnm); ++ + extern int check_env(char *name); + extern __u32 random32(void); + extern void random_uuid(__u8 *buf); +diff --git a/util.c b/util.c +index e2b490e1..bf79742f 100644 +--- a/util.c ++++ b/util.c +@@ -1932,6 +1932,35 @@ int mdmon_running(const char *devnm) + return 0; + } + ++/* ++ * wait_for_mdmon() - Waits for mdmon within specified time. ++ * @devnm: Device for which mdmon should start. ++ * ++ * Function waits for mdmon to start. It may need few seconds ++ * to start, we set timeout to 5, it should be sufficient. ++ * Do not wait if mdmon has been started. ++ * ++ * Return: MDADM_STATUS_SUCCESS if mdmon is running, error code otherwise. ++ */ ++mdadm_status_t wait_for_mdmon(const char *devnm) ++{ ++ const time_t mdmon_timeout = 5; ++ time_t start_time = time(0); ++ ++ if (mdmon_running(devnm)) ++ return MDADM_STATUS_SUCCESS; ++ ++ pr_info("Waiting for mdmon to start\n"); ++ while (time(0) - start_time < mdmon_timeout) { ++ sleep_for(0, MSEC_TO_NSEC(200), true); ++ if (mdmon_running(devnm)) ++ return MDADM_STATUS_SUCCESS; ++ }; ++ ++ pr_err("Timeout waiting for mdmon\n"); ++ return MDADM_STATUS_ERROR; ++} ++ + int start_mdmon(char *devnm) + { + int i; +-- +2.41.0 + diff --git a/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch b/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch new file mode 100644 index 0000000..4a8ed71 --- /dev/null +++ b/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch @@ -0,0 +1,62 @@ +From c5879860eac64ddd7bec4ba50c9adbfebcbf1d2e Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 15 May 2024 13:26:28 +0200 +Subject: [PATCH 1/1] mdadm: Fix compilation for 32-bit arch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Casting void pointer to __u64 works for 64-bit arch but fails to compile +on 32-bit arch like i686. + +Fail on i686 platform: +drive_encryption.c: In function ‘nvme_security_recv_ioctl’: +drive_encryption.c:236:25: error: cast from pointer to integer of +different size [-Werror=pointer-to-int-cast] + 236 | nvme_cmd.addr = (__u64)response_buffer; + | ^ +drive_encryption.c: In function ‘nvme_identify_ioctl’: +drive_encryption.c:271:25: error: cast from pointer to integer of +different size [-Werror=pointer-to-int-cast] + 271 | nvme_cmd.addr = (__u64)response_buffer; + | ^ +cc1: all warnings being treated as errors +make: *** [Makefile:211: drive_encryption.o] Error 1 + +This change adds cast void pointer to uintptr_t first to ensure that +proper pointer size is used for casting from pointer type. Then is safe to +cast it to __u64 because it is tracked as u_int, regardless it is 32-bit +or 64-bit arch. + +Reported-by: Xiao Ni +Fixes: cc48406887b3 ("Add reading Opal NVMe encryption information") +Signed-off-by: Blazej Kucman +--- + drive_encryption.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drive_encryption.c b/drive_encryption.c +index 27da9621..a4ad799f 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -233,7 +233,7 @@ nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *re + nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8; + nvme_cmd.cdw11 = buf_size; + nvme_cmd.data_len = buf_size; +- nvme_cmd.addr = (__u64)response_buffer; ++ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer; + + status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); + if (status != 0) { +@@ -268,7 +268,7 @@ nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const i + nvme_cmd.opcode = NVME_IDENTIFY; + nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA; + nvme_cmd.data_len = buf_size; +- nvme_cmd.addr = (__u64)response_buffer; ++ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer; + + status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); + if (status != 0) { +-- +2.41.0 + diff --git a/SOURCES/0070-add-checking-of-return-status-on-fstat-calls.patch b/SOURCES/0070-add-checking-of-return-status-on-fstat-calls.patch new file mode 100644 index 0000000..e81baeb --- /dev/null +++ b/SOURCES/0070-add-checking-of-return-status-on-fstat-calls.patch @@ -0,0 +1,267 @@ +From 95673c7d83c8ac7f2aeb91a34ead2971ba30e96e Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 20 May 2024 09:36:50 -0400 +Subject: [PATCH 070/157] add checking of return status on fstat calls + +There are a few places we don't check the return status when +calling fstat for success. Clean up the calls by adding a +check before continuing. + +Signed-off-by: Nigel Croxon +--- + Assemble.c | 41 +++++++++++++++++++++++------------------ + Dump.c | 11 +++++++++-- + Grow.c | 12 ++++++++---- + config.c | 3 ++- + mdstat.c | 3 ++- + super-ddf.c | 8 ++++++-- + super-intel.c | 8 ++++++-- + 7 files changed, 56 insertions(+), 30 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 83dced19..58dc2c5e 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -652,7 +652,9 @@ static int load_devices(struct devs *devices, char *devmap, + /* prepare useful information in info structures */ + struct stat stb2; + int err; +- fstat(mdfd, &stb2); ++ ++ if (fstat(mdfd, &stb2) != 0) ++ goto error; + + if (c->update == UOPT_UUID && !ident->uuid_set) + random_uuid((__u8 *)ident->uuid); +@@ -675,13 +677,10 @@ static int load_devices(struct devs *devices, char *devmap, + devname); + if (dfd >= 0) + close(dfd); +- close(mdfd); +- free(devices); +- free(devmap); + tst->ss->free_super(tst); + free(tst); + *stp = st; +- return -1; ++ goto error; + } + tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks); + +@@ -715,12 +714,9 @@ static int load_devices(struct devs *devices, char *devmap, + map_num(update_options, c->update), tst->ss->name); + tst->ss->free_super(tst); + free(tst); +- close(mdfd); + close(dfd); +- free(devices); +- free(devmap); + *stp = st; +- return -1; ++ goto error; + } + if (c->update == UOPT_UUID && + !ident->uuid_set) { +@@ -751,18 +747,23 @@ static int load_devices(struct devs *devices, char *devmap, + devname); + if (dfd >= 0) + close(dfd); +- close(mdfd); +- free(devices); +- free(devmap); + tst->ss->free_super(tst); + free(tst); + *stp = st; +- return -1; ++ goto error; + } + tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks); + } + +- fstat(dfd, &stb); ++ if (fstat(dfd, &stb) != 0) { ++ close(dfd); ++ free(devices); ++ free(devmap); ++ tst->ss->free_super(tst); ++ free(tst); ++ *stp = st; ++ return -1; ++ } + close(dfd); + + if (c->verbose > 0) +@@ -842,12 +843,9 @@ static int load_devices(struct devs *devices, char *devmap, + inargv ? "the list" : + "the\n DEVICE list in mdadm.conf" + ); +- close(mdfd); +- free(devices); +- free(devmap); + free(best); + *stp = st; +- return -1; ++ goto error; + } + if (best[i] == -1 || (devices[best[i]].i.events + < devices[devcnt].i.events)) +@@ -863,6 +861,13 @@ static int load_devices(struct devs *devices, char *devmap, + *bestp = best; + *stp = st; + return devcnt; ++ ++error: ++ close(mdfd); ++ free(devices); ++ free(devmap); ++ return -1; ++ + } + + static int force_array(struct mdinfo *content, +diff --git a/Dump.c b/Dump.c +index 736bcb60..81b94940 100644 +--- a/Dump.c ++++ b/Dump.c +@@ -37,6 +37,7 @@ int Dump_metadata(char *dev, char *dir, struct context *c, + unsigned long long size; + DIR *dirp; + struct dirent *de; ++ int ret = 0; + + if (stat(dir, &stb) != 0 || + (S_IFMT & stb.st_mode) != S_IFDIR) { +@@ -112,9 +113,15 @@ int Dump_metadata(char *dev, char *dir, struct context *c, + } + if (c->verbose >= 0) + printf("%s saved as %s.\n", dev, fname); +- fstat(fd, &dstb); +- close(fd); ++ + close(fl); ++ ret = fstat(fd, &dstb); ++ close(fd); ++ if (ret) { ++ unlink(fname); ++ free(fname); ++ return 1; ++ } + if ((dstb.st_mode & S_IFMT) != S_IFBLK) { + /* Not a block device, so cannot create links */ + free(fname); +diff --git a/Grow.c b/Grow.c +index 1923c27c..963792d0 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1223,13 +1223,14 @@ int reshape_open_backup_file(char *backup_file, + * way this will not notice, but it is better than + * nothing. + */ +- fstat(*fdlist, &stb); ++ if (fstat(*fdlist, &stb) != 0) ++ goto error; + dev = stb.st_dev; +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) ++ goto error; + if (stb.st_rdev == dev) { + pr_err("backup file must NOT be on the array being reshaped.\n"); +- close(*fdlist); +- return 0; ++ goto error; + } + + memset(buf, 0, 512); +@@ -1255,6 +1256,9 @@ int reshape_open_backup_file(char *backup_file, + } + + return 1; ++error: ++ close(*fdlist); ++ return 0; + } + + unsigned long compute_backup_blocks(int nchunk, int ochunk, +diff --git a/config.c b/config.c +index b46d71cb..612e700d 100644 +--- a/config.c ++++ b/config.c +@@ -949,7 +949,8 @@ void conf_file_or_dir(FILE *f) + struct dirent *dp; + struct fname *list = NULL; + +- fstat(fileno(f), &st); ++ if (fstat(fileno(f), &st) != 0) ++ return; + if (S_ISREG(st.st_mode)) + conf_file(f); + else if (!S_ISDIR(st.st_mode)) +diff --git a/mdstat.c b/mdstat.c +index 2fd792c5..e233f094 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -348,7 +348,8 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask) + + if (fd >= 0) { + struct stat stb; +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) ++ return; + if ((stb.st_mode & S_IFMT) == S_IFREG) + /* Must be a /proc or /sys fd, so expect + * POLLPRI +diff --git a/super-ddf.c b/super-ddf.c +index 21426c75..311001c1 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1053,7 +1053,10 @@ static int load_ddf_local(int fd, struct ddf_super *super, + 0); + dl->devname = devname ? xstrdup(devname) : NULL; + +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) { ++ free(dl); ++ return 1; ++ } + dl->major = major(stb.st_rdev); + dl->minor = minor(stb.st_rdev); + dl->next = super->dlist; +@@ -2786,7 +2789,8 @@ static int add_to_super_ddf(struct supertype *st, + /* This is device numbered dk->number. We need to create + * a phys_disk entry and a more detailed disk_data entry. + */ +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) ++ return 1; + n = find_unused_pde(ddf); + if (n == DDF_NOTFOUND) { + pr_err("No free slot in array, cannot add disk\n"); +diff --git a/super-intel.c b/super-intel.c +index 2b8b6fda..4d257371 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4239,7 +4239,10 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd) + + dl = xcalloc(1, sizeof(*dl)); + +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) { ++ free(dl); ++ return 1; ++ } + dl->major = major(stb.st_rdev); + dl->minor = minor(stb.st_rdev); + dl->next = super->disks; +@@ -5981,7 +5984,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, + if (super->current_vol >= 0) + return add_to_super_imsm_volume(st, dk, fd, devname); + +- fstat(fd, &stb); ++ if (fstat(fd, &stb) != 0) ++ return 1; + dd = xcalloc(sizeof(*dd), 1); + dd->major = major(stb.st_rdev); + dd->minor = minor(stb.st_rdev); +-- +2.41.0 + diff --git a/SOURCES/0071-super-intel-fix-typo-in-error-msg.patch b/SOURCES/0071-super-intel-fix-typo-in-error-msg.patch new file mode 100644 index 0000000..bb683d1 --- /dev/null +++ b/SOURCES/0071-super-intel-fix-typo-in-error-msg.patch @@ -0,0 +1,28 @@ +From c7790592bb7d050a990a9accb50de8f584879169 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 22 May 2024 11:13:17 +0200 +Subject: [PATCH 071/157] super-intel: fix typo in error msg + +Fix typo in encryption policy error msg. + +Signed-off-by: Blazej Kucman +--- + super-intel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index 4d257371..95856322 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11328,7 +11328,7 @@ check_policy: + return MDADM_STATUS_SUCCESS; + + fd2devname(disk_fd, devname); +- pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected eariler.\n", ++ pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected earlier.\n", + encryption_state, devname, expected_policy->value); + pr_vrb("Disks with different encryption status cannot be used.\n"); + return MDADM_STATUS_ERROR; +-- +2.41.0 + diff --git a/SOURCES/0072-mdadm-super-intel-remove-dead-code.patch b/SOURCES/0072-mdadm-super-intel-remove-dead-code.patch new file mode 100644 index 0000000..c25564b --- /dev/null +++ b/SOURCES/0072-mdadm-super-intel-remove-dead-code.patch @@ -0,0 +1,45 @@ +From 49145d4f574b21a6c0612ce691f255732cb91832 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Wed, 22 May 2024 16:05:25 -0400 +Subject: [PATCH 072/157] mdadm: super-intel remove dead code + +Execution cannot reach this statement: "while (devlist) { dv = de...". +Local variable "err" is assigned only once, to a constant value, +making it effectively constant throughout its scope. +Remove dead code. + +Signed-off-by: Nigel Croxon +--- + super-intel.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 95856322..d1b737c7 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7046,7 +7046,6 @@ get_devices(const char *hba_path) + struct md_list *dv; + struct dirent *ent; + DIR *dir; +- int err = 0; + + #if DEBUG_LOOP + devlist = get_loop_devices(); +@@ -7088,14 +7087,6 @@ get_devices(const char *hba_path) + dv->next = devlist; + devlist = dv; + } +- if (err) { +- while(devlist) { +- dv = devlist; +- devlist = devlist->next; +- free(dv->devname); +- free(dv); +- } +- } + closedir(dir); + return devlist; + } +-- +2.41.0 + diff --git a/SOURCES/0073-mdadm-super-intel-fix-bad-shift.patch b/SOURCES/0073-mdadm-super-intel-fix-bad-shift.patch new file mode 100644 index 0000000..f032dd4 --- /dev/null +++ b/SOURCES/0073-mdadm-super-intel-fix-bad-shift.patch @@ -0,0 +1,55 @@ +From 5c30864146412fcdfdcfddcdd94c5c449d9ddbed Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Wed, 22 May 2024 16:53:22 -0400 +Subject: [PATCH 073/157] mdadm: super-intel fix bad shift + +In the expression "1 << i", left shifting by more than 31 bits has undefined behavior. +The shift amount, "i", is as much as 63. The operand has type "int" (32 bits) and will +be shifted as an "int". The fix is to change to a 64 bit int. + +Signed-off-by: Nigel Croxon +--- + super-intel.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index d1b737c7..0287a618 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2343,7 +2343,8 @@ void print_encryption_information(int disk_fd, enum sys_dev_type hba_type) + get_encryption_status_string(information.status)); + } + +-static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_base, int verbose) ++static int ahci_enumerate_ports(struct sys_dev *hba, unsigned long port_count, int host_base, ++ int verbose) + { + /* dump an unsorted list of devices attached to AHCI Intel storage + * controller, as well as non-connected ports +@@ -2357,7 +2358,7 @@ static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_ba + + if (port_count > (int)sizeof(port_mask) * 8) { + if (verbose > 0) +- pr_err("port_count %d out of range\n", port_count); ++ pr_err("port_count %ld out of range\n", port_count); + return 2; + } + +@@ -2499,11 +2500,11 @@ static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_ba + if (dir) + closedir(dir); + if (err == 0) { +- int i; ++ unsigned long i; + + for (i = 0; i < port_count; i++) +- if (port_mask & (1 << i)) +- printf(" Port%d : - no device attached -\n", i); ++ if (port_mask & (1L << i)) ++ printf(" Port%ld : - no device attached -\n", i); + } + + return err; +-- +2.41.0 + diff --git a/SOURCES/0074-mdadm-deprecate-bitmap-custom-file.patch b/SOURCES/0074-mdadm-deprecate-bitmap-custom-file.patch new file mode 100644 index 0000000..5a2a0b2 --- /dev/null +++ b/SOURCES/0074-mdadm-deprecate-bitmap-custom-file.patch @@ -0,0 +1,438 @@ +From 50b100768a115526f5029113af957658ef76b383 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 29 Mar 2024 15:21:54 +0100 +Subject: [PATCH 074/157] mdadm: deprecate bitmap custom file + +This option has been deprecated in kernel by Christoph in commit +0ae1c9d38426 ("md: deprecate bitmap file support"). Do the same in +mdadm. + +With this change, user must acknowledge it, it is not +skippable. The implementation of custom bitmap file looks like it's +abandoned. It cannot be done by Incremental so it is not respected by +any udev based system and it seems to not be recorded by metadata. +User must assemble such volume manually. + +Tests for bitmap custom file are removed because now they will not +pass because interaction with user is mandatory. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.8.in | 34 +++++++++---------- + mdadm.c | 70 +++++++++++++++++++++++++++------------- + tests/05r1-bitmapfile | 49 ---------------------------- + tests/05r1-grow-external | 33 ------------------- + tests/05r1-n3-bitmapfile | 53 ------------------------------ + tests/05r5-bitmapfile | 49 ---------------------------- + tests/05r6-bitmapfile | 49 ---------------------------- + 7 files changed, 62 insertions(+), 275 deletions(-) + delete mode 100644 tests/05r1-bitmapfile + delete mode 100644 tests/05r1-grow-external + delete mode 100644 tests/05r1-n3-bitmapfile + delete mode 100644 tests/05r5-bitmapfile + delete mode 100644 tests/05r6-bitmapfile + +diff --git a/mdadm.8.in b/mdadm.8.in +index 9ba66825..aa0c5403 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -727,29 +727,25 @@ same as + + .TP + .BR \-b ", " \-\-bitmap= +-Specify a file to store a write-intent bitmap in. The file should not +-exist unless +-.B \-\-force +-is also given. The same file should be provided +-when assembling the array. If the word +-.B "internal" +-is given, then the bitmap is stored with the metadata on the array, +-and so is replicated on all devices. If the word +-.B "none" +-is given with +-.B \-\-grow +-mode, then any bitmap that is present is removed. If the word +-.B "clustered" +-is given, the array is created for a clustered environment. One bitmap +-is created for each node as defined by the ++Specify how to store a write-intent bitmap. Following values are supported: ++ ++.B internal ++- the bitmap is stored with the metadata on the array and so is replicated on all devices. ++ ++.B clustered ++- the array is created for a clustered environment. One bitmap is created for each node as defined ++by the + .B \-\-nodes + parameter and are stored internally. + +-To help catch typing errors, the filename must contain at least one +-slash ('/') if it is a real file (not 'internal' or 'none'). ++.B none ++- create array with no bitmap or remove any present bitmap (grow mode). + +-Note: external bitmaps are only known to work on ext2 and ext3. +-Storing bitmap files on other filesystems may result in serious problems. ++Setting bitmap for file is deprecated and should not be used. The file should not exist unless ++.B \-\-force ++is also given. The same file should be provided when assembling the array. The file name must ++contain at least one slash ('/'). Bitmap files are only known to work on ext2 and ext3. Storing ++bitmap files on other filesystems may result in serious problems. + + When creating an array on devices which are 100G or larger, + .I mdadm +diff --git a/mdadm.c b/mdadm.c +index d18619db..0b99fad4 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -29,6 +29,51 @@ + #include "md_p.h" + #include + ++/** ++ * set_bitmap_value() - set bitmap value. ++ * @s: Shape. ++ * @c: Context. ++ * @val: value to set. ++ * ++ * Validate and set bitmap. Context is needed for setting nodes for clustered bitmap. ++ */ ++static mdadm_status_t set_bitmap_value(struct shape *s, struct context *c, char *val) ++{ ++ if (s->bitmap_file) { ++ pr_err("--bitmap cannot be set twice. Second value: \"%s\".\n", val); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if (strcmp(val, "internal") == 0 || strcmp(optarg, STR_COMMON_NONE) == 0) { ++ s->bitmap_file = val; ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ if (strcmp(val, "clustered") == 0) { ++ s->bitmap_file = val; ++ /* Set the default number of cluster nodes ++ * to 4 if not already set by user ++ */ ++ if (c->nodes < 1) ++ c->nodes = 4; ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ if (strchr(val, '/')) { ++ pr_info("Custom write-intent bitmap file option is deprecated.\n"); ++ if (ask("Do you want to continue? (y/n)")) { ++ s->bitmap_file = val; ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ return MDADM_STATUS_ERROR; ++ } ++ ++ pr_err("--bitmap value must contain a '/' or be 'internal', 'clustered' or 'none'\n"); ++ pr_err("Current value is \"%s\"", val); ++ return MDADM_STATUS_ERROR; ++} ++ + static int scan_assemble(struct supertype *ss, + struct context *c, + struct mddev_ident *ident); +@@ -1094,30 +1139,9 @@ int main(int argc, char *argv[]) + case O(CREATE,Bitmap): /* here we create the bitmap */ + case O(GROW,'b'): + case O(GROW,Bitmap): +- if (s.bitmap_file) { +- pr_err("bitmap cannot be set twice. Second value: %s.\n", optarg); ++ if (set_bitmap_value(&s, &c, optarg)) + exit(2); +- } +- if (strcmp(optarg, "internal") == 0 || +- strcmp(optarg, STR_COMMON_NONE) == 0 || +- strchr(optarg, '/') != NULL) { +- s.bitmap_file = optarg; +- continue; +- } +- if (strcmp(optarg, "clustered") == 0) { +- s.bitmap_file = optarg; +- /* Set the default number of cluster nodes +- * to 4 if not already set by user +- */ +- if (c.nodes < 1) +- c.nodes = 4; +- continue; +- } +- /* probable typo */ +- pr_err("bitmap file must contain a '/', or be 'internal', or be 'clustered', or 'none'\n" +- " not '%s'\n", optarg); +- exit(2); +- ++ continue; + case O(GROW,BitmapChunk): + case O(BUILD,BitmapChunk): + case O(CREATE,BitmapChunk): /* bitmap chunksize */ +diff --git a/tests/05r1-bitmapfile b/tests/05r1-bitmapfile +deleted file mode 100644 +index f384f0ea..00000000 +--- a/tests/05r1-bitmapfile ++++ /dev/null +@@ -1,49 +0,0 @@ +- +-# +-# create a raid1 with a bitmap file +-# +-bmf=$targetdir/bitmap +-rm -f $bmf +-mdadm --create --run $md0 --level=1 -n2 --delay=1 --bitmap $bmf $dev1 $dev2 +-check wait +-testdev $md0 1 $mdsize1a 64 +-mdadm -S $md0 +- +-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 +-testdev $md0 1 $mdsize1a 64 +-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" +- exit 1 +-fi +-mdadm $md0 -f $dev1 +-testdev $md0 1 $mdsize1a 64 +-sleep 4 +-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" +- exit 2 +-fi +- +-mdadm -S $md0 +- +-mdadm --assemble -R $md0 --bitmap=$bmf $dev2 +-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-mdadm --zero $dev1 # force --add, not --re-add +-mdadm $md0 --add $dev1 +-#it is too fast# check recovery +- +-check wait +-sleep 4 +-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" +- exit 1 +-fi +- +-mdadm -S $md0 +diff --git a/tests/05r1-grow-external b/tests/05r1-grow-external +deleted file mode 100644 +index 69da3e90..00000000 +--- a/tests/05r1-grow-external ++++ /dev/null +@@ -1,33 +0,0 @@ +- +-# +-# create a raid1 array, add an external bitmap +-# +-mdadm --create --run $md0 -l 1 -n 2 $dev1 $dev2 +-check wait +-testdev $md0 1 $mdsize1a 64 +- +-bmf=$targetdir/bm +-rm -f $bmf +-#mdadm -E $dev1 +-mdadm --grow $md0 --bitmap=$bmf --delay=1 || { mdadm -X $bmf ; exit 1; } +-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-testdev $md0 1 $mdsize1a 64 +-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-#echo $dirty1 $dirty2 $dirty3 $dirty4 +-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] +-then +- echo bad dirty counts +- exit 1 +-fi +- +-# now to remove the bitmap +-check bitmap +-mdadm --grow $md0 --bitmap=none +-check nobitmap +-mdadm -S $md0 +diff --git a/tests/05r1-n3-bitmapfile b/tests/05r1-n3-bitmapfile +deleted file mode 100644 +index f1c3f1ee..00000000 +--- a/tests/05r1-n3-bitmapfile ++++ /dev/null +@@ -1,53 +0,0 @@ +- +-# +-# create a raid1 with 3 devices and a bitmap file +-# make sure resync does right thing. +-# +-# +-bmf=$targetdir/bitmap +-rm -f $bmf +-mdadm --create -e0.90 --run $md0 --level=1 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 +-check wait +-testdev $md0 1 $mdsize0 64 +-mdadm -S $md0 +- +-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 +-testdev $md0 1 $mdsize0 64 +-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" +- exit 1 +-fi +-mdadm $md0 -f $dev2 +-testdev $md0 1 $mdsize0 64 +-sleep 4 +-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" +- exit 2 +-fi +- +-mdadm -S $md0 +- +-mdadm --assemble -R $md0 --bitmap=$bmf $dev1 $dev3 +-check nosync +-mdadm --zero-superblock $dev2 +-mdadm $md0 --add $dev2 +-check recovery +- +-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-check wait +-sleep 4 +-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" +- exit 1 +-fi +- +-mdadm -S $md0 +-exit 0 +diff --git a/tests/05r5-bitmapfile b/tests/05r5-bitmapfile +deleted file mode 100644 +index 6d173d88..00000000 +--- a/tests/05r5-bitmapfile ++++ /dev/null +@@ -1,49 +0,0 @@ +- +-# +-# create a raid1 with a bitmap file +-# +-bmf=$targetdir/bitmap +-rm -f $bmf +-mdadm --create --run $md0 --level=5 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 +-check wait +-testdev $md0 2 $mdsize1 512 +-mdadm -S $md0 +- +-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 +-testdev $md0 2 $mdsize1 512 +-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" +- exit 1 +-fi +-mdadm $md0 -f $dev1 +-testdev $md0 2 $mdsize1 512 +-sleep 4 +-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" +- exit 2 +-fi +- +-mdadm -S $md0 +- +-mdadm --assemble -R $md0 --bitmap=$bmf $dev2 $dev3 +-mdadm --zero $dev1 # force add, not re-add +-mdadm $md0 --add $dev1 +-check recovery +- +-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-check wait +-sleep 4 +-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" +- exit 1 +-fi +- +-mdadm -S $md0 +diff --git a/tests/05r6-bitmapfile b/tests/05r6-bitmapfile +deleted file mode 100644 +index d11896db..00000000 +--- a/tests/05r6-bitmapfile ++++ /dev/null +@@ -1,49 +0,0 @@ +- +-# +-# create a raid1 with a bitmap file +-# +-bmf=$targetdir/bitmap +-rm -f $bmf +-mdadm --create --run $md0 --level=6 -n4 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 $dev4 +-check wait +-testdev $md0 2 $mdsize1 512 +-mdadm -S $md0 +- +-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 $dev4 +-testdev $md0 2 $mdsize1 512 +-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-sleep 4 +-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" +- exit 1 +-fi +-mdadm $md0 -f $dev3 +-testdev $md0 2 $mdsize1 512 +-sleep 4 +-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" +- exit 2 +-fi +- +-mdadm -S $md0 +- +-mdadm --assemble -R $md0 --bitmap=$bmf $dev1 $dev2 $dev4 +-mdadm --zero $dev3 # force --add, not --re-add +-mdadm $md0 --add $dev3 +-check recovery +- +-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-check wait +-sleep 4 +-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +- +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" +- exit 1 +-fi +- +-mdadm -S $md0 +-- +2.41.0 + diff --git a/SOURCES/0075-Makefile-fix-make-s-detection.patch b/SOURCES/0075-Makefile-fix-make-s-detection.patch new file mode 100644 index 0000000..ab5076a --- /dev/null +++ b/SOURCES/0075-Makefile-fix-make-s-detection.patch @@ -0,0 +1,31 @@ +From 906922ee321d64e2ce8458147e67d4892696fb58 Mon Sep 17 00:00:00 2001 +From: Valery Ushakov +Date: Wed, 22 May 2024 17:07:38 +0300 +Subject: [PATCH 075/157] Makefile: fix make -s detection + +Only check the first word of MAKEFLAGS for 's', that's where all the +single letter options are collected. + +MAKEFLAGS contains _all_ make flags, so if any command line argument +contains a letter 's', the silent test will be false positive. Think +e.g. make 'DESTDIR=.../aports/main/mdadm/pkg/mdadm' install +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index adac7905..446710bd 100644 +--- a/Makefile ++++ b/Makefile +@@ -157,7 +157,7 @@ ifndef UDEVDIR + UDEVDIR = /lib/udev + endif + +-ifeq (,$(findstring s,$(MAKEFLAGS))) ++ifeq (,$(findstring s,$(firstword -$(MAKEFLAGS)))) + ECHO=echo + else + ECHO=: +-- +2.41.0 + diff --git a/SOURCES/0076-Change-some-error-messages-to-info-level.patch b/SOURCES/0076-Change-some-error-messages-to-info-level.patch new file mode 100644 index 0000000..76442a9 --- /dev/null +++ b/SOURCES/0076-Change-some-error-messages-to-info-level.patch @@ -0,0 +1,81 @@ +From 13a0e92a3ed70c52246a0f0572dee61203994327 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:38 +0800 +Subject: [PATCH 076/157] Change some error messages to info level + +These logs are not error logs. Change them to info level. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 16 ++++++---------- + Manage.c | 2 +- + util.c | 4 ++-- + 3 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 58dc2c5e..0e6da593 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1214,23 +1214,19 @@ static int start_array(int mdfd, + if (rv == 0) { + sysfs_rules_apply(mddev, content); + if (c->verbose >= 0) { +- pr_err("%s has been started with %d drive%s", ++ pr_info("%s has been started with %d drive%s", + mddev, okcnt, okcnt==1?"":"s"); + if (okcnt < (unsigned)content->array.raid_disks) +- fprintf(stderr, " (out of %d)", +- content->array.raid_disks); ++ printf(" (out of %d)", content->array.raid_disks); + if (rebuilding_cnt) +- fprintf(stderr, "%s %d rebuilding", +- sparecnt?",":" and", ++ printf("%s %d rebuilding", sparecnt?",":" and", + rebuilding_cnt); + if (sparecnt) +- fprintf(stderr, " and %d spare%s", +- sparecnt, ++ printf(" and %d spare%s", sparecnt, + sparecnt == 1 ? "" : "s"); + if (content->journal_clean) +- fprintf(stderr, " and %d journal", +- journalcnt); +- fprintf(stderr, ".\n"); ++ printf(" and %d journal", journalcnt); ++ printf(".\n"); + } + if (content->reshape_active && + is_level456(content->array.level)) { +diff --git a/Manage.c b/Manage.c +index 96e5ee54..5db72b77 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -463,7 +463,7 @@ done: + } + + if (verbose >= 0) +- pr_err("stopped %s\n", devname); ++ pr_info("stopped %s\n", devname); + map_lock(&map); + map_remove(&map, devnm); + map_unlock(&map); +diff --git a/util.c b/util.c +index bf79742f..48c97545 100644 +--- a/util.c ++++ b/util.c +@@ -633,9 +633,9 @@ int check_ext2(int fd, char *name) + bsize = sb[24]|(sb[25]|(sb[26]|sb[27]<<8)<<8)<<8; + size = sb[4]|(sb[5]|(sb[6]|sb[7]<<8)<<8)<<8; + size <<= bsize; +- pr_err("%s appears to contain an ext2fs file system\n", ++ pr_info("%s appears to contain an ext2fs file system\n", + name); +- cont_err("size=%lluK mtime=%s", size, ctime(&mtime)); ++ pr_info("size=%lluK mtime=%s", size, ctime(&mtime)); + return 1; + } + +-- +2.41.0 + diff --git a/SOURCES/0077-mdadm-Start-update_opt-from-0.patch b/SOURCES/0077-mdadm-Start-update_opt-from-0.patch new file mode 100644 index 0000000..5578a24 --- /dev/null +++ b/SOURCES/0077-mdadm-Start-update_opt-from-0.patch @@ -0,0 +1,40 @@ +From 296398299391b10650bdd79d986b115588e60590 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:39 +0800 +Subject: [PATCH 077/157] mdadm: Start update_opt from 0 + +Before f2e8393bd722 ('Manage&Incremental: code refactor, string to enum'), it uses +NULL to represent it doesn't need to update. So init UOPT_UNDEFINED to 0. This +problem is found by test case 05r6tor0. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index b71d7b32..40818941 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -535,7 +535,8 @@ enum special_options { + }; + + enum update_opt { +- UOPT_NAME = 1, ++ UOPT_UNDEFINED = 0, ++ UOPT_NAME, + UOPT_PPL, + UOPT_NO_PPL, + UOPT_BITMAP, +@@ -575,7 +576,6 @@ enum update_opt { + UOPT_SPEC_FAILFAST, + UOPT_SPEC_NOFAILFAST, + UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, +- UOPT_UNDEFINED + }; + extern void fprint_update_options(FILE *outf, enum update_opt update_mode); + +-- +2.41.0 + diff --git a/SOURCES/0078-Don-t-control-reshape-speed-in-daemon.patch b/SOURCES/0078-Don-t-control-reshape-speed-in-daemon.patch new file mode 100644 index 0000000..3b4ed28 --- /dev/null +++ b/SOURCES/0078-Don-t-control-reshape-speed-in-daemon.patch @@ -0,0 +1,49 @@ +From f79f7189aa25b9da51736f2c578a51c2c4fe7706 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:40 +0800 +Subject: [PATCH 078/157] Don't control reshape speed in daemon + +It tries to set the max sync speed in reshape. This should be done by +administrators by control interfaces /proc/sys/dev/raid/speed_limit_max/min. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 963792d0..b135930d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -4488,7 +4488,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, + */ + char *buf; + int degraded = -1; +- unsigned long long speed; + unsigned long long suspend_point, array_size; + unsigned long long backup_point, wait_point; + unsigned long long reshape_completed; +@@ -4544,10 +4543,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, + if (posix_memalign((void**)&buf, 4096, disks * chunk)) + /* Don't start the 'reshape' */ + return 0; +- if (reshape->before.data_disks == reshape->after.data_disks) { +- sysfs_get_ll(sra, NULL, "sync_speed_min", &speed); +- sysfs_set_num(sra, NULL, "sync_speed_min", 200000); +- } + + if (increasing) { + array_size = sra->component_size * reshape->after.data_disks; +@@ -4680,8 +4675,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, + sysfs_set_num(sra, NULL, "suspend_lo", 0); + sysfs_set_num(sra, NULL, "sync_min", 0); + +- if (reshape->before.data_disks == reshape->after.data_disks) +- sysfs_set_num(sra, NULL, "sync_speed_min", speed); + free(buf); + return done; + } +-- +2.41.0 + diff --git a/SOURCES/0079-mdadm-tests-test-enhance.patch b/SOURCES/0079-mdadm-tests-test-enhance.patch new file mode 100644 index 0000000..ed4263c --- /dev/null +++ b/SOURCES/0079-mdadm-tests-test-enhance.patch @@ -0,0 +1,119 @@ +From 6e8af9475cf0ac22f7ac167040dbf92fbfdd97ab Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:41 +0800 +Subject: [PATCH 079/157] mdadm/tests: test enhance + +There are two changes. +First, if md module is not loaded, it gives error when reading +speed_limit_max. So read the value after loading md module which +is done in do_setup + +Second, sometimes the test reports error sync action doesn't +happen. But dmesg shows sync action is done. So limit the sync +speed before test. It doesn't affect the test run time. Because +check wait sets the max speed before waiting sync action. And +recording speed_limit_max/min in do_setup. + +Fixes: 4c12714d1ca0 ('test: run tests on system level mdadm') +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 10 +++++----- + tests/func.sh | 26 +++++++++++++++++++++++--- + 2 files changed, 28 insertions(+), 8 deletions(-) + +diff --git a/test b/test +index 338c2db4..ff403293 100755 +--- a/test ++++ b/test +@@ -6,7 +6,10 @@ targetdir="/var/tmp" + logdir="$targetdir" + config=/tmp/mdadm.conf + testdir=$PWD/tests +-system_speed_limit=`cat /proc/sys/dev/raid/speed_limit_max` ++system_speed_limit_max=0 ++system_speed_limit_min=0 ++test_speed_limit_min=100 ++test_speed_limit_max=500 + devlist= + + savelogs=0 +@@ -39,10 +42,6 @@ ctrl_c() { + ctrl_c_error=1 + } + +-restore_system_speed_limit() { +- echo $system_speed_limit > /proc/sys/dev/raid/speed_limit_max +-} +- + mdadm() { + rm -f $targetdir/stderr + case $* in +@@ -103,6 +102,7 @@ do_test() { + do_clean + # source script in a subshell, so it has access to our + # namespace, but cannot change it. ++ control_system_speed_limit + echo -ne "$_script... " + if ( set -ex ; . $_script ) &> $targetdir/log + then +diff --git a/tests/func.sh b/tests/func.sh +index b474442b..221cff15 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -136,6 +136,23 @@ check_env() { + fi + } + ++record_system_speed_limit() { ++ system_speed_limit_max=`cat /proc/sys/dev/raid/speed_limit_max` ++ system_speed_limit_min=`cat /proc/sys/dev/raid/speed_limit_min` ++} ++ ++# To avoid sync action finishes before checking it, it needs to limit ++# the sync speed ++control_system_speed_limit() { ++ echo $test_speed_limit_min > /proc/sys/dev/raid/speed_limit_min ++ echo $test_speed_limit_max > /proc/sys/dev/raid/speed_limit_max ++} ++ ++restore_system_speed_limit() { ++ echo $system_speed_limit_min > /proc/sys/dev/raid/speed_limit_max ++ echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max ++} ++ + do_setup() { + trap cleanup 0 1 3 15 + trap ctrl_c 2 +@@ -214,6 +231,7 @@ do_setup() { + ulimit -c unlimited + [ -f /proc/mdstat ] || modprobe md_mod + echo 0 > /sys/module/md_mod/parameters/start_ro ++ record_system_speed_limit + } + + # check various things +@@ -265,15 +283,17 @@ check() { + fi + ;; + wait ) +- p=`cat /proc/sys/dev/raid/speed_limit_max` +- echo 2000000 > /proc/sys/dev/raid/speed_limit_max ++ min=`cat /proc/sys/dev/raid/speed_limit_min` ++ max=`cat /proc/sys/dev/raid/speed_limit_max` ++ echo 200000 > /proc/sys/dev/raid/speed_limit_max + sleep 0.1 + while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat || + grep -v idle > /dev/null /sys/block/md*/md/sync_action + do + sleep 0.5 + done +- echo $p > /proc/sys/dev/raid/speed_limit_max ++ echo $min > /proc/sys/dev/raid/speed_limit_min ++ echo $max > /proc/sys/dev/raid/speed_limit_max + ;; + state ) + grep -sq "blocks.*\[$2\]\$" /proc/mdstat || +-- +2.41.0 + diff --git a/SOURCES/0080-mdadm-tests-test-don-t-fail-when-systemd-reports-err.patch b/SOURCES/0080-mdadm-tests-test-don-t-fail-when-systemd-reports-err.patch new file mode 100644 index 0000000..0d443c0 --- /dev/null +++ b/SOURCES/0080-mdadm-tests-test-don-t-fail-when-systemd-reports-err.patch @@ -0,0 +1,31 @@ +From 73ba062ef93d0a57360a2d5200bc7a8f8781e7b6 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:42 +0800 +Subject: [PATCH 080/157] mdadm/tests: test don't fail when systemd reports + error + +Sometimes systemd reports error in dmesg and test fails. Add +a condition to avoid this failure. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test b/test +index ff403293..3da53f87 100755 +--- a/test ++++ b/test +@@ -109,7 +109,7 @@ do_test() { + if [ -f "${_script}.inject_error" ]; then + echo "dmesg checking is skipped because test inject error" + else +- dmesg | grep -iq "error\|call trace\|segfault" && ++ dmesg | grep -iq "error\|call trace\|segfault" | grep -v "systemd" && + die "dmesg prints errors when testing $_basename!" + fi + echo "succeeded" +-- +2.41.0 + diff --git a/SOURCES/0081-mdadm-tests-names_template-enhance.patch b/SOURCES/0081-mdadm-tests-names_template-enhance.patch new file mode 100644 index 0000000..71bc49e --- /dev/null +++ b/SOURCES/0081-mdadm-tests-names_template-enhance.patch @@ -0,0 +1,109 @@ +From 41706a91568472d10153bf4ada3c3f0d93ef327a Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:43 +0800 +Subject: [PATCH 081/157] mdadm/tests: names_template enhance + +For super1, if the length of hostname is >= 32, it doesn't add hostname +in metadata name. Fix this problem by checking the length of hostname. +Because other cases may use need to check this, so do the check in +do_setup. + +And this patch adds a check if link /dev/md/name exists. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 5 +++++ + tests/func.sh | 13 +++++++++++++ + tests/templates/names_template | 14 ++++++++++++-- + 3 files changed, 30 insertions(+), 2 deletions(-) + +diff --git a/test b/test +index 3da53f87..814ce199 100755 +--- a/test ++++ b/test +@@ -11,6 +11,11 @@ system_speed_limit_min=0 + test_speed_limit_min=100 + test_speed_limit_max=500 + devlist= ++# If super1 metadata name doesn't have the same hostname with machine, ++# it's treated as foreign. ++# For example, /dev/md0 is created, stops it, then assemble it, the ++# device node will be /dev/md127 (127 is choosed by mdadm autumatically) ++is_foreign="no" + + savelogs=0 + exitonerror=1 +diff --git a/tests/func.sh b/tests/func.sh +index 221cff15..cfe83e55 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -153,6 +153,18 @@ restore_system_speed_limit() { + echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max + } + ++is_raid_foreign() { ++ ++ # If the length of hostname is >= 32, super1 doesn't use ++ # hostname in metadata ++ hostname=$(hostname) ++ if [ `expr length $(hostname)` -lt 32 ]; then ++ is_foreign="no" ++ else ++ is_foreign="yes" ++ fi ++} ++ + do_setup() { + trap cleanup 0 1 3 15 + trap ctrl_c 2 +@@ -232,6 +244,7 @@ do_setup() { + [ -f /proc/mdstat ] || modprobe md_mod + echo 0 > /sys/module/md_mod/parameters/start_ro + record_system_speed_limit ++ is_raid_foreign + } + + # check various things +diff --git a/tests/templates/names_template b/tests/templates/names_template +index 1b6cd14b..88ad5b8c 100644 +--- a/tests/templates/names_template ++++ b/tests/templates/names_template +@@ -30,6 +30,7 @@ function names_verify() { + local DEVNODE_NAME="$1" + local WANTED_LINK="$2" + local WANTED_NAME="$3" ++ local EXPECTED="" + + local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" + if [[ "$?" != "0" ]]; then +@@ -38,7 +39,12 @@ function names_verify() { + fi + + if [[ "$WANTED_LINK" != "empty" ]]; then +- local EXPECTED="MD_DEVNAME=$WANTED_LINK" ++ EXPECTED="MD_DEVNAME=$WANTED_LINK" ++ ++ if [ ! -b /dev/md/$WANTED_LINK ]; then ++ echo "/dev/md/$WANTED_LINK doesn't exit" ++ exit 1 ++ fi + fi + + if [[ "$RES" != "$EXPECTED" ]]; then +@@ -52,7 +58,11 @@ function names_verify() { + exit 1 + fi + +- local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" ++ if [ $is_foreign == "no" ]; then ++ EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" ++ else ++ EXPECTED="MD_NAME=$WANTED_NAME" ++ fi + if [[ "$RES" != "$EXPECTED" ]]; then + echo "$RES doesn't match $EXPECTED." + exit 1 +-- +2.41.0 + diff --git a/SOURCES/0082-mdadm-tests-03assem-incr-enhance.patch b/SOURCES/0082-mdadm-tests-03assem-incr-enhance.patch new file mode 100644 index 0000000..4c0cb2c --- /dev/null +++ b/SOURCES/0082-mdadm-tests-03assem-incr-enhance.patch @@ -0,0 +1,67 @@ +From 23f45965a0abe3506885c8e8005ee79473a66422 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:44 +0800 +Subject: [PATCH 082/157] mdadm/tests: 03assem-incr enhance + +It fails when hostname lenght > 32. Because the super1 metadata name +doesn't include hostname when hostname length > 32. Then mdadm thinks +the array is a foreign array if no device link is specified when +assembling the array. It chooses a minor number from 127. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 3 +++ + tests/03assem-incr | 20 +++++++++++++------- + 2 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/test b/test +index 814ce199..1fce6be2 100755 +--- a/test ++++ b/test +@@ -33,6 +33,9 @@ LVM_VOLGROUP=mdtest + md0=/dev/md0 + md1=/dev/md1 + md2=/dev/md2 ++# if user doesn't specify minor number, mdadm chooses minor number ++# automatically from 127. ++md127=/dev/md127 + mdp0=/dev/md_d0 + mdp1=/dev/md_d1 + +diff --git a/tests/03assem-incr b/tests/03assem-incr +index 38880a7f..21215a34 100644 +--- a/tests/03assem-incr ++++ b/tests/03assem-incr +@@ -9,15 +9,21 @@ set -x -e + levels=(raid0 raid1 raid5) + + if [ "$LINEAR" == "yes" ]; then +- levels+=( linear ) ++ levels+=( linear ) + fi + + for l in ${levels[@]} + do +- mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean +- mdadm -S md0 +- mdadm -I $dev1 +- mdadm -I $dev3 +- mdadm -A /dev/md0 $dev0 $dev1 $dev2 $dev3 $dev4 +- mdadm -S /dev/md0 ++ mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean ++ mdadm -S $md0 ++ mdadm -I $dev1 ++ mdadm -I $dev3 ++ mdadm -A $md0 $dev0 $dev1 $dev2 $dev3 $dev4 ++ # If one array is foreign (metadata name doesn't have the machine's ++ # hostname), mdadm chooses a minor number automatically from 127 ++ if [ $is_foreign == "no" ]; then ++ mdadm -S $md0 ++ else ++ mdadm -S $md127 ++ fi + done +-- +2.41.0 + diff --git a/SOURCES/0083-mdadm-tests-03r0assem-enhance.patch b/SOURCES/0083-mdadm-tests-03r0assem-enhance.patch new file mode 100644 index 0000000..6552599 --- /dev/null +++ b/SOURCES/0083-mdadm-tests-03r0assem-enhance.patch @@ -0,0 +1,38 @@ +From f136d9a8b7d8fdfd7539b96707bc9a03528754aa Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:45 +0800 +Subject: [PATCH 083/157] mdadm/tests 03r0assem enhance + +dcc22ae74a864 ('super1: remove support for name= in config') already +removes name= support. So remove related test codes in 03r0assem. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/03r0assem | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/tests/03r0assem b/tests/03r0assem +index f7c29e8c..4bf8b9e8 100644 +--- a/tests/03r0assem ++++ b/tests/03r0assem +@@ -33,16 +33,6 @@ mdadm -As -c $conf $md2 + $tst + mdadm -S $md2 + +-{ +- echo DEVICE $devlist +- echo array $md2 name=2 +-} > $conf +- +-mdadm -As -c $conf $md2 +-$tst +-mdadm -S $md2 +- +- + { + echo DEVICE $devlist + echo array $md2 devices=$dev0,$dev1,$dev2 +-- +2.41.0 + diff --git a/SOURCES/0084-mdadm-tests-remove-03r5assem-failed.patch b/SOURCES/0084-mdadm-tests-remove-03r5assem-failed.patch new file mode 100644 index 0000000..9086c99 --- /dev/null +++ b/SOURCES/0084-mdadm-tests-remove-03r5assem-failed.patch @@ -0,0 +1,35 @@ +From 5c1133ba8d026d65362953f25178fbf974b78ce9 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:46 +0800 +Subject: [PATCH 084/157] mdadm/tests: remove 03r5assem-failed + +03r5assem can run successfully with kernel 6.9.0-rc4 + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/03r5assem-failed | 12 ------------ + 1 file changed, 12 deletions(-) + delete mode 100644 tests/03r5assem-failed + +diff --git a/tests/03r5assem-failed b/tests/03r5assem-failed +deleted file mode 100644 +index d38241df..00000000 +--- a/tests/03r5assem-failed ++++ /dev/null +@@ -1,12 +0,0 @@ +- +-# Create an array, fail one device while array is active, stop array, +-# then re-assemble listing the failed device first. +- +-mdadm -CR $md1 -l5 -n4 $dev0 $dev1 $dev2 $dev3 +-check wait +- +-echo 2000 > /sys/block/md1/md/safe_mode_delay +-mkfs $md1 +-mdadm $md1 -f $dev0 +-mdadm -S $md1 +-mdadm -A $md1 $dev0 $dev1 $dev2 $dev3 || exit 1 +-- +2.41.0 + diff --git a/SOURCES/0085-mdadm-tests-03r5assemV1.patch b/SOURCES/0085-mdadm-tests-03r5assemV1.patch new file mode 100644 index 0000000..36eeb14 --- /dev/null +++ b/SOURCES/0085-mdadm-tests-03r5assemV1.patch @@ -0,0 +1,52 @@ +From 6077e9248acda8c70df58fabc8de23195c19a0cf Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:47 +0800 +Subject: [PATCH 085/157] mdadm/tests: 03r5assemV1 + +dcc22ae74a864 ('super1: remove support for name= in config') already +removes name= support. So remove related test codes in 03r5assemV1. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/03r5assemV1 | 17 ----------------- + 1 file changed, 17 deletions(-) + +diff --git a/tests/03r5assemV1 b/tests/03r5assemV1 +index bca0c583..6026011e 100644 +--- a/tests/03r5assemV1 ++++ b/tests/03r5assemV1 +@@ -31,14 +31,6 @@ conf=$targetdir/mdadm.conf + mdadm -As -c $conf $md1 + eval $tst + +-{ +- echo DEVICE $devlist +- echo array $md1 name=one +-} > $conf +- +-mdadm -As -c $conf +-eval $tst +- + { + echo DEVICE $devlist + echo array $md1 devices=$dev0,$dev1,$dev2,$dev3,$dev4 +@@ -88,15 +80,6 @@ mdadm -As -c $conf $md1 + check state U_U + eval $tst + +-{ +- echo DEVICE $devlist +- echo array $md1 name=one +-} > $conf +- +-mdadm -As -c $conf +-check state U_U +-eval $tst +- + { + echo DEVICE $devlist + echo array $md1 devices=$dev0,$dev1,$dev2 +-- +2.41.0 + diff --git a/SOURCES/0086-mdadm-tests-remove-04r5swap.broken.patch b/SOURCES/0086-mdadm-tests-remove-04r5swap.broken.patch new file mode 100644 index 0000000..7af555c --- /dev/null +++ b/SOURCES/0086-mdadm-tests-remove-04r5swap.broken.patch @@ -0,0 +1,30 @@ +From b9b8eaef49e075ce68846abb7cf0ca47c1ba9f2f Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:48 +0800 +Subject: [PATCH 086/157] mdadm/tests: remove 04r5swap.broken + +04r5swap can run successfully with kernel 6.9.0-rc4 + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/04r5swap.broken | 7 ------- + 1 file changed, 7 deletions(-) + delete mode 100644 tests/04r5swap.broken + +diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken +deleted file mode 100644 +index e38987db..00000000 +--- a/tests/04r5swap.broken ++++ /dev/null +@@ -1,7 +0,0 @@ +-always fails +- +-Fails with errors: +- +- mdadm: /dev/loop0 has no superblock - assembly aborted +- +- ERROR: no recovery happening +-- +2.41.0 + diff --git a/SOURCES/0087-tests-04update-metadata-skip-linear.patch b/SOURCES/0087-tests-04update-metadata-skip-linear.patch new file mode 100644 index 0000000..d6aee4a --- /dev/null +++ b/SOURCES/0087-tests-04update-metadata-skip-linear.patch @@ -0,0 +1,116 @@ +From 9808f110c5aea5454e9f56b2b660612a57adb347 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:49 +0800 +Subject: [PATCH 087/157] tests/04update-metadata skip linear + +Add one check that if kernel doesn't support linear/multipath, it can +skip linear/multipath testing. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 3 +++ + tests/04update-metadata | 35 ++++++++++++++++++++--------------- + tests/func.sh | 2 ++ + 3 files changed, 25 insertions(+), 15 deletions(-) + +diff --git a/test b/test +index 1fce6be2..f09994e7 100755 +--- a/test ++++ b/test +@@ -17,6 +17,9 @@ devlist= + # device node will be /dev/md127 (127 is choosed by mdadm autumatically) + is_foreign="no" + ++skipping_linear="no" ++skipping_multipath="no" ++ + savelogs=0 + exitonerror=1 + ctrl_c_error=0 +diff --git a/tests/04update-metadata b/tests/04update-metadata +index 2b72a303..c748770c 100644 +--- a/tests/04update-metadata ++++ b/tests/04update-metadata +@@ -8,24 +8,29 @@ set -xe + + dlist="$dev0 $dev1 $dev2 $dev3" + +-for ls in linear/4 raid1/1 raid5/3 raid6/2 ++if [ $skipping_linear == "yes" ]; then ++ level_list="raid1/1 raid5/3 raid6/2" ++else ++ level_list="linear/4 raid1/1 raid5/3 raid6/2" ++fi ++for ls in $level_list + do +- s=${ls#*/} l=${ls%/*} +- if [[ $l == 'raid1' ]]; then +- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist +- else +- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist +- fi +- testdev $md0 $s 19904 64 +- mdadm -S $md0 +- mdadm -A $md0 --update=metadata $dlist +- testdev $md0 $s 19904 64 check +- mdadm -S $md0 ++ s=${ls#*/} l=${ls%/*} ++ if [[ $l == 'raid1' ]]; then ++ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist ++ else ++ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist ++ fi ++ testdev $md0 $s 19904 64 ++ mdadm -S $md0 ++ mdadm -A $md0 --update=metadata $dlist ++ testdev $md0 $s 19904 64 check ++ mdadm -S $md0 + done + + if mdadm -A $md0 --update=metadata $dlist + then echo >&2 should fail with v1.0 metadata +- exit 1 ++ exit 1 + fi + + mdadm -CR -e 0.90 $md0 --level=6 -n4 -c32 $dlist +@@ -33,7 +38,7 @@ mdadm -S $md0 + + if mdadm -A $md0 --update=metadata $dlist + then echo >&2 should fail during resync +- exit 1 ++ exit 1 + fi + mdadm -A $md0 $dlist + mdadm --wait $md0 || true +@@ -48,5 +53,5 @@ mdadm -S $md0 + + if mdadm -A $md0 --update=metadata $dlist + then echo >&2 should fail when bitmap present +- exit 1 ++ exit 1 + fi +diff --git a/tests/func.sh b/tests/func.sh +index cfe83e55..db55542d 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -125,6 +125,7 @@ check_env() { + MULTIPATH="yes" + if [ "$MULTIPATH" != "yes" ]; then + echo "test: skipping tests for multipath, which is removed in upstream 6.8+ kernels" ++ skipping_multipath="yes" + fi + + # Check whether to run linear tests +@@ -133,6 +134,7 @@ check_env() { + LINEAR="yes" + if [ "$LINEAR" != "yes" ]; then + echo "test: skipping tests for linear, which is removed in upstream 6.8+ kernels" ++ skipping_linear="yes" + fi + } + +-- +2.41.0 + diff --git a/SOURCES/0088-mdadm-tests-05r5-internalbitmap.patch b/SOURCES/0088-mdadm-tests-05r5-internalbitmap.patch new file mode 100644 index 0000000..a01bb9a --- /dev/null +++ b/SOURCES/0088-mdadm-tests-05r5-internalbitmap.patch @@ -0,0 +1,68 @@ +From 7664a3851476cfcda931d35f495d03f51707bac9 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:50 +0800 +Subject: [PATCH 088/157] mdadm/tests: 05r5-internalbitmap + +It's not right to compare bitmap bits with a number after io comes. +Because maybe those bits are already flused. Remove the related +tests. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/05r5-internalbitmap | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/tests/05r5-internalbitmap b/tests/05r5-internalbitmap +index 13dc5921..1a64482f 100644 +--- a/tests/05r5-internalbitmap ++++ b/tests/05r5-internalbitmap +@@ -9,21 +9,20 @@ mdadm -S $md0 + + mdadm --assemble $md0 $dev1 $dev2 $dev3 + testdev $md0 2 $mdsize1 512 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" ++if [ $dirty1 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty1" + exit 1 + fi + mdadm $md0 -f $dev1 + testdev $md0 2 $mdsize1 512 + sleep 4 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++if [ $dirty2 -lt 400 ] + then +- echo >&2 "ERROR dirty count $dirty3 is too small" ++ echo >&2 "ERROR dirty count $dirty2 is too small" + exit 2 + fi + +@@ -33,14 +32,12 @@ mdadm --assemble -R $md0 $dev2 $dev3 + mdadm --zero $dev1 # force --add, not --re-add + mdadm $md0 --add $dev1 + check recovery +- +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + check wait + sleep 4 +-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" ++if [ $dirty3 -ne 0 ] ++then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty3" + exit 1 + fi + +-- +2.41.0 + diff --git a/SOURCES/0089-mdadm-tests-06name-enhance.patch b/SOURCES/0089-mdadm-tests-06name-enhance.patch new file mode 100644 index 0000000..8b3b6d2 --- /dev/null +++ b/SOURCES/0089-mdadm-tests-06name-enhance.patch @@ -0,0 +1,38 @@ +From 6e7d850a57d40e18d525d0739a4f4226f6057d91 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:52 +0800 +Subject: [PATCH 089/157] mdadm/tests: 06name enhance + +It needs to check hostname in metadata name if one array is +local. Add the check in this case. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/06name | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tests/06name b/tests/06name +index 86eaab69..c3213f6c 100644 +--- a/tests/06name ++++ b/tests/06name +@@ -3,8 +3,14 @@ set -x + # create an array with a name + + mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1 +-mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1 +-mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1 ++ ++if [ $is_foreign == "no" ]; then ++ mdadm -E $dev0 | grep "Name : $(hostname):Fred" > /dev/null || exit 1 ++ mdadm -D $md0 | grep "Name : $(hostname):Fred" > /dev/null || exit 1 ++else ++ mdadm -E $dev0 | grep "Name : Fred" > /dev/null || exit 1 ++ mdadm -D $md0 | grep "Name : Fred" > /dev/null || exit 1 ++fi + mdadm -S $md0 + + mdadm -A $md0 --name="Fred" $devlist +-- +2.41.0 + diff --git a/SOURCES/0090-mdadm-tests-07autoassemble.patch b/SOURCES/0090-mdadm-tests-07autoassemble.patch new file mode 100644 index 0000000..f36f95d --- /dev/null +++ b/SOURCES/0090-mdadm-tests-07autoassemble.patch @@ -0,0 +1,108 @@ +From 63e99a49cc02cbe4d1777b477719078897fc8308 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:53 +0800 +Subject: [PATCH 090/157] mdadm/tests: 07autoassemble + +This test is used to test stacked array auto assemble. + +There are two different cases depends on if array is foreign or not. +If the array is foreign, the stacked array (md0 is on md1 and md2) +can't be assembled with name md0. Because udev rule will run when md1 +and md2 are assembled and mdadm -I doesn't specify homehost. So it +will treat stacked array (md0) as foreign array and choose md127 as +the device node name (/dev/md127) + +Add the case that stacked array is local. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 2 ++ + tests/07autoassemble | 37 +++++++++++++++++++++++++++++++++++-- + tests/07autoassemble.broken | 8 -------- + 3 files changed, 37 insertions(+), 10 deletions(-) + delete mode 100644 tests/07autoassemble.broken + +diff --git a/test b/test +index f09994e7..4a88de58 100755 +--- a/test ++++ b/test +@@ -39,6 +39,8 @@ md2=/dev/md2 + # if user doesn't specify minor number, mdadm chooses minor number + # automatically from 127. + md127=/dev/md127 ++md126=/dev/md126 ++md125=/dev/md125 + mdp0=/dev/md_d0 + mdp1=/dev/md_d1 + +diff --git a/tests/07autoassemble b/tests/07autoassemble +index e689be7c..9dc78149 100644 +--- a/tests/07autoassemble ++++ b/tests/07autoassemble +@@ -10,7 +10,14 @@ mdadm -Ss + mdadm -As -c /dev/null --homehost=testing -vvv + testdev $md1 1 $mdsize1a 64 + testdev $md2 1 $mdsize1a 64 +-testdev $md0 2 $mdsize11a 512 ++# md1 and md2 will be incremental assemble by udev rule. And ++# the testing machines' hostname is not testing. The md0 will ++# be considered as a foreign array. It can use 0 as metadata ++# name. md127 will be used ++testdev $md127 2 $mdsize11a 512 ++mdadm --stop $md127 ++mdadm --zero-superblock $md1 ++mdadm --zero-superblock $md2 + mdadm -Ss + + mdadm --zero-superblock $dev0 $dev1 $dev2 $dev3 +@@ -20,5 +27,31 @@ mdadm -CR $md0 -l0 -n2 $md1 $dev2 --homehost=testing + mdadm -Ss + mdadm -As -c /dev/null --homehost=testing -vvv + testdev $md1 1 $mdsize1a 64 +-testdev $md0 1 $[mdsize1a+mdsize11a] 512 ++testdev $md127 1 $[mdsize1a+mdsize11a] 512 ++mdadm --stop $md127 ++mdadm --zero-superblock $md1 ++mdadm -Ss ++ ++# Don't specify homehost when creating raid and use the test ++# machine's homehost. For super1.2, if homehost name's length ++# is > 32, it doesn't use homehost name in metadata name and ++# the array will be treated as foreign array ++mdadm --zero-superblock $dev0 $dev1 $dev2 $dev3 ++mdadm -CR $md1 -l1 -n2 $dev0 $dev1 ++mdadm -CR $md2 -l1 -n2 $dev2 $dev3 ++mdadm -CR $md0 -l0 -n2 $md1 $md2 ++mdadm -Ss ++mdadm -As -c /dev/null ++if [ $is_foreign == "yes" ]; then ++ # md127 is md1 ++ testdev $md127 1 $mdsize1a 64 ++ # md126 is md0, udev rule incremental assemble it ++ testdev $md126 2 $mdsize11a 512 ++ # md125 is md2 ++ testdev $md125 1 $mdsize1a 64 ++else ++ testdev $md1 1 $mdsize1a 64 ++ testdev $md2 1 $mdsize1a 64 ++ testdev $md0 2 $mdsize11a 512 ++fi + mdadm -Ss +diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken +deleted file mode 100644 +index 8be09407..00000000 +--- a/tests/07autoassemble.broken ++++ /dev/null +@@ -1,8 +0,0 @@ +-always fails +- +-Prints lots of messages, but the array doesn't assemble. Error +-possibly related to: +- +- mdadm: /dev/md/1 is busy - skipping +- mdadm: no recogniseable superblock on /dev/md/testing:0 +- mdadm: /dev/md/2 is busy - skipping +-- +2.41.0 + diff --git a/SOURCES/0091-mdadm-tests-07autodetect.broken-can-be-removed.patch b/SOURCES/0091-mdadm-tests-07autodetect.broken-can-be-removed.patch new file mode 100644 index 0000000..89df7b2 --- /dev/null +++ b/SOURCES/0091-mdadm-tests-07autodetect.broken-can-be-removed.patch @@ -0,0 +1,28 @@ +From 1d0c61f4baa49bc218687017ccb2e3a664351390 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:54 +0800 +Subject: [PATCH 091/157] mdadm/tests: 07autodetect.broken can be removed + +07autodetect can run successfully without error in kernel 6.9.0-rc5. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/07autodetect.broken | 5 ----- + 1 file changed, 5 deletions(-) + delete mode 100644 tests/07autodetect.broken + +diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken +deleted file mode 100644 +index 294954a1..00000000 +--- a/tests/07autodetect.broken ++++ /dev/null +@@ -1,5 +0,0 @@ +-always fails +- +-Fails with error: +- +- ERROR: no resync happening +-- +2.41.0 + diff --git a/SOURCES/0092-mdadm-tests-07changelevelintr.patch b/SOURCES/0092-mdadm-tests-07changelevelintr.patch new file mode 100644 index 0000000..a1f0f24 --- /dev/null +++ b/SOURCES/0092-mdadm-tests-07changelevelintr.patch @@ -0,0 +1,73 @@ +From cd3b2350bef136b20c81190371fb0b60d62a0365 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:55 +0800 +Subject: [PATCH 092/157] mdadm/tests: 07changelevelintr + +It needs to specify a 2 powered array size when updating array size. +If not, it can't change chunksize. + +And sometimes it reports error reshape doesn't happen. In fact the +reshape has finished. It doesn't need to wait before checking +reshape action. Because check function waits itself. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/07changelevelintr | 9 +++++---- + tests/07changelevelintr.broken | 9 --------- + 2 files changed, 5 insertions(+), 13 deletions(-) + delete mode 100644 tests/07changelevelintr.broken + +diff --git a/tests/07changelevelintr b/tests/07changelevelintr +index 18c63092..d921f2b2 100644 +--- a/tests/07changelevelintr ++++ b/tests/07changelevelintr +@@ -27,11 +27,9 @@ checkgeo() { + } + + restart() { +- sleep 0.5 + check reshape + mdadm -S $md0 + mdadm -A $md0 $devs --backup-file=$bu +- sleep 0.5 + check reshape + } + +@@ -49,13 +47,16 @@ mdadm -G $md0 --layout rs --backup-file=$bu + restart + checkgeo md0 raid5 5 $[128*1024] 3 + +-mdadm -G $md0 --array-size 58368 ++# It needs to shrink array size first. Choose a value that ++# is power of 2 for array size. If not, it can't change ++# chunk size. ++mdadm -G $md0 --array-size 51200 + mdadm -G $md0 --raid-disks 4 -c 64 --backup-file=$bu + restart + checkgeo md0 raid5 4 $[64*1024] 3 + + devs="$dev0 $dev1 $dev2 $dev3" +-mdadm -G $md0 --array-size 19456 ++mdadm -G $md0 --array-size 18432 + mdadm -G $md0 -n 2 -c 256 --backup-file=$bu + restart + checkgeo md0 raid5 2 $[256*1024] 3 +diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken +deleted file mode 100644 +index 284b4906..00000000 +--- a/tests/07changelevelintr.broken ++++ /dev/null +@@ -1,9 +0,0 @@ +-always fails +- +-Fails with errors: +- +- mdadm: this change will reduce the size of the array. +- use --grow --array-size first to truncate array. +- e.g. mdadm --grow /dev/md0 --array-size 56832 +- +- ERROR: no reshape happening +-- +2.41.0 + diff --git a/SOURCES/0093-mdadm-tests-disable-selinux.patch b/SOURCES/0093-mdadm-tests-disable-selinux.patch new file mode 100644 index 0000000..e00b325 --- /dev/null +++ b/SOURCES/0093-mdadm-tests-disable-selinux.patch @@ -0,0 +1,68 @@ +From b914aa25ee1fe3e0bd97f58bdf2bfdd185992a79 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 22 May 2024 16:50:56 +0800 +Subject: [PATCH 093/157] mdadm/tests: disable selinux + +Sometimes systemd service fails because selinux. Disable selinux +during testing now. We can enable it in future when having a better +method. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + test | 3 +++ + tests/func.sh | 10 ++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/test b/test +index 4a88de58..47f53ad7 100755 +--- a/test ++++ b/test +@@ -16,6 +16,8 @@ devlist= + # For example, /dev/md0 is created, stops it, then assemble it, the + # device node will be /dev/md127 (127 is choosed by mdadm autumatically) + is_foreign="no" ++#disable selinux ++sys_selinux="Permissive" + + skipping_linear="no" + skipping_multipath="no" +@@ -351,6 +353,7 @@ main() { + fi + done + ++ restore_selinux + exit 0 + } + +diff --git a/tests/func.sh b/tests/func.sh +index db55542d..b2e4d122 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -167,6 +167,15 @@ is_raid_foreign() { + fi + } + ++record_selinux() { ++ sys_selinux=`getenforce` ++ setenforce Permissive ++} ++ ++restore_selinux() { ++ setenforce $sys_selinux ++} ++ + do_setup() { + trap cleanup 0 1 3 15 + trap ctrl_c 2 +@@ -247,6 +256,7 @@ do_setup() { + echo 0 > /sys/module/md_mod/parameters/start_ro + record_system_speed_limit + is_raid_foreign ++ record_selinux + } + + # check various things +-- +2.41.0 + diff --git a/SOURCES/0094-mdadm-platform-intel-buffer-overflow-detected.patch b/SOURCES/0094-mdadm-platform-intel-buffer-overflow-detected.patch new file mode 100644 index 0000000..7cf6d1d --- /dev/null +++ b/SOURCES/0094-mdadm-platform-intel-buffer-overflow-detected.patch @@ -0,0 +1,44 @@ +From 827e1870f320545796d907f50af594e901399417 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 28 May 2024 16:44:39 +0800 +Subject: [PATCH 094/157] mdadm/platform-intel: buffer overflow detected + +mdadm -CR /dev/md0 -l1 -n2 /dev/nvme0n1 /dev/nvme2n1 +*** buffer overflow detected ***: terminated +Aborted (core dumped) + +It doesn't happen 100% and it depends on the building environment. +It can be fixed by replacing sprintf with snprintf. + +Fixes: d835518b6b53 ('imsm: nvme multipath support') +Reported-by: Guang Wu +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 15a9fa5a..d6a53533 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -907,14 +907,14 @@ char *get_nvme_multipath_dev_hw_path(const char *dev_path) + return NULL; + + for (ent = readdir(dir); ent; ent = readdir(dir)) { +- char buf[strlen(dev_path) + strlen(ent->d_name) + 1]; ++ char buf[PATH_MAX]; + + /* Check if dir is a controller, ignore namespaces*/ + if (!(strncmp(ent->d_name, "nvme", 4) == 0) || + (strrchr(ent->d_name, 'n') != &ent->d_name[0])) + continue; + +- sprintf(buf, "%s/%s", dev_path, ent->d_name); ++ snprintf(buf, PATH_MAX, "%s/%s", dev_path, ent->d_name); + rp = realpath(buf, NULL); + break; + } +-- +2.41.0 + diff --git a/SOURCES/0095-mdadm-tests-bitmap-cases-enhance.patch b/SOURCES/0095-mdadm-tests-bitmap-cases-enhance.patch new file mode 100644 index 0000000..56b36b0 --- /dev/null +++ b/SOURCES/0095-mdadm-tests-bitmap-cases-enhance.patch @@ -0,0 +1,279 @@ +From c006602b313e2f6062b51aad37d93dccd29649de Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 28 May 2024 21:51:47 +0800 +Subject: [PATCH 095/157] mdadm/tests: bitmap cases enhance + +It fails because bitmap dirty number is smaller than 400 sometimes. It's not +good to compare bitmap dirty bits with a number. It depends on the test +machine, it can flush soon before checking the number. So remove related codes. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/05r1-grow-internal | 11 ++++------- + tests/05r1-grow-internal-1 | 12 ++++-------- + tests/05r1-internalbitmap | 22 ++++++++++------------ + tests/05r1-internalbitmap-v1a | 22 ++++++++++------------ + tests/05r1-internalbitmap-v1b | 23 ++++++++++------------- + tests/05r1-internalbitmap-v1c | 22 ++++++++++------------ + 6 files changed, 48 insertions(+), 64 deletions(-) + +diff --git a/tests/05r1-grow-internal b/tests/05r1-grow-internal +index 24b3aece..f7fff989 100644 +--- a/tests/05r1-grow-internal ++++ b/tests/05r1-grow-internal +@@ -8,18 +8,15 @@ testdev $md0 1 $mdsize1a 64 + + #mdadm -E $dev1 + mdadm --grow $md0 --bitmap=internal --bitmap-chunk=4 --delay=1 || { mdadm -X $dev2 ; exit 1; } +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + + testdev $md0 1 $mdsize1a 64 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-#echo $dirty1 $dirty2 $dirty3 $dirty4 +-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] +-then ++if [ $dirty1 -ne 0 -o $dirty2 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: dirty1 $dirty1, dirty2 $dirty2" + echo bad dirty counts + exit 1 + fi +diff --git a/tests/05r1-grow-internal-1 b/tests/05r1-grow-internal-1 +index 2f0d8237..f0f8349f 100644 +--- a/tests/05r1-grow-internal-1 ++++ b/tests/05r1-grow-internal-1 +@@ -8,19 +8,15 @@ testdev $md0 1 $mdsize1b 64 + + #mdadm -E $dev1 + mdadm --grow $md0 --bitmap=internal --bitmap-chunk=4 --delay=1 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + + testdev $md0 1 $mdsize1b 64 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-#echo $dirty1 $dirty2 $dirty3 $dirty4 +-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] +-then +- echo bad dirty counts ++if [ $dirty1 -ne 0 -o $dirty2 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: dirty1 $dirty1, dirty2 $dirty2" + exit 1 + fi + +diff --git a/tests/05r1-internalbitmap b/tests/05r1-internalbitmap +index dd7232a7..f1a2843e 100644 +--- a/tests/05r1-internalbitmap ++++ b/tests/05r1-internalbitmap +@@ -9,21 +9,20 @@ mdadm -S $md0 + + mdadm --assemble $md0 $dev1 $dev2 + testdev $md0 1 $mdsize0 64 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" ++if [ $dirty1 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty1" + exit 1 + fi + mdadm $md0 -f $dev1 + testdev $md0 1 $mdsize0 64 + sleep 4 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" ++total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++if [ $dirty2 -ne $total ] ++then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2" + exit 2 + fi + +@@ -34,13 +33,12 @@ mdadm --zero-superblock $dev1 + mdadm $md0 --add $dev1 + check recovery + +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + check wait + sleep 4 +-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" ++if [ $dirty3 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty3" + exit 1 + fi + +diff --git a/tests/05r1-internalbitmap-v1a b/tests/05r1-internalbitmap-v1a +index 3ddc082f..cf3f3972 100644 +--- a/tests/05r1-internalbitmap-v1a ++++ b/tests/05r1-internalbitmap-v1a +@@ -10,21 +10,20 @@ mdadm -S $md0 + + mdadm --assemble $md0 $dev1 $dev2 + testdev $md0 1 $mdsize1b 64 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" ++if [ $dirty1 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty1" + exit 1 + fi + mdadm $md0 -f $dev1 + testdev $md0 1 $mdsize1b 64 + sleep 4 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" ++total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++if [ $dirty2 -ne $total ] ++then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2" + exit 2 + fi + +@@ -35,13 +34,12 @@ mdadm --assemble -R $md0 $dev2 + mdadm $md0 --add $dev1 + check recovery + +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + check wait + sleep 4 +-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" ++if [ $dirty3 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty3" + exit 1 + fi + +diff --git a/tests/05r1-internalbitmap-v1b b/tests/05r1-internalbitmap-v1b +index 40f7abea..4952887e 100644 +--- a/tests/05r1-internalbitmap-v1b ++++ b/tests/05r1-internalbitmap-v1b +@@ -11,21 +11,20 @@ mdadm -S $md0 + mdadm --assemble $md0 $dev1 $dev2 + check bitmap + testdev $md0 1 $mdsize11 64 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" ++if [ $dirty1 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty1" + exit 1 + fi + mdadm $md0 -f $dev1 + testdev $md0 1 $mdsize11 64 + sleep 4 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" ++total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++if [ $dirty2 -ne $total ] ++then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2" + exit 2 + fi + +@@ -35,14 +34,12 @@ mdadm --zero-superblock $dev1 + mdadm --assemble -R $md0 $dev2 + mdadm $md0 --add $dev1 + check recovery +- +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + check wait + sleep 4 +-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" ++if [ $dirty3 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty3" + exit 1 + fi + +diff --git a/tests/05r1-internalbitmap-v1c b/tests/05r1-internalbitmap-v1c +index 2eaea59b..e1e4472f 100644 +--- a/tests/05r1-internalbitmap-v1c ++++ b/tests/05r1-internalbitmap-v1c +@@ -10,21 +10,20 @@ mdadm -S $md0 + + mdadm --assemble $md0 $dev1 $dev2 + testdev $md0 1 $mdsize12 64 +-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + sleep 4 +-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" ++if [ $dirty1 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty1" + exit 1 + fi + mdadm $md0 -f $dev1 + testdev $md0 1 $mdsize12 64 + sleep 4 +-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +-if [ $dirty3 -lt 400 ] +-then +- echo >&2 "ERROR dirty count $dirty3 is too small" ++total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'` ++dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++if [ $dirty2 -ne $total ] ++then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2" + exit 2 + fi + +@@ -35,13 +34,12 @@ mdadm --assemble -R $md0 $dev2 + mdadm $md0 --add $dev1 + check recovery + +-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + check wait + sleep 4 +-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` ++dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" ++if [ $dirty3 -ne 0 ] ++then echo >&2 "ERROR bad 'dirty' counts: $dirty3" + exit 1 + fi + +-- +2.41.0 + diff --git a/SOURCES/0096-mdadm-tests-04update-uuid.patch b/SOURCES/0096-mdadm-tests-04update-uuid.patch new file mode 100644 index 0000000..d3bf9ed --- /dev/null +++ b/SOURCES/0096-mdadm-tests-04update-uuid.patch @@ -0,0 +1,39 @@ +From 19cde79fda386329f69ead15ca6ae26527fab707 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 28 May 2024 21:51:48 +0800 +Subject: [PATCH 096/157] mdadm/tests: 04update-uuid + +Patch 50b100768a11('mdadm: deprecate bitmap custom file') needs to confirm when +creating raid device with bitmap file. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/04update-uuid | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/04update-uuid b/tests/04update-uuid +index a4409e78..25314ab5 100644 +--- a/tests/04update-uuid ++++ b/tests/04update-uuid +@@ -25,7 +25,7 @@ mdadm -S /dev/md0 + + # now if we have a bitmap, that needs updating too. + rm -f $targetdir/bitmap +-mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2 ++yes | mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2 + mdadm -S /dev/md0 + mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2 + no_errors +@@ -41,7 +41,7 @@ mdadm -S /dev/md0 + + # and bitmap for version1 + rm -f $targetdir/bitmap +-mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2 ++yes | mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2 + mdadm -S /dev/md0 + mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2 + no_errors +-- +2.41.0 + diff --git a/SOURCES/0097-mdadm-tests-05r1-re-add-nosuper.patch b/SOURCES/0097-mdadm-tests-05r1-re-add-nosuper.patch new file mode 100644 index 0000000..55ffbd8 --- /dev/null +++ b/SOURCES/0097-mdadm-tests-05r1-re-add-nosuper.patch @@ -0,0 +1,30 @@ +From c36477fac2e485fd294e5cb48d411b548c654f30 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 28 May 2024 21:51:49 +0800 +Subject: [PATCH 097/157] mdadm/tests: 05r1-re-add-nosuper + +Patch 50b100768a11('mdadm: deprecate bitmap custom file') needs to confirm when +creating raid device with bitmap file. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/05r1-re-add-nosuper | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/05r1-re-add-nosuper b/tests/05r1-re-add-nosuper +index 058d602d..7d41fd7b 100644 +--- a/tests/05r1-re-add-nosuper ++++ b/tests/05r1-re-add-nosuper +@@ -6,7 +6,7 @@ + # + bmf=$targetdir/bitmap2 + rm -f $bmf +-mdadm -B $md0 -l1 -n2 -b$bmf -d1 $dev1 $dev2 ++yes | mdadm -B $md0 -l1 -n2 -b$bmf -d1 $dev1 $dev2 + check resync + check wait + testdev $md0 1 $size 1 +-- +2.41.0 + diff --git a/SOURCES/0098-mdadm-tests-remove-strace-test.patch b/SOURCES/0098-mdadm-tests-remove-strace-test.patch new file mode 100644 index 0000000..964b06d --- /dev/null +++ b/SOURCES/0098-mdadm-tests-remove-strace-test.patch @@ -0,0 +1,44 @@ +From c5a4fe7874f94b3f172027043f9a94b037f4d4dd Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Tue, 28 May 2024 21:51:50 +0800 +Subject: [PATCH 098/157] mdadm/tests: remove strace test + +Some tests will fail if the test env doesn't have strace +commands. So remove the dependency. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/07revert-grow | 2 +- + tests/07revert-inplace | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/07revert-grow b/tests/07revert-grow +index c8c4e855..333483dc 100644 +--- a/tests/07revert-grow ++++ b/tests/07revert-grow +@@ -43,7 +43,7 @@ testdev $md0 2 $mdsize1 512 + mdadm -G $md0 -n 5 + sleep 3 + mdadm -S $md0 +-strace -o /tmp/str ./mdadm -A $md0 --update=revert-reshape $devlist4 ++mdadm -A $md0 --update=revert-reshape $devlist4 + check wait + check raid10 + testdev $md0 2 $mdsize1 512 +diff --git a/tests/07revert-inplace b/tests/07revert-inplace +index a73eb977..776324ac 100644 +--- a/tests/07revert-inplace ++++ b/tests/07revert-inplace +@@ -37,7 +37,7 @@ testdev $md0 3 $mdsize1 64 + mdadm -G $md0 -c 32 + sleep 2 + mdadm -S $md0 +-strace -o /tmp/str ./mdadm -A $md0 --update=revert-reshape $devlist5 ++mdadm -A $md0 --update=revert-reshape $devlist5 + check wait + check raid10 + testdev $md0 3 $mdsize1 64 +-- +2.41.0 + diff --git a/SOURCES/0099-mdadm.h-provide-basename-if-GLIBC-is-not-avialable.patch b/SOURCES/0099-mdadm.h-provide-basename-if-GLIBC-is-not-avialable.patch new file mode 100644 index 0000000..0a458da --- /dev/null +++ b/SOURCES/0099-mdadm.h-provide-basename-if-GLIBC-is-not-avialable.patch @@ -0,0 +1,37 @@ +From 9dbd11e091f84eb0bf9d717283774816c4c4453d Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 May 2024 16:26:33 +0200 +Subject: [PATCH 099/157] mdadm.h: provide basename if GLIBC is not avialable + +If GNU basename is not avilable, define it. It is safer to use that +rather than include libgen.h with XPG basename() definition. + +Fixes:#12 + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/mdadm.h b/mdadm.h +index 40818941..e9f764a2 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -223,6 +223,14 @@ struct dlm_lksb { + struct __una_u16 { __u16 x; } __attribute__ ((packed)); + struct __una_u32 { __u32 x; } __attribute__ ((packed)); + ++/* ++ * Ensure GNU basename behavior on GLIBC less systems. ++ */ ++#ifndef __GLIBC__ ++#define basename(path) \ ++ (strrchr((path), '/') ? strrchr((path),'/') + 1 : (path)) ++#endif ++ + static inline __u16 __get_unaligned16(const void *p) + { + const struct __una_u16 *ptr = (const struct __una_u16 *)p; +-- +2.41.0 + diff --git a/SOURCES/0100-imsm-fix-first-volume-autolayout-with-IMSM_NO_PLATFO.patch b/SOURCES/0100-imsm-fix-first-volume-autolayout-with-IMSM_NO_PLATFO.patch new file mode 100644 index 0000000..1ab7f08 --- /dev/null +++ b/SOURCES/0100-imsm-fix-first-volume-autolayout-with-IMSM_NO_PLATFO.patch @@ -0,0 +1,79 @@ +From 46f19270265fe54cda1c728cb156b755273b4ab6 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 23 May 2024 12:06:36 +0200 +Subject: [PATCH 100/157] imsm: fix first volume autolayout with + IMSM_NO_PLATFORM + +Autolayout_imsm() is not executed if IMSM_NO_PLATFORM=1 is set. +This causes that first volume cannot be created. Disk for new volume are +never configured. + +Fix it by making autolayout_imsm() independent from super->orom because +NULL there means that IMSM_NO_PLATFORM=1 is set. There are not platform +restrictions to create volume, we just analyze drives. It is safe. + +Fixes: 6d4d9ab295de ("imsm: use same slot across container") +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 0287a618..29652196 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7706,9 +7706,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + char *dev, unsigned long long *freesize, + int consistency_policy, int verbose) + { +- int fd, cfd; ++ struct intel_super *super = st->sb; + struct mdinfo *sra; + int is_member = 0; ++ imsm_status_t rv; ++ int fd, cfd; + + /* load capability + * if given unused devices create a container +@@ -7733,11 +7735,10 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + } + + if (!dev) { +- struct intel_super *super = st->sb; +- + /* + * Autolayout mode, st->sb must be set. + */ ++ + if (!super) { + pr_vrb("superblock must be set for autolayout, aborting\n"); + return 0; +@@ -7749,20 +7750,19 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + return 0; + + if (super->orom && freesize) { +- imsm_status_t rv; +- int count = count_volumes(super->hba, super->orom->dpa, +- verbose); ++ int count = count_volumes(super->hba, super->orom->dpa, verbose); ++ + if (super->orom->vphba <= count) { + pr_vrb("platform does not support more than %d raid volumes.\n", + super->orom->vphba); + return 0; + } ++ } + +- rv = autolayout_imsm(super, raiddisks, size, *chunk, +- freesize); ++ rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize); + if (rv != IMSM_STATUS_OK) + return 0; +- } ++ + return 1; + } + if (st->sb) { +-- +2.41.0 + diff --git a/SOURCES/0101-imsm-make-freesize-required-to-volume-autolayout.patch b/SOURCES/0101-imsm-make-freesize-required-to-volume-autolayout.patch new file mode 100644 index 0000000..ddd148e --- /dev/null +++ b/SOURCES/0101-imsm-make-freesize-required-to-volume-autolayout.patch @@ -0,0 +1,50 @@ +From 4f3efc34644d06f55fc650e4aa6b5a6ec22cea5f Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 11 Jun 2024 07:58:49 +0200 +Subject: [PATCH 101/157] imsm: make freesize required to volume autolayout + +Autolayout_imsm() shall be executed when IMSM_NO_PLATFORM=1 is set. +It was fixed by listed commit, checking super->orom was removed, but +also checking freesize. Freesize is not set for operations on RAID +volume with no size update, that's why it is not required to have +this value and always run autolayout_imsm(). +Fix it by making autolayout_imsm() dependent on freesize. + +Fixes: 46f192 ("imsm: fix first volume autolayout with IMSM_NO_PLATFORM") + +Signed-off-by: Kinga Stefaniuk +--- + super-intel.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 29652196..ef3f5da1 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7749,7 +7749,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + verbose)) + return 0; + +- if (super->orom && freesize) { ++ if (super->orom) { + int count = count_volumes(super->hba, super->orom->dpa, verbose); + + if (super->orom->vphba <= count) { +@@ -7759,9 +7759,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + } + } + +- rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize); +- if (rv != IMSM_STATUS_OK) +- return 0; ++ if (freesize) { ++ rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize); ++ if (rv != IMSM_STATUS_OK) ++ return 0; ++ } + + return 1; + } +-- +2.41.0 + diff --git a/SOURCES/0102-mdadm-Fix-hang-race-condition-in-wait_for_zero_forks.patch b/SOURCES/0102-mdadm-Fix-hang-race-condition-in-wait_for_zero_forks.patch new file mode 100644 index 0000000..3b8048a --- /dev/null +++ b/SOURCES/0102-mdadm-Fix-hang-race-condition-in-wait_for_zero_forks.patch @@ -0,0 +1,86 @@ +From 1a5c0e60308651a20d25ff52511230a20d830330 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Tue, 4 Jun 2024 10:38:36 -0600 +Subject: [PATCH 102/157] mdadm: Fix hang race condition in + wait_for_zero_forks() + +Running a create operation with --write-zeros can randomly hang +forever waiting for child processes. This happens roughly on in +ten runs with when running with small (20MB) loop devices. + +The bug is caused by the fact that signals can be coallesced into +one if they are not read by signalfd quick enough. So if two children +finish at exactly the same time, only one SIGCHLD will be received +by the parent. + +To fix this, wait on all processes with WNOHANG every time a SIGCHLD +is received and exit when all processes have been waited on. + +Reported-by: Xiao Ni +Signed-off-by: Logan Gunthorpe +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +diff --git a/Create.c b/Create.c +index d033eb68..4f992a22 100644 +--- a/Create.c ++++ b/Create.c +@@ -178,6 +178,7 @@ static int wait_for_zero_forks(int *zero_pids, int count) + bool interrupted = false; + sigset_t sigset; + ssize_t s; ++ pid_t pid; + + for (i = 0; i < count; i++) + if (zero_pids[i]) +@@ -196,7 +197,7 @@ static int wait_for_zero_forks(int *zero_pids, int count) + return 1; + } + +- while (1) { ++ while (wait_count) { + s = read(sfd, &fdsi, sizeof(fdsi)); + if (s != sizeof(fdsi)) { + pr_err("Invalid signalfd read: %s\n", strerror(errno)); +@@ -209,23 +210,24 @@ static int wait_for_zero_forks(int *zero_pids, int count) + pr_info("Interrupting zeroing processes, please wait...\n"); + interrupted = true; + } else if (fdsi.ssi_signo == SIGCHLD) { +- if (!--wait_count) +- break; ++ for (i = 0; i < count; i++) { ++ if (!zero_pids[i]) ++ continue; ++ ++ pid = waitpid(zero_pids[i], &wstatus, WNOHANG); ++ if (pid <= 0) ++ continue; ++ ++ zero_pids[i] = 0; ++ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) ++ ret = 1; ++ wait_count--; ++ } + } + } + + close(sfd); + +- for (i = 0; i < count; i++) { +- if (!zero_pids[i]) +- continue; +- +- waitpid(zero_pids[i], &wstatus, 0); +- zero_pids[i] = 0; +- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) +- ret = 1; +- } +- + if (interrupted) { + pr_err("zeroing interrupted!\n"); + return 1; +-- +2.41.0 + diff --git a/SOURCES/0103-mdadm-Block-SIGCHLD-processes-before-starting-childr.patch b/SOURCES/0103-mdadm-Block-SIGCHLD-processes-before-starting-childr.patch new file mode 100644 index 0000000..d2fe3f0 --- /dev/null +++ b/SOURCES/0103-mdadm-Block-SIGCHLD-processes-before-starting-childr.patch @@ -0,0 +1,37 @@ +From 539ad6e6f9a067646a018d77582af0babf8e125e Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Tue, 4 Jun 2024 10:38:37 -0600 +Subject: [PATCH 103/157] mdadm: Block SIGCHLD processes before starting + children + +There is a small race condition noticed during code review, but +never actully hit in practice, with the write_zero feature. + +If a write zeros fork finishes quickly before wait_for_zero_forks() +gets called, then the SIGCHLD will be delivered before the signalfd +is setup. + +While this is only theoretical, fix this by blocking the SIGCHLD +signal before forking any children. + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Create.c b/Create.c +index 4f992a22..bd4875e4 100644 +--- a/Create.c ++++ b/Create.c +@@ -401,6 +401,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, + */ + sigemptyset(&sigset); + sigaddset(&sigset, SIGINT); ++ sigaddset(&sigset, SIGCHLD); + sigprocmask(SIG_BLOCK, &sigset, &orig_sigset); + memset(zero_pids, 0, sizeof(zero_pids)); + +-- +2.41.0 + diff --git a/SOURCES/0104-test-pass-flags-to-services.patch b/SOURCES/0104-test-pass-flags-to-services.patch new file mode 100644 index 0000000..ad7606e --- /dev/null +++ b/SOURCES/0104-test-pass-flags-to-services.patch @@ -0,0 +1,137 @@ +From 29aa21d94bc7ff10f3f7ef0b7f490f3903f5c6fd Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Fri, 15 Mar 2024 16:03:09 -0400 +Subject: [PATCH 104/157] test: pass flags to services + +Commit 4c12714d1ca0 ("test: run tests on system level mdadm") removed +MDADM_NO_SYSTEMCTL flag from test suite. This causes imsm tests to fail +as mdadm no longer triggers mdmon and flags exists only within session. + +Use systemd set/unset-environment to pass necessary flags. + +Introduce colors to grab users attention to warnings and key messages. + +Make test suite setup systemd environment. +Add setup/clean_systemd_env() functions. +Warn user about altering systemd environment. + +Add colors to success/fail messages and warnings. + +Signed-off-by: Mateusz Kusiak +--- + test | 8 +++----- + tests/func.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 48 insertions(+), 6 deletions(-) + +diff --git a/test b/test +index 47f53ad7..3a05bc9b 100755 +--- a/test ++++ b/test +@@ -127,7 +127,7 @@ do_test() { + dmesg | grep -iq "error\|call trace\|segfault" | grep -v "systemd" && + die "dmesg prints errors when testing $_basename!" + fi +- echo "succeeded" ++ succeed "succeeded\n" + _fail=0 + else + save_log fail +@@ -315,10 +315,8 @@ parse_args() { + } + + print_warning() { +- cat <<-EOF +- Warning! Tests are performed on system level mdadm! +- If you want to test local build, you need to install it first! +- EOF ++ warn "Warning! Tests are performed on system level mdadm!\n" ++ echo "If you want to test local build, you need to install it first!" + } + + main() { +diff --git a/tests/func.sh b/tests/func.sh +index b2e4d122..8c142c76 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -23,6 +23,28 @@ mdsize12=19988 + # ddf needs bigger devices as 32Meg is reserved! + ddfsize=65536 + ++# Systemd flags ++devname_as_serial_flag="IMSM_DEVNAME_AS_SERIAL=1" ++no_platform_flag="IMSM_NO_PLATFORM=1" ++ ++# Common colors ++COLOR_FAIL='\033[0;31m' #RED ++COLOR_WARN='\033[1;33m' #YELLOW ++COLOR_SUCCESS='\033[0;32m' #GREEN ++COLOR_NONE='\033[0m' ++ ++fail() { ++ printf "${COLOR_FAIL}$1${COLOR_NONE}" ++} ++ ++warn() { ++ printf "${COLOR_WARN}$1${COLOR_NONE}" ++} ++ ++succeed() { ++ printf "${COLOR_SUCCESS}$1${COLOR_NONE}" ++} ++ + # $1 is optional parameter, it shows why to save log + save_log() { + status=$1 +@@ -36,7 +58,8 @@ save_log() { + cat /proc/mdstat >> $logdir/$logfile + array=($(mdadm -Ds | cut -d' ' -f2)) + [ "$1" == "fail" ] && +- echo "FAILED - see $logdir/$_basename.log and $logdir/$logfile for details" ++ fail "FAILED" ++ echo " - see $logdir/$_basename.log and $logdir/$logfile for details\n" + if [ $DEVTYPE == 'lvm' ] + then + # not supported lvm type yet +@@ -86,6 +109,7 @@ cleanup() { + $mdadm --zero ${disks[@]} &> /dev/null + ;; + esac ++ clean_systemd_env + } + + do_clean() +@@ -176,11 +200,31 @@ restore_selinux() { + setenforce $sys_selinux + } + ++setup_systemd_env() { ++ warn "Warning! Test suite will set up systemd environment!\n" ++ echo "Use \"systemctl show-environment\" to show systemd environment variables" ++ for env_var in $devname_as_serial_flag $no_platform_flag ++ do ++ systemctl set-environment $env_var ++ echo "Added $env_var" to systemd environment, use \ ++ \"systemctl unset-environment $env_var\" to remove it. ++ done ++} ++ ++clean_systemd_env() { ++ for env_var in $devname_as_serial_flag $no_platform_flag ++ do ++ systemctl unset-environment $env_var ++ echo "Removed $env_var from systemd environment." ++ done ++} ++ + do_setup() { + trap cleanup 0 1 3 15 + trap ctrl_c 2 + + check_env ++ setup_systemd_env + [ -d $logdir ] || mkdir -p $logdir + + devlist= +-- +2.41.0 + diff --git a/SOURCES/0105-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch b/SOURCES/0105-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch new file mode 100644 index 0000000..488f9b8 --- /dev/null +++ b/SOURCES/0105-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch @@ -0,0 +1,68 @@ +From 66a54b266f6c579e5f37b6253820903a55c3346c Mon Sep 17 00:00:00 2001 +From: Shminderjit Singh +Date: Tue, 4 Jun 2024 07:46:03 +0000 +Subject: [PATCH 105/157] mdadm: Fix socket connection failure when mdmon runs + in foreground mode. + +While creating an IMSM RAID, mdadm will wait for the mdmon main process +to finish if mdmon runs in forking mode. This is because with +"Type=forking" in the mdmon service unit file, "systemctl start service" +will block until the main process of mdmon exits. At that moment, mdmon +has already created the socket, so the subsequent socket connect from +mdadm will succeed. + +However, when mdmon runs in foreground mode (without "Type=forking" in +the service unit file), "systemctl start service" will return once the +mdmon process starts. This causes mdadm and mdmon to run in parallel, +which may lead to a socket connection failure since mdmon has not yet +initialized the socket when mdadm tries to connect. If the next +instruction/command is to access this device and try to write to it, a +permission error will occur since mdmon has not yet set the array to RW +mode. + +Signed-off-by: Shminderjit Singh +--- + msg.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/msg.c b/msg.c +index ba0e25be..d17f679d 100644 +--- a/msg.c ++++ b/msg.c +@@ -151,6 +151,7 @@ int connect_monitor(char *devname) + struct sockaddr_un addr; + int pos; + char *c; ++ int rv, retry_count = 0; + + pos = sprintf(path, "%s/", MDMON_DIR); + if (is_subarray(devname)) { +@@ -170,7 +171,24 @@ int connect_monitor(char *devname) + + addr.sun_family = PF_LOCAL; + strcpy(addr.sun_path, path); +- if (connect(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { ++ ++ /* In foreground mode, when mdadm is trying to connect to control ++ * socket it is possible that the mdmon has not created it yet. ++ * Give some time to mdmon to create socket. ++ */ ++ for (retry_count = 0; retry_count < 10; retry_count++) { ++ rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr)); ++ ++ if (rv < 0) { ++ sleep_for(0, MSEC_TO_NSEC(200), true); ++ continue; ++ } ++ break; ++ } ++ ++ if (rv < 0) { ++ pr_err("Failed to connect to control socket. (%s!!)\n", ++ strerror(errno)); + close(sfd); + return -1; + } +-- +2.41.0 + diff --git a/SOURCES/0106-Makefile-Do-not-call-gcc-directly.patch b/SOURCES/0106-Makefile-Do-not-call-gcc-directly.patch new file mode 100644 index 0000000..2708598 --- /dev/null +++ b/SOURCES/0106-Makefile-Do-not-call-gcc-directly.patch @@ -0,0 +1,50 @@ +From 027b2d37a8cd56973d117107acc25a64cfe0a92f Mon Sep 17 00:00:00 2001 +From: Gwendal Grignou +Date: Wed, 15 May 2024 14:30:59 -0700 +Subject: [PATCH 106/157] Makefile: Do not call gcc directly + +When mdadm is compiled with clang, direct gcc will fail. +Make sure to use $(CC) variable instead. + +Note that Clang does not support --help=warnings, +--print-diagnostic-options should be used instead. +So with Clang, the compilation will go through, but the +extra warning flags will never be added. + +Signed-off-by: Gwendal Grignou +--- + Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index 446710bd..3fe0a053 100644 +--- a/Makefile ++++ b/Makefile +@@ -56,21 +56,21 @@ CWFLAGS += -Wp -O3 + endif + + ifeq ($(origin FALLTHROUGH), undefined) +- FALLTHROUGH := $(shell gcc -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l) ++ FALLTHROUGH := $(shell $(CC) -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l) + ifneq "$(FALLTHROUGH)" "0" + CWFLAGS += -Wimplicit-fallthrough=0 + endif + endif + + ifeq ($(origin FORMATOVERFLOW), undefined) +- FORMATOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l) ++ FORMATOVERFLOW := $(shell $(CC) -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l) + ifneq "$(FORMATOVERFLOW)" "0" + CWFLAGS += -Wformat-overflow + endif + endif + + ifeq ($(origin STRINGOPOVERFLOW), undefined) +- STRINGOPOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l) ++ STRINGOPOVERFLOW := $(shell $(CC) -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l) + ifneq "$(STRINGOPOVERFLOW)" "0" + CWFLAGS += -Wstringop-overflow + endif +-- +2.41.0 + diff --git a/SOURCES/0107-mdadm-tests-judge-foreign-array-in-test-cases.patch b/SOURCES/0107-mdadm-tests-judge-foreign-array-in-test-cases.patch new file mode 100644 index 0000000..dc7f5be --- /dev/null +++ b/SOURCES/0107-mdadm-tests-judge-foreign-array-in-test-cases.patch @@ -0,0 +1,103 @@ +From 23aef35113553cb97ef2e7b01c760d5449592e14 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 14 Jun 2024 10:45:01 +0800 +Subject: [PATCH 107/157] mdadm/tests: judge foreign array in test cases + +It needs to use array name when judging if one array is foreign or not. +So calling is_raid_foreign in test cases which need it. + +Fixes: 41706a915684 ('mdadm/tests: names_template enhance') +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/03assem-incr | 2 ++ + tests/06name | 2 ++ + tests/07autoassemble | 3 +++ + tests/func.sh | 9 +++++---- + tests/templates/names_template | 2 ++ + 5 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/tests/03assem-incr b/tests/03assem-incr +index 21215a34..56afbf2c 100644 +--- a/tests/03assem-incr ++++ b/tests/03assem-incr +@@ -12,6 +12,8 @@ if [ "$LINEAR" == "yes" ]; then + levels+=( linear ) + fi + ++is_raid_foreign $md0 ++ + for l in ${levels[@]} + do + mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean +diff --git a/tests/06name b/tests/06name +index c3213f6c..9ec3437b 100644 +--- a/tests/06name ++++ b/tests/06name +@@ -2,6 +2,8 @@ set -x + + # create an array with a name + ++is_raid_foreign $md0 ++ + mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1 + + if [ $is_foreign == "no" ]; then +diff --git a/tests/07autoassemble b/tests/07autoassemble +index 9dc78149..b6630e17 100644 +--- a/tests/07autoassemble ++++ b/tests/07autoassemble +@@ -2,6 +2,9 @@ + # create two raid1s, build a raid0 on top, then + # tear it down and get auto-assemble to rebuild it. + ++#the length of md0/md1/md2 is same. So use md0 here. ++is_raid_foreign $md0 ++ + mdadm -CR $md1 -l1 -n2 $dev0 $dev1 --homehost=testing + mdadm -CR $md2 -l1 -n2 $dev2 $dev3 --homehost=testing + mdadm -CR $md0 -l0 -n2 $md1 $md2 --homehost=testing +diff --git a/tests/func.sh b/tests/func.sh +index 8c142c76..e7ccc4fc 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -181,10 +181,12 @@ restore_system_speed_limit() { + + is_raid_foreign() { + +- # If the length of hostname is >= 32, super1 doesn't use +- # hostname in metadata ++ name=$1 ++ # super1 uses this formula strlen(homehost)+1+strlen(name) < 32 ++ # to decide if an array is foreign or local. It adds homehost if ++ # one array is local + hostname=$(hostname) +- if [ `expr length $(hostname)` -lt 32 ]; then ++ if [ `expr length "$(hostname)$name"` -lt 31 ]; then + is_foreign="no" + else + is_foreign="yes" +@@ -299,7 +301,6 @@ do_setup() { + [ -f /proc/mdstat ] || modprobe md_mod + echo 0 > /sys/module/md_mod/parameters/start_ro + record_system_speed_limit +- is_raid_foreign + record_selinux + } + +diff --git a/tests/templates/names_template b/tests/templates/names_template +index 88ad5b8c..c94245ea 100644 +--- a/tests/templates/names_template ++++ b/tests/templates/names_template +@@ -4,6 +4,8 @@ function names_create() { + local NAME=$2 + local NEG_TEST=$3 + ++ is_raid_foreign $DEVNAME ++ + if [[ -z "$NAME" ]]; then + mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force + else +-- +2.41.0 + diff --git a/SOURCES/0108-Revert-mdadm-Fix-socket-connection-failure-when-mdmo.patch b/SOURCES/0108-Revert-mdadm-Fix-socket-connection-failure-when-mdmo.patch new file mode 100644 index 0000000..2bc632a --- /dev/null +++ b/SOURCES/0108-Revert-mdadm-Fix-socket-connection-failure-when-mdmo.patch @@ -0,0 +1,58 @@ +From f98340f1b830d950978abba752b2b9b004528faf Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 20 Jun 2024 15:22:50 +0200 +Subject: [PATCH 108/157] Revert "mdadm: Fix socket connection failure when + mdmon runs in foreground mode." + +This reverts commit 66a54b266f6c579e5f37b6253820903a55c3346c. + +connect_monitor() is called from ping_monitor() but this function is often +used as advice, without verification that mdmon is really working. This +produces hangs in many scenarios. + +Signed-off-by: Mariusz Tkaczyk +--- + msg.c | 20 +------------------- + 1 file changed, 1 insertion(+), 19 deletions(-) + +diff --git a/msg.c b/msg.c +index d17f679d..f0772b3f 100644 +--- a/msg.c ++++ b/msg.c +@@ -151,7 +151,6 @@ int connect_monitor(char *devname) + struct sockaddr_un addr; + int pos; + char *c; +- int rv, retry_count = 0; + + pos = sprintf(path, "%s/", MDMON_DIR); + if (is_subarray(devname)) { +@@ -171,24 +170,7 @@ int connect_monitor(char *devname) + + addr.sun_family = PF_LOCAL; + strcpy(addr.sun_path, path); +- +- /* In foreground mode, when mdadm is trying to connect to control +- * socket it is possible that the mdmon has not created it yet. +- * Give some time to mdmon to create socket. +- */ +- for (retry_count = 0; retry_count < 10; retry_count++) { +- rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr)); +- +- if (rv < 0) { +- sleep_for(0, MSEC_TO_NSEC(200), true); +- continue; +- } +- break; +- } +- +- if (rv < 0) { +- pr_err("Failed to connect to control socket. (%s!!)\n", +- strerror(errno)); ++ if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(sfd); + return -1; + } +-- +2.41.0 + diff --git a/SOURCES/0109-mdadm-Assemble.c-fix-coverity-issues.patch b/SOURCES/0109-mdadm-Assemble.c-fix-coverity-issues.patch new file mode 100644 index 0000000..6e9bcf1 --- /dev/null +++ b/SOURCES/0109-mdadm-Assemble.c-fix-coverity-issues.patch @@ -0,0 +1,149 @@ +From 3e6358e9aa0618f6a7de3a58e545caaada03739f Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 25 Jun 2024 07:57:28 -0400 +Subject: [PATCH 109/157] mdadm: Assemble.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event dereference: Dereferencing "pre_exist", which is known to be "NULL". +* Event parameter_hidden: Declaration hides parameter "c". +* Event leaked_storage: Variable "pre_exist" going out of scope leaks the + storage it points to. +* Event leaked_storage: Variable "avail" going out of scope leaks the + storage it points to. + +Signed-off-by: Nigel Croxon +--- + Assemble.c | 30 ++++++++++++++++++++++++------ + 1 file changed, 24 insertions(+), 6 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 0e6da593..77f2b50e 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -567,6 +567,9 @@ static int select_devices(struct mddev_dev *devlist, + tmpdev->used = 1; + content = *contentp; + ++ if (!st) ++ return -1; ++ + if (!st->sb) { + /* we need sb from one of the spares */ + int dfd = dev_open(tmpdev->devname, O_RDONLY); +@@ -815,12 +818,12 @@ static int load_devices(struct devs *devices, char *devmap, + if (i >= bestcnt) { + int newbestcnt = i+10; + int *newbest = xmalloc(sizeof(int)*newbestcnt); +- int c; +- for (c=0; c < newbestcnt; c++) +- if (c < bestcnt) +- newbest[c] = best[c]; ++ int cc; ++ for (cc = 0; cc < newbestcnt; cc++) ++ if (cc < bestcnt) ++ newbest[cc] = best[cc]; + else +- newbest[c] = -1; ++ newbest[cc] = -1; + if (best)free(best); + best = newbest; + bestcnt = newbestcnt; +@@ -1493,8 +1496,11 @@ try_again: + mp = map_by_uuid(&map, content->uuid); + if (mp) { + struct mdinfo *dv; +- /* array already exists. */ + pre_exist = sysfs_read(-1, mp->devnm, GET_LEVEL|GET_DEVS); ++ if (!pre_exist) ++ goto out; ++ ++ /* array already exists. */ + if (pre_exist->array.level != UnSet) { + pr_err("Found some drive for an array that is already active: %s\n", + mp->path); +@@ -1606,6 +1612,7 @@ try_again: + err = assemble_container_content(st, mdfd, content, c, + chosen_name, NULL); + close(mdfd); ++ sysfs_free(pre_exist); + return err; + } + +@@ -1745,23 +1752,27 @@ try_again: + : (O_RDONLY|O_EXCL)))< 0) { + pr_err("Cannot open %s: %s\n", + devices[j].devname, strerror(errno)); ++ free(avail); + goto out; + } + if (st->ss->load_super(st,fd, NULL)) { + close(fd); + pr_err("RAID superblock has disappeared from %s\n", + devices[j].devname); ++ free(avail); + goto out; + } + close(fd); + } + if (st->sb == NULL) { + pr_err("No suitable drives found for %s\n", mddev); ++ free(avail); + goto out; + } + st->ss->getinfo_super(st, content, NULL); + if (sysfs_init(content, mdfd, NULL)) { + pr_err("Unable to initialize sysfs\n"); ++ free(avail); + goto out; + } + +@@ -1824,12 +1835,14 @@ try_again: + if (fd < 0) { + pr_err("Could not open %s for write - cannot Assemble array.\n", + devices[chosen_drive].devname); ++ free(avail); + goto out; + } + if (st->ss->store_super(st, fd)) { + close(fd); + pr_err("Could not re-write superblock on %s\n", + devices[chosen_drive].devname); ++ free(avail); + goto out; + } + if (c->verbose >= 0) +@@ -1888,6 +1901,7 @@ try_again: + pr_err("Failed to restore critical section for reshape, sorry.\n"); + if (c->backup_file == NULL) + cont_err("Possibly you needed to specify the --backup-file\n"); ++ free(avail); + goto out; + } + } +@@ -1916,6 +1930,7 @@ try_again: + if (rv == 1 && !pre_exist) + ioctl(mdfd, STOP_ARRAY, NULL); + free(devices); ++ free(avail); + out: + map_unlock(&map); + if (rv == 0) { +@@ -1951,11 +1966,14 @@ out: + close(mdfd); + + free(best); ++ sysfs_free(pre_exist); ++ + /* '2' means 'OK, but not started yet' */ + if (rv == -1) { + free(devices); + return 1; + } ++ close(mdfd); + return rv == 2 ? 0 : rv; + } + +-- +2.41.0 + diff --git a/SOURCES/0111-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch b/SOURCES/0111-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch new file mode 100644 index 0000000..cbb4bff --- /dev/null +++ b/SOURCES/0111-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch @@ -0,0 +1,118 @@ +From 3cbe13403ec0c78374343dcd889609aefe791f9b Mon Sep 17 00:00:00 2001 +From: Shminderjit Singh +Date: Mon, 24 Jun 2024 08:58:51 +0000 +Subject: [PATCH 111/157] mdadm: Fix socket connection failure when mdmon runs + in foreground mode. + +While creating an IMSM RAID, mdadm will wait for the mdmon main process +to finish if mdmon runs in forking mode. This is because with +"Type=forking" in the mdmon service unit file, "systemctl start service" +will block until the main process of mdmon exits. At that moment, mdmon +has already created the socket, so the subsequent socket connect from +mdadm will succeed. + +However, when mdmon runs in foreground mode (without "Type=forking" in +the service unit file), "systemctl start service" will return once the +mdmon process starts. This causes mdadm and mdmon to run in parallel, +which may lead to a socket connection failure since mdmon has not yet +initialized the socket when mdadm tries to connect. If the next +instruction/command is to access this device and try to write to it, a +permission error will occur since mdmon has not yet set the array to RW +mode. + +Signed-off-by: Shminderjit Singh +--- + Create.c | 6 ++++-- + mdadm.h | 1 + + util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 50 insertions(+), 2 deletions(-) + +diff --git a/Create.c b/Create.c +index bd4875e4..479c2715 100644 +--- a/Create.c ++++ b/Create.c +@@ -1344,9 +1344,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + if (c->verbose >= 0) + pr_info("array %s started.\n", chosen_name); + if (st->ss->external && st->container_devnm[0]) { +- if (need_mdmon) ++ if (need_mdmon) { + start_mdmon(st->container_devnm); +- ++ if (wait_for_mdmon_control_socket(st->container_devnm) != MDADM_STATUS_SUCCESS) ++ goto abort; ++ } + ping_monitor(st->container_devnm); + close(container_fd); + } +diff --git a/mdadm.h b/mdadm.h +index e9f764a2..27009154 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1776,6 +1776,7 @@ extern int is_subarray_active(char *subarray, char *devname); + extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet); + extern struct superswitch *version_to_superswitch(char *vers); + ++extern mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm); + extern int mdmon_running(const char *devnm); + extern int mdmon_pid(const char *devnm); + extern mdadm_status_t wait_for_mdmon(const char *devnm); +diff --git a/util.c b/util.c +index 48c97545..908f8430 100644 +--- a/util.c ++++ b/util.c +@@ -1932,6 +1932,51 @@ int mdmon_running(const char *devnm) + return 0; + } + ++/* ++ * wait_for_mdmon_control_socket() - Waits for mdmon control socket ++ * to be created within specified time. ++ * @container_devnm: Device for which mdmon control socket should start. ++ * ++ * In foreground mode, when mdadm is trying to connect to control ++ * socket it is possible that the mdmon has not created it yet. ++ * Give some time to mdmon to create socket. Timeout set to 2 sec. ++ * ++ * Return: MDADM_STATUS_SUCCESS if connect succeed, otherwise return ++ * error code. ++ */ ++mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm) ++{ ++ enum mdadm_status status = MDADM_STATUS_SUCCESS; ++ int sfd, rv, retry_count = 0; ++ struct sockaddr_un addr; ++ char path[PATH_MAX]; ++ ++ snprintf(path, PATH_MAX, "%s/%s.sock", MDMON_DIR, container_devnm); ++ sfd = socket(PF_LOCAL, SOCK_STREAM, 0); ++ if (!is_fd_valid(sfd)) ++ return MDADM_STATUS_ERROR; ++ ++ addr.sun_family = PF_LOCAL; ++ strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); ++ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; ++ ++ for (retry_count = 0; retry_count < 10; retry_count++) { ++ rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr)); ++ if (rv < 0) { ++ sleep_for(0, MSEC_TO_NSEC(200), true); ++ continue; ++ } ++ break; ++ } ++ ++ if (rv < 0) { ++ pr_err("Failed to connect to control socket.\n"); ++ status = MDADM_STATUS_ERROR; ++ } ++ close(sfd); ++ return status; ++} ++ + /* + * wait_for_mdmon() - Waits for mdmon within specified time. + * @devnm: Device for which mdmon should start. +-- +2.41.0 + diff --git a/SOURCES/0113-config.c-Fix-memory-leak-in-load_containers.patch b/SOURCES/0113-config.c-Fix-memory-leak-in-load_containers.patch new file mode 100644 index 0000000..204ecf0 --- /dev/null +++ b/SOURCES/0113-config.c-Fix-memory-leak-in-load_containers.patch @@ -0,0 +1,28 @@ +From 44457789fd67168c37932060f9a991f0c611e5a2 Mon Sep 17 00:00:00 2001 +From: Anna Sztukowska +Date: Fri, 28 Jun 2024 12:32:16 +0200 +Subject: [PATCH 113/157] config.c: Fix memory leak in load_containers() + +Fix memory leak in load_containers() in config.c reported by SAST +analysis. + +Signed-off-by: Anna Sztukowska +--- + config.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/config.c b/config.c +index 612e700d..cd2379bd 100644 +--- a/config.c ++++ b/config.c +@@ -379,6 +379,7 @@ struct mddev_dev *load_containers(void) + map = NULL; + } + free_mdstat(mdstat); ++ map_free(map); + + return rv; + } +-- +2.41.0 + diff --git a/SOURCES/0114-mdadm-Build.c-fix-coverity-issues.patch b/SOURCES/0114-mdadm-Build.c-fix-coverity-issues.patch new file mode 100644 index 0000000..7dc51ce --- /dev/null +++ b/SOURCES/0114-mdadm-Build.c-fix-coverity-issues.patch @@ -0,0 +1,40 @@ +From 0244bac0a828e69aef36404437cac4ff148eaea0 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 2 Jul 2024 09:49:13 -0400 +Subject: [PATCH 114/157] mdadm: Build.c fix coverity issues + +Event leaked_handle: Handle variable "bitmap_fd" going out of +scope leaks the handle. + +Signed-off-by: Nigel Croxon +--- + Build.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Build.c b/Build.c +index 1be90e41..052b1bc2 100644 +--- a/Build.c ++++ b/Build.c +@@ -168,13 +168,13 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, + goto abort; + } + } +- if (bitmap_fd >= 0) { +- if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { +- pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, +- strerror(errno)); +- goto abort; +- } ++ if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { ++ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, ++ strerror(errno)); ++ close(bitmap_fd); ++ goto abort; + } ++ close(bitmap_fd); + } + if (ioctl(mdfd, RUN_ARRAY, ¶m)) { + pr_err("RUN_ARRAY failed: %s\n", strerror(errno)); +-- +2.41.0 + diff --git a/SOURCES/0115-mdadm-Create.c-fix-coverity-issues.patch b/SOURCES/0115-mdadm-Create.c-fix-coverity-issues.patch new file mode 100644 index 0000000..5d26f4b --- /dev/null +++ b/SOURCES/0115-mdadm-Create.c-fix-coverity-issues.patch @@ -0,0 +1,45 @@ +From 7c524aa83c4463c15a13f6f47a27a18ab4de9eef Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Fri, 5 Jul 2024 08:45:32 -0400 +Subject: [PATCH 115/157] mdadm: Create.c fix coverity issues + +* Event negative_returns: "fd" is passed to a parameter that cannot be negative. Which +is set to -1 to start. + +* Event open_fn: Returning handle opened by "open_dev_excl". +* Event var_assign: Assigning: "container_fd" = handle returned from +"open_dev_excl(st->container_devnm)" +* Event leaked_handle: Handle variable "container_fd" going out of scope leaks the handle + +Signed-off-by: Nigel Croxon +--- + Create.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Create.c b/Create.c +index 479c2715..7fde1c16 100644 +--- a/Create.c ++++ b/Create.c +@@ -297,7 +297,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, + dv->data_offset)) { + ioctl(mdfd, STOP_ARRAY, NULL); +- close(fd); ++ close_fd(&fd); + return 1; + } + st->ss->getinfo_super(st, info, NULL); +@@ -1370,8 +1370,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + map_remove(&map, fd2devnm(mdfd)); + map_unlock(&map); + +- if (mdfd >= 0) +- close(mdfd); ++ close_fd(&mdfd); ++ close_fd(&container_fd); + + dev_policy_free(custom_pols); + return 1; +-- +2.41.0 + diff --git a/SOURCES/0116-mdadm-super-ddf.c-fix-coverity-issues.patch b/SOURCES/0116-mdadm-super-ddf.c-fix-coverity-issues.patch new file mode 100644 index 0000000..9517bca --- /dev/null +++ b/SOURCES/0116-mdadm-super-ddf.c-fix-coverity-issues.patch @@ -0,0 +1,473 @@ +From 96b8035a09b6449ea99f2eb91f9ba4f6912e5bd6 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 2 Jul 2024 10:11:26 -0400 +Subject: [PATCH 116/157] mdadm: super-ddf.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Calling "lseek64" without checking return value. This library function may +fail and return an error code. +* Overrunning array "anchor->pad2" of 3 bytes by passing it to a function +which accesses it at byte offset 398 using argument "399UL". +* Event leaked_storage: Variable "sra" going out of scope leaks the storage +it points to. +* Event leaked_storage: Variable "super" going out of scope leaks the storage +it points to. +* Event leaked_handle: Handle variable "dfd" going out of scope leaks the +handle. +* Event leaked_storage: Variable "dl1" going out of scope leaks the storage +it points to +* Event leaked_handle: Handle variable "cfd" going out of scope leaks the +handle. +* Variable "avail" going out of scope leaks the storage it points to. +* Passing unterminated string "super->anchor.revision" to "fprintf", which +expects a null-terminated string. +* You might overrun the 32-character fixed-size string "st->container_devnm" +by copying the return value of "fd2devnm" without checking the length. +* Event fixed_size_dest: You might overrun the 33-character fixed-size string +"dev->name" by copying "(*d).devname" without checking the length. +* Event uninit_use_in_call: Using uninitialized value "info.array.raid_disks" +when calling "getinfo_super_ddf" + +V2: clean up validate_geometry_ddf() routine with Mariusz Tkaczyk recommendations. +V3: clean up spaces with Blazej Kucman recommendations. +V4: clean up recommended by Mariusz Tkaczyk. +V5: clean up recommended by Mariusz Tkaczyk. + +Signed-off-by: Nigel Croxon +--- + super-ddf.c | 172 +++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 115 insertions(+), 57 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 311001c1..d870102d 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -809,7 +809,7 @@ static int load_ddf_header(int fd, unsigned long long lba, + if (lba >= size-1) + return 0; + +- if (lseek64(fd, lba<<9, 0) < 0) ++ if (lseek64(fd, lba << 9, 0) == -1L) + return 0; + + if (read(fd, hdr, 512) != 512) +@@ -828,8 +828,7 @@ static int load_ddf_header(int fd, unsigned long long lba, + !be64_eq(anchor->primary_lba, hdr->primary_lba) || + !be64_eq(anchor->secondary_lba, hdr->secondary_lba) || + hdr->type != type || +- memcmp(anchor->pad2, hdr->pad2, 512 - +- offsetof(struct ddf_header, pad2)) != 0) { ++ memcmp(anchor->pad2, hdr->pad2, sizeof(anchor->pad2)) != 0) { + pr_err("header mismatch\n"); + return 0; + } +@@ -863,7 +862,7 @@ static void *load_section(int fd, struct ddf_super *super, void *buf, + else + offset += be64_to_cpu(super->active->secondary_lba); + +- if ((unsigned long long)lseek64(fd, offset<<9, 0) != (offset<<9)) { ++ if ((unsigned long long)lseek64(fd, offset << 9, 0) != (offset << 9)) { + if (dofree) + free(buf); + return NULL; +@@ -882,7 +881,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) + + get_dev_size(fd, NULL, &dsize); + +- if (lseek64(fd, dsize-512, 0) < 0) { ++ if (lseek64(fd, dsize - 512, 0) == -1L) { + if (devname) + pr_err("Cannot seek to anchor block on %s: %s\n", + devname, strerror(errno)); +@@ -909,8 +908,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) + if (memcmp(super->anchor.revision, DDF_REVISION_0, 8) != 0 && + memcmp(super->anchor.revision, DDF_REVISION_2, 8) != 0) { + if (devname) +- pr_err("can only support super revision %.8s and earlier, not %.8s on %s\n", +- DDF_REVISION_2, super->anchor.revision,devname); ++ pr_err("The DDF revision on %s\n is not supported", devname); + return 2; + } + super->active = NULL; +@@ -1610,6 +1608,7 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st) + return DDF_NOTFOUND; + } + ++ sysfs_free(sra); + return vcnum; + } + +@@ -1617,11 +1616,11 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose) + { + /* We just write a generic DDF ARRAY entry + */ +- struct mdinfo info; ++ struct mdinfo info = {0}; + char nbuf[64]; ++ + getinfo_super_ddf(st, &info, NULL); + fname_from_uuid(&info, nbuf); +- + printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5); + } + +@@ -1631,9 +1630,10 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + * by uuid and member by unit number and uuid. + */ + struct ddf_super *ddf = st->sb; +- struct mdinfo info; ++ struct mdinfo info = {0}; + unsigned int i; + char nbuf[64]; ++ + getinfo_super_ddf(st, &info, NULL); + fname_from_uuid(&info, nbuf); + +@@ -1658,8 +1658,9 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + + static void export_examine_super_ddf(struct supertype *st) + { +- struct mdinfo info; ++ struct mdinfo info = {0}; + char nbuf[64]; ++ + getinfo_super_ddf(st, &info, NULL); + fname_from_uuid(&info, nbuf); + printf("MD_METADATA=ddf\n"); +@@ -1692,10 +1693,12 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to) + if (!get_dev_size(from, NULL, &dsize)) + goto err; + +- if (lseek64(from, dsize-512, 0) < 0) ++ if (lseek64(from, dsize - 512, 0) == -1L) + goto err; ++ + if (read(from, buf, 512) != 512) + goto err; ++ + ddf = buf; + if (!be32_eq(ddf->magic, DDF_HEADER_MAGIC) || + !be32_eq(calc_crc(ddf, 512), ddf->crc) || +@@ -1711,9 +1714,9 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to) + + bytes = dsize - offset; + +- if (lseek64(from, offset, 0) < 0 || +- lseek64(to, offset, 0) < 0) ++ if (lseek64(from, offset, 0) == -1L || lseek64(to, offset, 0) == -1L) + goto err; ++ + while (written < bytes) { + int n = bytes - written; + if (n > 4096) +@@ -1795,6 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st, char *subarray) + char nbuf[64]; + struct ddf_super *ddf = st->sb; + unsigned int vcnum = get_vd_num_of_subarray(st); ++ + if (vcnum == DDF_CONTAINER) + uuid_from_super_ddf(st, info.uuid); + else if (vcnum == DDF_NOTFOUND) +@@ -2971,7 +2975,9 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type) + header->openflag = 1; + header->crc = calc_crc(header, 512); + +- lseek64(fd, sector<<9, 0); ++ if (lseek64(fd, sector << 9, 0) == -1L) ++ goto out; ++ + if (write(fd, header, 512) < 0) + goto out; + +@@ -2982,6 +2988,7 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type) + ddf->phys->crc = calc_crc(ddf->phys, ddf->pdsize); + if (write(fd, ddf->phys, ddf->pdsize) < 0) + goto out; ++ + ddf->virt->crc = calc_crc(ddf->virt, ddf->vdsize); + if (write(fd, ddf->virt, ddf->vdsize) < 0) + goto out; +@@ -3035,7 +3042,9 @@ out: + header->openflag = 0; + header->crc = calc_crc(header, 512); + +- lseek64(fd, sector<<9, 0); ++ if (lseek64(fd, sector << 9, 0) == -1L) ++ return 0; ++ + if (write(fd, header, 512) < 0) + ret = 0; + +@@ -3088,7 +3097,9 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d) + if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY)) + return 0; + +- lseek64(fd, (size-1)*512, SEEK_SET); ++ if (lseek64(fd, (size - 1) * 512, SEEK_SET) == -1L) ++ return 0; ++ + if (write(fd, &ddf->anchor, 512) < 0) + return 0; + +@@ -3299,9 +3310,10 @@ static int validate_geometry_ddf(struct supertype *st, + char *dev, unsigned long long *freesize, + int consistency_policy, int verbose) + { +- int fd; +- struct mdinfo *sra; ++ struct mdinfo *sra = NULL; ++ int ret = 1; + int cfd; ++ int fd; + + /* ddf potentially supports lots of things, but it depends on + * what devices are offered (and maybe kernel version?) +@@ -3369,7 +3381,7 @@ static int validate_geometry_ddf(struct supertype *st, + * Later we should check for a BVD and make an SVD. + */ + fd = open(dev, O_RDONLY|O_EXCL, 0); +- if (fd >= 0) { ++ if (is_fd_valid(fd)) { + close(fd); + /* Just a bare device, no good to us */ + if (verbose) +@@ -3377,44 +3389,58 @@ static int validate_geometry_ddf(struct supertype *st, + dev); + return 0; + } ++ + if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) { + if (verbose) + pr_err("ddf: Cannot open %s: %s\n", + dev, strerror(errno)); + return 0; + } ++ + /* Well, it is in use by someone, maybe a 'ddf' container. */ + cfd = open_container(fd); +- if (cfd < 0) { +- close(fd); ++ close(fd); ++ ++ if (!is_fd_valid(cfd)) { + if (verbose) +- pr_err("ddf: Cannot use %s: %s\n", +- dev, strerror(EBUSY)); ++ pr_err("ddf: Cannot use %s\n", dev); + return 0; + } ++ + sra = sysfs_read(cfd, NULL, GET_VERSION); +- close(fd); +- if (sra && sra->array.major_version == -1 && +- strcmp(sra->text_version, "ddf") == 0) { ++ if (!sra) { ++ pr_err("Cannot read sysfs for /dev/%s\n", fd2kname(cfd)); ++ goto error; ++ } ++ ++ if (sra->array.major_version == -1 && strcmp(sra->text_version, "ddf") == 0) { + /* This is a member of a ddf container. Load the container + * and try to create a bvd + */ +- struct ddf_super *ddf; ++ struct ddf_super *ddf = NULL; ++ + if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) { + st->sb = ddf; +- strcpy(st->container_devnm, fd2devnm(cfd)); ++ snprintf(st->container_devnm, sizeof(st->container_devnm), ++ "%s", fd2kname(cfd)); + close(cfd); +- return validate_geometry_ddf_bvd(st, level, layout, +- raiddisks, chunk, size, +- data_offset, +- dev, freesize, +- verbose); ++ free(sra); ++ ++ return validate_geometry_ddf_bvd(st, level, layout, raiddisks, ++ chunk, size, data_offset, dev, ++ freesize, verbose); + } +- close(cfd); +- } else /* device may belong to a different container */ +- return 0; ++ free(ddf); ++ } + +- return 1; ++ /* device may belong to a different container */ ++ ret = 0; ++ ++error: ++ free(sra); ++ close(cfd); ++ ++ return ret; + } + + static int validate_geometry_ddf_bvd(struct supertype *st, +@@ -3483,35 +3509,42 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + static int load_super_ddf_all(struct supertype *st, int fd, + void **sbp, char *devname) + { +- struct mdinfo *sra; +- struct ddf_super *super; + struct mdinfo *sd, *best = NULL; ++ struct ddf_super *super = NULL; ++ struct mdinfo *sra; + int bestseq = 0; +- int seq; ++ int ret = 1; + char nm[20]; ++ int seq; + int dfd; + + sra = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE); + if (!sra) + return 1; +- if (sra->array.major_version != -1 || +- sra->array.minor_version != -2 || ++ if (sra->array.major_version != -1 || sra->array.minor_version != -2 || + strcmp(sra->text_version, "ddf") != 0) +- return 1; ++ goto out; + + if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0) +- return 1; ++ goto out; ++ + memset(super, 0, sizeof(*super)); + + /* first, try each device, and choose the best ddf */ + for (sd = sra->devs ; sd ; sd = sd->next) { + int rv; ++ + sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor); ++ + dfd = dev_open(nm, O_RDONLY); +- if (dfd < 0) +- return 2; ++ if (!is_fd_valid(dfd)) { ++ ret = 2; ++ goto out; ++ } ++ + rv = load_ddf_headers(dfd, super, NULL); + close(dfd); ++ + if (rv == 0) { + seq = be32_to_cpu(super->active->seq); + if (super->active->openflag) +@@ -3523,28 +3556,39 @@ static int load_super_ddf_all(struct supertype *st, int fd, + } + } + if (!best) +- return 1; ++ goto out; ++ + /* OK, load this ddf */ + sprintf(nm, "%d:%d", best->disk.major, best->disk.minor); ++ + dfd = dev_open(nm, O_RDONLY); + if (dfd < 0) +- return 1; ++ goto out; ++ + load_ddf_headers(dfd, super, NULL); + load_ddf_global(dfd, super, NULL); + close(dfd); ++ + /* Now we need the device-local bits */ + for (sd = sra->devs ; sd ; sd = sd->next) { + int rv; + + sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor); ++ + dfd = dev_open(nm, O_RDWR); +- if (dfd < 0) +- return 2; ++ if (dfd < 0) { ++ ret = 2; ++ goto out; ++ } ++ + rv = load_ddf_headers(dfd, super, NULL); + if (rv == 0) + rv = load_ddf_local(dfd, super, NULL, 1); +- if (rv) +- return 1; ++ ++ if (rv) { ++ close(dfd); ++ goto out; ++ } + } + + *sbp = super; +@@ -3553,8 +3597,16 @@ static int load_super_ddf_all(struct supertype *st, int fd, + st->minor_version = 0; + st->max_devs = 512; + } +- strcpy(st->container_devnm, fd2devnm(fd)); +- return 0; ++ ++ snprintf(st->container_devnm, sizeof(st->container_devnm), "%s", fd2devnm(fd)); ++ ret = 0; ++ ++out: ++ if (sra) ++ free(sra); ++ if (super && ret != 0) ++ free(super); ++ return ret; + } + + static int load_container_ddf(struct supertype *st, int fd, +@@ -3791,7 +3843,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray + be64_to_cpu(LBA_OFFSET(ddf, bvd)[iphys]); + dev->component_size = be64_to_cpu(bvd->blocks); + if (d->devname) +- strcpy(dev->name, d->devname); ++ snprintf(dev->name, sizeof(dev->name), "%s", d->devname); + } + } + return rest; +@@ -3840,11 +3892,15 @@ static int store_super_ddf(struct supertype *st, int fd) + return 1; + memset(buf, 0, 512); + +- lseek64(fd, dsize-512, 0); ++ if (lseek64(fd, dsize - 512, 0) == -1L) { ++ free(buf); ++ return 1; ++ } + rc = write(fd, buf, 512); + free(buf); + if (rc < 0) + return 1; ++ + return 0; + } + +@@ -3959,6 +4015,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst, + if (posix_memalign((void **)&dl1->spare, 512, + first->conf_rec_len*512) != 0) { + pr_err("could not allocate spare info buf\n"); ++ free(dl1); + return 3; + } + memcpy(dl1->spare, dl2->spare, first->conf_rec_len*512); +@@ -4180,6 +4237,7 @@ static int get_bvd_state(const struct ddf_super *ddf, + state = DDF_state_part_optimal; + break; + } ++ free(avail); + return state; + } + +-- +2.41.0 + diff --git a/SOURCES/0117-mdadm-clustermd_tests-add-some-APIs-in-func.sh-to-su.patch b/SOURCES/0117-mdadm-clustermd_tests-add-some-APIs-in-func.sh-to-su.patch new file mode 100644 index 0000000..0458285 --- /dev/null +++ b/SOURCES/0117-mdadm-clustermd_tests-add-some-APIs-in-func.sh-to-su.patch @@ -0,0 +1,102 @@ +From cdce3219a52938fc35f93b5f17561f2ca7175e37 Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Tue, 9 Jul 2024 20:04:51 +0800 +Subject: [PATCH 117/157] mdadm/clustermd_tests: add some APIs in func.sh to + support running the tests without errors + +clustermd_tests/func.sh lacks some APIs to run, this patch makes +clustermd_tests runnable from the test suite. + +Signed-off-by: Heming Zhao +Signed-off-by: Mariusz Tkaczyk +--- + clustermd_tests/func.sh | 60 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 60 insertions(+) + +diff --git a/clustermd_tests/func.sh b/clustermd_tests/func.sh +index 801d6043..e659c0ba 100644 +--- a/clustermd_tests/func.sh ++++ b/clustermd_tests/func.sh +@@ -1,5 +1,22 @@ + #!/bin/bash + ++COLOR_FAIL='\033[0;31m' #RED ++COLOR_WARN='\033[1;33m' #YELLOW ++COLOR_SUCCESS='\033[0;32m' #GREEN ++COLOR_NONE='\033[0m' ++ ++fail() { ++ printf "${COLOR_FAIL}$1${COLOR_NONE}" ++} ++ ++warn() { ++ printf "${COLOR_WARN}$1${COLOR_NONE}" ++} ++ ++succeed() { ++ printf "${COLOR_SUCCESS}$1${COLOR_NONE}" ++} ++ + check_ssh() + { + NODE1="$(grep '^NODE1' $CLUSTER_CONF | cut -d'=' -f2)" +@@ -151,6 +168,33 @@ stop_md() + fi + } + ++record_system_speed_limit() { ++ system_speed_limit_max=`cat /proc/sys/dev/raid/speed_limit_max` ++ system_speed_limit_min=`cat /proc/sys/dev/raid/speed_limit_min` ++} ++ ++# To avoid sync action finishes before checking it, it needs to limit ++# the sync speed ++control_system_speed_limit() { ++ echo $test_speed_limit_min > /proc/sys/dev/raid/speed_limit_min ++ echo $test_speed_limit_max > /proc/sys/dev/raid/speed_limit_max ++} ++ ++restore_system_speed_limit() { ++ echo $system_speed_limit_min > /proc/sys/dev/raid/speed_limit_max ++ echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max ++} ++ ++record_selinux() { ++ # empty ++ return 0 ++} ++ ++restore_selinux() { ++ # empty ++ return 0 ++} ++ + # $1/optional, it shows why to save log + save_log() + { +@@ -240,6 +284,22 @@ check() + die "$ip: check '$2' failed." + done + ;; ++ recovery-remote ) ++ cnt=5 ++ for ip in ${NODES[@]} ++ do ++ while ! ssh $ip "grep -sqE 'recovery|REMOTE' /proc/mdstat" ++ do ++ if [ "$cnt" -gt '0' ] ++ then ++ sleep 0.2 ++ cnt=$[cnt-1] ++ else ++ die "$ip: no '$2' happening!" ++ fi ++ done ++ done ++ ;; + PENDING | recovery | resync | reshape ) + cnt=5 + for ip in ${NODES[@]} +-- +2.41.0 + diff --git a/SOURCES/0118-mdadm-clustermd_tests-adjust-test-cases-to-support-m.patch b/SOURCES/0118-mdadm-clustermd_tests-adjust-test-cases-to-support-m.patch new file mode 100644 index 0000000..1f8e409 --- /dev/null +++ b/SOURCES/0118-mdadm-clustermd_tests-adjust-test-cases-to-support-m.patch @@ -0,0 +1,81 @@ +From bde21cc929d4864bd4b9f459f46ce63dd8c793ca Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Tue, 9 Jul 2024 20:04:52 +0800 +Subject: [PATCH 118/157] mdadm/clustermd_tests: adjust test cases to support + md module changes + +Since kernel commit db5e653d7c9f ("md: delay choosing sync action to +md_start_sync()") delays the start of the sync action, clustermd +array sync/resync jobs can happen on any leg of the array. This +commit adjusts the test cases to follow the new kernel layer behavior. + +Signed-off-by: Heming Zhao +Signed-off-by: Mariusz Tkaczyk +--- + clustermd_tests/02r10_Manage_re-add | 3 ++- + clustermd_tests/02r1_Manage_re-add | 1 + + clustermd_tests/03r10_switch-recovery | 4 ++-- + clustermd_tests/03r1_switch-recovery | 4 ++-- + 4 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/clustermd_tests/02r10_Manage_re-add b/clustermd_tests/02r10_Manage_re-add +index 2288a008..d8764667 100644 +--- a/clustermd_tests/02r10_Manage_re-add ++++ b/clustermd_tests/02r10_Manage_re-add +@@ -9,7 +9,8 @@ check all state UU + check all dmesg + mdadm --manage $md0 --fail $dev0 --remove $dev0 + mdadm --manage $md0 --re-add $dev0 +-check $NODE1 recovery ++#non-clustered array also doesn't do sync job ++#check $NODE1 recovery + check all wait + check all state UU + check all dmesg +diff --git a/clustermd_tests/02r1_Manage_re-add b/clustermd_tests/02r1_Manage_re-add +index d0d13e53..811df87b 100644 +--- a/clustermd_tests/02r1_Manage_re-add ++++ b/clustermd_tests/02r1_Manage_re-add +@@ -9,6 +9,7 @@ check all state UU + check all dmesg + mdadm --manage $md0 --fail $dev0 --remove $dev0 + mdadm --manage $md0 --re-add $dev0 ++check all wait + check all state UU + check all dmesg + stop_md all $md0 +diff --git a/clustermd_tests/03r10_switch-recovery b/clustermd_tests/03r10_switch-recovery +index 867388d0..7d0b8812 100644 +--- a/clustermd_tests/03r10_switch-recovery ++++ b/clustermd_tests/03r10_switch-recovery +@@ -10,9 +10,9 @@ check all state UU + check all dmesg + mdadm --manage $md0 --fail $dev0 + sleep 0.2 +-check $NODE1 recovery ++check $NODE1 recovery-remote + stop_md $NODE1 $md0 +-check $NODE2 recovery ++check $NODE2 recovery-remote + check $NODE2 wait + check $NODE2 state UU + check all dmesg +diff --git a/clustermd_tests/03r1_switch-recovery b/clustermd_tests/03r1_switch-recovery +index a1a7cbe7..d8483c45 100644 +--- a/clustermd_tests/03r1_switch-recovery ++++ b/clustermd_tests/03r1_switch-recovery +@@ -10,9 +10,9 @@ check all state UU + check all dmesg + mdadm --manage $md0 --fail $dev0 + sleep 0.3 +-check $NODE1 recovery ++check $NODE1 recovery-remote + stop_md $NODE1 $md0 +-check $NODE2 recovery ++check $NODE2 recovery-remote + check $NODE2 wait + check $NODE2 state UU + check all dmesg +-- +2.41.0 + diff --git a/SOURCES/0119-mapfile.c-Fix-STRING_OVERFLOW-issue.patch b/SOURCES/0119-mapfile.c-Fix-STRING_OVERFLOW-issue.patch new file mode 100644 index 0000000..a239400 --- /dev/null +++ b/SOURCES/0119-mapfile.c-Fix-STRING_OVERFLOW-issue.patch @@ -0,0 +1,40 @@ +From 48c365376ce7763fd9a9e7735b1e9ec5d0ff1631 Mon Sep 17 00:00:00 2001 +From: Anna Sztukowska +Date: Wed, 3 Jul 2024 14:11:58 +0200 +Subject: [PATCH 119/157] mapfile.c: Fix STRING_OVERFLOW issue + +Fix STRING_OVERFLOW issue found by SAST analysis in map_add() and +map_update() in mapfile.c. + +Signed-off-by: Anna Sztukowska +--- + mapfile.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/mapfile.c b/mapfile.c +index f1f3ee2c..ea9837ac 100644 +--- a/mapfile.c ++++ b/mapfile.c +@@ -165,8 +165,8 @@ void map_add(struct map_ent **melp, + { + struct map_ent *me = xmalloc(sizeof(*me)); + +- strcpy(me->devnm, devnm); +- strcpy(me->metadata, metadata); ++ snprintf(me->devnm, sizeof(me->devnm), "%s", devnm); ++ snprintf(me->metadata, sizeof(me->metadata), "%s", metadata); + memcpy(me->uuid, uuid, 16); + me->path = path ? xstrdup(path) : NULL; + me->next = *melp; +@@ -227,7 +227,7 @@ int map_update(struct map_ent **mpp, char *devnm, char *metadata, + + for (mp = map ; mp ; mp=mp->next) + if (strcmp(mp->devnm, devnm) == 0) { +- strcpy(mp->metadata, metadata); ++ snprintf(mp->metadata, sizeof(mp->metadata), "%s", metadata); + memcpy(mp->uuid, uuid, 16); + free(mp->path); + mp->path = path ? xstrdup(path) : NULL; +-- +2.41.0 + diff --git a/SOURCES/0120-mdadm-Manage.c-fix-coverity-issues.patch b/SOURCES/0120-mdadm-Manage.c-fix-coverity-issues.patch new file mode 100644 index 0000000..382544d --- /dev/null +++ b/SOURCES/0120-mdadm-Manage.c-fix-coverity-issues.patch @@ -0,0 +1,484 @@ +From 1b4b73fd535a6487075e98f620454ff2e13b5240 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Wed, 10 Jul 2024 08:55:08 -0400 +Subject: [PATCH 120/157] mdadm: Manage.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event parameter_hidden: declaration hides parameter "dv". +* Event leaked_storage: Variable "mdi" going out of scope leaks the storage +it points to. +* Event overwrite_var: Overwriting "mdi" in "mdi = mdi->devs" leaks the +storage that "mdi" points to. +* Event leaked_handle: Handle variable "lfd" going out of scope leaks +the handle. +* Event leaked_handle: Returning without closing handle "fd" leaks it. +* Event fixed_size_dest: You might overrun the 32-character fixed-sizei +string "devnm" by copying the return value of "fd2devnm" without +checking the length. +* Event fixed_size_dest: You might overrun the 32-character fixed-size +string "nm" by copying "nmp" without checking the length. +* Event fixed_size_dest: You might overrun the 32-character fixed-size +string "devnm" by copying the return value of "fd2devnm" without +checking the length. +* Event assigned_value: Assigning value "-1" to "tfd" here, but that +stored value is overwritten before it can be used. + +Signed-off-by: Nigel Croxon +--- + Manage.c | 149 ++++++++++++++++++++++++++----------------------------- + 1 file changed, 71 insertions(+), 78 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 5db72b77..aa5e80b2 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -56,7 +56,7 @@ int Manage_ro(char *devname, int fd, int readonly) + vers[9] = '-'; + sysfs_set_str(mdi, NULL, "metadata_version", vers); + +- close(fd); ++ close_fd(&fd); + rv = sysfs_set_str(mdi, NULL, "array_state", "readonly"); + + if (rv < 0) { +@@ -165,7 +165,7 @@ int Manage_run(char *devname, int fd, struct context *c) + pr_err("Cannot find %s in sysfs!!\n", devname); + return 1; + } +- strcpy(nm, nmp); ++ snprintf(nm, sizeof(nm), "%s", nmp); + return IncrementalScan(c, nm); + } + +@@ -187,7 +187,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + if (will_retry && verbose == 0) + verbose = -1; + +- strcpy(devnm, fd2devnm(fd)); ++ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd)); + /* Get EXCL access first. If this fails, then attempting + * to stop is probably a bad idea. + */ +@@ -195,7 +195,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + if (mdi && is_subarray(mdi->text_version)) + sysfs_get_container_devnm(mdi, container); + +- close(fd); ++ close_fd(&fd); + count = 5; + while (((fd = ((devname[0] == '/') + ?open(devname, O_RDONLY|O_EXCL) +@@ -206,14 +206,12 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + * is a container, so we might be racing with mdmon, so + * retry for a bit. + */ +- if (fd >= 0) +- close(fd); ++ close_fd(&fd); + flush_mdmon(container); + count--; + } + if (fd < 0 || strcmp(fd2devnm(fd), devnm) != 0) { +- if (fd >= 0) +- close(fd); ++ close_fd(&fd); + if (verbose >= 0) + pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n", + devname); +@@ -228,7 +226,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + is_subarray(mdi->text_version)) { + int err; + /* This is mdmon managed. */ +- close(fd); ++ close_fd(&fd); + + /* As we had an O_EXCL open, any use of the device + * which blocks STOP_ARRAY is probably a transient use, +@@ -430,8 +428,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + break; + sysfs_wait(scfd, &delay); + } +- if (scfd >= 0) +- close(scfd); ++ close_fd(&scfd); + + } + done: +@@ -469,6 +466,7 @@ done: + map_unlock(&map); + out: + sysfs_free(mdi); ++ close_fd(&fd); + + return rv; + } +@@ -664,7 +662,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + devname, verbose, 0, NULL); + if (rv == 0) + rv = dev_st->ss->store_super(dev_st, tfd); +- close(tfd); ++ close_fd(&tfd); + if (rv != 0) { + pr_err("failed to update superblock during re-add\n"); + return -1; +@@ -766,15 +764,15 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + rv = MDADM_STATUS_SUCCESS; + + out: +- close(container_fd); ++ close_fd(&container_fd); + dev_policy_free(pols); + + if (sra) + sysfs_free(sra); + +- if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd)) ++ if (rv != MDADM_STATUS_SUCCESS) + /* Metadata handler records this descriptor, so release it only on failure. */ +- close(disk_fd); ++ close_fd(&disk_fd); + + if (st->sb) + st->ss->free_super(st); +@@ -845,10 +843,10 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + continue; + if (tst->ss->load_super(tst, dfd, + NULL)) { +- close(dfd); ++ close_fd(&dfd); + continue; + } +- close(dfd); ++ close_fd(&dfd); + break; + } + /* FIXME this is a bad test to be using */ +@@ -1100,7 +1098,8 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + */ + int ret; + char devnm[32]; +- strcpy(devnm, fd2devnm(fd)); ++ ++ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd)); + lfd = open_dev_excl(devnm); + if (lfd < 0) { + pr_err("Cannot get exclusive access to container - odd\n"); +@@ -1134,13 +1133,13 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + if (ret == 0) { + pr_err("%s is not a member, cannot remove.\n", + dv->devname); +- close(lfd); ++ close_fd(&lfd); + return -1; + } + if (ret >= 2) { + pr_err("%s is still in use, cannot remove.\n", + dv->devname); +- close(lfd); ++ close_fd(&lfd); + return -1; + } + } +@@ -1157,26 +1156,27 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + /* Old kernels rejected this if no personality + * is registered */ + struct mdinfo *sra = sysfs_read(fd, NULL, GET_DEVS); +- struct mdinfo *dv = NULL; +- if (sra) +- dv = sra->devs; +- for ( ; dv ; dv=dv->next) +- if (dv->disk.major == (int)major(rdev) && +- dv->disk.minor == (int)minor(rdev)) +- break; +- if (dv) +- err = sysfs_set_str(sra, dv, +- "state", "remove"); +- else ++ struct mdinfo *dev = NULL; ++ ++ if (!sra) { + err = -1; +- sysfs_free(sra); ++ } else { ++ for (dev = sra->devs; dev ; dev = dev->next) ++ if (dev->disk.major == (int)major(rdev) && ++ dev->disk.minor == (int)minor(rdev)) ++ break; ++ ++ if (dev) ++ err = sysfs_set_str(sra, dev, ++ "state", "remove"); ++ sysfs_free(sra); ++ } + } + } + if (err) { + pr_err("hot remove failed for %s: %s\n", dv->devname, + strerror(errno)); +- if (lfd >= 0) +- close(lfd); ++ close_fd(&lfd); + return -1; + } + if (tst->ss->external) { +@@ -1190,13 +1190,13 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + + if (!devnm) { + pr_err("unable to get container name\n"); ++ close_fd(&lfd); + return -1; + } + + ping_manager(devnm); + } +- if (lfd >= 0) +- close(lfd); ++ close_fd(&lfd); + if (verbose >= 0) + pr_err("hot removed %s from %s\n", + dv->devname, devname); +@@ -1218,7 +1218,7 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv, + if (!mdi || !mdi->devs) { + pr_err("Cannot find status of %s to enable replacement - strange\n", + devname); +- return -1; ++ goto abort; + } + for (di = mdi->devs; di; di = di->next) + if (di->disk.major == (int)major(rdev) && +@@ -1229,16 +1229,14 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv, + if (di->disk.raid_disk < 0) { + pr_err("%s is not active and so cannot be replaced.\n", + dv->devname); +- sysfs_free(mdi); +- return -1; ++ goto abort; + } + rv = sysfs_set_str(mdi, di, + "state", "want_replacement"); + if (rv) { +- sysfs_free(mdi); + pr_err("Failed to request replacement for %s\n", + dv->devname); +- return -1; ++ goto abort; + } + if (verbose >= 0) + pr_err("Marked %s (device %d in %s) for replacement\n", +@@ -1252,11 +1250,13 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv, + dv->disposition = 'w'; + dv->used = di->disk.raid_disk; + } ++ sysfs_free(mdi); + return 1; + } +- sysfs_free(mdi); + pr_err("%s not found in %s so cannot --replace it\n", + dv->devname, devname); ++abort: ++ sysfs_free(mdi); + return -1; + } + +@@ -1269,7 +1269,7 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, + if (!mdi || !mdi->devs) { + pr_err("Cannot find status of %s to enable replacement - strange\n", + devname); +- return -1; ++ goto abort; + } + for (di = mdi->devs; di; di = di->next) + if (di->disk.major == (int)major(rdev) && +@@ -1280,31 +1280,30 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, + if (di->disk.state & (1<devname); +- sysfs_free(mdi); +- return -1; ++ goto abort; + } + if (di->disk.raid_disk >= 0) { + pr_err("%s is active and cannot be a replacement\n", + dv->devname); +- sysfs_free(mdi); +- return -1; ++ goto abort; + } + rv = sysfs_set_num(mdi, di, + "slot", dv->used); + if (rv) { +- sysfs_free(mdi); + pr_err("Failed to set %s as preferred replacement.\n", + dv->devname); +- return -1; ++ goto abort; + } + if (verbose >= 0) + pr_err("Marked %s in %s as replacement for device %d\n", + dv->devname, devname, dv->used); ++ sysfs_free(mdi); + return 1; + } +- sysfs_free(mdi); + pr_err("%s not found in %s so cannot make it preferred replacement\n", + dv->devname, devname); ++abort: ++ sysfs_free(mdi); + return -1; + } + +@@ -1324,6 +1323,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + { + dev_t devid = devnm2devid(devname + 5); + struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE); ++ struct mdinfo *disk; + + if (!mdi) { + if (verbose) +@@ -1333,14 +1333,14 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + + char *avail = xcalloc(array->raid_disks, sizeof(char)); + +- for (mdi = mdi->devs; mdi; mdi = mdi->next) { +- if (mdi->disk.raid_disk < 0) ++ for (disk = mdi->devs; disk; disk = mdi->next) { ++ if (disk->disk.raid_disk < 0) + continue; +- if (!(mdi->disk.state & (1 << MD_DISK_SYNC))) ++ if (!(disk->disk.state & (1 << MD_DISK_SYNC))) + continue; +- if (makedev(mdi->disk.major, mdi->disk.minor) == devid) ++ if (makedev(disk->disk.major, disk->disk.minor) == devid) + continue; +- avail[mdi->disk.raid_disk] = 1; ++ avail[disk->disk.raid_disk] = 1; + } + sysfs_free(mdi); + +@@ -1550,7 +1550,7 @@ int Manage_subdevs(char *devname, int fd, + rdev = makedev(mj,mn); + found = 1; + } +- close(sysfd); ++ close_fd(&sysfd); + sysfd = -1; + } + if (!found) { +@@ -1572,7 +1572,7 @@ int Manage_subdevs(char *devname, int fd, + tfd = dev_open(dv->devname, O_RDONLY); + if (tfd >= 0) { + fstat_is_blkdev(tfd, dv->devname, &rdev); +- close(tfd); ++ close_fd(&tfd); + } else { + int open_err = errno; + if (!stat_is_blkdev(dv->devname, &rdev)) { +@@ -1635,7 +1635,7 @@ int Manage_subdevs(char *devname, int fd, + * need non-exclusive access to add it, so + * do that now. + */ +- close(tfd); ++ close_fd(&tfd); + tfd = dev_open(dv->devname, O_RDONLY); + } + if (tfd < 0) { +@@ -1654,8 +1654,7 @@ int Manage_subdevs(char *devname, int fd, + rv = Manage_add(fd, tfd, dv, tst, &array, + force, verbose, devname, update, + rdev, array_size, raid_slot); +- close(tfd); +- tfd = -1; ++ close_fd(&tfd); + if (rv < 0) + goto abort; + if (rv > 0) +@@ -1672,7 +1671,7 @@ int Manage_subdevs(char *devname, int fd, + rdev, verbose, force, + devname); + if (sysfd >= 0) +- close(sysfd); ++ close_fd(&sysfd); + sysfd = -1; + if (rv < 0) + goto abort; +@@ -1684,8 +1683,7 @@ int Manage_subdevs(char *devname, int fd, + if (!is_remove_safe(&array, fd, dv->devname, verbose)) { + pr_err("Cannot remove %s from %s, array will be failed.\n", + dv->devname, devname); +- if (sysfd >= 0) +- close(sysfd); ++ close_fd(&sysfd); + goto abort; + } + case 'I': /* incremental fail */ +@@ -1696,13 +1694,10 @@ int Manage_subdevs(char *devname, int fd, + busy = 1; + pr_err("set device faulty failed for %s: %s\n", + dv->devname, strerror(errno)); +- if (sysfd >= 0) +- close(sysfd); ++ close_fd(&sysfd); + goto abort; + } +- if (sysfd >= 0) +- close(sysfd); +- sysfd = -1; ++ close_fd(&sysfd); + count++; + if (verbose >= 0) + pr_err("set %s faulty in %s\n", +@@ -1762,7 +1757,7 @@ int autodetect(void) + if (fd >= 0) { + if (ioctl(fd, RAID_AUTORUN, 0) == 0) + rv = 0; +- close(fd); ++ close_fd(&fd); + } + return rv; + } +@@ -1825,7 +1820,7 @@ free_super: + if (info) + free(info); + st->ss->free_super(st); +- close(fd); ++ close_fd(&fd); + + return rv; + } +@@ -1843,10 +1838,8 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + int fd2 = open(from_devname, O_RDONLY); + + if (fd1 < 0 || fd2 < 0) { +- if (fd1 >= 0) +- close(fd1); +- if (fd2 >= 0) +- close(fd2); ++ close_fd(&fd1); ++ close_fd(&fd2); + return 0; + } + +@@ -1865,15 +1858,15 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + /* make sure manager is aware of changes */ + ping_manager(to_devname); + ping_manager(from_devname); +- close(fd1); +- close(fd2); ++ close_fd(&fd1); ++ close_fd(&fd2); + return 1; + } + else + Manage_subdevs(from_devname, fd2, &devlist, + -1, 0, UOPT_UNDEFINED, 0); + } +- close(fd1); +- close(fd2); ++ close_fd(&fd1); ++ close_fd(&fd2); + return 0; + } +-- +2.41.0 + diff --git a/SOURCES/0121-Manage-fix-is_remove_safe.patch b/SOURCES/0121-Manage-fix-is_remove_safe.patch new file mode 100644 index 0000000..d66c542 --- /dev/null +++ b/SOURCES/0121-Manage-fix-is_remove_safe.patch @@ -0,0 +1,29 @@ +From ec72668a9768ad01b409b68f31f3ca7ffeeaab4e Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 16 Jul 2024 15:37:34 +0200 +Subject: [PATCH 121/157] Manage: fix is_remove_safe() + +Fix for to make --set-faulty working. + +Fixes: 1b4b73fd535a ("mdadm: Manage.c fix coverity issues") +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Manage.c b/Manage.c +index aa5e80b2..f0304e1e 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1333,7 +1333,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + + char *avail = xcalloc(array->raid_disks, sizeof(char)); + +- for (disk = mdi->devs; disk; disk = mdi->next) { ++ for (disk = mdi->devs; disk; disk = disk->next) { + if (disk->disk.raid_disk < 0) + continue; + if (!(disk->disk.state & (1 << MD_DISK_SYNC))) +-- +2.41.0 + diff --git a/SOURCES/0122-imsm-add-indent-for-encryption-details.patch b/SOURCES/0122-imsm-add-indent-for-encryption-details.patch new file mode 100644 index 0000000..22e783b --- /dev/null +++ b/SOURCES/0122-imsm-add-indent-for-encryption-details.patch @@ -0,0 +1,28 @@ +From f8274feea5c63300e893109840943513df924da2 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 15 Jul 2024 12:21:19 +0200 +Subject: [PATCH 122/157] imsm: add indent for encryption details + +Improve readability of the output. + +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index ef3f5da1..713bfccf 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2318,7 +2318,7 @@ void print_encryption_information(int disk_fd, enum sys_dev_type hba_type) + { + struct encryption_information information = {0}; + mdadm_status_t status = MDADM_STATUS_SUCCESS; +- const char *indent = " "; ++ const char *indent = " "; + + switch (hba_type) { + case SYS_DEV_VMD: +-- +2.41.0 + diff --git a/SOURCES/0123-mdadm-Monitor.c-fix-coverity-issues.patch b/SOURCES/0123-mdadm-Monitor.c-fix-coverity-issues.patch new file mode 100644 index 0000000..da0ac6b --- /dev/null +++ b/SOURCES/0123-mdadm-Monitor.c-fix-coverity-issues.patch @@ -0,0 +1,67 @@ +From 5cb6df3f190feccc8b3e82da2b01a0e01e612a25 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 15 Jul 2024 10:13:46 -0400 +Subject: [PATCH 123/157] mdadm: Monitor.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event check_return: Calling "fcntl(fd, 2, 1)" without checking +return value. This library function may fail and return an error code. + +* Dereferencing "sl", which is known to be "NULL". + +* Event fixed_size_dest: You might overrun the 32-character fixed-size +string "devnm" by copying "tmp" without checking the length. + +Signed-off-by: Nigel Croxon +--- + Monitor.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 9b016bc3..26c53e13 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -782,7 +782,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (!is_container && !md_array_active(fd)) + goto disappeared; + +- fcntl(fd, F_SETFD, FD_CLOEXEC); ++ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) ++ goto out; ++ + if (md_get_array_info(fd, &array) < 0) + goto disappeared; + +@@ -997,7 +999,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + snprintf(st->parent_devnm, MD_NAME_MAX, + "%s", mse->metadata_version + 10); + sl = strchr(st->parent_devnm, '/'); +- *sl = 0; ++ if (sl) ++ *sl = 0; + } else + st->parent_devnm[0] = 0; + *statelist = st; +@@ -1261,7 +1264,7 @@ int Wait(char *dev) + return 2; + } + +- strcpy(devnm, tmp); ++ snprintf(devnm, sizeof(devnm), "%s", tmp); + + while(1) { + struct mdstat_ent *ms = mdstat_read(1, 0); +@@ -1332,7 +1335,8 @@ int WaitClean(char *dev, int verbose) + return 1; + } + +- strcpy(devnm, fd2devnm(fd)); ++ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd)); ++ + mdi = sysfs_read(fd, devnm, GET_VERSION|GET_LEVEL|GET_SAFEMODE); + if (!mdi) { + if (verbose) +-- +2.41.0 + diff --git a/SOURCES/0124-mdadm-Query.c-fix-coverity-issues.patch b/SOURCES/0124-mdadm-Query.c-fix-coverity-issues.patch new file mode 100644 index 0000000..57b7079 --- /dev/null +++ b/SOURCES/0124-mdadm-Query.c-fix-coverity-issues.patch @@ -0,0 +1,42 @@ +From bcc3ab1728da61e5519e1f01597c8da0c5bc769b Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 16 Jul 2024 07:19:34 -0400 +Subject: [PATCH 124/157] mdadm: Query.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event leaked_storage: Variable "sra" going out of scope leaks the +storage it points to. + +* Event uninit_use_in_call: Using uninitialized value "larray_size" when +calling "human_size_brief". + +Signed-off-by: Nigel Croxon +--- + Query.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Query.c b/Query.c +index adcd231e..aedb4ce7 100644 +--- a/Query.c ++++ b/Query.c +@@ -39,7 +39,7 @@ int Query(char *dev) + struct mdinfo info; + struct mdinfo *sra; + struct supertype *st = NULL; +- unsigned long long larray_size; ++ unsigned long long larray_size = 0; + struct stat stb; + char *mddev; + mdu_disk_info_t disc; +@@ -136,5 +136,7 @@ int Query(char *dev) + if (st->ss == &super0) + put_md_name(mddev); + } ++ free(sra); ++ + return 0; + } +-- +2.41.0 + diff --git a/SOURCES/0125-mdadm-lib.c-fix-coverity-issues.patch b/SOURCES/0125-mdadm-lib.c-fix-coverity-issues.patch new file mode 100644 index 0000000..a31b904 --- /dev/null +++ b/SOURCES/0125-mdadm-lib.c-fix-coverity-issues.patch @@ -0,0 +1,43 @@ +From da7aecdf25371e1476da4ec56e9ec5ddf13af5da Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 16 Jul 2024 07:20:10 -0400 +Subject: [PATCH 125/157] mdadm: lib.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event fixed_size_dest: You might overrun the 32-character fixed-size +string "devnm" by copying "cp + 1" without checking the length. + +* Event fixed_size_dest: You might overrun the 32-character fixed-size +string "devnm" by copying "cp" without checking the length. + +Signed-off-by: Nigel Croxon +--- + lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib.c b/lib.c +index 2b09293c..13d4e4f1 100644 +--- a/lib.c ++++ b/lib.c +@@ -109,7 +109,7 @@ char *devid2kname(dev_t devid) + link[n] = 0; + cp = strrchr(link, '/'); + if (cp) { +- strcpy(devnm, cp + 1); ++ snprintf(devnm, sizeof(devnm), "%s", cp + 1); + return devnm; + } + } +@@ -159,7 +159,7 @@ char *devid2devnm(dev_t devid) + ep = strchr(cp, '/'); + if (ep) + *ep = 0; +- strcpy(devnm, cp); ++ snprintf(devnm, sizeof(devnm), "%s", cp); + return devnm; + } + } +-- +2.41.0 + diff --git a/SOURCES/0126-mdadm-do-not-allow-leading-dot-in-MD-device-name.patch b/SOURCES/0126-mdadm-do-not-allow-leading-dot-in-MD-device-name.patch new file mode 100644 index 0000000..1fa0e52 --- /dev/null +++ b/SOURCES/0126-mdadm-do-not-allow-leading-dot-in-MD-device-name.patch @@ -0,0 +1,158 @@ +From 998544c198c156db027a6e4f1b201910b138041e Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 15 Jul 2024 12:29:24 +0200 +Subject: [PATCH 126/157] mdadm: do not allow leading dot in MD device name + +Do not allow to use '.' on first place for named MD device. +Having leading dot might be confusing, MD device cannot be hidden. +It also removes possibility to create md device with name '.'. + +Additionally, code optimalizations are done. + +Signed-off-by: Mariusz Tkaczyk +--- + config.c | 75 +++++++++++++++++++++++++++++++------------------------- + 1 file changed, 41 insertions(+), 34 deletions(-) + +diff --git a/config.c b/config.c +index cd2379bd..6ea905f3 100644 +--- a/config.c ++++ b/config.c +@@ -188,8 +188,36 @@ inline void ident_init(struct mddev_ident *ident) + ident->uuid_set = 0; + } + ++/** ident_check_name() - helper function to verify name. ++ * @name: name to check. ++ * @prop_name: the name of the property it is validated against, used for logging. ++ * @cmdline: context dependent actions. ++ * ++ * @name must follow name's criteria, be POSIX compatible and does not have leading dot. ++ */ ++static mdadm_status_t ident_check_name(const char *name, const char *prop_name, const bool cmdline) ++{ ++ if (!is_string_lq(name, MD_NAME_MAX + 1)) { ++ ident_log(prop_name, name, "Too long or empty", cmdline); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if (*name == '.') { ++ /* MD device should not be considered as hidden. */ ++ ident_log(prop_name, name, "Leading dot forbidden", cmdline); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if (!is_name_posix_compatible(name)) { ++ ident_log(prop_name, name, "Not POSIX compatible", cmdline); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ + /** +- * _ident_set_devname()- verify devname and set it in &mddev_ident. ++ * _ident_set_devname() - verify devname and set it in &mddev_ident. + * @ident: pointer to &mddev_ident. + * @devname: devname to be set. + * @cmdline: context dependent actions. If set, ignore keyword is not allowed. +@@ -202,8 +230,7 @@ inline void ident_init(struct mddev_ident *ident) + * /dev/md/{name} + * {name} + * +- * {name} must follow name's criteria and be POSIX compatible. +- * If criteria passed, duplicate memory and set devname in @ident. ++ * If verification passed, duplicate memory and set devname in @ident. + * + * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. + */ +@@ -216,6 +243,7 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname + static const char named_dev_pref[] = DEV_NUM_PREF "_"; + static const int named_dev_pref_size = sizeof(named_dev_pref) - 1; + const char *prop_name = "devname"; ++ mdadm_status_t ret; + const char *name; + + if (ident->devname) { +@@ -242,53 +270,40 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname + else + name = devname; + +- if (is_name_posix_compatible(name) == false) { +- ident_log(prop_name, name, "Not POSIX compatible", cmdline); +- return MDADM_STATUS_ERROR; +- } +- +- if (is_string_lq(name, MD_NAME_MAX + 1) == false) { +- ident_log(prop_name, devname, "Invalid length", cmdline); +- return MDADM_STATUS_ERROR; +- } ++ ret = ident_check_name(name, prop_name, cmdline); ++ if (ret) ++ return ret; + pass: + ident->devname = xstrdup(devname); + return MDADM_STATUS_SUCCESS; + } + + /** +- * _ident_set_name()- set name in &mddev_ident. ++ * _ident_set_name() - set name in &mddev_ident. + * @ident: pointer to &mddev_ident. + * @name: name to be set. +- * @cmdline: context dependent actions. + * + * If criteria passed, set name in @ident. + * Note: name is not used by config file, it for cmdline only. + * + * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. + */ +-static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *name, +- const bool cmdline) ++mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name) + { + assert(name); + assert(ident); + + const char *prop_name = "name"; ++ mdadm_status_t ret; + + if (ident->name[0]) { +- ident_log(prop_name, name, "Already defined", cmdline); ++ ident_log(prop_name, name, "Already defined", true); + return MDADM_STATUS_ERROR; + } + +- if (is_string_lq(name, MD_NAME_MAX + 1) == false) { +- ident_log(prop_name, name, "Too long or empty", cmdline); +- return MDADM_STATUS_ERROR; +- } +- +- if (is_name_posix_compatible(name) == false) { +- ident_log(prop_name, name, "Not POSIX compatible", cmdline); +- return MDADM_STATUS_ERROR; +- } ++ ret = ident_check_name(name, prop_name, true); ++ if (ret) ++ return ret; + + snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); + return MDADM_STATUS_SUCCESS; +@@ -302,14 +317,6 @@ mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *name) + return _ident_set_devname(ident, name, true); + } + +-/** +- * ident_set_name()- exported, for cmdline. +- */ +-mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name) +-{ +- return _ident_set_name(ident, name, true); +-} +- + struct conf_dev { + struct conf_dev *next; + char *name; +-- +2.41.0 + diff --git a/SOURCES/0128-Detail-fix-detail-export-for-uuid_zero.patch b/SOURCES/0128-Detail-fix-detail-export-for-uuid_zero.patch new file mode 100644 index 0000000..3c3ae7f --- /dev/null +++ b/SOURCES/0128-Detail-fix-detail-export-for-uuid_zero.patch @@ -0,0 +1,36 @@ +From 5be749ce416852e7acbb2415be380be358859612 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 23 Jul 2024 15:38:41 +0200 +Subject: [PATCH 128/157] Detail: fix --detail --export for uuid_zero + +Mentioned commit (see Fixes) causes that devices with UUID +equal to uuid_zero was not recognized properly. For few devices +the first one was taken always, and the same information was +printed. It caused regression, when few containers were created, +symlinks were generated only for the first one. + +Add checking if uuid is uuid_zero and, if yes, use devname to +differentiate devices. + +Fixes: 60c19530dd7c ("Detail: remove duplicated code") +Signed-off-by: Kinga Stefaniuk +--- + Detail.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Detail.c b/Detail.c +index 55a086d3..f8b9e847 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -274,7 +274,7 @@ int Detail(char *dev, struct context *c) + array.minor_version); + } + +- if (info) ++ if (info && memcmp(info->uuid, uuid_zero, sizeof(int[4])) != 0) + mp = map_by_uuid(&map, info->uuid); + if (!mp) + mp = map_by_devnm(&map, fd2devnm(fd)); +-- +2.41.0 + diff --git a/SOURCES/0129-drive_encryption-Fix-ata-passthrough12-verify.patch b/SOURCES/0129-drive_encryption-Fix-ata-passthrough12-verify.patch new file mode 100644 index 0000000..1427a93 --- /dev/null +++ b/SOURCES/0129-drive_encryption-Fix-ata-passthrough12-verify.patch @@ -0,0 +1,84 @@ +From 2bb4efb504d0991eaba755242d3e70facb5d994b Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Tue, 23 Jul 2024 12:45:10 +0200 +Subject: [PATCH 129/157] drive_encryption: Fix ata passthrough12 verify + +Based on documentation SCSI Primary Commands - 4 (SPC-4) only first 7 bits +of first byte in sense data are used to store response code. The current +verification uses all 8 bits for comparison of response code. + +Incorrect verification may make impossible to use SATA disks with IMSM, +because IMSM requires verification of the encryption state before use. + +There was issue in kernel libata [1]. This issue hides bug in mdadm because +last bit was not set. + +Example output with affected mdadm: + + Port3 : /dev/sde (BTPR212503EK120LGN) +mdadm: Failed ata passthrough12 ioctl. Device: /dev/sde. +mdadm: Failed to get drive encryption information + +The fix is use the first 7 bits of Byte 0, to compare with the expected +values. + +[1] https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux.git/commit/?id=38dab832c3f4 + +Fixes: df38df3052c3 ("Add reading SATA encryption information") +Signed-off-by: Blazej Kucman +--- + drive_encryption.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drive_encryption.c b/drive_encryption.c +index a4ad799f..63bdab1a 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -65,6 +65,7 @@ + #define SENSE_DATA_CURRENT_FIXED (0x70) + #define SENSE_DATA_CURRENT_DESC (0x72) + #define SENSE_CURRENT_RES_DESC_POS (8) ++#define SENSE_RESPONSE_CODE_MASK (0x7f) + #define SG_DRIVER_SENSE (0x08) + + typedef enum drive_feature_support_status { +@@ -473,6 +474,7 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1 + { + __u8 cdb[ATA_INQUIRY_LENGTH] = {0}; + __u8 sense[SG_SENSE_SIZE] = {0}; ++ __u8 sense_response_code; + __u8 *sense_desc = NULL; + sg_io_hdr_t sg = {0}; + +@@ -517,15 +519,17 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1 + return MDADM_STATUS_ERROR; + } + ++ sense_response_code = sense[0] & SENSE_RESPONSE_CODE_MASK; + /* verify expected sense response code */ +- if (!(sense[0] == SENSE_DATA_CURRENT_DESC || sense[0] == SENSE_DATA_CURRENT_FIXED)) { ++ if (!(sense_response_code == SENSE_DATA_CURRENT_DESC || ++ sense_response_code == SENSE_DATA_CURRENT_FIXED)) { + pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); + return MDADM_STATUS_ERROR; + } + + sense_desc = sense + SENSE_CURRENT_RES_DESC_POS; + /* verify sense data current response with descriptor format */ +- if (sense[0] == SENSE_DATA_CURRENT_DESC && ++ if (sense_response_code == SENSE_DATA_CURRENT_DESC && + !(sense_desc[0] == ATA_STATUS_RETURN_DESCRIPTOR && + sense_desc[1] == ATA_INQUIRY_LENGTH)) { + pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", +@@ -534,7 +538,7 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1 + } + + /* verify sense data current response with fixed format */ +- if (sense[0] == SENSE_DATA_CURRENT_FIXED && ++ if (sense_response_code == SENSE_DATA_CURRENT_FIXED && + !(sense[12] == ATA_PT_INFORMATION_AVAILABLE_ASC && + sense[13] == ATA_PT_INFORMATION_AVAILABLE_ASCQ)) { + pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", +-- +2.41.0 + diff --git a/SOURCES/0130-super0-use-define-for-char-array-in-examine_super0.patch b/SOURCES/0130-super0-use-define-for-char-array-in-examine_super0.patch new file mode 100644 index 0000000..639a401 --- /dev/null +++ b/SOURCES/0130-super0-use-define-for-char-array-in-examine_super0.patch @@ -0,0 +1,46 @@ +From 0af8c9ebf50b68ad5f80efad7e94688235544a3d Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Thu, 4 Jul 2024 14:53:35 +0200 +Subject: [PATCH 130/157] super0: use define for char array in examine_super0 + +Using nb with 11 length may cause format-truncation errors, +because it was possible to use snprintf with 12 length input +and write it to 11 length output. Added new define and use it +to avoid this error. + +Signed-off-by: Kinga Stefaniuk +--- + mdadm.h | 3 +++ + super0.c | 2 +- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/mdadm.h b/mdadm.h +index 27009154..22d5e8f4 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -2021,6 +2021,9 @@ enum r0layout { + #define PATH_MAX 4096 + #endif + ++/* The max string length necessary for decimal conversion, cannot be longer than count of bits */ ++#define INT_2_DEC_STR_MAX (sizeof(int) * 8) ++ + #define RESYNC_NONE -1 + #define RESYNC_DELAYED -2 + #define RESYNC_PENDING -3 +diff --git a/super0.c b/super0.c +index 9b8a1bd6..9b4e187e 100644 +--- a/super0.c ++++ b/super0.c +@@ -229,7 +229,7 @@ static void examine_super0(struct supertype *st, char *homehost) + d++) { + mdp_disk_t *dp; + char *dv; +- char nb[11]; ++ char nb[INT_2_DEC_STR_MAX]; + int wonly, failfast; + if (d>=0) dp = &sb->disks[d]; + else dp = &sb->this_disk; +-- +2.41.0 + diff --git a/SOURCES/0131-Makefile-add-more-compiler-flags.patch b/SOURCES/0131-Makefile-add-more-compiler-flags.patch new file mode 100644 index 0000000..81157ab --- /dev/null +++ b/SOURCES/0131-Makefile-add-more-compiler-flags.patch @@ -0,0 +1,61 @@ +From 93c5215677a71e9772f68a449533cb3c97d2b869 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Thu, 4 Jul 2024 15:01:06 +0200 +Subject: [PATCH 131/157] Makefile: add more compiler flags + +It is essential to avoid vulnerabilities in code as much +as possible using safe compilation flags. It is easier if +they are added to the Makefile and applied during compilation. +Add new gcc flags and make them configurable, because they +may not be supported for some compilers. +Set FORTIFY_SOURCE with the highest supported value for platform. + +Signed-off-by: Kinga Stefaniuk +--- + Makefile | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 3fe0a053..a914b178 100644 +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,7 @@ + + # define "CXFLAGS" to give extra flags to CC. + # e.g. make CXFLAGS=-O to optimise +-CXFLAGS ?=-O2 -D_FORTIFY_SOURCE=2 ++CXFLAGS ?=-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE + TCC = tcc + UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found ) + #DIET_GCC = diet gcc +@@ -76,6 +76,27 @@ ifeq ($(origin STRINGOPOVERFLOW), undefined) + endif + endif + ++ifeq ($(origin NOSTRICTOVERFLOW), undefined) ++ NOSTRICTOVERFLOW := $(shell $(CC) -Q --help=warning 2>&1 | grep "strict-overflow" | wc -l) ++ ifneq "$(NOSTRICTOVERFLOW)" "0" ++ CWFLAGS += -fno-strict-overflow ++ endif ++endif ++ ++ifeq ($(origin NODELETENULLPOINTER), undefined) ++ NODELETENULLPOINTER := $(shell $(CC) -Q --help=optimizers 2>&1 | grep "delete-null-pointer-checks" | wc -l) ++ ifneq "$(NODELETENULLPOINTER)" "0" ++ CWFLAGS += -fno-delete-null-pointer-checks ++ endif ++endif ++ ++ifeq ($(origin WRAPV), undefined) ++ WRAPV := $(shell $(CC) -Q --help=optimizers 2>&1 | grep "wrapv" | wc -l) ++ ifneq "$(WRAPV)" "0" ++ CWFLAGS += -fwrapv ++ endif ++endif ++ + ifdef DEBIAN + CPPFLAGS += -DDEBIAN + endif +-- +2.41.0 + diff --git a/SOURCES/0133-mdstat-Rework-mdstat-external-arrays-handling.patch b/SOURCES/0133-mdstat-Rework-mdstat-external-arrays-handling.patch new file mode 100644 index 0000000..c87f869 --- /dev/null +++ b/SOURCES/0133-mdstat-Rework-mdstat-external-arrays-handling.patch @@ -0,0 +1,575 @@ +From 4b3644ab4ce6df8c7f64c189c12b66627ff3e027 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 5 Jul 2024 10:49:27 +0200 +Subject: [PATCH 133/157] mdstat: Rework mdstat external arrays handling + +To avoid repeating mdstat_read() in IncrementalRemove(), new function +mdstat_find_by_member_name() has been proposed. With that, +IncrementalRemove() handles own copy of mdstat content and there is no +need to repeat reading for external stop. + +Additionally, It proposed few helper to avoid repeating +mdstat_ent->metadata_version checks across code. + +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 9 ++-- + Incremental.c | 37 +++++++++------ + Manage.c | 6 +-- + Monitor.c | 18 +++---- + config.c | 49 ++++++++++--------- + mapfile.c | 12 ++--- + mdadm.h | 6 ++- + mdmon.c | 4 +- + mdmon.h | 2 +- + mdstat.c | 129 ++++++++++++++++++++++++++++++++++++-------------- + super-intel.c | 9 ++-- + util.c | 10 ---- + 12 files changed, 167 insertions(+), 124 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 77f2b50e..a2bb7b64 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -114,14 +114,11 @@ static int is_member_busy(char *metadata_version) + int busy = 0; + + for (ent = mdstat; ent; ent = ent->next) { +- if (ent->metadata_version == NULL) +- continue; +- if (strncmp(ent->metadata_version, "external:", 9) != 0) +- continue; +- if (!is_subarray(&ent->metadata_version[9])) ++ if (!is_mdstat_ent_subarray(ent)) + continue; ++ + /* Skip first char - it can be '/' or '-' */ +- if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) { ++ if (strcmp(&ent->metadata_version[10], metadata_version + 1) == 0) { + busy = 1; + break; + } +diff --git a/Incremental.c b/Incremental.c +index 83db0712..abc7721b 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1686,12 +1686,13 @@ static void remove_from_member_array(struct mdstat_ent *memb, + */ + int IncrementalRemove(char *devname, char *id_path, int verbose) + { +- int mdfd; +- int rv = 0; +- struct mdstat_ent *ent; ++ struct mdstat_ent *ent = NULL; ++ char buf[SYSFS_MAX_BUF_SIZE]; ++ struct mdstat_ent *mdstat; + struct mddev_dev devlist; + struct mdinfo mdi; +- char buf[SYSFS_MAX_BUF_SIZE]; ++ int rv = 1; ++ int mdfd; + + if (!id_path) + dprintf("incremental removal without --path lacks the possibility to re-add new device in this port\n"); +@@ -1700,16 +1701,25 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + pr_err("incremental removal requires a kernel device name, not a file: %s\n", devname); + return 1; + } +- ent = mdstat_by_component(devname); ++ ++ mdstat = mdstat_read(0, 0); ++ if (!mdstat) { ++ pr_err("Cannot read /proc/mdstat file, aborting\n"); ++ return 1; ++ } ++ ++ ent = mdstat_find_by_member_name(mdstat, devname); + if (!ent) { + if (verbose >= 0) + pr_err("%s does not appear to be a component of any array\n", devname); +- return 1; ++ goto out; + } ++ + if (sysfs_init(&mdi, -1, ent->devnm)) { + pr_err("unable to initialize sysfs for: %s\n", devname); +- return 1; ++ goto out; + } ++ + mdfd = open_dev_excl(ent->devnm); + if (is_fd_valid(mdfd)) { + close_fd(&mdfd); +@@ -1725,8 +1735,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + if (mdfd < 0) { + if (verbose >= 0) + pr_err("Cannot open array %s!!\n", ent->devnm); +- free_mdstat(ent); +- return 1; ++ goto out; + } + + if (id_path) { +@@ -1741,16 +1750,13 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + devlist.devname = devname; + devlist.disposition = 'I'; + /* for a container, we must fail each member array */ +- if (ent->metadata_version && +- strncmp(ent->metadata_version, "external:", 9) == 0) { +- struct mdstat_ent *mdstat = mdstat_read(0, 0); ++ if (is_mdstat_ent_external(ent)) { + struct mdstat_ent *memb; + for (memb = mdstat ; memb ; memb = memb->next) { + if (is_container_member(memb, ent->devnm)) + remove_from_member_array(memb, + &devlist, verbose); + } +- free_mdstat(mdstat); + } else { + /* + * This 'I' incremental remove is a try-best effort, +@@ -1765,7 +1771,8 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + rv = Manage_subdevs(ent->devnm, mdfd, &devlist, + verbose, 0, UOPT_UNDEFINED, 0); + +- close(mdfd); +- free_mdstat(ent); ++ close_fd(&mdfd); ++out: ++ free_mdstat(mdstat); + return rv; + } +diff --git a/Manage.c b/Manage.c +index f0304e1e..241de055 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -276,10 +276,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + */ + mds = mdstat_read(0, 0); + for (m = mds; m; m = m->next) +- if (m->metadata_version && +- strncmp(m->metadata_version, "external:", 9)==0 && +- metadata_container_matches(m->metadata_version+9, +- devnm)) { ++ if (is_mdstat_ent_external(m) && ++ metadata_container_matches(m->metadata_version + 9, devnm)) { + if (verbose >= 0) + pr_err("Cannot stop container %s: member %s still active\n", + devname, m->devnm); +diff --git a/Monitor.c b/Monitor.c +index 26c53e13..cf14fbb3 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -879,9 +879,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + last_disk = i; + +- if (mse->metadata_version && +- strncmp(mse->metadata_version, "external:", 9) == 0 && +- is_subarray(mse->metadata_version+9)) { ++ if (is_mdstat_ent_subarray(mse)) { + char *sl; + snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10); + sl = strchr(st->parent_devnm, '/'); +@@ -991,13 +989,12 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm); + st->percent = RESYNC_UNKNOWN; + st->expected_spares = -1; +- if (mse->metadata_version && +- strncmp(mse->metadata_version, +- "external:", 9) == 0 && +- is_subarray(mse->metadata_version+9)) { ++ ++ if (is_mdstat_ent_subarray(mse)) { + char *sl; +- snprintf(st->parent_devnm, MD_NAME_MAX, +- "%s", mse->metadata_version + 10); ++ ++ snprintf(st->parent_devnm, MD_NAME_MAX, "%s", ++ mse->metadata_version + 10); + sl = strchr(st->parent_devnm, '/'); + if (sl) + *sl = 0; +@@ -1297,8 +1294,7 @@ int Wait(char *dev) + } + } + if (!e || e->percent == RESYNC_NONE) { +- if (e && e->metadata_version && +- strncmp(e->metadata_version, "external:", 9) == 0) { ++ if (e && is_mdstat_ent_external(e)) { + if (is_subarray(&e->metadata_version[9])) + ping_monitor(&e->metadata_version[9]); + else +diff --git a/config.c b/config.c +index 6ea905f3..5411a480 100644 +--- a/config.c ++++ b/config.c +@@ -360,35 +360,38 @@ struct mddev_dev *load_partitions(void) + struct mddev_dev *load_containers(void) + { + struct mdstat_ent *mdstat = mdstat_read(0, 0); ++ struct mddev_dev *dev_list = NULL; ++ struct map_ent *map_list = NULL; + struct mdstat_ent *ent; +- struct mddev_dev *d; +- struct mddev_dev *rv = NULL; +- struct map_ent *map = NULL, *me; + +- if (!mdstat) +- return NULL; ++ for (ent = mdstat; ent; ent = ent->next) { ++ struct mddev_dev *d; ++ struct map_ent *map; + +- for (ent = mdstat; ent; ent = ent->next) +- if (ent->metadata_version && +- strncmp(ent->metadata_version, "external:", 9) == 0 && +- !is_subarray(&ent->metadata_version[9])) { +- d = xcalloc(1, sizeof(*d)); +- me = map_by_devnm(&map, ent->devnm); +- if (me) +- d->devname = xstrdup(me->path); +- else if (asprintf(&d->devname, "/dev/%s", ent->devnm) < 0) { +- free(d); +- continue; +- } +- d->next = rv; +- rv = d; +- map_free(map); +- map = NULL; ++ if (!is_mdstat_ent_external(ent)) ++ continue; ++ ++ if (is_mdstat_ent_subarray(ent)) ++ continue; ++ ++ d = xcalloc(1, sizeof(*d)); ++ ++ map = map_by_devnm(&map_list, ent->devnm); ++ if (map) { ++ d->devname = xstrdup(map->path); ++ } else if (asprintf(&d->devname, "/dev/%s", ent->devnm) < 0) { ++ free(d); ++ continue; + } ++ ++ d->next = dev_list; ++ dev_list = d; ++ } ++ + free_mdstat(mdstat); +- map_free(map); ++ map_free(map_list); + +- return rv; ++ return dev_list; + } + + struct createinfo createinfo = { +diff --git a/mapfile.c b/mapfile.c +index ea9837ac..632cf5e8 100644 +--- a/mapfile.c ++++ b/mapfile.c +@@ -339,18 +339,14 @@ struct map_ent *map_by_name(struct map_ent **map, char *name) + */ + static char *get_member_info(struct mdstat_ent *ent) + { ++ char *subarray; + +- if (ent->metadata_version == NULL || +- strncmp(ent->metadata_version, "external:", 9) != 0) ++ if (!is_mdstat_ent_subarray(ent)) + return NULL; + +- if (is_subarray(&ent->metadata_version[9])) { +- char *subarray; ++ subarray = strrchr(ent->metadata_version, '/'); + +- subarray = strrchr(ent->metadata_version, '/'); +- return subarray + 1; +- } +- return NULL; ++ return subarray + 1; + } + + void RebuildMap(void) +diff --git a/mdadm.h b/mdadm.h +index 22d5e8f4..5c3a9836 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -743,8 +743,12 @@ extern int mdstat_wait(int seconds); + extern void mdstat_wait_fd(int fd, const sigset_t *sigmask); + extern int mddev_busy(char *devnm); + extern struct mdstat_ent *mdstat_by_component(char *name); ++extern struct mdstat_ent *mdstat_find_by_member_name(struct mdstat_ent *mdstat, char *member_devnm); + extern struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container); + ++extern bool is_mdstat_ent_external(struct mdstat_ent *ent); ++extern bool is_mdstat_ent_subarray(struct mdstat_ent *ent); ++ + struct map_ent { + struct map_ent *next; + char devnm[32]; +@@ -1771,7 +1775,7 @@ extern int is_mddev(char *dev); + extern int open_container(int fd); + extern int metadata_container_matches(char *metadata, char *devnm); + extern int metadata_subdev_matches(char *metadata, char *devnm); +-extern int is_container_member(struct mdstat_ent *ent, char *devname); ++extern bool is_container_member(struct mdstat_ent *ent, char *devname); + extern int is_subarray_active(char *subarray, char *devname); + extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet); + extern struct superswitch *version_to_superswitch(char *vers); +diff --git a/mdmon.c b/mdmon.c +index 5fdb5cdb..95e350f4 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -394,9 +394,7 @@ int main(int argc, char *argv[]) + /* launch an mdmon instance for each container found */ + mdstat = mdstat_read(0, 0); + for (e = mdstat; e; e = e->next) { +- if (e->metadata_version && +- strncmp(e->metadata_version, "external:", 9) == 0 && +- !is_subarray(&e->metadata_version[9])) { ++ if (is_mdstat_ent_external(e) && !is_mdstat_ent_subarray(e)) { + /* update cmdline so this mdmon instance can be + * distinguished from others in a call to ps(1) + */ +diff --git a/mdmon.h b/mdmon.h +index b3d72ac3..110cbef2 100644 +--- a/mdmon.h ++++ b/mdmon.h +@@ -78,7 +78,7 @@ void do_manager(struct supertype *container); + extern int sigterm; + + int read_dev_state(int fd); +-int is_container_member(struct mdstat_ent *mdstat, char *container); ++bool is_container_member(struct mdstat_ent *mdstat, char *container); + + struct mdstat_ent *mdstat_read(int hold, int start); + +diff --git a/mdstat.c b/mdstat.c +index e233f094..cbbace3d 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -110,6 +110,28 @@ static int add_member_devname(struct dev_member **m, char *name) + return 1; + } + ++/* Detach element from the list, it may modify list_head */ ++static void mdstat_ent_list_detach_element(struct mdstat_ent **list_head, struct mdstat_ent *el) ++{ ++ struct mdstat_ent *ent = *list_head; ++ ++ if (ent == el) { ++ *list_head = ent->next; ++ } else { ++ while (ent) { ++ if (ent->next == el) { ++ ent->next = el->next; ++ break; ++ } ++ } ++ ++ ent = ent->next; ++ } ++ ++ assert(ent); ++ ent->next = NULL; ++} ++ + void free_mdstat(struct mdstat_ent *ms) + { + while (ms) { +@@ -124,6 +146,32 @@ void free_mdstat(struct mdstat_ent *ms) + } + } + ++bool is_mdstat_ent_external(struct mdstat_ent *ent) ++{ ++ if (!ent->metadata_version) ++ return false; ++ ++ if (strncmp(ent->metadata_version, "external:", 9) == 0) ++ return true; ++ return false; ++} ++ ++bool is_mdstat_ent_subarray(struct mdstat_ent *ent) ++{ ++ if (is_mdstat_ent_external(ent) && is_subarray(ent->metadata_version + 9)) ++ return true; ++ return false; ++} ++ ++bool is_container_member(struct mdstat_ent *mdstat, char *container) ++{ ++ if (is_mdstat_ent_external(mdstat) && ++ metadata_container_matches(mdstat->metadata_version + 9, container)) ++ return true; ++ ++ return false; ++} ++ + static int mdstat_fd = -1; + struct mdstat_ent *mdstat_read(int hold, int start) + { +@@ -382,61 +430,70 @@ int mddev_busy(char *devnm) + return me != NULL; + } + +-struct mdstat_ent *mdstat_by_component(char *name) ++/** ++ * mdstat_find_by_member_devnm()- Return first array or external container with member device. ++ * @mdstat: Preloaded mdstat to iterate over. ++ * @member_devnm: devnm of the device to find. ++ * ++ * External subarrays are skipped. ++ */ ++struct mdstat_ent *mdstat_find_by_member_name(struct mdstat_ent *mdstat, char *member_devnm) + { +- struct mdstat_ent *mdstat = mdstat_read(0, 0); ++ struct mdstat_ent *ent; + +- while (mdstat) { +- struct dev_member *m; +- struct mdstat_ent *ent; +- if (mdstat->metadata_version && +- strncmp(mdstat->metadata_version, "external:", 9) == 0 && +- is_subarray(mdstat->metadata_version+9)) +- /* don't return subarrays, only containers */ +- ; +- else for (m = mdstat->members; m; m = m->next) { +- if (strcmp(m->name, name) == 0) { +- free_mdstat(mdstat->next); +- mdstat->next = NULL; +- return mdstat; +- } +- } +- ent = mdstat; +- mdstat = mdstat->next; +- ent->next = NULL; +- free_mdstat(ent); ++ for (ent = mdstat; ent; ent = ent->next) { ++ struct dev_member *member; ++ ++ if (is_mdstat_ent_subarray(ent)) ++ continue; ++ ++ for (member = ent->members; member; member = member->next) ++ if (strcmp(member->name, member_devnm) == 0) ++ return ent; + } ++ + return NULL; + } + ++ ++struct mdstat_ent *mdstat_by_component(char *name) ++{ ++ struct mdstat_ent *mdstat = mdstat_read(0, 0); ++ struct mdstat_ent *ent = mdstat_find_by_member_name(mdstat, name); ++ ++ if (ent) ++ mdstat_ent_list_detach_element(&mdstat, ent); ++ ++ free_mdstat(mdstat); ++ ++ return ent; ++} ++ + struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container) + { + struct mdstat_ent *mdstat = mdstat_read(0, 0); + struct mdstat_ent *ent = NULL; + +- while (mdstat) { ++ for (ent = mdstat; ent; ent = ent->next) { + /* metadata version must match: + * external:[/-]%s/%s + * where first %s is 'container' and second %s is 'subdev' + */ +- if (ent) +- free_mdstat(ent); +- ent = mdstat; +- mdstat = mdstat->next; +- ent->next = NULL; + +- if (ent->metadata_version == NULL || +- strncmp(ent->metadata_version, "external:", 9) != 0) ++ if (!is_mdstat_ent_external(ent)) + continue; + +- if (!metadata_container_matches(ent->metadata_version+9, +- container) || +- !metadata_subdev_matches(ent->metadata_version+9, +- subdev)) ++ if (!metadata_container_matches(ent->metadata_version + 9, container)) ++ continue; ++ if (!metadata_subdev_matches(ent->metadata_version + 9, subdev)) + continue; + +- free_mdstat(mdstat); +- return ent; ++ break; + } +- return NULL; ++ ++ if (ent) ++ mdstat_ent_list_detach_element(&mdstat, ent); ++ ++ free_mdstat(mdstat); ++ return ent; + } +diff --git a/super-intel.c b/super-intel.c +index 713bfccf..c215b910 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6974,13 +6974,11 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, + int found; + + for (memb = mdstat ; memb ; memb = memb->next) { +- if (memb->metadata_version && +- (strncmp(memb->metadata_version, "external:", 9) == 0) && +- (strcmp(&memb->metadata_version[9], name) == 0) && +- !is_subarray(memb->metadata_version+9) && +- memb->members) { ++ if (is_mdstat_ent_external(memb) && !is_subarray(memb->metadata_version + 9) && ++ strcmp(&memb->metadata_version[9], name) == 0 && memb->members) { + struct dev_member *dev = memb->members; + int fd = -1; ++ + while (dev && !is_fd_valid(fd)) { + char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1); + num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name); +@@ -6998,7 +6996,6 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, + struct mdstat_ent *vol; + for (vol = mdstat ; vol ; vol = vol->next) { + if (vol->active > 0 && +- vol->metadata_version && + is_container_member(vol, memb->devnm)) { + found++; + count++; +diff --git a/util.c b/util.c +index 908f8430..83d42833 100644 +--- a/util.c ++++ b/util.c +@@ -1671,16 +1671,6 @@ int metadata_subdev_matches(char *metadata, char *devnm) + return 0; + } + +-int is_container_member(struct mdstat_ent *mdstat, char *container) +-{ +- if (mdstat->metadata_version == NULL || +- strncmp(mdstat->metadata_version, "external:", 9) != 0 || +- !metadata_container_matches(mdstat->metadata_version+9, container)) +- return 0; +- +- return 1; +-} +- + int is_subarray_active(char *subarray, char *container) + { + struct mdstat_ent *mdstat = mdstat_read(0, 0); +-- +2.41.0 + diff --git a/SOURCES/0134-mdadm-managemon.c-fix-coverity-issues.patch b/SOURCES/0134-mdadm-managemon.c-fix-coverity-issues.patch new file mode 100644 index 0000000..daa2b66 --- /dev/null +++ b/SOURCES/0134-mdadm-managemon.c-fix-coverity-issues.patch @@ -0,0 +1,56 @@ +From 2a4c40766d654dcbf5911d1b7b63bbbe8b2c0128 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Wed, 24 Jul 2024 09:04:08 -0400 +Subject: [PATCH 134/157] mdadm: managemon.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event check_return: Calling "fcntl(fd, 4, fl)" without checking +return value. This library function may fail and return an error code. + +* Event check_after_deref: Null-checking "new" suggests that it may +be null, but it has already been dereferenced on all paths leading +to the check. + +Signed-off-by: Nigel Croxon +--- + managemon.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/managemon.c b/managemon.c +index 358459e7..add6a79e 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -776,10 +776,8 @@ static void manage_new(struct mdstat_ent *mdstat, + + error: + pr_err("failed to monitor %s\n", mdstat->metadata_version); +- if (new) { +- new->container = NULL; +- free_aa(new); +- } ++ new->container = NULL; ++ free_aa(new); + if (mdi) + sysfs_free(mdi); + } +@@ -870,8 +868,15 @@ void read_sock(struct supertype *container) + return; + + fl = fcntl(fd, F_GETFL, 0); ++ if (fl < 0) { ++ close_fd(&fd); ++ return; ++ } + fl |= O_NONBLOCK; +- fcntl(fd, F_SETFL, fl); ++ if (fcntl(fd, F_SETFL, fl) < 0) { ++ close_fd(&fd); ++ return; ++ } + + do { + msg.buf = NULL; +-- +2.41.0 + diff --git a/SOURCES/0135-mdadm-msg.c-fix-coverity-issues.patch b/SOURCES/0135-mdadm-msg.c-fix-coverity-issues.patch new file mode 100644 index 0000000..b34933f --- /dev/null +++ b/SOURCES/0135-mdadm-msg.c-fix-coverity-issues.patch @@ -0,0 +1,40 @@ +From 87f96c870399cd029933a9742ba72e85e3251c3e Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Wed, 24 Jul 2024 09:20:28 -0400 +Subject: [PATCH 135/157] mdadm: msg.c fix coverity issues + +Fixing the following coding errors the coverity tools found: + +* Event check_return: Calling "fcntl(sfd, 4, fl)" without +checking return value. This library function may fail and +return an error code. + +Signed-off-by: Nigel Croxon +--- + msg.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/msg.c b/msg.c +index f0772b3f..b6da91d3 100644 +--- a/msg.c ++++ b/msg.c +@@ -176,8 +176,15 @@ int connect_monitor(char *devname) + } + + fl = fcntl(sfd, F_GETFL, 0); ++ if (fl < 0) { ++ close(sfd); ++ return -1; ++ } + fl |= O_NONBLOCK; +- fcntl(sfd, F_SETFL, fl); ++ if (fcntl(sfd, F_SETFL, fl) < 0) { ++ close(sfd); ++ return -1; ++ } + + return sfd; + } +-- +2.41.0 + diff --git a/SOURCES/0136-imsm-refactor-chunk-size-print.patch b/SOURCES/0136-imsm-refactor-chunk-size-print.patch new file mode 100644 index 0000000..292994d --- /dev/null +++ b/SOURCES/0136-imsm-refactor-chunk-size-print.patch @@ -0,0 +1,150 @@ +From a944180a7e6a7d6d4cd08f6afcb83e58986c35f9 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 24 Jul 2024 22:17:42 +0200 +Subject: [PATCH 136/157] imsm: refactor chunk size print + +- add imsm_chunk_ops struct for better code readability, +- move chunk size mapping to string into array, +- add function to print supported chunk sizes by IMSM controller. + +Signed-off-by: Blazej Kucman +--- + super-intel.c | 92 +++++++++++++++++++++++++++------------------------ + 1 file changed, 49 insertions(+), 43 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index c215b910..ab9b5d3f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -647,6 +647,31 @@ static const char *_sys_dev_type[] = { + [SYS_DEV_SATA_VMD] = "SATA VMD" + }; + ++struct imsm_chunk_ops { ++ uint chunk; ++ char *chunk_str; ++}; ++ ++static const struct imsm_chunk_ops imsm_chunk_ops[] = { ++ {IMSM_OROM_SSS_2kB, "2k"}, ++ {IMSM_OROM_SSS_4kB, "4k"}, ++ {IMSM_OROM_SSS_8kB, "8k"}, ++ {IMSM_OROM_SSS_16kB, "16k"}, ++ {IMSM_OROM_SSS_32kB, "32k"}, ++ {IMSM_OROM_SSS_64kB, "64k"}, ++ {IMSM_OROM_SSS_128kB, "128k"}, ++ {IMSM_OROM_SSS_256kB, "256k"}, ++ {IMSM_OROM_SSS_512kB, "512k"}, ++ {IMSM_OROM_SSS_1MB, "1M"}, ++ {IMSM_OROM_SSS_2MB, "2M"}, ++ {IMSM_OROM_SSS_4MB, "4M"}, ++ {IMSM_OROM_SSS_8MB, "8M"}, ++ {IMSM_OROM_SSS_16MB, "16M"}, ++ {IMSM_OROM_SSS_32MB, "32M"}, ++ {IMSM_OROM_SSS_64MB, "64M"}, ++ {0, NULL} ++}; ++ + static int no_platform = -1; + + static int check_no_platform(void) +@@ -2626,6 +2651,16 @@ static void print_imsm_level_capability(const struct imsm_orom *orom) + printf("%s ", imsm_level_ops[idx].name); + } + ++static void print_imsm_chunk_size_capability(const struct imsm_orom *orom) ++{ ++ int idx; ++ ++ for (idx = 0; imsm_chunk_ops[idx].chunk_str; idx++) ++ if (imsm_chunk_ops[idx].chunk & orom->sss) ++ printf("%s ", imsm_chunk_ops[idx].chunk_str); ++} ++ ++ + static void print_imsm_capability(const struct imsm_orom *orom) + { + printf(" Platform : Intel(R) "); +@@ -2638,41 +2673,25 @@ static void print_imsm_capability(const struct imsm_orom *orom) + imsm_orom_is_enterprise(orom) ? " enterprise" : ""); + if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) { + if (imsm_orom_is_vmd_without_efi(orom)) +- printf(" Version : %d.%d\n", orom->major_ver, +- orom->minor_ver); ++ printf(" Version : %d.%d\n", orom->major_ver, orom->minor_ver); + else +- printf(" Version : %d.%d.%d.%d\n", orom->major_ver, +- orom->minor_ver, orom->hotfix_ver, orom->build); ++ printf(" Version : %d.%d.%d.%d\n", orom->major_ver, orom->minor_ver, ++ orom->hotfix_ver, orom->build); + } + + printf(" RAID Levels : "); + print_imsm_level_capability(orom); + printf("\n"); + +- printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", +- imsm_orom_has_chunk(orom, 2) ? " 2k" : "", +- imsm_orom_has_chunk(orom, 4) ? " 4k" : "", +- imsm_orom_has_chunk(orom, 8) ? " 8k" : "", +- imsm_orom_has_chunk(orom, 16) ? " 16k" : "", +- imsm_orom_has_chunk(orom, 32) ? " 32k" : "", +- imsm_orom_has_chunk(orom, 64) ? " 64k" : "", +- imsm_orom_has_chunk(orom, 128) ? " 128k" : "", +- imsm_orom_has_chunk(orom, 256) ? " 256k" : "", +- imsm_orom_has_chunk(orom, 512) ? " 512k" : "", +- imsm_orom_has_chunk(orom, 1024*1) ? " 1M" : "", +- imsm_orom_has_chunk(orom, 1024*2) ? " 2M" : "", +- imsm_orom_has_chunk(orom, 1024*4) ? " 4M" : "", +- imsm_orom_has_chunk(orom, 1024*8) ? " 8M" : "", +- imsm_orom_has_chunk(orom, 1024*16) ? " 16M" : "", +- imsm_orom_has_chunk(orom, 1024*32) ? " 32M" : "", +- imsm_orom_has_chunk(orom, 1024*64) ? " 64M" : ""); +- printf(" 2TB volumes :%s supported\n", +- (orom->attr & IMSM_OROM_ATTR_2TB)?"":" not"); ++ printf(" Chunk Sizes : "); ++ print_imsm_chunk_size_capability(orom); ++ printf("\n"); ++ ++ printf(" 2TB volumes :%s supported\n", (orom->attr & IMSM_OROM_ATTR_2TB) ? "" : " not"); + printf(" 2TB disks :%s supported\n", +- (orom->attr & IMSM_OROM_ATTR_2TB_DISK)?"":" not"); ++ (orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "" : " not"); + printf(" Max Disks : %d\n", orom->tds); +- printf(" Max Volumes : %d per array, %d per %s\n", +- orom->vpa, orom->vphba, ++ printf(" Max Volumes : %d per array, %d per %s\n", orom->vpa, orom->vphba, + imsm_orom_is_nvme(orom) ? "platform" : "controller"); + return; + } +@@ -2688,23 +2707,10 @@ static void print_imsm_capability_export(const struct imsm_orom *orom) + print_imsm_level_capability(orom); + printf("\n"); + +- printf("IMSM_SUPPORTED_CHUNK_SIZES=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", +- imsm_orom_has_chunk(orom, 2) ? "2k " : "", +- imsm_orom_has_chunk(orom, 4) ? "4k " : "", +- imsm_orom_has_chunk(orom, 8) ? "8k " : "", +- imsm_orom_has_chunk(orom, 16) ? "16k " : "", +- imsm_orom_has_chunk(orom, 32) ? "32k " : "", +- imsm_orom_has_chunk(orom, 64) ? "64k " : "", +- imsm_orom_has_chunk(orom, 128) ? "128k " : "", +- imsm_orom_has_chunk(orom, 256) ? "256k " : "", +- imsm_orom_has_chunk(orom, 512) ? "512k " : "", +- imsm_orom_has_chunk(orom, 1024*1) ? "1M " : "", +- imsm_orom_has_chunk(orom, 1024*2) ? "2M " : "", +- imsm_orom_has_chunk(orom, 1024*4) ? "4M " : "", +- imsm_orom_has_chunk(orom, 1024*8) ? "8M " : "", +- imsm_orom_has_chunk(orom, 1024*16) ? "16M " : "", +- imsm_orom_has_chunk(orom, 1024*32) ? "32M " : "", +- imsm_orom_has_chunk(orom, 1024*64) ? "64M " : ""); ++ printf("IMSM_SUPPORTED_CHUNK_SIZES="); ++ print_imsm_chunk_size_capability(orom); ++ printf("\n"); ++ + printf("IMSM_2TB_VOLUMES=%s\n",(orom->attr & IMSM_OROM_ATTR_2TB) ? "yes" : "no"); + printf("IMSM_2TB_DISKS=%s\n",(orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "yes" : "no"); + printf("IMSM_MAX_DISKS=%d\n",orom->tds); +-- +2.41.0 + diff --git a/SOURCES/0137-mdadm-Grow-fix-coverity-issue-CHECKED_RETURN.patch b/SOURCES/0137-mdadm-Grow-fix-coverity-issue-CHECKED_RETURN.patch new file mode 100644 index 0000000..2992b16 --- /dev/null +++ b/SOURCES/0137-mdadm-Grow-fix-coverity-issue-CHECKED_RETURN.patch @@ -0,0 +1,109 @@ +From e0373b734db511cdfec248ff6d769270ec8fd492 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:03 +0800 +Subject: [PATCH 137/157] mdadm/Grow: fix coverity issue CHECKED_RETURN + +It needs to check return value when functions have return value. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 43 ++++++++++++++++++++++++++++++++++++------- + 1 file changed, 36 insertions(+), 7 deletions(-) + +diff --git a/Grow.c b/Grow.c +index b135930d..7ae967bd 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3261,7 +3261,12 @@ static int reshape_array(char *container, int fd, char *devname, + /* This is a spare that wants to + * be part of the array. + */ +- add_disk(fd, st, info2, d); ++ if (add_disk(fd, st, info2, d) < 0) { ++ pr_err("Can not add disk %s\n", ++ d->sys_name); ++ free(info2); ++ goto release; ++ } + } + } + sysfs_free(info2); +@@ -4413,7 +4418,10 @@ static void validate(int afd, int bfd, unsigned long long offset) + */ + if (afd < 0) + return; +- lseek64(bfd, offset - 4096, 0); ++ if (lseek64(bfd, offset - 4096, 0) < 0) { ++ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno)); ++ return; ++ } + if (read(bfd, &bsb2, 512) != 512) + fail("cannot read bsb"); + if (bsb2.sb_csum != bsb_csum((char*)&bsb2, +@@ -4444,12 +4452,19 @@ static void validate(int afd, int bfd, unsigned long long offset) + } + } + +- lseek64(bfd, offset, 0); ++ if (lseek64(bfd, offset, 0) < 0) { ++ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno)); ++ goto out; ++ } + if ((unsigned long long)read(bfd, bbuf, len) != len) { + //printf("len %llu\n", len); + fail("read first backup failed"); + } +- lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0); ++ ++ if (lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0) < 0) { ++ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno)); ++ goto out; ++ } + if ((unsigned long long)read(afd, abuf, len) != len) + fail("read first from array failed"); + if (memcmp(bbuf, abuf, len) != 0) +@@ -4466,15 +4481,25 @@ static void validate(int afd, int bfd, unsigned long long offset) + bbuf = xmalloc(abuflen); + } + +- lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0); ++ if (lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0) < 0) { ++ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno)); ++ goto out; ++ } + if ((unsigned long long)read(bfd, bbuf, len) != len) + fail("read second backup failed"); +- lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0); ++ if (lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0) < 0) { ++ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno)); ++ goto out; ++ } + if ((unsigned long long)read(afd, abuf, len) != len) + fail("read second from array failed"); + if (memcmp(bbuf, abuf, len) != 0) + fail("data2 compare failed"); + } ++out: ++ free(abuf); ++ free(bbuf); ++ return; + } + + int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape, +@@ -5033,7 +5058,11 @@ int Grow_continue_command(char *devname, int fd, struct context *c) + goto Grow_continue_command_exit; + } + content = &array; +- sysfs_init(content, fd, NULL); ++ if (sysfs_init(content, fd, NULL) < 0) { ++ pr_err("sysfs_init fails\n"); ++ ret_val = 1; ++ goto Grow_continue_command_exit; ++ } + /* Need to load a superblock. + * FIXME we should really get what we need from + * sysfs +-- +2.41.0 + diff --git a/SOURCES/0138-mdadm-Grow-fix-coverity-issue-RESOURCE_LEAK.patch b/SOURCES/0138-mdadm-Grow-fix-coverity-issue-RESOURCE_LEAK.patch new file mode 100644 index 0000000..a43344e --- /dev/null +++ b/SOURCES/0138-mdadm-Grow-fix-coverity-issue-RESOURCE_LEAK.patch @@ -0,0 +1,166 @@ +From 54c09eaa8bc057dfd88ae20d259f88457f67fd1c Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:04 +0800 +Subject: [PATCH 138/157] mdadm/Grow: fix coverity issue RESOURCE_LEAK + +Fix some resource leak problems. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 42 +++++++++++++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 11 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 7ae967bd..907a6e1b 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -530,8 +530,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n"); + pr_err("Cannot set bitmap file for %s: %s\n", + devname, strerror(err)); ++ close_fd(&bitmap_fd); + return 1; + } ++ close_fd(&bitmap_fd); + } + + return 0; +@@ -3083,6 +3085,7 @@ static int reshape_array(char *container, int fd, char *devname, + int done; + struct mdinfo *sra = NULL; + char buf[SYSFS_MAX_BUF_SIZE]; ++ bool located_backup = false; + + /* when reshaping a RAID0, the component_size might be zero. + * So try to fix that up. +@@ -3165,8 +3168,10 @@ static int reshape_array(char *container, int fd, char *devname, + goto release; + } + +- if (!backup_file) ++ if (!backup_file) { + backup_file = locate_backup(sra->sys_name); ++ located_backup = true; ++ } + + goto started; + } +@@ -3612,15 +3617,13 @@ started: + mdstat_wait(30 - (delayed-1) * 25); + } while (delayed); + mdstat_close(); +- if (check_env("MDADM_GROW_VERIFY")) +- fd = open(devname, O_RDONLY | O_DIRECT); +- else +- fd = -1; + mlockall(MCL_FUTURE); + + if (signal_s(SIGTERM, catch_term) == SIG_ERR) + goto release; + ++ if (check_env("MDADM_GROW_VERIFY")) ++ fd = open(devname, O_RDONLY | O_DIRECT); + if (st->ss->external) { + /* metadata handler takes it from here */ + done = st->ss->manage_reshape( +@@ -3632,6 +3635,7 @@ started: + fd, sra, &reshape, st, blocks, fdlist, offsets, + d - odisks, fdlist + odisks, offsets + odisks); + ++ close_fd(&fd); + free(fdlist); + free(offsets); + +@@ -3701,6 +3705,8 @@ out: + exit(0); + + release: ++ if (located_backup) ++ free(backup_file); + free(fdlist); + free(offsets); + if (orig_level != UnSet && sra) { +@@ -3839,6 +3845,7 @@ int reshape_container(char *container, char *devname, + pr_err("Unable to initialize sysfs for %s\n", + mdstat->devnm); + rv = 1; ++ close_fd(&fd); + break; + } + +@@ -4717,6 +4724,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, + unsigned long long *offsets; + unsigned long long nstripe, ostripe; + int ndata, odata; ++ int fd, backup_fd = -1; + + odata = info->array.raid_disks - info->delta_disks - 1; + if (info->array.level == 6) +@@ -4732,9 +4740,18 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, + * been used + */ + old_disks = cnt; ++ ++ if (backup_file) { ++ backup_fd = open(backup_file, O_RDONLY); ++ if (!is_fd_valid(backup_fd)) { ++ pr_err("Can't open backup file %s : %s\n", ++ backup_file, strerror(errno)); ++ return -EINVAL; ++ } ++ } ++ + for (i=old_disks-(backup_file?1:0); iss->store_super(st, fdlist[j]); + st->ss->free_super(st); + } ++ close_fd(&backup_fd); + return 0; + } ++ ++ close_fd(&backup_fd); ++ + /* Didn't find any backup data, try to see if any + * was needed. + */ +-- +2.41.0 + diff --git a/SOURCES/0139-mdadm-Grow-fix-coverity-issue-STRING_OVERFLOW.patch b/SOURCES/0139-mdadm-Grow-fix-coverity-issue-STRING_OVERFLOW.patch new file mode 100644 index 0000000..d5bf8e3 --- /dev/null +++ b/SOURCES/0139-mdadm-Grow-fix-coverity-issue-STRING_OVERFLOW.patch @@ -0,0 +1,29 @@ +From 13c1f4a56b3bedbf802d66e86afd787e318e25fb Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:05 +0800 +Subject: [PATCH 139/157] mdadm/Grow: fix coverity issue STRING_OVERFLOW + +Fix string overflow problems in Grow.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 907a6e1b..a5f9027d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1694,7 +1694,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + /* Current RAID6 layout has a RAID5 + * equivalent - good + */ +- strcat(strcpy(layout, ls), "-6"); ++ snprintf(layout, 40, "%s-6", ls); + l = map_name(r6layout, layout); + if (l == UnSet) + return "Cannot find RAID6 layout to convert to"; +-- +2.41.0 + diff --git a/SOURCES/0140-mdadm-Incremental-fix-coverity-issues.patch b/SOURCES/0140-mdadm-Incremental-fix-coverity-issues.patch new file mode 100644 index 0000000..b308af6 --- /dev/null +++ b/SOURCES/0140-mdadm-Incremental-fix-coverity-issues.patch @@ -0,0 +1,87 @@ +From 17c99bab3e2e3606961d7ecec62c29921b5d6660 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:06 +0800 +Subject: [PATCH 140/157] mdadm/Incremental: fix coverity issues. + +There are two issues PW.PARAMETER_HIDDEN (declaration hides +parameter 'devname') and INTEGER_OVERFLOW. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index abc7721b..fc4e68ff 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -770,7 +770,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra, + replcnt++; + st->ss->free_super(st); + } +- if (max_journal_events >= max_events - 1) ++ if (max_events > 0 && max_journal_events >= max_events - 1) + bestinfo->journal_clean = 1; + + if (!avail) +@@ -1113,7 +1113,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + int fd = -1; + struct mdinfo info; + struct supertype *st2 = NULL; +- char *devname = NULL; ++ char *dev_path_name = NULL; + unsigned long long devsectors; + char *pathlist[2]; + +@@ -1142,14 +1142,14 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + domain_free(domlist); + domlist = NULL; + +- if (asprintf(&devname, "/dev/disk/by-path/%s", de->d_name) != 1) { +- devname = NULL; ++ if (asprintf(&dev_path_name, "/dev/disk/by-path/%s", de->d_name) != 1) { ++ dev_path_name = NULL; + goto next; + } +- fd = open(devname, O_RDONLY); ++ fd = open(dev_path_name, O_RDONLY); + if (fd < 0) + goto next; +- if (get_dev_size(fd, devname, &devsectors) == 0) ++ if (get_dev_size(fd, dev_path_name, &devsectors) == 0) + goto next; + devsectors >>= 9; + +@@ -1188,8 +1188,8 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + if (chosen == NULL || chosen_size < info.component_size) { + chosen_size = info.component_size; + free(chosen); +- chosen = devname; +- devname = NULL; ++ chosen = dev_path_name; ++ dev_path_name = NULL; + if (chosen_st) { + chosen_st->ss->free_super(chosen_st); + free(chosen_st); +@@ -1199,7 +1199,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + } + + next: +- free(devname); ++ free(dev_path_name); + domain_free(domlist); + dev_policy_free(pol2); + if (st2) +@@ -1246,7 +1246,7 @@ static int is_bare(int dfd) + + /* OK, first 4K appear blank, try the end. */ + get_dev_size(dfd, NULL, &size); +- if (lseek(dfd, size-4096, SEEK_SET) < 0 || ++ if ((size >= 4096 && lseek(dfd, size-4096, SEEK_SET) < 0) || + read(dfd, buf, 4096) != 4096) + return 0; + +-- +2.41.0 + diff --git a/SOURCES/0141-mdadm-mdmon-fix-coverity-issue-CHECKED_RETURN.patch b/SOURCES/0141-mdadm-mdmon-fix-coverity-issue-CHECKED_RETURN.patch new file mode 100644 index 0000000..efc7c9d --- /dev/null +++ b/SOURCES/0141-mdadm-mdmon-fix-coverity-issue-CHECKED_RETURN.patch @@ -0,0 +1,46 @@ +From f9949a04355f0fca29c6bc02ead8425e76daa573 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:07 +0800 +Subject: [PATCH 141/157] mdadm/mdmon: fix coverity issue CHECKED_RETURN + +It needs to check return values when functions have return value. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdmon.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 95e350f4..cae63841 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -198,8 +198,12 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) + /* Wait for monitor to exit by reading from the socket, after + * clearing the non-blocking flag */ + fl = fcntl(sock, F_GETFL, 0); ++ if (fl < 0) ++ return; ++ + fl &= ~O_NONBLOCK; +- fcntl(sock, F_SETFL, fl); ++ if (fcntl(sock, F_SETFL, fl) < 0) ++ return; + n = read(sock, buf, 100); + + /* If there is I/O going on it might took some time to get to +@@ -249,7 +253,10 @@ static int make_control_sock(char *devname) + listen(sfd, 10); + fl = fcntl(sfd, F_GETFL, 0); + fl |= O_NONBLOCK; +- fcntl(sfd, F_SETFL, fl); ++ if (fcntl(sfd, F_SETFL, fl) < 0) { ++ close_fd(&sfd); ++ return -1; ++ } + return sfd; + } + +-- +2.41.0 + diff --git a/SOURCES/0142-mdadm-mdmon-fix-coverity-issue-RESOURCE_LEAK.patch b/SOURCES/0142-mdadm-mdmon-fix-coverity-issue-RESOURCE_LEAK.patch new file mode 100644 index 0000000..38ae3d5 --- /dev/null +++ b/SOURCES/0142-mdadm-mdmon-fix-coverity-issue-RESOURCE_LEAK.patch @@ -0,0 +1,49 @@ +From e7623d5ae4724c72e873e8af17f2ed6bfdc54427 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:08 +0800 +Subject: [PATCH 142/157] mdadm/mdmon: fix coverity issue RESOURCE_LEAK + +Fix resource leak problem in mdmon.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdmon.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index cae63841..6e28b56e 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -456,22 +456,25 @@ static int mdmon(char *devnm, int must_fork, int takeover) + if (must_fork) { + if (pipe(pfd) != 0) { + pr_err("failed to create pipe\n"); ++ close_fd(&mdfd); + return 1; + } + switch(fork()) { + case -1: + pr_err("failed to fork: %s\n", strerror(errno)); ++ close_fd(&mdfd); + return 1; + case 0: /* child */ +- close(pfd[0]); ++ close_fd(&pfd[0]); + break; + default: /* parent */ +- close(pfd[1]); ++ close_fd(&pfd[1]); + if (read(pfd[0], &status, sizeof(status)) != sizeof(status)) { + wait(&status); + status = WEXITSTATUS(status); + } +- close(pfd[0]); ++ close_fd(&pfd[0]); ++ close_fd(&mdfd); + return status; + } + } else +-- +2.41.0 + diff --git a/SOURCES/0143-mdadm-mdopen-fix-coverity-issue-CHECKED_RETURN.patch b/SOURCES/0143-mdadm-mdopen-fix-coverity-issue-CHECKED_RETURN.patch new file mode 100644 index 0000000..5786c84 --- /dev/null +++ b/SOURCES/0143-mdadm-mdopen-fix-coverity-issue-CHECKED_RETURN.patch @@ -0,0 +1,33 @@ +From f34040081c36ff92180674b89c39ddc7bdd47288 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:09 +0800 +Subject: [PATCH 143/157] mdadm/mdopen: fix coverity issue CHECKED_RETURN + +It needs to check return values when functions return value. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdopen.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/mdopen.c b/mdopen.c +index eaa59b59..c9fda131 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -406,7 +406,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + perror("chown"); + if (chmod(devname, ci->mode)) + perror("chmod"); +- stat(devname, &stb); ++ if (stat(devname, &stb) < 0) { ++ pr_err("failed to stat %s\n", ++ devname); ++ return -1; ++ } + add_dev(devname, &stb, 0, NULL); + } + if (use_mdp == 1) +-- +2.41.0 + diff --git a/SOURCES/0144-mdadm-mdopen-fix-coverity-issue-STRING_OVERFLOW.patch b/SOURCES/0144-mdadm-mdopen-fix-coverity-issue-STRING_OVERFLOW.patch new file mode 100644 index 0000000..7e3e410 --- /dev/null +++ b/SOURCES/0144-mdadm-mdopen-fix-coverity-issue-STRING_OVERFLOW.patch @@ -0,0 +1,29 @@ +From debf421db02c85f176b5eda2e8dcc9d17d89623c Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:10 +0800 +Subject: [PATCH 144/157] mdadm/mdopen: fix coverity issue STRING_OVERFLOW + +Fix string overflow problems in mdopen.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdopen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdopen.c b/mdopen.c +index c9fda131..e49defb6 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -376,7 +376,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + + sprintf(devname, "/dev/%s", devnm); + +- if (dev && dev[0] == '/') ++ if (dev && dev[0] == '/' && strlen(dev) < 400) + strcpy(chosen, dev); + else if (cname[0] == 0) + strcpy(chosen, devname); +-- +2.41.0 + diff --git a/SOURCES/0145-mdadm-mdstat-fix-coverity-issue-CHECKED_RETURN.patch b/SOURCES/0145-mdadm-mdstat-fix-coverity-issue-CHECKED_RETURN.patch new file mode 100644 index 0000000..fd7f863 --- /dev/null +++ b/SOURCES/0145-mdadm-mdstat-fix-coverity-issue-CHECKED_RETURN.patch @@ -0,0 +1,46 @@ +From 6984814b6fd879efae178acb057c1025aa4c64e8 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:11 +0800 +Subject: [PATCH 145/157] mdadm/mdstat: fix coverity issue CHECKED_RETURN + +It needs to check return values when functions return value. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + mdstat.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/mdstat.c b/mdstat.c +index cbbace3d..a971a957 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -194,8 +194,11 @@ struct mdstat_ent *mdstat_read(int hold, int start) + f = fopen("/proc/mdstat", "r"); + if (f == NULL) + return NULL; +- else +- fcntl(fileno(f), F_SETFD, FD_CLOEXEC); ++ ++ if (fcntl(fileno(f), F_SETFD, FD_CLOEXEC) < 0) { ++ fclose(f); ++ return NULL; ++ } + + all = NULL; + end = &all; +@@ -329,7 +332,10 @@ struct mdstat_ent *mdstat_read(int hold, int start) + } + if (hold && mdstat_fd == -1) { + mdstat_fd = dup(fileno(f)); +- fcntl(mdstat_fd, F_SETFD, FD_CLOEXEC); ++ if (fcntl(mdstat_fd, F_SETFD, FD_CLOEXEC) < 0) { ++ fclose(f); ++ return NULL; ++ } + } + fclose(f); + +-- +2.41.0 + diff --git a/SOURCES/0146-mdadm-super0-fix-coverity-issue-CHECKED_RETURN-and-E.patch b/SOURCES/0146-mdadm-super0-fix-coverity-issue-CHECKED_RETURN-and-E.patch new file mode 100644 index 0000000..b10b123 --- /dev/null +++ b/SOURCES/0146-mdadm-super0-fix-coverity-issue-CHECKED_RETURN-and-E.patch @@ -0,0 +1,56 @@ +From e055d9236a7d0dca2a311e8bb8013018dc571d6a Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:12 +0800 +Subject: [PATCH 146/157] mdadm/super0: fix coverity issue CHECKED_RETURN and + EVALUATION_ORDER + +Fix coverity problems in super0. It needs to check return value when +functions return value. And fix EVALUATION_ORDER problems in super0.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + super0.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/super0.c b/super0.c +index 9b4e187e..c428e2a6 100644 +--- a/super0.c ++++ b/super0.c +@@ -83,6 +83,9 @@ static void examine_super0(struct supertype *st, char *homehost) + int d; + int delta_extra = 0; + char *c; ++ unsigned long expected_csum = 0; ++ ++ expected_csum = calc_sb0_csum(sb); + + printf(" Magic : %08x\n", sb->md_magic); + printf(" Version : %d.%02d.%02d\n", +@@ -187,11 +190,11 @@ static void examine_super0(struct supertype *st, char *homehost) + printf("Working Devices : %d\n", sb->working_disks); + printf(" Failed Devices : %d\n", sb->failed_disks); + printf(" Spare Devices : %d\n", sb->spare_disks); +- if (calc_sb0_csum(sb) == sb->sb_csum) ++ if (expected_csum == sb->sb_csum) + printf(" Checksum : %x - correct\n", sb->sb_csum); + else + printf(" Checksum : %x - expected %lx\n", +- sb->sb_csum, calc_sb0_csum(sb)); ++ sb->sb_csum, expected_csum); + printf(" Events : %llu\n", + ((unsigned long long)sb->events_hi << 32) + sb->events_lo); + printf("\n"); +@@ -1212,7 +1215,8 @@ static int locate_bitmap0(struct supertype *st, int fd, int node_num) + + offset += MD_SB_BYTES; + +- lseek64(fd, offset, 0); ++ if (lseek64(fd, offset, 0) < 0) ++ return -1; + return 0; + } + +-- +2.41.0 + diff --git a/SOURCES/0147-mdadm-super1-fix-coverity-issue-CHECKED_RETURN.patch b/SOURCES/0147-mdadm-super1-fix-coverity-issue-CHECKED_RETURN.patch new file mode 100644 index 0000000..e99adc0 --- /dev/null +++ b/SOURCES/0147-mdadm-super1-fix-coverity-issue-CHECKED_RETURN.patch @@ -0,0 +1,67 @@ +From eb9834599c8c9764bb3e711b6f291b10797eff27 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:13 +0800 +Subject: [PATCH 147/157] mdadm/super1: fix coverity issue CHECKED_RETURN + +It needs to check return value when functions return value. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/super1.c b/super1.c +index 81d29a65..4e4c7bfd 100644 +--- a/super1.c ++++ b/super1.c +@@ -260,7 +260,10 @@ static int aread(struct align_fd *afd, void *buf, int len) + n = read(afd->fd, b, iosize); + if (n <= 0) + return n; +- lseek(afd->fd, len - n, 1); ++ if (lseek(afd->fd, len - n, 1) < 0) { ++ pr_err("lseek fails\n"); ++ return -1; ++ } + if (n > len) + n = len; + memcpy(buf, b, n); +@@ -294,14 +297,20 @@ static int awrite(struct align_fd *afd, void *buf, int len) + n = read(afd->fd, b, iosize); + if (n <= 0) + return n; +- lseek(afd->fd, -n, 1); ++ if (lseek(afd->fd, -n, 1) < 0) { ++ pr_err("lseek fails\n"); ++ return -1; ++ } + } + + memcpy(b, buf, len); + n = write(afd->fd, b, iosize); + if (n <= 0) + return n; +- lseek(afd->fd, len - n, 1); ++ if (lseek(afd->fd, len - n, 1) < 0) { ++ pr_err("lseek fails\n"); ++ return -1; ++ } + return len; + } + +@@ -2667,7 +2676,10 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) + } + if (mustfree) + free(sb); +- lseek64(fd, offset<<9, 0); ++ if (lseek64(fd, offset<<9, 0) < 0) { ++ pr_err("lseek fails\n"); ++ ret = -1; ++ } + return ret; + } + +-- +2.41.0 + diff --git a/SOURCES/0148-mdadm-super1-fix-coverity-issue-DEADCODE.patch b/SOURCES/0148-mdadm-super1-fix-coverity-issue-DEADCODE.patch new file mode 100644 index 0000000..4d8df9f --- /dev/null +++ b/SOURCES/0148-mdadm-super1-fix-coverity-issue-DEADCODE.patch @@ -0,0 +1,29 @@ +From 7904dc1c576a742c601c40dab4d0a6e562c4d00c Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:14 +0800 +Subject: [PATCH 148/157] mdadm/super1: fix coverity issue DEADCODE + +optimal_space is at most 2046. So space can't be larger than UINT16_MAX. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/super1.c b/super1.c +index 4e4c7bfd..24bc1026 100644 +--- a/super1.c ++++ b/super1.c +@@ -1466,8 +1466,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + __le32_to_cpu(sb->chunksize)); + if (space > optimal_space) + space = optimal_space; +- if (space > UINT16_MAX) +- space = UINT16_MAX; + } + + sb->ppl.offset = __cpu_to_le16(offset); +-- +2.41.0 + diff --git a/SOURCES/0149-mdadm-super1-fix-coverity-issue-EVALUATION_ORDER.patch b/SOURCES/0149-mdadm-super1-fix-coverity-issue-EVALUATION_ORDER.patch new file mode 100644 index 0000000..a8834ea --- /dev/null +++ b/SOURCES/0149-mdadm-super1-fix-coverity-issue-EVALUATION_ORDER.patch @@ -0,0 +1,46 @@ +From 38f712dba339bb9bd6a73cc7219d217871e7f27a Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:15 +0800 +Subject: [PATCH 149/157] mdadm/super1: fix coverity issue EVALUATION_ORDER + +Fix evaluation order problems in super1.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/super1.c b/super1.c +index 24bc1026..243eeb1a 100644 +--- a/super1.c ++++ b/super1.c +@@ -340,6 +340,9 @@ static void examine_super1(struct supertype *st, char *homehost) + unsigned long long sb_offset; + struct mdinfo info; + int inconsistent = 0; ++ unsigned int expected_csum = 0; ++ ++ expected_csum = calc_sb_1_csum(sb); + + printf(" Magic : %08x\n", __le32_to_cpu(sb->magic)); + printf(" Version : 1"); +@@ -507,13 +510,13 @@ static void examine_super1(struct supertype *st, char *homehost) + printf("\n"); + } + +- if (calc_sb_1_csum(sb) == sb->sb_csum) ++ if (expected_csum == sb->sb_csum) + printf(" Checksum : %x - correct\n", + __le32_to_cpu(sb->sb_csum)); + else + printf(" Checksum : %x - expected %x\n", + __le32_to_cpu(sb->sb_csum), +- __le32_to_cpu(calc_sb_1_csum(sb))); ++ __le32_to_cpu(expected_csum)); + printf(" Events : %llu\n", + (unsigned long long)__le64_to_cpu(sb->events)); + printf("\n"); +-- +2.41.0 + diff --git a/SOURCES/0150-mdadm-super1-fix-coverity-issue-RESOURCE_LEAK.patch b/SOURCES/0150-mdadm-super1-fix-coverity-issue-RESOURCE_LEAK.patch new file mode 100644 index 0000000..e86d4b7 --- /dev/null +++ b/SOURCES/0150-mdadm-super1-fix-coverity-issue-RESOURCE_LEAK.patch @@ -0,0 +1,41 @@ +From ae2308ddf38b8f24a2b5e8e14e31153dfe608239 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 26 Jul 2024 15:14:16 +0800 +Subject: [PATCH 150/157] mdadm/super1: fix coverity issue RESOURCE_LEAK + +Fix resource leak problems in super1.c + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/super1.c b/super1.c +index 243eeb1a..9c9c7dd1 100644 +--- a/super1.c ++++ b/super1.c +@@ -923,10 +923,12 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + offset <<= 9; + if (lseek64(fd, offset, 0) < 0) { + pr_err("Cannot seek to bad-blocks list\n"); ++ free(bbl); + return 1; + } + if (read(fd, bbl, size) != size) { + pr_err("Cannot read bad-blocks list\n"); ++ free(bbl); + return 1; + } + /* 64bits per entry. 10 bits is block-count, 54 bits is block +@@ -947,6 +949,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + + printf("%20llu for %d sectors\n", sector, count); + } ++ free(bbl); + return 0; + } + +-- +2.41.0 + diff --git a/SOURCES/0151-policy.c-Fix-check_return-issue-in-Write_rules.patch b/SOURCES/0151-policy.c-Fix-check_return-issue-in-Write_rules.patch new file mode 100644 index 0000000..25a5f46 --- /dev/null +++ b/SOURCES/0151-policy.c-Fix-check_return-issue-in-Write_rules.patch @@ -0,0 +1,66 @@ +From 44c2a293260952fbb14db23d1ad07e6066641e0a Mon Sep 17 00:00:00 2001 +From: Anna Sztukowska +Date: Thu, 11 Jul 2024 14:31:57 +0200 +Subject: [PATCH 151/157] policy.c: Fix check_return issue in Write_rules() + +Refactor Write_rules() in policy.c to eliminate check_return issue found +by SAST analysis. Create udev rules file directly using rule_name +instead of creating temporary file and renaming it. + +Signed-off-by: Anna Sztukowska +--- + policy.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +diff --git a/policy.c b/policy.c +index dfaafdc0..4d4b248d 100644 +--- a/policy.c ++++ b/policy.c +@@ -969,19 +969,13 @@ int generate_entries(int fd) + */ + int Write_rules(char *rule_name) + { +- int fd; +- char udev_rule_file[PATH_MAX]; ++ int fd = fileno(stdout); + +- if (rule_name) { +- strncpy(udev_rule_file, rule_name, sizeof(udev_rule_file) - 6); +- udev_rule_file[sizeof(udev_rule_file) - 6] = '\0'; +- strcat(udev_rule_file, ".temp"); +- fd = creat(udev_rule_file, +- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +- if (fd == -1) +- return 1; +- } else +- fd = 1; ++ if (rule_name) ++ fd = creat(rule_name, 0644); ++ ++ if (!is_fd_valid(fd)) ++ return 1; + + /* write static invocation */ + if (write(fd, udev_template_start, sizeof(udev_template_start) - 1) != +@@ -993,15 +987,14 @@ int Write_rules(char *rule_name) + goto abort; + + fsync(fd); +- if (rule_name) { ++ if (rule_name) + close(fd); +- rename(udev_rule_file, rule_name); +- } ++ + return 0; + abort: + if (rule_name) { + close(fd); +- unlink(udev_rule_file); ++ unlink(rule_name); + } + return 1; + } +-- +2.41.0 + diff --git a/SOURCES/0152-super-gpt.c-Fix-check_return-issue-in-load_gpt.patch b/SOURCES/0152-super-gpt.c-Fix-check_return-issue-in-load_gpt.patch new file mode 100644 index 0000000..b91cd90 --- /dev/null +++ b/SOURCES/0152-super-gpt.c-Fix-check_return-issue-in-load_gpt.patch @@ -0,0 +1,40 @@ +From 483ff037f1036f5f604e085cf76097a87e2be348 Mon Sep 17 00:00:00 2001 +From: Anna Sztukowska +Date: Wed, 24 Jul 2024 11:46:57 +0200 +Subject: [PATCH 152/157] super-gpt.c: Fix check_return issue in load_gpt() + +Fix check_return issue in load_gpt() reported by SAST analysis in +super-gpt.c. + +Signed-off-by: Anna Sztukowska +--- + super-gpt.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/super-gpt.c b/super-gpt.c +index a1e9aa9d..ec3cf53f 100644 +--- a/super-gpt.c ++++ b/super-gpt.c +@@ -105,7 +105,8 @@ static int load_gpt(struct supertype *st, int fd, char *devname) + return 1; + } + /* Set offset to second block (GPT header) */ +- lseek(fd, sector_size, SEEK_SET); ++ if (lseek(fd, sector_size, SEEK_SET) == -1L) ++ goto no_read; + /* Seem to have GPT, load the header */ + gpt_head = (struct GPT*)(super+1); + if (read(fd, gpt_head, sizeof(*gpt_head)) != sizeof(*gpt_head)) +@@ -118,7 +119,8 @@ static int load_gpt(struct supertype *st, int fd, char *devname) + to_read = __le32_to_cpu(gpt_head->part_cnt) * sizeof(struct GPT_part_entry); + to_read = ((to_read+511)/512) * 512; + /* Set offset to third block (GPT entries) */ +- lseek(fd, sector_size*2, SEEK_SET); ++ if (lseek(fd, sector_size * 2, SEEK_SET) == -1L) ++ goto no_read; + if (read(fd, gpt_head+1, to_read) != to_read) + goto no_read; + +-- +2.41.0 + diff --git a/SOURCES/0153-super-intel-fix-compilation-error.patch b/SOURCES/0153-super-intel-fix-compilation-error.patch new file mode 100644 index 0000000..dc0cfe3 --- /dev/null +++ b/SOURCES/0153-super-intel-fix-compilation-error.patch @@ -0,0 +1,46 @@ +From 734de8b02022bf3b7a5f2111f5314a87ddebcc83 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 6 Aug 2024 11:14:02 +0200 +Subject: [PATCH 153/157] super-intel: fix compilation error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix compilation error: + +super-intel.c: In function ‘end_migration’: +super-intel.c:4360:29: error: writing 2 bytes into a region + of size 0 [-Werror=stringop-overflow=] + 4360 | dev->vol.migr_state = 0; + | ~~~~~~~~~~~~~~~~~~~~^~~ +cc1: note: destination object is likely at address zero +cc1: all warnings being treated as errors +make: *** [Makefile:232: super-intel.o] Error 1 + +reported, when GCC 14 is used. Return when dev is NULL, to avoid it. + +Signed-off-by: Kinga Stefaniuk +--- + super-intel.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index ab9b5d3f..f6745e10 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4330,6 +4330,12 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super, + static void end_migration(struct imsm_dev *dev, struct intel_super *super, + __u8 map_state) + { ++ /* To avoid compilation error, saying dev can't be NULL when ++ * migr_state is assigned. ++ */ ++ if (dev == NULL) ++ return; ++ + struct imsm_map *map = get_imsm_map(dev, MAP_0); + struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == 0 ? + MAP_0 : MAP_1); +-- +2.41.0 + diff --git a/SOURCES/0154-super-intel-add-define-for-migr_state.patch b/SOURCES/0154-super-intel-add-define-for-migr_state.patch new file mode 100644 index 0000000..fd3b049 --- /dev/null +++ b/SOURCES/0154-super-intel-add-define-for-migr_state.patch @@ -0,0 +1,92 @@ +From 125217e0903ab0eb574d20c698c49b04e3b1a99c Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Wed, 31 Jul 2024 15:06:42 +0200 +Subject: [PATCH 154/157] super-intel: add define for migr_state + +Represent migr_state with the define, which helps in code readability. +Add new values for Normal and Migration states. + +Signed-off-by: Kinga Stefaniuk +--- + super-intel.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index f6745e10..354c292a 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -194,6 +194,8 @@ ASSERT_SIZE(imsm_map, 52) + struct imsm_vol { + __u32 curr_migr_unit_lo; + __u32 checkpoint_id; /* id to access curr_migr_unit */ ++#define MIGR_STATE_NORMAL 0 ++#define MIGR_STATE_MIGRATING 1 + __u8 migr_state; /* Normal or Migrating */ + #define MIGR_INIT 0 + #define MIGR_REBUILD 1 +@@ -4303,7 +4305,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super, + struct imsm_map *dest; + struct imsm_map *src = get_imsm_map(dev, MAP_0); + +- dev->vol.migr_state = 1; ++ dev->vol.migr_state = MIGR_STATE_MIGRATING; + set_migr_type(dev, migr_type); + set_vol_curr_migr_unit(dev, 0); + dest = get_imsm_map(dev, MAP_1); +@@ -4337,7 +4339,7 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super, + return; + + struct imsm_map *map = get_imsm_map(dev, MAP_0); +- struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == 0 ? ++ struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == MIGR_STATE_NORMAL ? + MAP_0 : MAP_1); + int i, j; + +@@ -4369,7 +4371,7 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super, + map_state = imsm_check_degraded(super, dev, failed, MAP_0); + } + +- dev->vol.migr_state = 0; ++ dev->vol.migr_state = MIGR_STATE_NORMAL; + set_migr_type(dev, 0); + set_vol_curr_migr_unit(dev, 0); + map->map_state = map_state; +@@ -4449,7 +4451,7 @@ int check_mpb_migr_compatibility(struct intel_super *super) + for (i = 0; i < super->anchor->num_raid_devs; i++) { + struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i); + +- if (dev_iter->vol.migr_state == 1 && ++ if (dev_iter->vol.migr_state == MIGR_STATE_MIGRATING && + dev_iter->vol.migr_type == MIGR_GEN_MIGR) { + /* This device is migrating */ + map0 = get_imsm_map(dev_iter, MAP_0); +@@ -5654,7 +5656,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + set_imsm_dev_size(dev, array_blocks); + dev->status = (DEV_READ_COALESCING | DEV_WRITE_COALESCING); + vol = &dev->vol; +- vol->migr_state = 0; ++ vol->migr_state = MIGR_STATE_NORMAL; + set_migr_type(dev, MIGR_INIT); + vol->dirty = !info->state; + set_vol_curr_migr_unit(dev, 0); +@@ -8631,7 +8633,7 @@ static void imsm_progress_container_reshape(struct intel_super *super) + copy_map_size = sizeof_imsm_map(map); + prev_num_members = map->num_members; + map->num_members = prev_disks; +- dev->vol.migr_state = 1; ++ dev->vol.migr_state = MIGR_STATE_MIGRATING; + set_vol_curr_migr_unit(dev, 0); + set_migr_type(dev, MIGR_GEN_MIGR); + for (i = prev_num_members; +@@ -9863,7 +9865,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u, + dprintf("imsm: modifying subdev: %i\n", + id->index); + devices_to_reshape--; +- newdev->vol.migr_state = 1; ++ newdev->vol.migr_state = MIGR_STATE_MIGRATING; + set_vol_curr_migr_unit(newdev, 0); + set_migr_type(newdev, MIGR_GEN_MIGR); + newmap->num_members = u->new_raid_disks; +-- +2.41.0 + diff --git a/SOURCES/0156-Grow_reshape-set-only-component_size-for-size-grow.patch b/SOURCES/0156-Grow_reshape-set-only-component_size-for-size-grow.patch new file mode 100644 index 0000000..575e984 --- /dev/null +++ b/SOURCES/0156-Grow_reshape-set-only-component_size-for-size-grow.patch @@ -0,0 +1,52 @@ +From c653054b322a03e8912ac05accc87b6a1ba8daab Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Fri, 26 Apr 2024 08:33:00 +0200 +Subject: [PATCH 156/157] Grow_reshape: set only component_size for size grow + +Component_size couldn't be set using ioctl when new drive size is big +(e.g. 5TB). Command value is bigger than 32 bits and error is reported +- it is known ioctl limitation. Remove updating array properties using +ioctl, use sysfs instead. Sysfs was introduced in 3.10, so now it is old +enough to be safely used. Array_size in sysfs should be set for every +size change for external metadata, when grow is performed without +errors. + +Signed-off-by: Kinga Stefaniuk +--- + Grow.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/Grow.c b/Grow.c +index a5f9027d..5810b128 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2149,19 +2149,14 @@ int Grow_reshape(char *devname, int fd, + if (s->size == MAX_SIZE) + s->size = 0; + array.size = s->size; +- if (s->size & ~INT32_MAX) { +- /* got truncated to 32bit, write to +- * component_size instead +- */ +- rv = sysfs_set_num(sra, NULL, "component_size", s->size); +- } else { +- rv = md_set_array_info(fd, &array); ++ rv = sysfs_set_num(sra, NULL, "component_size", s->size); + +- /* manage array size when it is managed externally +- */ +- if ((rv == 0) && st->ss->external) +- rv = set_array_size(st, sra, sra->text_version); +- } ++ /* ++ * For native metadata, md/array_size is updated by kernel, ++ * for external management update it here. ++ */ ++ if (st->ss->external && rv == MDADM_STATUS_SUCCESS) ++ rv = set_array_size(st, sra, sra->text_version); + + if (raid0_takeover) { + /* do not recync non-existing parity, +-- +2.41.0 + diff --git a/SOURCES/0157-mdstat-fix-list-detach-issues.patch b/SOURCES/0157-mdstat-fix-list-detach-issues.patch new file mode 100644 index 0000000..e4c3618 --- /dev/null +++ b/SOURCES/0157-mdstat-fix-list-detach-issues.patch @@ -0,0 +1,43 @@ +From 4b041873ff5556882bc6f17ac3de00c72eebcc4f Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 6 Aug 2024 16:11:18 +0200 +Subject: [PATCH 157/157] mdstat: fix list detach issues + +Move ent = ent->next; to while. It was outside the loop so if there +are more than 2 elements and we are looking for 3rd element it causes +infinite loop.. + +Fix el->next zeroing. It causes segfault in mdstat_free(). Theses +issues were not visible in my testing because I had only 2 MD devices. + +Fixes: 4b3644ab4ce6 ("mdstat: Rework mdstat external arrays handling") +Signed-off-by: Mariusz Tkaczyk +--- + mdstat.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/mdstat.c b/mdstat.c +index a971a957..29e78362 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -123,13 +123,15 @@ static void mdstat_ent_list_detach_element(struct mdstat_ent **list_head, struct + ent->next = el->next; + break; + } ++ ++ ent = ent->next; + } + +- ent = ent->next; + } + ++ /* Guard if not found or list is empty - not allowed */ + assert(ent); +- ent->next = NULL; ++ el->next = NULL; + } + + void free_mdstat(struct mdstat_ent *ms) +-- +2.41.0 + diff --git a/SOURCES/md-auto-readd.rule b/SOURCES/md-auto-readd.rule new file mode 100644 index 0000000..5ce29fb --- /dev/null +++ b/SOURCES/md-auto-readd.rule @@ -0,0 +1,27 @@ +# +# Enable/Disable - default is Disabled +# to disable this rule, GOTO="md_end" should be the first active command. +# to enable this rule, Comment out GOTO="md_end". +GOTO="md_end" + +# Required: MD arrays must have a bitmap for transient devices to +# be added back in the array. +# mdadm -CR /dev/md0 -l1 -n2 /dev/sd[ab] –bitmap=internal + +# Don't process any events if anaconda is running as anaconda brings up +# raid devices manually +ENV{ANACONDA}=="?*", GOTO="md_end" + +# Also don't process disks that are slated to be a multipath device +ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end" + +# We process add events on block devices (since they are ready as soon as +# they are added to the system) + +ACTION!="add", GOTO="md_end" +ENV{ID_FS_TYPE}!="linux_raid_member", GOTO="md_end" +SUBSYSTEM=="block", RUN{program}+="/usr/sbin/md-auto-readd.sh $devnode" + +# +# Land here to exit cleanly +LABEL="md_end" diff --git a/SOURCES/md-auto-readd.sh b/SOURCES/md-auto-readd.sh new file mode 100644 index 0000000..f15c482 --- /dev/null +++ b/SOURCES/md-auto-readd.sh @@ -0,0 +1,17 @@ +#!/usr/bin/bash +MDADM=/sbin/mdadm +DEVNAME=$1 + +export $(${MDADM} --examine --export ${DEVNAME}) +if [ -z "${MD_UUID}" ]; then + exit 1 +fi + +UUID_LINK=$(readlink /dev/disk/by-id/md-uuid-${MD_UUID}) +MD_DEVNAME=${UUID_LINK##*/} +export $(${MDADM} --detail --export /dev/${MD_DEVNAME}) +if [ -z "${MD_METADATA}" ] ; then + exit 1 +fi + +${MDADM} --manage /dev/${MD_DEVNAME} --re-add ${DEVNAME} --verbose diff --git a/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch new file mode 100644 index 0000000..188b478 --- /dev/null +++ b/SOURCES/mdadm-2.5.2-static.patch @@ -0,0 +1,23 @@ +--- mdadm-3.2.1/Makefile.static 2021-01-11 15:46:47.292126848 +0800 ++++ mdadm-3.2.1/Makefile 2021-01-11 15:46:10.720192519 +0800 +@@ -248,16 +248,16 @@ + install : install-bin install-man install-udev + + install-static : mdadm.static install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static + + install-tcc : mdadm.tcc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm.tcc + + install-uclibc : mdadm.uclibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm.uclibc + + install-klibc : mdadm.klibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm.klibc + + install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 + $(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8 diff --git a/SOURCES/mdadm-raid-check-sysconfig b/SOURCES/mdadm-raid-check-sysconfig new file mode 100644 index 0000000..8e82270 --- /dev/null +++ b/SOURCES/mdadm-raid-check-sysconfig @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Configuration file for /etc/cron.weekly/raid-check +# +# options: +# ENABLED - must be yes in order for the raid check to proceed +# CHECK - can be either check or repair depending on the type of +# operation the user desires. A check operation will scan +# the drives looking for bad sectors and automatically +# repairing only bad sectors. If it finds good sectors that +# contain bad data (meaning that the data in a sector does +# not agree with what the data from another disk indicates +# the data should be, for example the parity block + the other +# data blocks would cause us to think that this data block +# is incorrect), then it does nothing but increments the +# counter in the file /sys/block/$dev/md/mismatch_count. +# This allows the sysadmin to inspect the data in the sector +# and the data that would be produced by rebuilding the +# sector from redundant information and pick the correct +# data to keep. The repair option does the same thing, but +# when it encounters a mismatch in the data, it automatically +# updates the data to be consistent. However, since we really +# don't know whether it's the parity or the data block that's +# correct (or which data block in the case of raid1), it's +# luck of the draw whether or not the user gets the right +# data instead of the bad data. This option is the default +# option for devices not listed in either CHECK_DEVS or +# REPAIR_DEVS. +# CHECK_DEVS - a space delimited list of devs that the user specifically +# wants to run a check operation on. +# REPAIR_DEVS - a space delimited list of devs that the user +# specifically wants to run a repair on. +# SKIP_DEVS - a space delimited list of devs that should be skipped +# NICE - Change the raid check CPU and IO priority in order to make +# the system more responsive during lengthy checks. Valid +# values are high, normal, low, idle. +# MAXCONCURENT - Limit the number of devices to be checked at a time. +# By default all devices will be checked at the same time. +# +# Note: the raid-check script intentionaly runs last in the cron.weekly +# sequence. This is so we can wait for all the resync operations to complete +# and then check the mismatch_count on each array without unduly delaying +# other weekly cron jobs. If any arrays have a non-0 mismatch_count after +# the check completes, we echo a warning to stdout which will then me emailed +# to the admin as long as mails from cron jobs have not been redirected to +# /dev/null. We do not wait for repair operations to complete as the +# md stack will correct any mismatch_cnts automatically. +# +# Note2: you can not use symbolic names for the raid devices, such as you +# /dev/md/root. The names used in this file must match the names seen in +# /proc/mdstat and in /sys/block. + +ENABLED=yes +CHECK=check +NICE=low +# To check devs /dev/md0 and /dev/md3, use "md0 md3" +CHECK_DEVS="" +REPAIR_DEVS="" +SKIP_DEVS="" +MAXCONCURRENT= diff --git a/SOURCES/mdadm-udev.patch b/SOURCES/mdadm-udev.patch new file mode 100644 index 0000000..a9d4d93 --- /dev/null +++ b/SOURCES/mdadm-udev.patch @@ -0,0 +1,26 @@ +--- mdadm/udev-md-raid-assembly.rules.orig 2023-01-06 16:37:03.780756100 +0800 ++++ mdadm/udev-md-raid-assembly.rules 2023-01-06 17:04:09.536159980 +0800 +@@ -5,6 +5,9 @@ + ENV{ANACONDA}=="?*", GOTO="md_inc_end" + # assemble md arrays + ++# Also don't process disks that are slated to be a multipath device ++ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_inc_end" ++ + SUBSYSTEM!="block", GOTO="md_inc_end" + + # skip non-initialized devices +@@ -33,6 +36,13 @@ + + LABEL="md_inc" + ++# Make sure we don't handle dm devices when some limits are set. ++# And linux_raid_member only be set when change/remove event happen. ++# So we don't need to consider add event here. ++KERNEL=="dm-*", ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="md_inc_end" ++KERNEL=="dm-*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="md_inc_end" ++KERNEL=="dm-*", ENV{DM_SUSPENDED}=="1", GOTO="md_inc_end" ++ + # Bare disks are ready when add event happens, the raid can be assembled. + ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end" + diff --git a/SOURCES/mdadm.conf b/SOURCES/mdadm.conf new file mode 100644 index 0000000..3207dda --- /dev/null +++ b/SOURCES/mdadm.conf @@ -0,0 +1 @@ +d /run/mdadm 0710 root root - diff --git a/SOURCES/mdadm_event.conf b/SOURCES/mdadm_event.conf new file mode 100644 index 0000000..1a6c479 --- /dev/null +++ b/SOURCES/mdadm_event.conf @@ -0,0 +1,5 @@ +# Save /proc/mdstat in case of crash in mdadm/mdmon + +EVENT=post-create component=mdadm + cat /proc/mdstat >> mdstat_data + echo "Saved output of /proc/mdstat" diff --git a/SOURCES/mdcheck b/SOURCES/mdcheck new file mode 100644 index 0000000..700c3e2 --- /dev/null +++ b/SOURCES/mdcheck @@ -0,0 +1,166 @@ +#!/bin/bash + +# Copyright (C) 2014-2017 Neil Brown +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Author: Neil Brown +# Email: + +# This script should be run periodically to automatically +# perform a 'check' on any md arrays. +# +# It supports a 'time budget' such that any incomplete 'check' +# will be checkpointed when that time has expired. +# A subsequent invocation can allow the 'check' to continue. +# +# Options are: +# --continue Don't start new checks, only continue old ones. +# --duration This is passed to "date --date=$duration" to find out +# when to finish +# +# To support '--continue', arrays are identified by UUID and the 'sync_completed' +# value is stored in /var/lib/mdcheck/$UUID + +# convert a /dev/md name into /sys/.../md equivalent +sysname() { + set `ls -lLd $1` + maj=${5%,} + min=$6 + readlink -f /sys/dev/block/$maj:$min +} + +args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@") +rv=$? +if [ $rv -ne 0 ]; then exit $rv; fi + +eval set -- $args + +cont= +endtime= +while [ " $1" != " --" ] +do + case $1 in + --help ) + echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]' + echo >&2 ' time-offset must be understood by "date --date"' + exit 0 + ;; + --continue ) cont=yes ;; + --duration ) shift; dur=$1 + endtime=$(date --date "$dur" "+%s") + ;; + esac + shift +done +shift + +# We need a temp file occasionally... +tmp=/var/lib/mdcheck/.md-check-$$ +trap 'rm -f "$tmp"' 0 2 3 15 + + +# firstly, clean out really old state files +mkdir -p /var/lib/mdcheck +find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \; + +# Now look at each md device. +cnt=0 +for dev in /dev/md?* +do + [ -e "$dev" ] || continue + sys=`sysname $dev` + if [ ! -f "$sys/md/sync_action" ] + then # cannot check this array + continue + fi + if [ "`cat $sys/md/sync_action`" != 'idle' ] + then # This array is busy + continue + fi + + mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue + source $tmp + fl="/var/lib/mdcheck/MD_UUID_$MD_UUID" + if [ -z "$cont" ] + then + start=0 + logger -p daemon.info mdcheck start checking $dev + elif [ -z "$MD_UUID" -o ! -f "$fl" ] + then + # Nothing to continue here + continue + else + start=`cat "$fl"` + logger -p daemon.info mdcheck continue checking $dev from $start + fi + + cnt=$[cnt+1] + eval MD_${cnt}_fl=\$fl + eval MD_${cnt}_sys=\$sys + eval MD_${cnt}_dev=\$dev + echo $start > $fl + echo $start > $sys/md/sync_min + echo check > $sys/md/sync_action +done + +if [ -z "$endtime" ] +then + exit 0 +fi + +while [ `date +%s` -lt $endtime ] +do + any= + for i in `eval echo {1..$cnt}` + do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + logger -p daemon.info mdcheck finished checking $dev + eval MD_${i}_fl= + rm -f $fl + continue; + fi + read a rest < $sys/md/sync_completed + echo $a > $fl + any=yes + done + if [ -z "$any" ]; then exit 0; fi + sleep 120 +done + +# We've waited, and there are still checks running. +# Time to stop them. +for i in `eval echo {1..$cnt}` +do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + eval MD_${i}_fl= + rm -f $fl + continue; + fi + echo idle > $sys/md/sync_action + cat $sys/md/sync_min > $fl + logger -p daemon.info pause checking $dev at `cat $fl` +done diff --git a/SOURCES/mdmonitor.service b/SOURCES/mdmonitor.service new file mode 100644 index 0000000..a2f53d9 --- /dev/null +++ b/SOURCES/mdmonitor.service @@ -0,0 +1,12 @@ +[Unit] +Description=Software RAID monitoring and management +ConditionPathExists=/etc/mdadm.conf + +[Service] +Type=forking +PIDFile=/run/mdadm/mdadm.pid +EnvironmentFile=-/etc/sysconfig/mdmonitor +ExecStart=/sbin/mdadm --monitor --scan --syslog -f --pid-file=/run/mdadm/mdadm.pid + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/raid-check b/SOURCES/raid-check new file mode 100644 index 0000000..7b2fb59 --- /dev/null +++ b/SOURCES/raid-check @@ -0,0 +1,135 @@ +#!/bin/bash +# +# This script reads it's configuration from /etc/sysconfig/raid-check +# Please use that file to enable/disable this script or to set the +# type of check you wish performed. + +# We might be on a kernel with no raid support at all, exit if so +[ -f /proc/mdstat ] || exit 0 + +# and exit if we haven't been set up properly +[ -f /etc/sysconfig/raid-check ] || exit 0 +. /etc/sysconfig/raid-check + +# Wait until no more than arg1 arrays in arg2 list are busy +waitbusy() { + local threshold=$(($1 + 1)) + local dev_list="$2" + while true + do + local busy=0 + local dev="" + for dev in $dev_list; do + local sync_action=`cat /sys/block/$dev/md/sync_action` + if [ "$sync_action" != "idle" ]; then + let busy++ + fi + done + [ $busy -lt $threshold ] && break + sleep 60 + done +} + +[ "$ENABLED" != "yes" ] && exit 0 + +case "$CHECK" in + check) ;; + repair) ;; + *) exit 0;; +esac + +ionice="" +renice="" +case $NICE in + high) + renice="-n -5" + ;; + low) + renice="-n 5" + ionice="-c2 -n7" + ;; + idle) + renice="-n 15" + ionice="-c3" + ;; + *) + ;; +esac + +active_list=`grep "^md.*: active" /proc/mdstat | cut -f 1 -d ' '` +[ -z "$active_list" ] && exit 0 + +declare -A check +dev_list="" +check_list="" +for dev in $active_list; do + echo $SKIP_DEVS | grep -w $dev >&/dev/null && continue + if [ -f /sys/block/$dev/md/sync_action ]; then + # Only perform the checks on idle, healthy arrays, but delay + # actually writing the check field until the next loop so we + # don't switch currently idle arrays to active, which happens + # when two or more arrays are on the same physical disk + array_state=`cat /sys/block/$dev/md/array_state` + if [ "$array_state" != "clean" -a "$array_state" != "active" ]; then + continue + fi + sync_action=`cat /sys/block/$dev/md/sync_action` + if [ "$sync_action" != idle ]; then + continue + fi + ck="" + echo $REPAIR_DEVS | grep -w $dev >&/dev/null && ck="repair" + echo $CHECK_DEVS | grep -w $dev >&/dev/null && ck="check" + [ -z "$ck" ] && ck=$CHECK + dev_list="$dev_list $dev" + check[$dev]=$ck + [ "$ck" = "check" ] && check_list="$check_list $dev" + fi +done +[ -z "$dev_list" ] && exit 0 + +for dev in $dev_list; do + #Only run $MAXCONCURRENT checks at a time + if [ -n "$MAXCONCURRENT" ]; then + waitbusy $((MAXCONCURRENT - 1)) "$dev_list" + fi + echo "${check[$dev]}" > /sys/block/$dev/md/sync_action + + resync_pid="" + wait=10 + while [ $wait -gt 0 -a -z "$resync_pid" ]; do + sleep 6 + let wait-- + resync_pid=$(ps -ef | awk -v mddev=$dev 'BEGIN { pattern = "^\\[" mddev "_resync]$" } $8 ~ pattern { print $2 }') + done + [ -n "$resync_pid" -a -n "$renice" ] && + renice $renice -p $resync_pid >&/dev/null + [ -n "$resync_pid" -a -n "$ionice" ] && + ionice $ionice -p $resync_pid >&/dev/null +done +[ -z "$check_list" ] && exit 0 + +waitbusy 0 "$check_list" + +for dev in $check_list; do + mismatch_cnt=`cat /sys/block/$dev/md/mismatch_cnt` + # Due to the fact that raid1/10 writes in the kernel are unbuffered, + # a raid1 array can have non-0 mismatch counts even when the + # array is healthy. These non-0 counts will only exist in + # transient data areas where they don't pose a problem. However, + # since we can't tell the difference between a non-0 count that + # is just in transient data or a non-0 count that signifies a + # real problem, simply don't check the mismatch_cnt on raid1 + # devices as it's providing far too many false positives. But by + # leaving the raid1 device in the check list and performing the + # check, we still catch and correct any bad sectors there might + # be in the device. + raid_lvl=`cat /sys/block/$dev/md/level` + if [ "$raid_lvl" = "raid1" -o "$raid_lvl" = "raid10" ]; then + continue + fi + if [ "$mismatch_cnt" -ne 0 ]; then + echo "WARNING: mismatch_cnt is not 0 on /dev/$dev" + fi +done + diff --git a/SOURCES/raid-check.service b/SOURCES/raid-check.service new file mode 100644 index 0000000..f8ed5ac --- /dev/null +++ b/SOURCES/raid-check.service @@ -0,0 +1,6 @@ +[Unit] +Description=RAID setup health check + +[Service] +Type=oneshot +ExecStart=/usr/sbin/raid-check diff --git a/SOURCES/raid-check.timer b/SOURCES/raid-check.timer new file mode 100644 index 0000000..c33bc24 --- /dev/null +++ b/SOURCES/raid-check.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Weekly RAID setup health check + +[Timer] +OnCalendar=Sun *-*-* 01:00:00 +Persistent=true +AccuracySec=24h + +[Install] +WantedBy=timers.target diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec new file mode 100644 index 0000000..d28d6e1 --- /dev/null +++ b/SPECS/mdadm.spec @@ -0,0 +1,1312 @@ +%bcond abrt %{undefined rhel} + +Name: mdadm +Version: 4.3 +# extraversion is used to define rhel internal version +%define extraversion 3 +Release: %{extraversion}%{?dist} +Summary: The mdadm program controls Linux md devices (software RAID arrays) +URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ +License: GPLv2+ + +Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}%{?subversion:-%{subversion}}.tar.xz +Source1: raid-check +Source2: mdadm-raid-check-sysconfig +Source3: mdmonitor.service +Source4: mdadm.conf +Source5: mdadm_event.conf +Source6: raid-check.timer +Source7: raid-check.service +Source8: mdcheck +Source9: md-auto-readd.rule +Source10: md-auto-readd.sh + +Patch000: 0001-Remove-hardcoded-checkpoint-interval-checking.patch +Patch001: 0002-monitor-refactor-checkpoint-update.patch +Patch002: 0003-Super-intel-Fix-first-checkpoint-restart.patch +Patch003: 0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch +Patch004: 0005-Add-understanding-output-section-in-man.patch +Patch005: 0006-Create-add_disk_to_super-fix-resource-leak.patch +Patch006: 0007-mdadm-signal_s-init-variables.patch +Patch007: 0008-Monitor-open-file-before-check-in-check_one_sharer.patch +Patch008: 0009-Grow-remove-dead-condition-in-Grow_reshape.patch +Patch009: 0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch +Patch010: 0011-mdmon-refactor-md-device-name-check-in-main.patch +Patch011: 0012-test-run-tests-on-system-level-mdadm.patch +Patch012: 0013-Monitor-Allow-no-PID-in-check_one_sharer.patch +Patch013: 0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch +Patch014: 0015-mdadm-remove-TODO.patch +Patch015: 0016-mdadm-remove-makedist.patch +Patch016: 0017-mdadm-remove-mdadm.spec.patch +Patch017: 0018-mdadm-remove-mkinitramfs-stuff.patch +Patch018: 0019-mdadm-move-documentation-to-folder.patch +Patch019: 0020-Detail-remove-duplicated-code.patch +Patch020: 0021-mdadm-Add-functions-for-spare-criteria-verification.patch +Patch021: 0022-mdadm-drop-get_required_spare_criteria.patch +Patch022: 0023-Manage-fix-check-after-dereference-issue.patch +Patch023: 0024-Manage-implement-manage_add_external.patch +Patch024: 0025-mdadm-introduce-sysfs_get_container_devnm.patch +Patch025: 0026-mdadm.h-Introduce-custom-device-policies.patch +Patch026: 0027-mdadm-test_and_add-device-policies-implementation.patch +Patch027: 0028-Create-Use-device-policies.patch +Patch028: 0029-Manage-check-device-policies-in-manage_add_external.patch +Patch029: 0030-Monitor-Incremental-use-device-policies.patch +Patch030: 0031-imsm-test_and_add_device_policies-implementation.patch +Patch031: 0032-mdadm-drop-get_disk_controller_domain.patch +Patch032: 0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch +Patch033: 0034-mdadm-remove-inventory-file.patch +Patch034: 0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch +Patch035: 0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch +Patch036: 0037-mdadm-set-swapuuid-in-all-handlers.patch +Patch037: 0038-mdadm-Fix-native-detail-export.patch +Patch038: 0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch +Patch039: 0040-mdadm-fix-grow-segfault-for-IMSM.patch +Patch040: 0041-Remove-all-if-zeros-pt.2.patch +Patch041: 0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch +Patch042: 0043-Add-reading-Opal-NVMe-encryption-information.patch +Patch043: 0044-Add-reading-SATA-encryption-information.patch +Patch044: 0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch +Patch045: 0046-imsm-print-disk-encryption-information.patch +Patch046: 0047-imsm-drive-encryption-policy-implementation.patch +Patch047: 0048-mdadm-add-CHANGELOG.md.patch +Patch048: 0049-mdadm-Add-MAINTAINERS.md.patch +Patch049: 0050-mdadm-Add-README.md.patch +Patch050: 0051-Create.c-fix-uclibc-build.patch +Patch051: 0052-mdadm-pass-struct-context-for-external-reshapes.patch +Patch052: 0053-mdadm-use-struct-context-in-reshape_super.patch +Patch053: 0054-imsm-add-support-for-literal-RAID-10.patch +Patch054: 0055-imsm-refactor-RAID-level-handling.patch +Patch055: 0056-imsm-bump-minimal-version.patch +Patch056: 0057-imsm-define-RAID_10-attribute.patch +Patch057: 0058-imsm-simplify-imsm_check_attributes.patch +Patch058: 0059-imsm-support-RAID-10-with-more-than-4-drives.patch +Patch059: 0060-tests-01r5fail-enhance.patch +Patch060: 0061-tests-01r5integ.broken.patch +Patch061: 0062-tests-01raid6integ.broken-can-be-removed.patch +Patch062: 0063-Makefile-Move-pie-to-LDFLAGS.patch +Patch063: 0064-tests-23rdev-lifetime-fix-a-typo.patch +Patch064: 0065-util.c-change-devnm-to-const-in-mdmon-functions.patch +Patch065: 0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch +Patch066: 0069-mdadm-Fix-compilation-for-32-bit-arch.patch +Patch067: 0070-add-checking-of-return-status-on-fstat-calls.patch +Patch068: 0071-super-intel-fix-typo-in-error-msg.patch +Patch069: 0072-mdadm-super-intel-remove-dead-code.patch +Patch070: 0073-mdadm-super-intel-fix-bad-shift.patch +Patch071: 0074-mdadm-deprecate-bitmap-custom-file.patch +Patch072: 0075-Makefile-fix-make-s-detection.patch +Patch073: 0076-Change-some-error-messages-to-info-level.patch +Patch074: 0077-mdadm-Start-update_opt-from-0.patch +Patch075: 0078-Don-t-control-reshape-speed-in-daemon.patch +Patch076: 0079-mdadm-tests-test-enhance.patch +Patch077: 0080-mdadm-tests-test-don-t-fail-when-systemd-reports-err.patch +Patch078: 0081-mdadm-tests-names_template-enhance.patch +Patch079: 0082-mdadm-tests-03assem-incr-enhance.patch +Patch080: 0083-mdadm-tests-03r0assem-enhance.patch +Patch081: 0084-mdadm-tests-remove-03r5assem-failed.patch +Patch082: 0085-mdadm-tests-03r5assemV1.patch +Patch083: 0086-mdadm-tests-remove-04r5swap.broken.patch +Patch084: 0087-tests-04update-metadata-skip-linear.patch +Patch085: 0088-mdadm-tests-05r5-internalbitmap.patch +Patch086: 0089-mdadm-tests-06name-enhance.patch +Patch087: 0090-mdadm-tests-07autoassemble.patch +Patch088: 0091-mdadm-tests-07autodetect.broken-can-be-removed.patch +Patch089: 0092-mdadm-tests-07changelevelintr.patch +Patch090: 0093-mdadm-tests-disable-selinux.patch +Patch091: 0094-mdadm-platform-intel-buffer-overflow-detected.patch +Patch092: 0095-mdadm-tests-bitmap-cases-enhance.patch +Patch093: 0096-mdadm-tests-04update-uuid.patch +Patch094: 0097-mdadm-tests-05r1-re-add-nosuper.patch +Patch095: 0098-mdadm-tests-remove-strace-test.patch +Patch096: 0099-mdadm.h-provide-basename-if-GLIBC-is-not-avialable.patch +Patch097: 0100-imsm-fix-first-volume-autolayout-with-IMSM_NO_PLATFO.patch +Patch098: 0101-imsm-make-freesize-required-to-volume-autolayout.patch +Patch099: 0102-mdadm-Fix-hang-race-condition-in-wait_for_zero_forks.patch +Patch100: 0103-mdadm-Block-SIGCHLD-processes-before-starting-childr.patch +Patch101: 0104-test-pass-flags-to-services.patch +Patch102: 0105-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch +Patch103: 0106-Makefile-Do-not-call-gcc-directly.patch +Patch104: 0107-mdadm-tests-judge-foreign-array-in-test-cases.patch +Patch105: 0108-Revert-mdadm-Fix-socket-connection-failure-when-mdmo.patch +Patch106: 0109-mdadm-Assemble.c-fix-coverity-issues.patch +Patch107: 0111-mdadm-Fix-socket-connection-failure-when-mdmon-runs-.patch +Patch108: 0113-config.c-Fix-memory-leak-in-load_containers.patch +Patch109: 0114-mdadm-Build.c-fix-coverity-issues.patch +Patch110: 0115-mdadm-Create.c-fix-coverity-issues.patch +Patch111: 0116-mdadm-super-ddf.c-fix-coverity-issues.patch +Patch112: 0117-mdadm-clustermd_tests-add-some-APIs-in-func.sh-to-su.patch +Patch113: 0118-mdadm-clustermd_tests-adjust-test-cases-to-support-m.patch +Patch114: 0119-mapfile.c-Fix-STRING_OVERFLOW-issue.patch +Patch115: 0120-mdadm-Manage.c-fix-coverity-issues.patch +Patch116: 0121-Manage-fix-is_remove_safe.patch +Patch117: 0122-imsm-add-indent-for-encryption-details.patch +Patch118: 0123-mdadm-Monitor.c-fix-coverity-issues.patch +Patch119: 0124-mdadm-Query.c-fix-coverity-issues.patch +Patch120: 0125-mdadm-lib.c-fix-coverity-issues.patch +Patch121: 0126-mdadm-do-not-allow-leading-dot-in-MD-device-name.patch +Patch122: 0128-Detail-fix-detail-export-for-uuid_zero.patch +Patch123: 0129-drive_encryption-Fix-ata-passthrough12-verify.patch +Patch124: 0130-super0-use-define-for-char-array-in-examine_super0.patch +Patch125: 0131-Makefile-add-more-compiler-flags.patch +Patch126: 0133-mdstat-Rework-mdstat-external-arrays-handling.patch +Patch127: 0134-mdadm-managemon.c-fix-coverity-issues.patch +Patch128: 0135-mdadm-msg.c-fix-coverity-issues.patch +Patch129: 0136-imsm-refactor-chunk-size-print.patch +Patch130: 0137-mdadm-Grow-fix-coverity-issue-CHECKED_RETURN.patch +Patch131: 0138-mdadm-Grow-fix-coverity-issue-RESOURCE_LEAK.patch +Patch132: 0139-mdadm-Grow-fix-coverity-issue-STRING_OVERFLOW.patch +Patch133: 0140-mdadm-Incremental-fix-coverity-issues.patch +Patch134: 0141-mdadm-mdmon-fix-coverity-issue-CHECKED_RETURN.patch +Patch135: 0142-mdadm-mdmon-fix-coverity-issue-RESOURCE_LEAK.patch +Patch136: 0143-mdadm-mdopen-fix-coverity-issue-CHECKED_RETURN.patch +Patch137: 0144-mdadm-mdopen-fix-coverity-issue-STRING_OVERFLOW.patch +Patch138: 0145-mdadm-mdstat-fix-coverity-issue-CHECKED_RETURN.patch +Patch139: 0146-mdadm-super0-fix-coverity-issue-CHECKED_RETURN-and-E.patch +Patch140: 0147-mdadm-super1-fix-coverity-issue-CHECKED_RETURN.patch +Patch141: 0148-mdadm-super1-fix-coverity-issue-DEADCODE.patch +Patch142: 0149-mdadm-super1-fix-coverity-issue-EVALUATION_ORDER.patch +Patch143: 0150-mdadm-super1-fix-coverity-issue-RESOURCE_LEAK.patch +Patch144: 0151-policy.c-Fix-check_return-issue-in-Write_rules.patch +Patch145: 0152-super-gpt.c-Fix-check_return-issue-in-load_gpt.patch +Patch146: 0153-super-intel-fix-compilation-error.patch +Patch147: 0154-super-intel-add-define-for-migr_state.patch +Patch148: 0156-Grow_reshape-set-only-component_size-for-size-grow.patch +Patch149: 0157-mdstat-fix-list-detach-issues.patch + +# Fedora customization patches +Patch197: mdadm-udev.patch +Patch198: mdadm-2.5.2-static.patch + +BuildRequires: make +BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel +%if %{with abrt} +Requires: libreport-filesystem +%endif +Requires(post): systemd coreutils +Requires(preun): systemd +Requires(postun): systemd coreutils + +%description +The mdadm program is used to create, manage, and monitor Linux MD (software +RAID) devices. As such, it provides similar functionality to the raidtools +package. However, mdadm is a single program, and it can perform +almost all functions without a configuration file, though a configuration +file can be used to help with some common tasks. + +%prep +%autosetup -p1 -n %{name}-%{version}%{?subversion:_%{subversion}} + +%build +#If extraversion is defined, add EXTRAVERSION="%{extraversion}" +make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" EXTRAVERSION="%{extraversion}" mdadm mdmon + +%install +make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} UDEVDIR=/usr/lib/udev/ install install-systemd +install -Dp -m 755 %{SOURCE1} %{buildroot}%{_sbindir}/raid-check +install -Dp -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/raid-check +mkdir -p -m 710 %{buildroot}/run/mdadm +mkdir -p -m 700 %{buildroot}/usr/share/mdadm +install -Dp -m 755 %{SOURCE8} %{buildroot}/usr/share/mdadm/mdcheck +install -Dp -m 644 %{SOURCE9} %{buildroot}%{_udevrulesdir}/66-md-auto-readd.rules +install -Dp -m 755 %{SOURCE10} %{buildroot}%{_sbindir}/md-auto-readd.sh + +# systemd +mkdir -p %{buildroot}%{_unitdir} +install -m644 %{SOURCE3} %{buildroot}%{_unitdir} +install -m644 %{SOURCE6} %{buildroot}%{_unitdir} +install -m644 %{SOURCE7} %{buildroot}%{_unitdir} + +# tmpfile +mkdir -p %{buildroot}%{_tmpfilesdir} +install -m 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf +mkdir -p %{buildroot}%{_localstatedir}/run/ +install -d -m 0710 %{buildroot}/run/%{name}/ + +# abrt +%if %{with abrt} +mkdir -p %{buildroot}/etc/libreport/events.d +install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d +%endif + +%post +%systemd_post mdmonitor.service raid-check.timer +%{_bindir}/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || : + +%preun +%systemd_preun mdmonitor.service raid-check.timer + +%postun +%systemd_postun_with_restart mdmonitor.service + +%files +%license COPYING +%doc documentation/mdadm.conf-example misc/* +%{_udevrulesdir}/* +%{_sbindir}/* +%{_unitdir}/* +%{_mandir}/man*/md* +%{_prefix}/lib/systemd/system-shutdown/* +%config(noreplace) %{_sysconfdir}/sysconfig/* +%dir /run/%{name}/ +%config(noreplace) %{_tmpfilesdir}/%{name}.conf +%if %{with abrt} +/etc/libreport/events.d/* +%endif +/usr/share/mdadm/mdcheck + +%changelog +* Tue Nov 26 2024 MSVSphere Packaging Team - 4.3-3 +- Rebuilt for MSVSphere 10 + +* Sun Aug 11 2024 Xiao Ni - 4.3-3 +- Fix coverity issue and update to latest upstream +- Resolves: RHEL-34533, RHEL-50776 + +* Tue Jul 16 2024 Michal Srb - 4.3-2.2 +- Avoid libreport dependency on RHEL +- Resolves: RHEL-45523 + +* Mon Jun 24 2024 Troy Dawson - 4.3-2.1 +- Bump release for June 2024 mass rebuild + +* Wed May 15 2024 Xiao Ni 4.3-2 +- Update to latest upstream and add gating test +- Resolves RHEL-30530 + +* Fri Mar 29 2024 Xiao Ni 4.3-1 +- Update to 4.3 and to latest upstream +- Resolves RHEL-30530 + +* Thu Jan 25 2024 Fedora Release Engineering - 4.2-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sun Jan 21 2024 Fedora Release Engineering - 4.2-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Thu Jul 20 2023 Fedora Release Engineering - 4.2-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Wed Apr 12 2023 Xiao Ni - 4.2-5 +- Update to latest upstream for rawhide(f39) and fix mdcheck service bug +- Resolves bz#2175540 + +* Mon Jan 30 2023 Xiao Ni - 4.2-4 +- Update to latest upstream for f38 +- Resolves bz#2163711 + +* Thu Jan 19 2023 Fedora Release Engineering - 4.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Jul 21 2022 Fedora Release Engineering - 4.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Mon Mar 21 2022 Xiao Ni - 4.2-1 +- Update to mdadm-4.2 +- Resolves bz#2066150 + +* Thu Jan 20 2022 Fedora Release Engineering - 4.2-rc2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Aug 09 2021 Xiao Ni - 4.2-rc2 +- Update to mdadm-4.2-rc2 +- Resolves bz#1988236 + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 4.1-8 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* Tue Jan 26 2021 Fedora Release Engineering - 4.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jul 28 2020 Fedora Release Engineering - 4.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed May 27 2020 Xiao Ni - 4.1-5 +- Don't enable raid-check.service to avoid raid check after every boot +- Resolves bz1838409 + +* Sun Mar 08 2020 Peter Robinson - 4.1-4 +- Fix install location of udev rules (rhbz 1809117) + +* Fri Feb 07 2020 Alejandro Domínguez Muñoz - 4.1-3 +- Replace raid-check cron job with systemd timer + +* Wed Jan 29 2020 Fedora Release Engineering - 4.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Jan 13 2020 Peter Robinson 4.1-1 +- Update to 4.1 GA +- Spec cleanups and updates +- Update mdadm.pid location (rhbz 1701114, rhbz 1557623, rhbz 1557623) + +* Sun Dec 15 2019 Julian Sikorski - 4.1-rc2.0.5.2 +- Fix invalid substitution type error +- Resolves bz1740662, bz1749859 + +* Thu Jul 25 2019 Fedora Release Engineering - 4.1-rc2.0.5.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Jun 04 2019 Xiao Ni - 4.1-rc2.0.5 +- Update tmpfiles directory to non-legacy location +- Resolves bz1704517 + +* Wed Apr 17 2019 Xiao Ni - 4.1-rc2.0.4 +- Change tmpfiles directory to /run/mdadm +- Resovles bz1701821 + +* Sat Mar 16 2019 Björn Esser - 4.1-rc2.0.3 +- Add patch to build without -Werror, fixes FTBFS (#1675363) + +* Fri Feb 01 2019 Fedora Release Engineering - 4.1-rc2.0.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Sep 13 2018 Adam Williamson - 4.1-rc2.0.2 +- Fix multipath check in udev rule, broke array init in F29 +- Resolves bz1628192 + +* Sun Aug 26 2018 Peter Robinson 4.1-rc2.0.1 +- Update to 4.1 rc2 + +* Fri Jul 20 2018 Xiao Ni - 4.1-rc1_1.2 +- Add gcc into BuildRequires +- Resolves bz1604811 + +* Fri Jul 13 2018 Fedora Release Engineering - 4.1-rc1_1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jul 09 2018 Xiao Ni 4.1-rc1-1 +- Update to latest upstream version 4.1-rc1 +- Resolves bz1556591 + +* Wed Jul 4 2018 Peter Robinson 4.0-7 +- Cleanup spec, use %%licenece, drop old sys-v migration bits + +* Thu Feb 08 2018 Fedora Release Engineering - 4.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 4.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 4.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Apr 26 2017 Xiao Ni - 4.0-3 +- Fix building errors against newer gcc (>=7.0) +- Resolves bz1444756 + +* Fri Feb 10 2017 Fedora Release Engineering - 4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Xiao Ni - 4.0-1 +- Upgrade to mdadm-4.0 +- Resolves bz1411555 + +* Mon Aug 15 2016 Jes Sorensen - 3.4-3 +- Fix build against newer glibc (Fedora 26+) + +* Fri Aug 12 2016 Jes Sorensen - 3.4-2 +- Fix i686 build error +- Fix problem where it was not possible to stop an IMSM array during reshape +- Fix Degraded Raid1 array becomes inactive after rebooting +- Fix problem with raid0 arrays not being detected by Anaconda due to it + setting MALLOC_PERTURB_ +- Fix problem with reshaping IMSM arrays, where a new reshape could be + launched before the first reshape had fully completed, leading to + unpected results. +- Fix problem with mdadm large device names overflowing an internal buffer +- Fix problem about reshape stuck at beginning +- Resolves bz1303380 + +* Fri Aug 12 2016 Jes Sorensen - 3.4-1 +- Upgrade to mdadm-3.4 +- Resolves bz1303380 + +* Mon May 30 2016 Xiao Ni - 3.3.4-4 +- Fix Degraded Raid1 array becomes inactive after rebooting +- Resolves bz1337004 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.3.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Oct 5 2015 Jes Sorensen - 3.3.4-2 +- Fix race when assembling or stopping IMSM RAID arrays +- Resolves bz1268955 + +* Mon Oct 5 2015 Jes Sorensen - 3.3.4-1 +- Upgrade to mdadm-3.3.4 +- Resolves bz1246474 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Aug 26 2014 Jes Sorensen - 3.3.2-1 +- Upgrade to mdadm-3.3.2 +- Resolves bz1132847 +* Sun Aug 17 2014 Fedora Release Engineering - 3.3.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Aug 5 2014 Jes Sorensen - 3.3.1-6 +- Apply proper fix for bz1125883, clean up after rogue patch application +- Resolves bz1125883 + +* Mon Aug 04 2014 Dan Horák - 3.3.1-5 +- revert the previous fix, not upstream yet + +* Mon Aug 04 2014 Dan Horák - 3.3.1-4 +- fix FTBFS on ppc64 (#1125883) + +* Tue Jul 29 2014 Jes Sorensen - 3.3.1-3 +- Improve error message for "--grow -n2" when used on Linear arrays +- Fix problem where explicitly specified arrays were not assembled if + they were disabled in /etc/mdadm.conf +- Resolves bz1122146, bz1124310 + +* Thu Jun 12 2014 Jes Sorensen - 3.3.1-2 +- Revert 'change' event support fix from 3.3.1-1 - this requires a lot + more testing if we are to go there. + +* Tue Jun 10 2014 Jes Sorensen - 3.3.1-1 +- Update to mdadm-3.3.1 +- Fixup mdadm.rules to honor 'change' events +- Resolvez bz1105136 + +* Sat Jun 07 2014 Fedora Release Engineering - 3.3-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Mar 14 2014 Jes Sorensen - 3.3-7 +- Don't depend on syslog.target in mdmonitor.service +- Resolves bz1055202 + +* Fri Jan 31 2014 Jes Sorensen - 3.3-6 +- Revert changes introduced in 3.3-5, they were based on incorrect + recommendations. +- Resolves bz1053176 + +* Thu Jan 30 2014 Jes Sorensen - 3.3-5 +- Do not create /var/run/mdadm in the rpm file, since this is sitting on + tmpfs and is created by tmpfiles during boot. +- Resolves bz1053176 + +* Thu Oct 10 2013 Jes Sorensen - 3.3-4 +- Fix byteswap macros return types to allow for building on big endian + architectures again. +- Resolves bz1015494 + +* Wed Oct 9 2013 Jes Sorensen - 3.3-3 +- Check for DM_UDEV_DISABLE_OTHER_RULES_FLAG instead of + DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules +- Resolves bz1015521 + +* Tue Oct 8 2013 Jes Sorensen - 3.3-2 +- Fix dracut requirement, minimum version 034-1 + +* Thu Sep 5 2013 Jes Sorensen - 3.3-1 +- Update to mdadm-3.3 +- Resolves bz977826 + +* Tue Aug 13 2013 Jes Sorensen - 3.2.6-21 +- Fix pointless rpmbuild noise over mismatching date info +- Remove Fedora 17 support +- Fix problem where first stop command doesn't stop container during + IMSM volume's reshape bz956053 (f18), bz956056 (f19) + +* Sat Aug 03 2013 Fedora Release Engineering - 3.2.6-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Apr 24 2013 Jes Sorensen - 3.2.6-19 +- Fix problem where rebuild of IMSM RAID5 volume started in OROM, + does not proceed in OS +- Resolves bz956021 (f18), bz956026 (f17), bz956031 (f19) + +* Tue Apr 23 2013 Jes Sorensen - 3.2.6-18 +- Fix problem with IMSM metadata where resync progress would be lost + if an array was stopped during ongoing expansion of a RAID1/5 volume. +- Resolves bz948745 + +* Tue Apr 23 2013 Jes Sorensen - 3.2.6-17 +- Reorder patches to allow for udev query patch to be applied on + Fedora 17 as well. + +* Mon Apr 22 2013 Jes Sorensen - 3.2.6-16 +- Rely on rpm macros to place files in correct directories, and match /usr + move +- Resolves bz955248 + +* Thu Mar 7 2013 Jes Sorensen - 3.2.6-15 +- Cleanup .spec file handling of different Fedora versions +- Resolves bz914629 + +* Tue Feb 5 2013 Jes Sorensen - 3.2.6-14 +- Resync with final version of upstream patches for launching mdmon + via systemctl. Require dracut 024-025 or later to match. +- Resolves bz879327 + +* Fri Feb 1 2013 Jes Sorensen - 3.2.6-13 +- Update to upstream solution for launching mdmon via systemctl +- Resolves bz879327 + +* Mon Jan 21 2013 Jes Sorensen - 3.2.6-12 +- Launch mdmon via systemctl to avoid it ending up in the wrong cgroup + and getting killed in the boot process when switching from the + initrd to the real root. +- Resolves bz879327 + +* Tue Jan 8 2013 Jes Sorensen - 3.2.6-11 +- Move code to leave udev cgroup into mdmon and excute it after we + work, to make sure it actually does the right thing. + +* Mon Jan 7 2013 Jes Sorensen - 3.2.6-10 +- Fix mdmonitor-takeover.service dangling symlink problem for real + +* Mon Jan 7 2013 Jes Sorensen - 3.2.6-9 +- Reintroduce fix for removing dangling symlink of + mdmonitor-takeover.service which got lost in the fix introduced in + 3.2.6-8 + +* Fri Jan 4 2013 Jes Sorensen - 3.2.6-8 +- mdmonitor-takeover.service is obsolete with the --offroot support, + and it is harmful as of 3.2.6 +- Resolves bz834245 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-7 +- Fix issue with udev scripts where if an raid volume with one of + the disks failing, the failed disk is still present in the volume + and container. The raid volume stays is in normal state (should be + degraded) and the rebuild cannot start. +- Resolves bz886123 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-5 +- mdadm-sysvinit is obsolete given that we no longer support booting + using sysvinit scripts +- Resolves bz884993 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-4 +- Fix typo in error message in fix for 880972. No functional changes + +* Fri Nov 30 2012 Jes Sorensen - 3.2.6-3 +- Disallow creating a second IMSM RAID array size 0 (bz880972) +- Disallow creating IMSM RAIDs that spans multiple controllers (bz880974) +- Resolves bz880972, bz880974 + +* Thu Nov 15 2012 Doug Ledford - 3.2.6-2 +- Modify mdadm to set the cgroup of mdmon to systemd if it's available +- Related bz873576 (and others) + +* Thu Oct 25 2012 Jes Sorensen - 3.2.6-1 +- Upgrade to mdadm-3.2.6 +- Resolves bz869930 + +* Fri Oct 19 2012 Jes Sorensen - 3.2.5-14 +- Dummy update to work around bodhi breakage. No actual code changes. + +* Fri Oct 19 2012 Jes Sorensen - 3.2.5-13 +- Relax installation requirements for abrt script to only depend on + libreport-filesystem rather than the full abrt package + +* Thu Oct 18 2012 Jes Sorensen - 3.2.5-12 +- Add abrt script to retrieve /proc/mdstat output in case of crash +- Resolves bz867842 + +* Wed Oct 17 2012 Jes Sorensen - 3.2.5-11 +- Remove package requirements for udev and initscripts for F18+ +- Resolves bz864562 + +* Wed Oct 3 2012 Jes Sorensen - 3.2.5-9 +- Resolve issue with ambiguous licenses +- Resolves bz862761 + +* Mon Sep 10 2012 Jes Sorensen - 3.2.5-8 +- Switch to using new systemd macros for F18+ +- Resolves bz850202 + +* Thu Aug 2 2012 Jes Sorensen - 3.2.5-7 +- Remove bogus rogue patch applied in 3.2.5-5 with justification and + without following the structure of the mdadm package. + +* Fri Jul 27 2012 Fedora Release Engineering - 3.2.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 18 2012 Karsten Hopp 3.2.5-5 +- include in some to avoid type clashes. + same problem as rhbz #840902 + +* Mon Jul 16 2012 Jes Sorensen - 3.2.5-4 +- Move /etc/tmpfiles.d/mdadm.conf to /lib/tmpfiles.d/ to comply with + Fedora tmpfile rules +- Resolves bz840187 + +* Mon Jun 25 2012 Jes Sorensen - 3.2.5-3 +- Fix problem where reshape of RAID volume is broken after trying to + stop all MD devices. +- Enhance raid-check to allow the adming to specify the max number of + concurrent arrays to be checked at any given time. +- Resolves bz830177, bz820124 + +* Wed Jun 13 2012 Jes Sorensen - 3.2.5-2 +- Fix uninstall script to remove dangling symlink to + mdmonitor-takeover.service, if the mdadm package is uninstalled from + the system. +- Resolves bz828354 + +* Mon May 21 2012 Jes Sorensen - 3.2.5-1 +- Upgrade to mdadm-3.2.5 +- Resolves bz822850 + +* Tue May 15 2012 Jes Sorensen - 3.2.4-3 +- Fix mdadm-3.2.4 introduced bug where --add fails in common cases +- Resolves bz821717 (f17) bz821718 (f16) bz821719 (f15) + +* Thu May 10 2012 Jes Sorensen - 3.2.4-2 +- Fix mdadm.conf to use 'd' for /var/run/mdadm creation, to avoid the + map file getting deleted during boot. + +* Thu May 10 2012 Jes Sorensen - 3.2.4-1 +- Upgrade to mdadm-3.2.4 +- Resolves bz820534 (rawhide) bz820527 (f17) bz820531 (f16) bz820532 (f15) + +* Mon Apr 30 2012 Jes Sorensen - 3.2.3-9 +- Fix Monitor mode sometimes crashes when a resync completes +- Fix missing symlink for mdadm container device when incremental creates + the array +- Make sure when creating a second array in a container that the second + array uses all available space since leaving space for a third array + is invalid +- Validate the number of imsm volumes per controller +- Fix issues with imsm arrays and disks larger than 2TB +- Add support for expanding imsm arrays/containers +- The support for expanding imsm arrays/containers was accepted upstream, + update to the official patches from there +- Fix for the issue of --add not being very smart +- Fix an issue causing rebuilds to fail to restart on reboot (data + corrupter level problem) +- Reset the bad flag on map file updates +- Correctly fix failure when trying to add internal bitmap to 1.0 arrays +- Resolves: bz817023 (f17) bz817024 (f17) bz817026 (f17) bz817028 (f17) +- Resolves: bz817029 (f17) bz817032 (f17) bz817038 (f17) bz808774 (f17) +- Resolves: bz817039 (f17) bz817042 (f17) + +* Mon Apr 30 2012 Jes Sorensen - 3.2.3-8 +- Fix bug where IMSM arrays stay inactive in case a reboot is +- performed during the reshape process. +- Resolves: bz817522 (f17) bz817535 (f16) bz817537 (f15) + +* Wed Mar 28 2012 Jes Sorensen - 3.2.3-7 +- Fix issue when re-adding drive to a raid1 array with bitmap +- Resolves: bz807743 (f17) bz769323 (f16) bz791159 (f15) + +* Thu Feb 23 2012 Jes Sorensen - 3.2.3-6 +- Fix double free on buggy old kernel sysfs read +- Fix segfault if trying to write superblock to non existing device +- Resolves: bz795707 (f17) bz795747 (f16) bz795748 (f15) +- Resolves: bz795461 (f17) bz795749 (f16) bz795750 (f15) + +* Thu Feb 16 2012 Jes Sorensen - 3.2.3-5 +- Fix issue with devices failing to be added to a raid using bitmaps, + due to trying to write the bitmap with mis-aligned buffers using + O_DIRECT +- Resolves: bz789898 (f16) bz791189 (f15) + +* Mon Jan 30 2012 Jes Sorensen - 3.2.3-4 +- Add support for --offroot to mdadm/mdmon +- Resolves: bz785739 (rawhide) bz785737 (f16) bz771405 (f15) + +* Thu Jan 12 2012 Jes Sorensen - 3.2.3-3 +- Fix case where we have to retry in case a remove fails due to an array + being busy +- Resolves: bz773337 (rawhide) bz773340 (f16) bz773341 (f15) + +* Thu Jan 5 2012 Jes Sorensen - 3.2.3-2 +- Workaround for gcc-4.7 strict aliasing breaking the build + +* Wed Jan 4 2012 Jes Sorensen - 3.2.3-1 +- Update to upstream 3.2.3 +- Resolves: bz770110 (rawhide) bz771413 (f16) bz759014 (rawhide) +- Resolves: bz759015 (f16) bz759035 (rawhide) bz759036 (f16) +- Resolves: bz771608 (f15) bz759016 (f15) bz759039 (f15) + +* Mon Nov 21 2011 Jes Sorensen - 3.2.2-15 +- Backport upstream fix for memory leak that can prevent migration to + RAID5 from completing. +- Backport upstream fix preventing mounting a device while it is in + process of reshaping +- Resolves: bz755005 bz755009 + +* Wed Nov 9 2011 Jes Sorensen - 3.2.2-14 +- Backport upstream fixes to prevent growing v0.90 metadata raid out + of supported size. +- Add missing 'disable' argument to systemctl in preun script +- Resolves: bz735306 (Fedora 15) bz748731 (Fedora 16) bz748732 (rawhide), + Resolves: bz751716 + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.2-13 +- Rebuilt for glibc bug#747377 + +* Sat Oct 22 2011 Jes Sorensen - 3.2.2-12 +- Backport upstream version of fix for IMSM RAID assembly problem, + which resolves issues when booting off sysvinit based system. +- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16) + +* Wed Oct 19 2011 Jes Sorensen - 3.2.2-11 +- Fix systemd dependency problem +- Resolves: bz741115 (F16) bz744226 (rawhide) + +* Wed Oct 19 2011 Jes Sorensen - 3.2.2-10 +- Fix problem where a dirty IMSM RAID isn't assembled correctly during + boot, preventing booting from this RAID device. +- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16) +- Fix race between udev and mdadm when assembling md device using + mdadm -I, where udev would spawn an additional mdadm command to + perform the assembly in parallel. + +* Wed Aug 31 2011 Doug Ledford - 3.2.2-9 +- Fix boot with older imsm arrays that have an unused attribute set +- Resolves: bz729205 + +* Thu Aug 25 2011 Doug Ledford - 3.2.2-8 +- Rework the 65-md-incremental.rules file to add the following support: + Nested md raid arrays should now work + MD on top of LUKS or other lvm based devices should now work + We should no longer grab multipath paths before multipath can + +* Wed Jul 27 2011 Doug Ledford - 3.2.2-7 +- Fix a bug with readding a device +- Fix a bug with writemostly flag handling + +* Mon Jul 18 2011 Doug Ledford - 3.2.2-6 +- Bump and rebuild again + +* Fri Jul 15 2011 Doug Ledford - 3.2.2-5 +- Bump and rebuild to keep version ahead of f15 version + +* Thu Jul 14 2011 Doug Ledford - 3.2.2-4 +- Fix minor issue in man page +- Resolves: bz717795 + +* Thu Jul 07 2011 Milan Broz - 3.2.2-3 +- Use unit files with systemd. (johannbg) +- Add sub-package sysvinit for SysV init script. +- Resolves: bz713573 + +* Wed Jul 06 2011 Milan Broz - 3.2.2-2 +- Fix build on PPC. +- Resolves: bz719380 + +* Tue Jun 28 2011 Milan Broz - 3.2.2-1 +- Update to latest upstream version +- Resolves: bz714083 + +* Tue Jun 14 2011 Doug Ledford - 3.2.1-5 +- Fix for bz710646 + +* Thu Mar 31 2011 Doug Ledford - 3.2.1-4 +- Somehow the 64-md-raid.rules file went missing. Put it back. +- Resolves: bz692248 + +* Thu Mar 31 2011 Doug Ledford - 3.2.1-3 +- Fix mdmonitor init script setup of SELinux on PIDPATH +- Resolves: bz692559 + +* Mon Mar 28 2011 Doug Ledford - 3.2.1-2 +- Restore build command to sane command instead of test command + +* Mon Mar 28 2011 Doug Ledford - 3.2.1-1 +- Update to latest upstream version +- Resolves: 691353 + +* Fri Mar 25 2011 Doug Ledford - 3.1.5-1 +- Update to latest upstream stable release +- Update mdadm.rules file to honor noiswmd and nodmraid command line options +- Ghost the directory in /var/run, create /var/run/mdadm in mdmonitor init + script +- Don't report mismatch counts on either raid1 or raid10 +- Check both active and idle arrays during raid check runs +- Move the raid-check script from cron.weekly to /usr/sbin, add a crontab + file to /etc/cron.d and mark it config(noreplace). This way users can + select their own raid-check frequency and have it honored through + upgrades. +- Allow the raid-check script to set the process and io priority of the + thread performing the check in order to preserve responsiveness of the + machine during the check. +- Resolves: 633229, 656620. 679843, 671076, 659933 + +* Tue Feb 08 2011 Fedora Release Engineering - 3.1.3-0.git20100804.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Aug 04 2010 Doug Ledford - 3.1.3-0.git20100804.2 +- Add udev patch to not have incremental assembly in two rules files + +* Wed Aug 04 2010 Doug Ledford - 3.1.3-0.git20100804.1 +- Update to latest upstream release (resolves an issue with stale lock + files on the md device map file) + +* Thu Jul 22 2010 Doug Ledford - 3.1.3-0.git20100722.2 +- Remove the glibc-static buildreq and don't build the static mdadm since + we don't install it anyway +- Remove the udev file since adding it was supposed to be a rawhide only change + +* Thu Jul 22 2010 Doug Ledford - 3.1.3-0.git20100722.1 +- Change git date format to the correct format (YYYYMMDD) +- Update to latest upstream push (fixes bz604023) + +* Tue Jul 20 2010 Doug Ledford - 3.1.3-0.git07202010.2 +- Fix racy locking of mapfile (bz616596) + +* Tue Jul 20 2010 Doug Ledford - 3.1.3-0.git07202010.1 +- Update to latest git repo (3.1.2 plus pending changes, fixes bz602457) +- Add in 64-md-raid.rules to compensate for it no longer being in udev + (bz581905) +- Remove mdadm.static as its no longer used in initrd creation + +* Tue Apr 13 2010 Doug Ledford - 3.1.2-10 +- Minor update to mdadm.rules to make anaconda happy + +* Thu Apr 08 2010 Doug Ledford - 3.1.2-9 +- Slight fix on container patch + +* Thu Apr 08 2010 Doug Ledford - 3.1.2-8 +- Updated container patch that also enables mdadm -IRs for imsm devices + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-7 +- Fix up directory in mdmonitor init script so that we restart mdmon like we + are supposed to +- Add a rule to run incremental assembly on containers in case there are + multiple volumes in a container and we only started some of them in the + initramfs +- Make -If work with imsm arrays. We had too restrictive of a test in + sysfs_unique_holder. +- Make incremental assembly of containers act like incremental assembly of + regular devices (aka, --run is needed to start a degraded array) + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-6 +- Typo in new rules file + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-5 +- Enable incremental support for imsm devices + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-4 +- One line fix for ppc64 compiles + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-3 +- Clean up directory mess once and for all +- Add incremental remove support + +* Wed Mar 17 2010 Doug Ledford - 3.1.2-2 +- Add a little more paranoia checking to the RebuildMap code to avoid ever + having the same infinite loop as in bz569019 again even if we change file + locations to somewhere where we can't create a mapfile + +* Tue Mar 16 2010 Doug Ledford - 3.1.2-1 +- Grab latest upstream release instead of git repo snapshot (bz552344, bz572561) +- The lack of /dev/md is causing problems, so add code to mapfile.c to cause + us to create /dev/md if it doesn't exist (bz569019) + +* Tue Feb 23 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.6 +- Newer version of imsm patch that leaves warning, but only when there + actually are too many devices on the command line (bz554974) + +* Sun Feb 21 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.5 +- The uuid patch cause a different problem during assembly, so use a gross + hack to work around the uuid issue that won't break assembly until fixed + properly upstream (bz567132) + +* Sun Feb 21 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.4 +- Fix problem with booting multiple imsm containers when they aren't listed + "just so" in the mdadm.conf file (bz554974) + +* Fri Feb 19 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.3 +- Don't run the raid-check script if the kernel doesn't support + md devices (bz557053) +- Don't report any mismatch_cnt issues on raid1 devices as there are + legitimate reasons why the count may not be 0 and we are getting enough + false positives that it renders the check useless (bz554217, bz547128) + +* Thu Feb 18 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.2 +- Fix s390/ppc64 UUID byte swap issue + +* Wed Feb 17 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.1 +- Update to head of upstream git repo, which contains a significant number + of bug fixes we need (bz543746) + +* Fri Jan 15 2010 Doug Ledford - 3.0.3-3 +- Fix crash when AUTO keyword is in mdadm.conf (bz552342) + +* Tue Dec 01 2009 Doug Ledford - 3.0.3-2 +- Minor tweak to init script for LSB compliance (bz527957) + +* Wed Nov 04 2009 Doug Ledford - 3.0.3-1 +- New upstream release 3.0.3 (bz523320, bz527281) +- Update a couple internal patches +- Drop a patch in that was in Neil's tree for 3.0.3 that we had pulled for + immediate use to resolve a bug +- Drop the endian patch because it no longer applied cleanly and all attempts + to reproduce the original problem as reported in bz510605 failed, even up + to and including downloading the specific package that was reported as + failing in that bug and trying to reproduce with it on both ppc and ppc64 + hardware and with both ppc and ppc64 versions on the 64bit hardware. + Without a reproducer, it is impossible to determine if a rehashed patch + to apply to this code would actually solve the problem, so remove the patch + entirely since the original problem, as reported, was an easy to detect DOA + issue where installing to a raid array was bound to fail on reboot and so + we should be able to quickly and definitively tell if the problem resurfaces. +- Update the mdmonitor init script for LSB compliance (bz527957) +- Link from mdadm.static man page to mdadm man page (bz529314) +- Fix a problem in the raid-check script (bz523000) +- Fix the intel superblock handler so we can test on non-scsi block devices + +* Fri Oct 2 2009 Hans de Goede - 3.0.2-1 +- New upstream release 3.0.2 +- Add a patch fixing mdadm --detail -export segfaults (bz526761, bz523862) +- Add a patch making mdmon store its state under /dev/.mdadm for initrd + mdmon, rootfs mdmon handover +- Restart mdmon from initscript (when running) for rootfs mdmon handover + +* Thu Sep 17 2009 Doug Ledford - 3.0-4 +- Stop some mdmon segfaults (bz523860) + +* Tue Sep 15 2009 Doug Ledford - 3.0-3 +- Update to current head of upstream git repo for various imsm related fixes + (fixes bz523262) +- Fix display of metadata version in output of Detail mode +- Add UUID output to --detail --export (bz523314) + +* Fri Jul 24 2009 Doug Ledford - 3.0-2 +- Improved raid-check script as well as the ability to configure what devices + get checked +- Endian patch for uuid generation + +* Mon Jun 29 2009 Doug Ledford - 3.0-1 +- Remove stale patches already accepted by upstream +- Fix the raid-check script to only try and check a device if it is + checkable +- Update to official mdadm-3.0 version +- Resolves: bz505587, bz505552 + +* Tue May 19 2009 Doug Ledford - 3.0-0.devel3.7 +- Move the mdadm.map file from /dev/md/ to /dev/ so the installer doesn't + need to precreate the /dev/md/ directory in order for incremental + assembly to work + +* Tue May 19 2009 Doug Ledford - 3.0-0.devel3.6 +- Only check raid devices automatically, do not attempt to repair them + during the weekly data scrubbing + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.5 +- Fix a few issues with the new code to determine when a device gets to + keep its name and when it doesn't + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.4 +- Change the perms on the udev rules file, it doesn't need to be +x + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.3 +- Slightly tweak the udev rules to make sure we don't start arrays + while running in rc.sysinit...leave array starting to it instead +- Modify mdadm to put its mapfile in /dev/md instead of /var/run/mdadm + since at startup /var/run/mdadm is read-only by default and this + breaks incremental assembly +- Change how mdadm decides to assemble incremental devices using their + preferred name or a random name to avoid possible conflicts when plugging + a foreign array into a host + +* Wed Mar 18 2009 Doug Ledford - 3.0-0.devel3.2 +- Change around the mdadm udev rules we ship to avoid a udev file conflict + +* Tue Mar 17 2009 Doug Ledford - 3.0-0.devel3.1 +- Update to latest devel release +- Remove the no longer necessary udev patch +- Remove the no longer necessary warn patch +- Remove the no longer necessary alias patch +- Update the mdadm.rules file to only pay attention to device adds, not + changes and to enable incremental assembly +- Add a cron job to run a weekly repair of the array to correct bad sectors +- Resolves: bz474436, bz490972 + +* Wed Feb 25 2009 Fedora Release Engineering - 3.0-0.devel2.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Doug Ledford - 3.0-0.devel2.2 +- Readd our old mdadm rules file that does incremental assembly +- Remove the new mdadm rules file from upstream as we already have this in + our udev package (and the one in the udev package already has a bug fixed) + +* Thu Feb 12 2009 Doug Ledford - 3.0-0.devel2.1 +- Update to latest upstream devel release +- Use the udev rules file included with mdadm instead of our own +- Drop all the no longer relevant patches +- Fix a build error in mdopen.c +- Fix the udev rules path in Makefile +- Fix a compile issue with the __le32_to_cpu() macro usage (bad juju to + to operations on the target of the macro as it could get executed + multiple times, and gcc now throws an error on that) +- Add some casts to some print statements to keep gcc from complaining + +* Fri Oct 24 2008 Doug Ledford - 2.6.7.1-1 +- Updated to latest upstream stable release (#466803) +- Change udev rule to not assemble degraded arrays (#453314) +- Fix metadata matching in config file (#466078) +- Fix assembly of raid10 devices (#444237) +- Fix incremental assembly of partitioned raid devices (#447818) + +* Thu Jun 26 2008 Doug Ledford - 2.6.7-1 +- Update to latest upstream version (should resolve #444237) +- Drop incremental patch as it's now part of upstream +- Clean up all the open() calls in the code (#437145) +- Fix the build process to actually generate mdassemble (#446988) +- Update the udev rules to get additional info about arrays being assembled + from the /etc/mdadm.conf file (--scan option) (#447818) +- Update the udev rules to run degraded arrays (--run option) (#452459) + +* Thu Apr 17 2008 Bill Nottingham - 2.6.4-4 +- make /dev/md if necessary in incremental mode (#429604) +- open RAID devices with O_EXCL to avoid racing against other --incremental processes (#433932) + +* Fri Feb 1 2008 Bill Nottingham - 2.6.4-3 +- add a udev rules file for device assembly (#429604) + +* Fri Jan 18 2008 Doug Ledford - 2.6.4-2 +- Bump version and rebuild + +* Fri Oct 19 2007 Doug Ledford - 2.6.4-1 +- Update to latest upstream and remove patches upstream has taken + +* Tue Aug 28 2007 Fedora Release Engineering - 2.6.2-5 +- Rebuild for selinux ppc32 issue. + +* Mon Jul 09 2007 Doug Ledford - 2.6.2-4 +- Oops, if we call -C -e1, minor_version is no longer properly set, fix that + up +- Related: bz230207 + +* Fri Jul 06 2007 Doug Ledford - 2.6.2-3 +- Oops, had to update the file leak patch, missed one thing +- Minor tweak to return codes in init script and add LSB header +- Resolves: bz244582, bz246980 + +* Mon Jul 02 2007 Doug Ledford - 2.6.2-2 +- Fix a file leak issue when mdadm is in monitor mode +- Update mdadm init script so that status will always run and so + return codes are standards compliant +- Fix assembly of version 1 superblock devices +- Make the attempt to create an already running device have a clearer + error message +- Allow the creation of a degraded raid4 array like we allow for raid5 +- Make mdadm actually pay attention to raid4 devices when in monitor mode +- Make the mdmonitor script use daemon() correctly +- Fix a bug where manage mode would not add disks correctly under certain + conditions +- Resolves: bz244582, bz242688, bz230207, bz169516, bz171862, bz171938 +- Resolves: bz174642, bz224272, bz186524 + +* Mon Jul 02 2007 Doug Ledford - 2.6.2-1 +- Update to latest upstream +- Remove requirement for /usr/sbin/sendmail - it's optional and not on by + default, and sendmail isn't *required* for mdadm itself to work, and isn't + even required for the monitoring capability to work, just if you want to + have the monitoring capability do the automatic email thing instead of + run your own program (and if you use the program option of the monitor + capability, your program could email you in a different manner entirely) + +* Mon Apr 16 2007 Doug Ledford - 2.6.1-4 +- More cleanups for merge review process +- Related: bz226134 + +* Wed Apr 11 2007 Doug Ledford - 2.6.1-3 +- Various cleanups as part of merge review process +- Related: bz226134 + +* Sat Mar 31 2007 Doug Ledford - 2.6.1-2 +- Oops, missing a dependency in the Makefile + +* Sat Mar 31 2007 Doug Ledford - 2.6.1-1 +- Update to latest upstream version +- Resolves: bz233422 + +* Fri Jan 26 2007 Doug Ledford - 2.6-1 +- Update to latest upstream version +- Remove the mdmpd daemon entirely. Now that multipath tools from the lvm/dm + packages handles multipath devices well, this is no longer needed. +- Various cleanups in the spec file + +* Thu Nov 09 2006 Doug Ledford - 2.5.4-3 +- Add a fix for the broken printout of array GUID when using the -E --brief + flags + +* Fri Oct 13 2006 Doug Ledford - 2.5.4-2 +- tag present on another branch and can't be forcibly moved + required number bump + +* Fri Oct 13 2006 Doug Ledford - 2.5.4-1 +- Update to 2.5.4 (listed as a bugfix update by upstream) +- Remove previous bitmap patch that's now part of 2.5.4 + +* Sun Oct 8 2006 Doug Ledford - 2.5.3-2 +- Fix a big-endian machine error in the bitmap code (Paul Clements) + +* Mon Aug 7 2006 Doug Ledford - 2.5.3-1 +- Update to 2.5.3 which upstream calls a "bug fix" release + +* Wed Jul 12 2006 Jesse Keating - 2.5.2-1.1 +- rebuild + +* Fri Jul 7 2006 Doug Ledford - 2.5.2-1 +- Update to 2.5.2 +- Remove auto default patch as upstream now has a preferred default auto method + +* Wed Mar 8 2006 Peter Jones - 2.3.1-3 +- fix build on ppc64 + +* Wed Mar 8 2006 Jeremy Katz - 2.3.1-2 +- fix build on ppc + +* Wed Mar 8 2006 Jeremy Katz - 2.3.1-1 +- update to 2.3.1 to fix raid5 (#184284) + +* Fri Feb 10 2006 Jesse Keating - 2.2-1.fc5.2.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2.2-1.fc5.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Mon Dec 05 2005 Warren Togami 2.2-1 +- 2.2 upgrade (#167897) +- disable diet because we don't ship it anymore + and we don't actually use mdassemble now + +* Mon May 16 2005 Doug Ledford 1.11.0-4.fc4 +- Make the mdmonitor init script use the pid-file option, major cleanup + of the script now possible (#134459) + +* Mon May 16 2005 Doug Ledford 1.11.0-3.fc4 +- Put back the obsoletes: raidtools that was present in 1.11.0-1.fc4 + +* Mon May 16 2005 Doug Ledford 1.11.0-2.fc4 +- Change the default auto= mode so it need not be on the command line to + work with udev, however it is still supported on the command line (#132706) +- Add a man page (from Luca Berra) for mdassemble + +* Wed May 11 2005 Doug Ledford - 1.11.0-1.fc4 +- Upgrade to 1.11.0 + +* Wed Apr 27 2005 Jeremy Katz - 1.9.0-3.fc4 +- fix mdmonitor initscript (#144717) + +* Mon Mar 21 2005 Doug Ledford 1.9.0-2 +- Build mdadm.static and mdassemble (static as well) to be used in initrd + images + +* Wed Mar 09 2005 Doug Ledford 1.9.0-1 +- Initial upgrade to 1.9.0 and update of doc files +- Fix an s390 build error + +* Mon Oct 04 2004 Doug Ledford 1.6.0-2 +- Remove /etc/mdadm.conf from the file list. Anaconda will write one out + if it's needed. + +* Fri Oct 01 2004 Doug Ledford 1.6.0-1 +- Update to newer upstream version +- Make mdmpd work on kernels that don't have the event interface patch + +* Fri Jul 30 2004 Dan Walsh 1.5.0-11 +- Create a directory /var/run/mdadm to contain mdadm.pid +- This cleans up SELinux problem + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Sat May 22 2004 Doug Ledford - 1.5.0-9 +- Fix Makefile and build method to satisfy bz #123769 +- Add mdmpd man page, update mdmpd version to 0.3 - bz #117160 +- Make sure mdadm --monitor closes all md device files so that md devices + can be stopped while mdadm is still running - bz #119532 + +* Thu May 20 2004 Jeremy Katz - 1.5.0-8 +- remove unneeded patch, can use --run instead + +* Wed May 19 2004 Jeremy Katz - 1.5.0-7 +- add patch with reallyforce mode on creation to be used by anaconda + +* Wed May 12 2004 Doug Ledford 2.5.0-6 +- Fix a bug in the postun scriptlet related to downgrading to a version + of mdadm that doesn't include the mdmpd daemon. + +* Fri May 07 2004 Doug Ledford 1.5.0-5 +- Disable service mdmpd by default to avoid [Failed] messages on + current 2.6 kernels. Possibly re-enable it by default once the + 2.6 kernels have the md event interface. + +* Thu Apr 22 2004 Doug Ledford 1.5.0-4 +- Update mdmonitor script to start daemon more cleanly +- Repackage mdmpd tarball to include gcc-3.4 changes and to make + mdmpd properly daemonize at startup instead of forking and leaving + the child attached to the terminal. + +* Thu Mar 4 2004 Bill Nottingham 1.5.0-3 +- ship /var/run/mpmpd (#117497) + +* Thu Feb 26 2004 Doug Ledford 1.5.0-2 +- Add a default MAILADDR line to the mdadm.conf file installed by default + (Bugzilla #92447) +- Make it build with gcc-3.4 + +* Mon Feb 23 2004 Doug Ledford 1.5.0-1 +- Update to 1.5.0 (from Matthew J. Galgoci ) + +* Sun Nov 16 2003 Doug Ledford 1.4.0-1 +- fix problem with recovery thread sleeping in mdmpd + +* Fri Nov 14 2003 Doug Ledford +- sync upstream +- add mdmpd package into mdadm package + +* Wed Sep 10 2003 Michael K. Johnson 1.3.0-1 +- sync upstream + +* Tue Mar 11 2003 Michael K. Johnson 1.1.0-1 +- sync upstream + +* Tue Jan 28 2003 Michael K. Johnson 1.0.1-1 +- update for rebuild + +* Wed Dec 25 2002 Tim Powers 1.0.0-8 +- fix references to %%install in the changelog so that it will build + +* Fri Dec 13 2002 Elliot Lee 1.0.0-7 +- Rebuild + +* Fri Jul 12 2002 Michael K. Johnson +- Changed RPM Group to System Environment/Base + +* Wed May 15 2002 Michael K. Johnson +- minor cleanups to the text, conditionalize rm -rf +- added mdmonitor init script + +* Fri May 10 2002 +- update to 1.0.0 +- Set CXFLAGS instead of CFLAGS + +* Sat Apr 6 2002 +- change %%install to use "make install" + +* Fri Mar 15 2002 +- beautification +- made mdadm.conf non-replaceable config +- renamed Copyright to License in the header +- added missing license file +- used macros for file paths + +* Fri Mar 15 2002 Luca Berra +- Added Obsoletes: mdctl +- missingok for configfile + +* Tue Mar 12 2002 NeilBrown +- Add md.4 and mdadm.conf.5 man pages + +* Fri Mar 08 2002 Chris Siebenmann +- builds properly as non-root. + +* Fri Mar 08 2002 Derek Vadala +- updated for 0.7, fixed /usr/share/doc and added manpage + +* Tue Aug 07 2001 Danilo Godec +- initial RPM build