From d100e0a4c3f68557f6686106310efb1f90b1972b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 18:58:57 +0000 Subject: [PATCH 01/22] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 9f8e3a0..155e516 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,7 +1,7 @@ Name: mdadm Version: 4.2 %define subversion rc2 -Release: %{?subversion:%{subversion}}%{?dist} +Release: %{?subversion:%{subversion}}%{?dist}.1 Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -90,6 +90,9 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* 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 From 5538bbe1334165ffb994a2e409bc4e5b24946ae8 Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Mon, 21 Mar 2022 13:07:28 +0800 Subject: [PATCH 02/22] Update to mdadm 4.2 Resolves: bz#1988236 Signed-off-by: Xiao Ni --- mdadm.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mdadm.spec b/mdadm.spec index 9f8e3a0..1c49967 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,7 +1,6 @@ Name: mdadm Version: 4.2 -%define subversion rc2 -Release: %{?subversion:%{subversion}}%{?dist} +Release: 1%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -90,6 +89,10 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* Mon Mar 21 2022 Xiao Ni - 4.2 +- Update to mdadm-4.2 +- Resolves bz#1988236 + * Mon Aug 09 2021 Xiao Ni - 4.2-rc2 - Update to mdadm-4.2-rc2 - Resolves bz#1988236 diff --git a/sources b/sources index a190524..6b62e85 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (mdadm-4.2-rc2.tar.xz) = 09a3657284c7f98892f5be663d5e034252ff319d8ff1d235597efc373c156188d450e12f64a9a0fb9266b00035c1602133e487ce1961db1a12db05f7f9829249 +SHA512 (mdadm-4.2.tar.xz) = 57897a2b7fb8b0b88bece50501099872bb45ddb076cfc323d563588096d2b66b1ecba3724534943f651ace2bfe591482570700616500dc3398552e4f9ff0c37d From a5a30cdfb257bc8d2e1826d1da53d77016408a08 Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Mon, 21 Mar 2022 15:08:03 +0800 Subject: [PATCH 03/22] Update to mdadm-4.2 Resolves: bz#2066150 Signed-off-by: Xiao Ni --- mdadm.spec | 7 +++++-- sources | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mdadm.spec b/mdadm.spec index 155e516..c25f40b 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,7 +1,6 @@ Name: mdadm Version: 4.2 -%define subversion rc2 -Release: %{?subversion:%{subversion}}%{?dist}.1 +Release: 1%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -90,6 +89,10 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* 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 diff --git a/sources b/sources index a190524..6b62e85 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (mdadm-4.2-rc2.tar.xz) = 09a3657284c7f98892f5be663d5e034252ff319d8ff1d235597efc373c156188d450e12f64a9a0fb9266b00035c1602133e487ce1961db1a12db05f7f9829249 +SHA512 (mdadm-4.2.tar.xz) = 57897a2b7fb8b0b88bece50501099872bb45ddb076cfc323d563588096d2b66b1ecba3724534943f651ace2bfe591482570700616500dc3398552e4f9ff0c37d From 5ff6e957c0055e2210a088c3af068e64c26f8bf5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 20:49:03 +0000 Subject: [PATCH 04/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index c25f40b..297147b 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -89,6 +89,9 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* 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 From f2f7e3407463a974265fb4cd4bf68fe00325fd3e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 19:15:55 +0000 Subject: [PATCH 05/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 297147b..06886b6 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 2%{?dist} +Release: 3%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -89,6 +89,9 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* 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 From cdf21d08ef36728f088f69a79e30aa996ccd5a67 Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Mon, 30 Jan 2023 16:08:49 +0800 Subject: [PATCH 06/22] Update to latest upstream After updating to latest upstream, bug2163711 can be fixed. We don't use rhel only udev rule anymore and we use the udev rules from upstream. So we don't need to modify our rhel only udev rule again. Resolves: bz#2163711 Signed-off-by: Xiao Ni --- 0001-Unify-error-message.patch | 47 + 0002-mdadm-Fix-double-free.patch | 33 + ...-r0-grow-size-error-message-and-upda.patch | 83 + 0004-udev-adapt-rules-to-systemd-v247.patch | 67 + ...ce-error-prone-signal-with-sigaction.patch | 252 +++ ...-Respect-config-file-location-in-man.patch | 1533 +++++++++++++++++ 0007-mdadm-Update-ReadMe.patch | 48 + ...fig-man-regarding-default-files-and-.patch | 203 +++ 0009-mdadm-Update-config-manual.patch | 45 + 0010-Create-Build-use-default_layout.patch | 153 ++ 0011-mdadm-add-map_num_s.patch | 382 ++++ ...mdmon-Stop-parsing-duplicate-options.patch | 122 ++ 0014-Grow-block-n-on-external-volumes.patch | 41 + ...x-possible-memory-and-resource-leaks.patch | 90 + 0016-Mdmonitor-Fix-segfault.patch | 98 ++ 0017-Mdmonitor-Improve-logging-method.patch | 61 + ...LL-ptr-dereferences-and-memory-leaks.patch | 73 + ...ibility-for-get_imsm_dev-to-return-N.patch | 301 ++++ ...dadm-fix-coredump-of-mdadm-monitor-r.patch | 85 + ...util-replace-ioctl-use-with-function.patch | 31 + ...tore-commit-45a87c2f31335-to-fix-clu.patch | 110 ++ ...-imsm-introduce-get_disk_slot_in_dev.patch | 122 ++ ...-imsm-use-same-slot-across-container.patch | 252 +++ ...block-changing-slots-during-creation.patch | 122 ++ ...ck-update-ppl-for-non-raid456-levels.patch | 177 ++ ...m-Fix-array-size-mismatch-after-grow.patch | 30 + ...-dead-code-in-imsm_fix_size_mismatch.patch | 34 + ...ame-as-char-array-instead-of-pointer.patch | 40 + ...tor-use-snprintf-to-fill-device-name.patch | 133 ++ ...uild-static-build-with-everything-an.patch | 42 + ...anup-validate_geometry_ddf_container.patch | 141 ++ ...nter-dereference-in-validate_geometr.patch | 49 + ...se-after-close-bug-by-closing-after-.patch | 85 + ...gfault-when-calling-NULL-get_bad_blo.patch | 36 + ...Fix-mdadm-r-remove-option-regression.patch | 78 + ...-Fix-optional-write-behind-parameter.patch | 42 + ...d-a-test-that-validates-raid0-with-l.patch | 38 + ...ts-fix-raid0-tests-for-0.90-metadata.patch | 99 ++ ...etadata-avoid-passing-chunk-size-to-.patch | 39 + ...ow-clear-the-superblock-at-every-ite.patch | 31 + ...Add-a-mode-to-repeat-specified-tests.patch | 88 + ...Mark-and-ignore-broken-test-failures.patch | 120 ++ ...dd-broken-files-for-all-broken-tests.patch | 447 +++++ ...place-obsolete-usleep-with-nanosleep.patch | 316 ++++ ...-Run-udevadm-settle-before-setting-r.patch | 36 + 0047-tests-add-test-for-names.patch | 119 ++ 0048-mdadm-remove-symlink-option.patch | 176 ++ ...adm-move-data_offset-to-struct-shape.patch | 232 +++ ...en-md-device-for-CREATE-and-ASSEMBLE.patch | 162 ++ ...it-Grow_reshape-into-helper-function.patch | 231 +++ ...f-device-is-container-before-schedul.patch | 36 + 0053-super1-report-truncated-device.patch | 112 ++ ...typos-punctuation-and-grammar-in-man.patch | 616 +++++++ 0055-Manage-Block-unsafe-member-failing.patch | 91 + 0056-Monitor-Fix-statelist-memory-leaks.patch | 112 ++ ...ort-for-Intel-Alderlake-RST-on-VMD-p.patch | 64 + ...entation-entries-to-systemd-services.patch | 111 ++ 0059-ReadMe-fix-command-line-help.patch | 32 + ...container-level-checking-with-inline.patch | 257 +++ 0061-Mdmonitor-Omit-non-md-devices.patch | 58 + ...-Split-alert-into-separate-functions.patch | 233 +++ ...-block-if-monitor-modes-are-combined.patch | 41 + 0064-Update-mdadm-Monitor-manual.patch | 119 ++ 0065-Grow-fix-possible-memory-leak.patch | 38 + 0066-mdadm-create-ident_init.patch | 148 ++ ...ption-validation-for-update-subarray.patch | 287 +++ ...Fix-update-subarray-on-active-volume.patch | 54 + ...code-specific-update-options-to-enum.patch | 77 + 0070-super-ddf-Remove-update_super_ddf.patch | 106 ++ 0071-super0-refactor-the-code-for-enum.patch | 212 +++ 0072-super1-refactor-the-code-for-enum.patch | 302 ++++ ...per-intel-refactor-the-code-for-enum.patch | 106 ++ ...-enum-in-update_super-and-update_sub.patch | 424 +++++ ...emental-code-refactor-string-to-enum.patch | 279 +++ ...enum-in-context-update-refactor-code.patch | 289 ++++ 0077-mdmon-fix-segfault.patch | 86 + ...emove-obsolete-code-from-get_md_name.patch | 116 ++ ...t-handle-change-event-on-raw-devices.patch | 54 + ...eck-array-state-when-drive-is-remove.patch | 33 + ...nage-do-not-verify-if-remove-is-safe.patch | 59 + ...-freesize-not-required-for-chunk-siz.patch | 52 + ...ve-comment-with-function-description.patch | 105 ++ mdadm-udev.patch | 26 + mdadm.rules | 67 - mdadm.spec | 119 +- 85 files changed, 12212 insertions(+), 84 deletions(-) create mode 100644 0001-Unify-error-message.patch create mode 100644 0002-mdadm-Fix-double-free.patch create mode 100644 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch create mode 100644 0004-udev-adapt-rules-to-systemd-v247.patch create mode 100644 0005-Replace-error-prone-signal-with-sigaction.patch create mode 100644 0006-mdadm-Respect-config-file-location-in-man.patch create mode 100644 0007-mdadm-Update-ReadMe.patch create mode 100644 0008-mdadm-Update-config-man-regarding-default-files-and-.patch create mode 100644 0009-mdadm-Update-config-manual.patch create mode 100644 0010-Create-Build-use-default_layout.patch create mode 100644 0011-mdadm-add-map_num_s.patch create mode 100644 0013-mdmon-Stop-parsing-duplicate-options.patch create mode 100644 0014-Grow-block-n-on-external-volumes.patch create mode 100644 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch create mode 100644 0016-Mdmonitor-Fix-segfault.patch create mode 100644 0017-Mdmonitor-Improve-logging-method.patch create mode 100644 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch create mode 100644 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch create mode 100644 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch create mode 100644 0021-util-replace-ioctl-use-with-function.patch create mode 100644 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch create mode 100644 0023-imsm-introduce-get_disk_slot_in_dev.patch create mode 100644 0024-imsm-use-same-slot-across-container.patch create mode 100644 0025-imsm-block-changing-slots-during-creation.patch create mode 100644 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch create mode 100644 0027-mdadm-Fix-array-size-mismatch-after-grow.patch create mode 100644 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch create mode 100644 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch create mode 100644 0030-Monitor-use-snprintf-to-fill-device-name.patch create mode 100644 0031-Makefile-Don-t-build-static-build-with-everything-an.patch create mode 100644 0032-DDF-Cleanup-validate_geometry_ddf_container.patch create mode 100644 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch create mode 100644 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch create mode 100644 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch create mode 100644 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch create mode 100644 0037-mdadm-Fix-optional-write-behind-parameter.patch create mode 100644 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch create mode 100644 0039-tests-fix-raid0-tests-for-0.90-metadata.patch create mode 100644 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch create mode 100644 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch create mode 100644 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch create mode 100644 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch create mode 100644 0044-tests-Add-broken-files-for-all-broken-tests.patch create mode 100644 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch create mode 100644 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch create mode 100644 0047-tests-add-test-for-names.patch create mode 100644 0048-mdadm-remove-symlink-option.patch create mode 100644 0049-mdadm-move-data_offset-to-struct-shape.patch create mode 100644 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch create mode 100644 0051-Grow-Split-Grow_reshape-into-helper-function.patch create mode 100644 0052-Assemble-check-if-device-is-container-before-schedul.patch create mode 100644 0053-super1-report-truncated-device.patch create mode 100644 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch create mode 100644 0055-Manage-Block-unsafe-member-failing.patch create mode 100644 0056-Monitor-Fix-statelist-memory-leaks.patch create mode 100644 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch create mode 100644 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch create mode 100644 0059-ReadMe-fix-command-line-help.patch create mode 100644 0060-mdadm-replace-container-level-checking-with-inline.patch create mode 100644 0061-Mdmonitor-Omit-non-md-devices.patch create mode 100644 0062-Mdmonitor-Split-alert-into-separate-functions.patch create mode 100644 0063-Monitor-block-if-monitor-modes-are-combined.patch create mode 100644 0064-Update-mdadm-Monitor-manual.patch create mode 100644 0065-Grow-fix-possible-memory-leak.patch create mode 100644 0066-mdadm-create-ident_init.patch create mode 100644 0067-mdadm-Add-option-validation-for-update-subarray.patch create mode 100644 0068-Fix-update-subarray-on-active-volume.patch create mode 100644 0069-Add-code-specific-update-options-to-enum.patch create mode 100644 0070-super-ddf-Remove-update_super_ddf.patch create mode 100644 0071-super0-refactor-the-code-for-enum.patch create mode 100644 0072-super1-refactor-the-code-for-enum.patch create mode 100644 0073-super-intel-refactor-the-code-for-enum.patch create mode 100644 0074-Change-update-to-enum-in-update_super-and-update_sub.patch create mode 100644 0075-Manage-Incremental-code-refactor-string-to-enum.patch create mode 100644 0076-Change-char-to-enum-in-context-update-refactor-code.patch create mode 100644 0077-mdmon-fix-segfault.patch create mode 100644 0078-util-remove-obsolete-code-from-get_md_name.patch create mode 100644 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch create mode 100644 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch create mode 100644 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch create mode 100644 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch create mode 100644 0083-manage-move-comment-with-function-description.patch create mode 100644 mdadm-udev.patch delete mode 100644 mdadm.rules diff --git a/0001-Unify-error-message.patch b/0001-Unify-error-message.patch new file mode 100644 index 0000000..14dc69c --- /dev/null +++ b/0001-Unify-error-message.patch @@ -0,0 +1,47 @@ +From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Tue, 15 Mar 2022 09:30:30 +0100 +Subject: [PATCH 01/83] Unify error message. + +Provide the same error message for the same error that can occur in Grow.c and super-intel.c. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + Grow.c | 4 ++-- + super-intel.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 9c6fc95e..9a947204 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1001,8 +1001,8 @@ int remove_disks_for_takeover(struct supertype *st, + rv = 1; + sysfs_free(arrays); + if (rv) { +- pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm); +- pr_err("For this operation it MUST be single array in container\n"); ++ pr_err("Error. Cannot perform operation on %s- for this operation " ++ "it MUST be single array in container\n", st->devnm); + return rv; + } + } +diff --git a/super-intel.c b/super-intel.c +index d5fad102..5ffa7636 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + struct imsm_super *mpb = super->anchor; + + if (mpb->num_raid_devs > 1) { +- pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n", +- geo->dev_name); ++ pr_err("Error. Cannot perform operation on %s- for this operation " ++ "it MUST be single array in container\n", geo->dev_name); + change = -1; + } + } +-- +2.38.1 + diff --git a/0002-mdadm-Fix-double-free.patch b/0002-mdadm-Fix-double-free.patch new file mode 100644 index 0000000..e6b7d37 --- /dev/null +++ b/0002-mdadm-Fix-double-free.patch @@ -0,0 +1,33 @@ +From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 25 Mar 2022 12:48:59 +0100 +Subject: [PATCH 02/83] mdadm: Fix double free + +If there was a size mismatch after creation it would get fixed on grow +in imsm_fix_size_mismatch(), but due to double free "double free or corruption (fasttop)" +error occurs and grow cannot proceed. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 5ffa7636..6ff336ee 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) + st->update_tail = &st->updates; + } else { + imsm_sync_metadata(st); ++ free(update); + } +- +- free(update); + } + ret_val = 0; + exit: +-- +2.38.1 + diff --git a/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch b/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch new file mode 100644 index 0000000..e43cdaa --- /dev/null +++ b/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch @@ -0,0 +1,83 @@ +From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 23 Mar 2022 15:05:19 +0100 +Subject: [PATCH 03/83] Grow_reshape: Add r0 grow size error message and update + man + +Grow size on r0 is not supported for imsm and native metadata. +Add proper error message. +Update man for proper use of --size. +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Grow.c | 6 ++++++ + mdadm.8.in | 19 ++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 9a947204..aa72490b 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1998,6 +1998,12 @@ int Grow_reshape(char *devname, int fd, + goto release; + } + ++ if (array.level == 0) { ++ pr_err("Component size change is not supported for RAID0\n"); ++ rv = 1; ++ goto release; ++ } ++ + if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, + devname, APPLY_METADATA_CHANGES, + c->verbose > 0)) { +diff --git a/mdadm.8.in b/mdadm.8.in +index be902dba..e2a42425 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -459,7 +459,8 @@ number of spare devices. + + .TP + .BR \-z ", " \-\-size= +-Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6. ++Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10 ++and for RAID 0 on external metadata. + This must be a multiple of the chunk size, and must leave about 128Kb + of space at the end of the drive for the RAID superblock. + If this is not specified +@@ -478,10 +479,19 @@ To guard against this it can be useful to set the initial size + slightly smaller than the smaller device with the aim that it will + still be larger than any replacement. + ++This option can be used with ++.B \-\-create ++for determining initial size of an array. For external metadata, ++it can be used on a volume, but not on a container itself. ++Setting initial size of ++.B RAID 0 ++array is only valid for external metadata. ++ + This value can be set with + .B \-\-grow +-for RAID level 1/4/5/6 though ++for RAID level 1/4/5/6/10 though + DDF arrays may not be able to support this. ++RAID 0 array size cannot be changed. + If the array was created with a size smaller than the currently + active drives, the extra space can be accessed using + .BR \-\-grow . +@@ -501,11 +511,6 @@ problems the array can be made bigger again with no loss with another + .B "\-\-grow \-\-size=" + command. + +-This value cannot be used when creating a +-.B CONTAINER +-such as with DDF and IMSM metadata, though it perfectly valid when +-creating an array inside a container. +- + .TP + .BR \-Z ", " \-\-array\-size= + This is only meaningful with +-- +2.38.1 + diff --git a/0004-udev-adapt-rules-to-systemd-v247.patch b/0004-udev-adapt-rules-to-systemd-v247.patch new file mode 100644 index 0000000..a755c53 --- /dev/null +++ b/0004-udev-adapt-rules-to-systemd-v247.patch @@ -0,0 +1,67 @@ +From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 14 Jan 2022 16:44:33 +0100 +Subject: [PATCH 04/83] udev: adapt rules to systemd v247 + +New events have been added in kernel 4.14 ("bind" and "unbind"). +Systemd maintainer suggests to modify "add|change" branches. +This patches implements their suggestions. There is no issue yet because +new event types are not used in md. + +Please see systemd announcement for details[1]. + +[1] https://lists.freedesktop.org/archives/systemd-devel/2020-November/045646.html + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + udev-md-raid-arrays.rules | 2 +- + udev-md-raid-assembly.rules | 5 +++-- + udev-md-raid-safe-timeouts.rules | 2 +- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index 13c9076e..2967ace1 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -3,7 +3,7 @@ + SUBSYSTEM!="block", GOTO="md_end" + + # handle md arrays +-ACTION!="add|change", GOTO="md_end" ++ACTION=="remove", GOTO="md_end" + KERNEL!="md*", GOTO="md_end" + + # partitions have no md/{array_state,metadata_version}, but should not +diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules +index d668cddd..39b4344b 100644 +--- a/udev-md-raid-assembly.rules ++++ b/udev-md-raid-assembly.rules +@@ -30,8 +30,9 @@ LABEL="md_inc" + + # remember you can limit what gets auto/incrementally assembled by + # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' +-ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" +-ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" ++ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" ++ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" ++ + ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" + ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" + +diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules +index 12bdcaa8..2e185cee 100644 +--- a/udev-md-raid-safe-timeouts.rules ++++ b/udev-md-raid-safe-timeouts.rules +@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end" + + IMPORT{program}="/sbin/mdadm --examine --export $devnode" + +-ACTION=="add|change", \ ++ACTION!="remove", \ + ENV{ID_FS_TYPE}=="linux_raid_member", \ + ENV{MD_LEVEL}=="raid[1-9]*", \ + TEST=="/sys/block/$parent/device/timeout", \ +-- +2.38.1 + diff --git a/0005-Replace-error-prone-signal-with-sigaction.patch b/0005-Replace-error-prone-signal-with-sigaction.patch new file mode 100644 index 0000000..dd04b8c --- /dev/null +++ b/0005-Replace-error-prone-signal-with-sigaction.patch @@ -0,0 +1,252 @@ +From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Mon, 21 Feb 2022 13:05:20 +0100 +Subject: [PATCH 05/83] Replace error prone signal() with sigaction() + +Up to this date signal() was used which implementation could vary [1]. +Sigaction() call is preferred. This commit introduces replacement +from signal() to sigaction() by the use of signal_s() wrapper. +Also remove redundant signal.h header includes. + +[1] https://man7.org/linux/man-pages/man2/signal.2.html + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + Grow.c | 4 ++-- + Monitor.c | 5 +++-- + managemon.c | 1 - + mdadm.h | 22 ++++++++++++++++++++++ + mdmon.c | 1 - + monitor.c | 1 - + probe_roms.c | 6 +++--- + raid6check.c | 25 +++++++++++++++---------- + util.c | 1 - + 9 files changed, 45 insertions(+), 21 deletions(-) + +diff --git a/Grow.c b/Grow.c +index aa72490b..18c5719b 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -26,7 +26,6 @@ + #include + #include + #include +-#include + #include + + #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) +@@ -3566,7 +3565,8 @@ started: + fd = -1; + mlockall(MCL_FUTURE); + +- signal(SIGTERM, catch_term); ++ if (signal_s(SIGTERM, catch_term) == SIG_ERR) ++ goto release; + + if (st->ss->external) { + /* metadata handler takes it from here */ +diff --git a/Monitor.c b/Monitor.c +index 30c031a2..c0ab5412 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -26,7 +26,6 @@ + #include "md_p.h" + #include "md_u.h" + #include +-#include + #include + #include + #ifndef NO_LIBUDEV +@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) + if (mp) { + FILE *mdstat; + char hname[256]; ++ + gethostname(hname, sizeof(hname)); +- signal(SIGPIPE, SIG_IGN); ++ signal_s(SIGPIPE, SIG_IGN); ++ + if (info->mailfrom) + fprintf(mp, "From: %s\n", info->mailfrom); + else +diff --git a/managemon.c b/managemon.c +index bb7334cf..0e9bdf00 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -106,7 +106,6 @@ + #include "mdmon.h" + #include + #include +-#include + + static void close_aa(struct active_array *aa) + { +diff --git a/mdadm.h b/mdadm.h +index c7268a71..26e7e5cd 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); + #include + #include + #include ++#include + /* Newer glibc requires sys/sysmacros.h directly for makedev() */ + #include + #ifdef __dietlibc__ +@@ -1729,6 +1730,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) + return &ent->metadata_version[10+strlen(container)+1]; + } + ++/** ++ * signal_s() - Wrapper for sigaction() with signal()-like interface. ++ * @sig: The signal to set the signal handler to. ++ * @handler: The signal handler. ++ * ++ * Return: previous handler or SIG_ERR on failure. ++ */ ++static inline sighandler_t signal_s(int sig, sighandler_t handler) ++{ ++ struct sigaction new_act; ++ struct sigaction old_act; ++ ++ new_act.sa_handler = handler; ++ new_act.sa_flags = 0; ++ ++ if (sigaction(sig, &new_act, &old_act) == 0) ++ return old_act.sa_handler; ++ ++ return SIG_ERR; ++} ++ + #ifdef DEBUG + #define dprintf(fmt, arg...) \ + fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) +diff --git a/mdmon.c b/mdmon.c +index c71e62c6..5570574b 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -56,7 +56,6 @@ + #include + #include + #include +-#include + #include + #ifdef USE_PTHREADS + #include +diff --git a/monitor.c b/monitor.c +index e0d3be67..b877e595 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -22,7 +22,6 @@ + #include "mdmon.h" + #include + #include +-#include + + static char *array_states[] = { + "clear", "inactive", "suspended", "readonly", "read-auto", +diff --git a/probe_roms.c b/probe_roms.c +index 7ea04c7a..94c80c2c 100644 +--- a/probe_roms.c ++++ b/probe_roms.c +@@ -22,7 +22,6 @@ + #include "probe_roms.h" + #include "mdadm.h" + #include +-#include + #include + #include + #include +@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val) + + void probe_roms_exit(void) + { +- signal(SIGBUS, SIG_DFL); ++ signal_s(SIGBUS, SIG_DFL); ++ + if (rom_fd >= 0) { + close(rom_fd); + rom_fd = -1; +@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align) + if (roms_init()) + return -1; + +- if (signal(SIGBUS, sigbus) == SIG_ERR) ++ if (signal_s(SIGBUS, sigbus) == SIG_ERR) + rc = -1; + if (rc == 0) { + fd = open("/dev/mem", O_RDONLY); +diff --git a/raid6check.c b/raid6check.c +index a8e6005b..99477761 100644 +--- a/raid6check.c ++++ b/raid6check.c +@@ -24,7 +24,6 @@ + + #include "mdadm.h" + #include +-#include + #include + + #define CHECK_PAGE_BITS (12) +@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size) + } + + int lock_stripe(struct mdinfo *info, unsigned long long start, +- int chunk_size, int data_disks, sighandler_t *sig) { ++ int chunk_size, int data_disks, sighandler_t *sig) ++{ + int rv; ++ ++ sig[0] = signal_s(SIGTERM, SIG_IGN); ++ sig[1] = signal_s(SIGINT, SIG_IGN); ++ sig[2] = signal_s(SIGQUIT, SIG_IGN); ++ ++ if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR) ++ return 1; ++ + if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { + return 2; + } + +- sig[0] = signal(SIGTERM, SIG_IGN); +- sig[1] = signal(SIGINT, SIG_IGN); +- sig[2] = signal(SIGQUIT, SIG_IGN); +- + rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks); + rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks); + return rv * 256; + } + +-int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) { ++int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) ++{ + int rv; + rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL); + rv |= sysfs_set_num(info, NULL, "suspend_hi", 0); + rv |= sysfs_set_num(info, NULL, "suspend_lo", 0); + +- signal(SIGQUIT, sig[2]); +- signal(SIGINT, sig[1]); +- signal(SIGTERM, sig[0]); ++ signal_s(SIGQUIT, sig[2]); ++ signal_s(SIGINT, sig[1]); ++ signal_s(SIGTERM, sig[0]); + + if(munlockall() != 0) + return 3; +diff --git a/util.c b/util.c +index 3d05d074..cc94f96e 100644 +--- a/util.c ++++ b/util.c +@@ -35,7 +35,6 @@ + #include + #include + #include +-#include + #include + + +-- +2.38.1 + diff --git a/0006-mdadm-Respect-config-file-location-in-man.patch b/0006-mdadm-Respect-config-file-location-in-man.patch new file mode 100644 index 0000000..bee28ac --- /dev/null +++ b/0006-mdadm-Respect-config-file-location-in-man.patch @@ -0,0 +1,1533 @@ +From e9dd5644843e2013a7dd1a8a5da2b9fa35837416 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:04 +0100 +Subject: [PATCH 06/83] mdadm: Respect config file location in man + +Default config file location could differ depending on OS (e.g. Debian family). +This patch takes default config file into consideration when creating mdadm.man +file as well as mdadm.conf.man. + +Rename mdadm.conf.5 to mdadm.conf.5.in. Now mdadm.conf.5 is generated automatically. + +Signed-off-by: Lukasz Florczak +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + .gitignore | 1 + + Makefile | 7 +- + mdadm.8.in | 16 +- + mdadm.conf.5 | 706 ------------------------------------------------ + mdadm.conf.5.in | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 721 insertions(+), 715 deletions(-) + delete mode 100644 mdadm.conf.5 + create mode 100644 mdadm.conf.5.in + +diff --git a/.gitignore b/.gitignore +index 217fe76d..8d791c6f 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -3,6 +3,7 @@ + /*-stamp + /mdadm + /mdadm.8 ++/mdadm.conf.5 + /mdadm.udeb + /mdassemble + /mdmon +diff --git a/Makefile b/Makefile +index 2a51d813..bf126033 100644 +--- a/Makefile ++++ b/Makefile +@@ -227,7 +227,12 @@ raid6check : raid6check.o mdadm.h $(CHECK_OBJS) + + mdadm.8 : mdadm.8.in + sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \ +- -e 's,{MAP_PATH},$(MAP_PATH),g' mdadm.8.in > mdadm.8 ++ -e 's,{MAP_PATH},$(MAP_PATH),g' -e 's,{CONFFILE},$(CONFFILE),g' \ ++ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.8.in > mdadm.8 ++ ++mdadm.conf.5 : mdadm.conf.5.in ++ sed -e 's,{CONFFILE},$(CONFFILE),g' \ ++ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.conf.5.in > mdadm.conf.5 + + mdadm.man : mdadm.8 + man -l mdadm.8 > mdadm.man +diff --git a/mdadm.8.in b/mdadm.8.in +index e2a42425..8b21ffd4 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -267,13 +267,13 @@ the exact meaning of this option in different contexts. + .TP + .BR \-c ", " \-\-config= + Specify the config file or directory. Default is to use +-.B /etc/mdadm.conf ++.B {CONFFILE} + and +-.BR /etc/mdadm.conf.d , ++.BR {CONFFILE}.d , + or if those are missing then +-.B /etc/mdadm/mdadm.conf ++.B {CONFFILE2} + and +-.BR /etc/mdadm/mdadm.conf.d . ++.BR {CONFFILE2}.d . + If the config file given is + .B "partitions" + then nothing will be read, but +@@ -2014,9 +2014,9 @@ The config file is only used if explicitly named with + or requested with (a possibly implicit) + .BR \-\-scan . + In the later case, +-.B /etc/mdadm.conf ++.B {CONFFILE} + or +-.B /etc/mdadm/mdadm.conf ++.B {CONFFILE2} + is used. + + If +@@ -3344,7 +3344,7 @@ uses this to find arrays when + is given in Misc mode, and to monitor array reconstruction + on Monitor mode. + +-.SS /etc/mdadm.conf ++.SS {CONFFILE} (or {CONFFILE2}) + + The config file lists which devices may be scanned to see if + they contain MD super block, and gives identifying information +@@ -3352,7 +3352,7 @@ they contain MD super block, and gives identifying information + .BR mdadm.conf (5) + for more details. + +-.SS /etc/mdadm.conf.d ++.SS {CONFFILE}.d (or {CONFFILE2}.d) + + A directory containing configuration files which are read in lexical + order. +diff --git a/mdadm.conf.5 b/mdadm.conf.5 +deleted file mode 100644 +index 74a21c5f..00000000 +--- a/mdadm.conf.5 ++++ /dev/null +@@ -1,706 +0,0 @@ +-.\" Copyright Neil Brown and others. +-.\" 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. +-.\" See file COPYING in distribution for details. +-.TH MDADM.CONF 5 +-.SH NAME +-mdadm.conf \- configuration for management of Software RAID with mdadm +-.SH SYNOPSIS +-/etc/mdadm.conf +-.SH DESCRIPTION +-.PP +-.I mdadm +-is a tool for creating, managing, and monitoring RAID devices using the +-.B md +-driver in Linux. +-.PP +-Some common tasks, such as assembling all arrays, can be simplified +-by describing the devices and arrays in this configuration file. +- +-.SS SYNTAX +-The file should be seen as a collection of words separated by white +-space (space, tab, or newline). +-Any word that beings with a hash sign (#) starts a comment and that +-word together with the remainder of the line is ignored. +- +-Spaces can be included in a word using quotation characters. Either +-single quotes +-.RB ( ' ) +-or double quotes (\fB"\fP) +-may be used. All the characters from one quotation character to +-next identical character are protected and will not be used to +-separate words to start new quoted strings. To include a single quote +-it must be between double quotes. To include a double quote it must +-be between single quotes. +- +-Any line that starts with white space (space or tab) is treated as +-though it were a continuation of the previous line. +- +-Empty lines are ignored, but otherwise each (non continuation) line +-must start with a keyword as listed below. The keywords are case +-insensitive and can be abbreviated to 3 characters. +- +-The keywords are: +-.TP +-.B DEVICE +-A +-.B device +-line lists the devices (whole devices or partitions) that might contain +-a component of an MD array. When looking for the components of an +-array, +-.I mdadm +-will scan these devices (or any devices listed on the command line). +- +-The +-.B device +-line may contain a number of different devices (separated by spaces) +-and each device name can contain wild cards as defined by +-.BR glob (7). +- +-Also, there may be several device lines present in the file. +- +-Alternatively, a +-.B device +-line can contain either or both of the words +-.B containers +-and +-.BR partitions . +-The word +-.B containers +-will cause +-.I mdadm +-to look for assembled CONTAINER arrays and included them as a source +-for assembling further arrays. +- +-The word +-.I partitions +-will cause +-.I mdadm +-to read +-.I /proc/partitions +-and include all devices and partitions found therein. +-.I mdadm +-does not use the names from +-.I /proc/partitions +-but only the major and minor device numbers. It scans +-.I /dev +-to find the name that matches the numbers. +- +-If no DEVICE line is present, then "DEVICE partitions containers" is assumed. +- +-For example: +-.IP +-DEVICE /dev/hda* /dev/hdc* +-.br +-DEV /dev/sd* +-.br +-DEVICE /dev/disk/by-path/pci* +-.br +-DEVICE partitions +- +-.TP +-.B ARRAY +-The ARRAY lines identify actual arrays. The second word on the line +-may be the name of the device where the array is normally +-assembled, such as +-.B /dev/md1 +-or +-.BR /dev/md/backup . +-If the name does not start with a slash +-.RB (' / '), +-it is treated as being in +-.BR /dev/md/ . +-Alternately the word +-.B +-(complete with angle brackets) can be given in which case any array +-which matches the rest of the line will never be automatically assembled. +-If no device name is given, +-.I mdadm +-will use various heuristics to determine an appropriate name. +- +-Subsequent words identify the array, or identify the array as a member +-of a group. If multiple identities are given, +-then a component device must match ALL identities to be considered a +-match. Each identity word has a tag, and equals sign, and some value. +-The tags are: +-.RS 4 +-.TP +-.B uuid= +-The value should be a 128 bit uuid in hexadecimal, with punctuation +-interspersed if desired. This must match the uuid stored in the +-superblock. +-.TP +-.B name= +-The value should be a simple textual name as was given to +-.I mdadm +-when the array was created. This must match the name stored in the +-superblock on a device for that device to be included in the array. +-Not all superblock formats support names. +-.TP +-.B super\-minor= +-The value is an integer which indicates the minor number that was +-stored in the superblock when the array was created. When an array is +-created as /dev/mdX, then the minor number X is stored. +-.TP +-.B devices= +-The value is a comma separated list of device names or device name +-patterns. +-Only devices with names which match one entry in the list will be used +-to assemble the array. Note that the devices +-listed there must also be listed on a DEVICE line. +-.TP +-.B level= +-The value is a RAID level. This is not normally used to +-identify an array, but is supported so that the output of +- +-.B "mdadm \-\-examine \-\-scan" +- +-can be use directly in the configuration file. +-.TP +-.B num\-devices= +-The value is the number of devices in a complete active array. As with +-.B level= +-this is mainly for compatibility with the output of +- +-.BR "mdadm \-\-examine \-\-scan" . +- +-.TP +-.B spares= +-The value is a number of spare devices to expect the array to have. +-The sole use of this keyword and value is as follows: +-.B mdadm \-\-monitor +-will report an array if it is found to have fewer than this number of +-spares when +-.B \-\-monitor +-starts or when +-.B \-\-oneshot +-is used. +- +-.TP +-.B spare\-group= +-The value is a textual name for a group of arrays. All arrays with +-the same +-.B spare\-group +-name are considered to be part of the same group. The significance of +-a group of arrays is that +-.I mdadm +-will, when monitoring the arrays, move a spare drive from one array in +-a group to another array in that group if the first array had a failed +-or missing drive but no spare. +- +-.TP +-.B auto= +-This option is rarely needed with mdadm-3.0, particularly if use with +-the Linux kernel v2.6.28 or later. +-It tells +-.I mdadm +-whether to use partitionable array or non-partitionable arrays and, +-in the absence of +-.IR udev , +-how many partition devices to create. From 2.6.28 all md array +-devices are partitionable, hence this option is not needed. +- +-The value of this option can be "yes" or "md" to indicate that a +-traditional, non-partitionable md array should be created, or "mdp", +-"part" or "partition" to indicate that a partitionable md array (only +-available in linux 2.6 and later) should be used. This later set can +-also have a number appended to indicate how many partitions to create +-device files for, e.g. +-.BR auto=mdp5 . +-The default is 4. +- +-.TP +-.B bitmap= +-The option specifies a file in which a write-intent bitmap should be +-found. When assembling the array, +-.I mdadm +-will provide this file to the +-.B md +-driver as the bitmap file. This has the same function as the +-.B \-\-bitmap\-file +-option to +-.BR \-\-assemble . +- +-.TP +-.B metadata= +-Specify the metadata format that the array has. This is mainly +-recognised for comparability with the output of +-.BR "mdadm \-Es" . +- +-.TP +-.B container= +-Specify that this array is a member array of some container. The +-value given can be either a path name in /dev, or a UUID of the +-container array. +- +-.TP +-.B member= +-Specify that this array is a member array of some container. Each +-type of container has some way to enumerate member arrays, often a +-simple sequence number. The value identifies which member of a +-container the array is. It will usually accompany a "container=" word. +-.RE +- +-.TP +-.B MAILADDR +-The +-.B mailaddr +-line gives an E-mail address that alerts should be +-sent to when +-.I mdadm +-is running in +-.B \-\-monitor +-mode (and was given the +-.B \-\-scan +-option). There should only be one +-.B MAILADDR +-line and it should have only one address. Any subsequent addresses +-are silently ignored. +- +-.TP +-.B MAILFROM +-The +-.B mailfrom +-line (which can only be abbreviated to at least 5 characters) gives an +-address to appear in the "From" address for alert mails. This can be +-useful if you want to explicitly set a domain, as the default from +-address is "root" with no domain. All words on this line are +-catenated with spaces to form the address. +- +-Note that this value cannot be set via the +-.I mdadm +-commandline. It is only settable via the config file. +- +-.TP +-.B PROGRAM +-The +-.B program +-line gives the name of a program to be run when +-.B "mdadm \-\-monitor" +-detects potentially interesting events on any of the arrays that it +-is monitoring. This program gets run with two or three arguments, they +-being the Event, the md device, and possibly the related component +-device. +- +-There should only be one +-.B program +-line and it should be give only one program. +- +- +-.TP +-.B CREATE +-The +-.B create +-line gives default values to be used when creating arrays, new members +-of arrays, and device entries for arrays. +-These include: +- +-.RS 4 +-.TP +-.B owner= +-.TP +-.B group= +-These can give user/group ids or names to use instead of system +-defaults (root/wheel or root/disk). +-.TP +-.B mode= +-An octal file mode such as 0660 can be given to override the default +-of 0600. +-.TP +-.B auto= +-This corresponds to the +-.B \-\-auto +-flag to mdadm. Give +-.BR yes , +-.BR md , +-.BR mdp , +-.B part +-\(em possibly followed by a number of partitions \(em to indicate how +-missing device entries should be created. +- +-.TP +-.B metadata= +-The name of the metadata format to use if none is explicitly given. +-This can be useful to impose a system-wide default of version-1 superblocks. +- +-.TP +-.B symlinks=no +-Normally when creating devices in +-.B /dev/md/ +-.I mdadm +-will create a matching symlink from +-.B /dev/ +-with a name starting +-.B md +-or +-.BR md_ . +-Give +-.B symlinks=no +-to suppress this symlink creation. +- +-.TP +-.B names=yes +-Since Linux 2.6.29 it has been possible to create +-.B md +-devices with a name like +-.B md_home +-rather than just a number, like +-.BR md3 . +-.I mdadm +-will use the numeric alternative by default as other tools that interact +-with md arrays may expect only numbers. +-If +-.B names=yes +-is given in +-.I mdadm.conf +-then +-.I mdadm +-will use a name when appropriate. +-If +-.B names=no +-is given, then non-numeric +-.I md +-device names will not be used even if the default changes in a future +-release of +-.IR mdadm . +- +-.TP +-.B bbl=no +-By default, +-.I mdadm +-will reserve space for a bad block list (bbl) on all devices +-included in or added to any array that supports them. Setting +-.B bbl=no +-will prevent this, so newly added devices will not have a bad +-block log. +-.RE +- +-.TP +-.B HOMEHOST +-The +-.B homehost +-line gives a default value for the +-.B \-\-homehost= +-option to mdadm. There should normally be only one other word on the line. +-It should either be a host name, or one of the special words +-.BR , +-.B +-and +-.BR . +-If +-.B +-is given, then the +-.BR gethostname ( 2 ) +-systemcall is used to get the host name. This is the default. +- +-If +-.B +-is given, then a flag is set so that when arrays are being +-auto-assembled the checking of the recorded +-.I homehost +-is disabled. +-If +-.B +-is given it is also possible to give an explicit name which will be +-used when creating arrays. This is the only case when there can be +-more that one other word on the +-.B HOMEHOST +-line. If there are other words, or other +-.B HOMEHOST +-lines, they are silently ignored. +- +-If +-.B +-is given, then the default of using +-.BR gethostname ( 2 ) +-is over-ridden and no homehost name is assumed. +- +-When arrays are created, this host name will be stored in the +-metadata. When arrays are assembled using auto-assembly, arrays which +-do not record the correct homehost name in their metadata will be +-assembled using a "foreign" name. A "foreign" name alway ends with a +-digit string preceded by an underscore to differentiate it +-from any possible local name. e.g. +-.B /dev/md/1_1 +-or +-.BR /dev/md/home_0 . +-.TP +-.B AUTO +-A list of names of metadata format can be given, each preceded by a +-plus or minus sign. Also the word +-.I homehost +-is allowed as is +-.I all +-preceded by plus or minus sign. +-.I all +-is usually last. +- +-When +-.I mdadm +-is auto-assembling an array, either via +-.I \-\-assemble +-or +-.I \-\-incremental +-and it finds metadata of a given type, it checks that metadata type +-against those listed in this line. The first match wins, where +-.I all +-matches anything. +-If a match is found that was preceded by a plus sign, the auto +-assembly is allowed. If the match was preceded by a minus sign, the +-auto assembly is disallowed. If no match is found, the auto assembly +-is allowed. +- +-If the metadata indicates that the array was created for +-.I this +-host, and the word +-.I homehost +-appears before any other match, then the array is treated as a valid +-candidate for auto-assembly. +- +-This can be used to disable all auto-assembly (so that only arrays +-explicitly listed in mdadm.conf or on the command line are assembled), +-or to disable assembly of certain metadata types which might be +-handled by other software. It can also be used to disable assembly of +-all foreign arrays - normally such arrays are assembled but given a +-non-deterministic name in +-.BR /dev/md/ . +- +-The known metadata types are +-.BR 0.90 , +-.BR 1.x , +-.BR ddf , +-.BR imsm . +- +-.B AUTO +-should be given at most once. Subsequent lines are silently ignored. +-Thus an earlier config file in a config directory will over-ride +-the setting in a later config file. +- +-.TP +-.B POLICY +-This is used to specify what automatic behavior is allowed on devices +-newly appearing in the system and provides a way of marking spares that can +-be moved to other arrays as well as the migration domains. +-.I Domain +-can be defined through +-.I policy +-line by specifying a domain name for a number of paths from +-.BR /dev/disk/by-path/ . +-A device may belong to several domains. The domain of an array is a union +-of domains of all devices in that array. A spare can be automatically +-moved from one array to another if the set of the destination array's +-.I domains +-contains all the +-.I domains +-of the new disk or if both arrays have the same +-.IR spare-group . +- +-To update hot plug configuration it is necessary to execute +-.B mdadm \-\-udev\-rules +-command after changing the config file +- +-Keywords used in the +-.I POLICY +-line and supported values are: +- +-.RS 4 +-.TP +-.B domain= +-any arbitrary string +-.TP +-.B metadata= +-0.9 1.x ddf or imsm +-.TP +-.B path= +-file glob matching anything from +-.B /dev/disk/by-path +-.TP +-.B type= +-either +-.B disk +-or +-.BR part . +-.TP +-.B action= +-include, re-add, spare, spare-same-slot, or force-spare +-.TP +-.B auto= +-yes, no, or homehost. +- +-.P +-The +-.I action +-item determines the automatic behavior allowed for devices matching the +-.I path +-and +-.I type +-in the same line. If a device matches several lines with different +-.I actions +-then the most permissive will apply. The ordering of policy lines +-is irrelevant to the end result. +-.TP +-.B include +-allows adding a disk to an array if metadata on that disk matches that array +-.TP +-.B re\-add +-will include the device in the array if it appears to be a current member +-or a member that was recently removed and the array has a +-write-intent-bitmap to allow the +-.B re\-add +-functionality. +-.TP +-.B spare +-as above and additionally: if the device is bare it can +-become a spare if there is any array that it is a candidate for based +-on domains and metadata. +-.TP +-.B spare\-same\-slot +-as above and additionally if given slot was used by an array that went +-degraded recently and the device plugged in has no metadata then it will +-be automatically added to that array (or it's container) +-.TP +-.B force\-spare +-as above and the disk will become a spare in remaining cases +-.RE +- +-.TP +-.B PART-POLICY +-This is similar to +-.B POLICY +-and accepts the same keyword assignments. It allows a consistent set +-of policies to applied to each of the partitions of a device. +- +-A +-.B PART-POLICY +-line should set +-.I type=disk +-and identify the path to one or more disk devices. Each partition on +-these disks will be treated according to the +-.I action= +-setting from this line. If a +-.I domain +-is set in the line, then the domain associated with each patition will +-be based on the domain, but with +-.RB \(dq -part N\(dq +-appended, when N is the partition number for the partition that was +-found. +- +-.TP +-.B SYSFS +-The +-.B SYSFS +-line lists custom values of MD device's sysfs attributes which will be +-stored in sysfs after the array is assembled. Multiple lines are allowed and each +-line has to contain the uuid or the name of the device to which it relates. +-.RS 4 +-.TP +-.B uuid= +-hexadecimal identifier of MD device. This has to match the uuid stored in the +-superblock. +-.TP +-.B name= +-name of the MD device as was given to +-.I mdadm +-when the array was created. It will be ignored if +-.B uuid +-is not empty. +-.RE +- +-.TP +-.B MONITORDELAY +-The +-.B monitordelay +-line gives a delay in seconds +-.I mdadm +-shall wait before pooling md arrays +-when +-.I mdadm +-is running in +-.B \-\-monitor +-mode. +-.B \-d/\-\-delay +-command line argument takes precedence over the config file +- +-.SH EXAMPLE +-DEVICE /dev/sd[bcdjkl]1 +-.br +-DEVICE /dev/hda1 /dev/hdb1 +- +-# /dev/md0 is known by its UUID. +-.br +-ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 +-.br +-# /dev/md1 contains all devices with a minor number of +-.br +-# 1 in the superblock. +-.br +-ARRAY /dev/md1 superminor=1 +-.br +-# /dev/md2 is made from precisely these two devices +-.br +-ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 +- +-# /dev/md4 and /dev/md5 are a spare-group and spares +-.br +-# can be moved between them +-.br +-ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df +-.br +- spare\-group=group1 +-.br +-ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 +-.br +- spare\-group=group1 +-.br +-# /dev/md/home is created if need to be a partitionable md array +-.br +-# any spare device number is allocated. +-.br +-ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b +-.br +- auto=part +-.br +-# The name of this array contains a space. +-.br +-ARRAY /dev/md9 name='Data Storage' +-.sp +-POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* +-.br +- action=spare +-.br +-POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* +-.br +- action=include +-.br +-# One domain comprising of devices attached to specified paths is defined. +-.br +-# Bare device matching first path will be made an imsm spare on hot plug. +-.br +-# If more than one array is created on devices belonging to domain1 and +-.br +-# one of them becomes degraded, then any imsm spare matching any path for +-.br +-# given domain name can be migrated. +-.br +-MAILADDR root@mydomain.tld +-.br +-PROGRAM /usr/sbin/handle\-mdadm\-events +-.br +-CREATE group=system mode=0640 auto=part\-8 +-.br +-HOMEHOST +-.br +-AUTO +1.x homehost \-all +-.br +-SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 +-.br +-SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 +-sync_speed_max=1000000 +-.br +-MONITORDELAY 60 +- +-.SH SEE ALSO +-.BR mdadm (8), +-.BR md (4). +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +new file mode 100644 +index 00000000..83edd008 +--- /dev/null ++++ b/mdadm.conf.5.in +@@ -0,0 +1,706 @@ ++.\" Copyright Neil Brown and others. ++.\" 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. ++.\" See file COPYING in distribution for details. ++.TH MDADM.CONF 5 ++.SH NAME ++mdadm.conf \- configuration for management of Software RAID with mdadm ++.SH SYNOPSIS ++{CONFFILE} ++.SH DESCRIPTION ++.PP ++.I mdadm ++is a tool for creating, managing, and monitoring RAID devices using the ++.B md ++driver in Linux. ++.PP ++Some common tasks, such as assembling all arrays, can be simplified ++by describing the devices and arrays in this configuration file. ++ ++.SS SYNTAX ++The file should be seen as a collection of words separated by white ++space (space, tab, or newline). ++Any word that beings with a hash sign (#) starts a comment and that ++word together with the remainder of the line is ignored. ++ ++Spaces can be included in a word using quotation characters. Either ++single quotes ++.RB ( ' ) ++or double quotes (\fB"\fP) ++may be used. All the characters from one quotation character to ++next identical character are protected and will not be used to ++separate words to start new quoted strings. To include a single quote ++it must be between double quotes. To include a double quote it must ++be between single quotes. ++ ++Any line that starts with white space (space or tab) is treated as ++though it were a continuation of the previous line. ++ ++Empty lines are ignored, but otherwise each (non continuation) line ++must start with a keyword as listed below. The keywords are case ++insensitive and can be abbreviated to 3 characters. ++ ++The keywords are: ++.TP ++.B DEVICE ++A ++.B device ++line lists the devices (whole devices or partitions) that might contain ++a component of an MD array. When looking for the components of an ++array, ++.I mdadm ++will scan these devices (or any devices listed on the command line). ++ ++The ++.B device ++line may contain a number of different devices (separated by spaces) ++and each device name can contain wild cards as defined by ++.BR glob (7). ++ ++Also, there may be several device lines present in the file. ++ ++Alternatively, a ++.B device ++line can contain either or both of the words ++.B containers ++and ++.BR partitions . ++The word ++.B containers ++will cause ++.I mdadm ++to look for assembled CONTAINER arrays and included them as a source ++for assembling further arrays. ++ ++The word ++.I partitions ++will cause ++.I mdadm ++to read ++.I /proc/partitions ++and include all devices and partitions found therein. ++.I mdadm ++does not use the names from ++.I /proc/partitions ++but only the major and minor device numbers. It scans ++.I /dev ++to find the name that matches the numbers. ++ ++If no DEVICE line is present, then "DEVICE partitions containers" is assumed. ++ ++For example: ++.IP ++DEVICE /dev/hda* /dev/hdc* ++.br ++DEV /dev/sd* ++.br ++DEVICE /dev/disk/by-path/pci* ++.br ++DEVICE partitions ++ ++.TP ++.B ARRAY ++The ARRAY lines identify actual arrays. The second word on the line ++may be the name of the device where the array is normally ++assembled, such as ++.B /dev/md1 ++or ++.BR /dev/md/backup . ++If the name does not start with a slash ++.RB (' / '), ++it is treated as being in ++.BR /dev/md/ . ++Alternately the word ++.B ++(complete with angle brackets) can be given in which case any array ++which matches the rest of the line will never be automatically assembled. ++If no device name is given, ++.I mdadm ++will use various heuristics to determine an appropriate name. ++ ++Subsequent words identify the array, or identify the array as a member ++of a group. If multiple identities are given, ++then a component device must match ALL identities to be considered a ++match. Each identity word has a tag, and equals sign, and some value. ++The tags are: ++.RS 4 ++.TP ++.B uuid= ++The value should be a 128 bit uuid in hexadecimal, with punctuation ++interspersed if desired. This must match the uuid stored in the ++superblock. ++.TP ++.B name= ++The value should be a simple textual name as was given to ++.I mdadm ++when the array was created. This must match the name stored in the ++superblock on a device for that device to be included in the array. ++Not all superblock formats support names. ++.TP ++.B super\-minor= ++The value is an integer which indicates the minor number that was ++stored in the superblock when the array was created. When an array is ++created as /dev/mdX, then the minor number X is stored. ++.TP ++.B devices= ++The value is a comma separated list of device names or device name ++patterns. ++Only devices with names which match one entry in the list will be used ++to assemble the array. Note that the devices ++listed there must also be listed on a DEVICE line. ++.TP ++.B level= ++The value is a RAID level. This is not normally used to ++identify an array, but is supported so that the output of ++ ++.B "mdadm \-\-examine \-\-scan" ++ ++can be use directly in the configuration file. ++.TP ++.B num\-devices= ++The value is the number of devices in a complete active array. As with ++.B level= ++this is mainly for compatibility with the output of ++ ++.BR "mdadm \-\-examine \-\-scan" . ++ ++.TP ++.B spares= ++The value is a number of spare devices to expect the array to have. ++The sole use of this keyword and value is as follows: ++.B mdadm \-\-monitor ++will report an array if it is found to have fewer than this number of ++spares when ++.B \-\-monitor ++starts or when ++.B \-\-oneshot ++is used. ++ ++.TP ++.B spare\-group= ++The value is a textual name for a group of arrays. All arrays with ++the same ++.B spare\-group ++name are considered to be part of the same group. The significance of ++a group of arrays is that ++.I mdadm ++will, when monitoring the arrays, move a spare drive from one array in ++a group to another array in that group if the first array had a failed ++or missing drive but no spare. ++ ++.TP ++.B auto= ++This option is rarely needed with mdadm-3.0, particularly if use with ++the Linux kernel v2.6.28 or later. ++It tells ++.I mdadm ++whether to use partitionable array or non-partitionable arrays and, ++in the absence of ++.IR udev , ++how many partition devices to create. From 2.6.28 all md array ++devices are partitionable, hence this option is not needed. ++ ++The value of this option can be "yes" or "md" to indicate that a ++traditional, non-partitionable md array should be created, or "mdp", ++"part" or "partition" to indicate that a partitionable md array (only ++available in linux 2.6 and later) should be used. This later set can ++also have a number appended to indicate how many partitions to create ++device files for, e.g. ++.BR auto=mdp5 . ++The default is 4. ++ ++.TP ++.B bitmap= ++The option specifies a file in which a write-intent bitmap should be ++found. When assembling the array, ++.I mdadm ++will provide this file to the ++.B md ++driver as the bitmap file. This has the same function as the ++.B \-\-bitmap\-file ++option to ++.BR \-\-assemble . ++ ++.TP ++.B metadata= ++Specify the metadata format that the array has. This is mainly ++recognised for comparability with the output of ++.BR "mdadm \-Es" . ++ ++.TP ++.B container= ++Specify that this array is a member array of some container. The ++value given can be either a path name in /dev, or a UUID of the ++container array. ++ ++.TP ++.B member= ++Specify that this array is a member array of some container. Each ++type of container has some way to enumerate member arrays, often a ++simple sequence number. The value identifies which member of a ++container the array is. It will usually accompany a "container=" word. ++.RE ++ ++.TP ++.B MAILADDR ++The ++.B mailaddr ++line gives an E-mail address that alerts should be ++sent to when ++.I mdadm ++is running in ++.B \-\-monitor ++mode (and was given the ++.B \-\-scan ++option). There should only be one ++.B MAILADDR ++line and it should have only one address. Any subsequent addresses ++are silently ignored. ++ ++.TP ++.B MAILFROM ++The ++.B mailfrom ++line (which can only be abbreviated to at least 5 characters) gives an ++address to appear in the "From" address for alert mails. This can be ++useful if you want to explicitly set a domain, as the default from ++address is "root" with no domain. All words on this line are ++catenated with spaces to form the address. ++ ++Note that this value cannot be set via the ++.I mdadm ++commandline. It is only settable via the config file. ++ ++.TP ++.B PROGRAM ++The ++.B program ++line gives the name of a program to be run when ++.B "mdadm \-\-monitor" ++detects potentially interesting events on any of the arrays that it ++is monitoring. This program gets run with two or three arguments, they ++being the Event, the md device, and possibly the related component ++device. ++ ++There should only be one ++.B program ++line and it should be give only one program. ++ ++ ++.TP ++.B CREATE ++The ++.B create ++line gives default values to be used when creating arrays, new members ++of arrays, and device entries for arrays. ++These include: ++ ++.RS 4 ++.TP ++.B owner= ++.TP ++.B group= ++These can give user/group ids or names to use instead of system ++defaults (root/wheel or root/disk). ++.TP ++.B mode= ++An octal file mode such as 0660 can be given to override the default ++of 0600. ++.TP ++.B auto= ++This corresponds to the ++.B \-\-auto ++flag to mdadm. Give ++.BR yes , ++.BR md , ++.BR mdp , ++.B part ++\(em possibly followed by a number of partitions \(em to indicate how ++missing device entries should be created. ++ ++.TP ++.B metadata= ++The name of the metadata format to use if none is explicitly given. ++This can be useful to impose a system-wide default of version-1 superblocks. ++ ++.TP ++.B symlinks=no ++Normally when creating devices in ++.B /dev/md/ ++.I mdadm ++will create a matching symlink from ++.B /dev/ ++with a name starting ++.B md ++or ++.BR md_ . ++Give ++.B symlinks=no ++to suppress this symlink creation. ++ ++.TP ++.B names=yes ++Since Linux 2.6.29 it has been possible to create ++.B md ++devices with a name like ++.B md_home ++rather than just a number, like ++.BR md3 . ++.I mdadm ++will use the numeric alternative by default as other tools that interact ++with md arrays may expect only numbers. ++If ++.B names=yes ++is given in ++.I mdadm.conf ++then ++.I mdadm ++will use a name when appropriate. ++If ++.B names=no ++is given, then non-numeric ++.I md ++device names will not be used even if the default changes in a future ++release of ++.IR mdadm . ++ ++.TP ++.B bbl=no ++By default, ++.I mdadm ++will reserve space for a bad block list (bbl) on all devices ++included in or added to any array that supports them. Setting ++.B bbl=no ++will prevent this, so newly added devices will not have a bad ++block log. ++.RE ++ ++.TP ++.B HOMEHOST ++The ++.B homehost ++line gives a default value for the ++.B \-\-homehost= ++option to mdadm. There should normally be only one other word on the line. ++It should either be a host name, or one of the special words ++.BR , ++.B ++and ++.BR . ++If ++.B ++is given, then the ++.BR gethostname ( 2 ) ++systemcall is used to get the host name. This is the default. ++ ++If ++.B ++is given, then a flag is set so that when arrays are being ++auto-assembled the checking of the recorded ++.I homehost ++is disabled. ++If ++.B ++is given it is also possible to give an explicit name which will be ++used when creating arrays. This is the only case when there can be ++more that one other word on the ++.B HOMEHOST ++line. If there are other words, or other ++.B HOMEHOST ++lines, they are silently ignored. ++ ++If ++.B ++is given, then the default of using ++.BR gethostname ( 2 ) ++is over-ridden and no homehost name is assumed. ++ ++When arrays are created, this host name will be stored in the ++metadata. When arrays are assembled using auto-assembly, arrays which ++do not record the correct homehost name in their metadata will be ++assembled using a "foreign" name. A "foreign" name alway ends with a ++digit string preceded by an underscore to differentiate it ++from any possible local name. e.g. ++.B /dev/md/1_1 ++or ++.BR /dev/md/home_0 . ++.TP ++.B AUTO ++A list of names of metadata format can be given, each preceded by a ++plus or minus sign. Also the word ++.I homehost ++is allowed as is ++.I all ++preceded by plus or minus sign. ++.I all ++is usually last. ++ ++When ++.I mdadm ++is auto-assembling an array, either via ++.I \-\-assemble ++or ++.I \-\-incremental ++and it finds metadata of a given type, it checks that metadata type ++against those listed in this line. The first match wins, where ++.I all ++matches anything. ++If a match is found that was preceded by a plus sign, the auto ++assembly is allowed. If the match was preceded by a minus sign, the ++auto assembly is disallowed. If no match is found, the auto assembly ++is allowed. ++ ++If the metadata indicates that the array was created for ++.I this ++host, and the word ++.I homehost ++appears before any other match, then the array is treated as a valid ++candidate for auto-assembly. ++ ++This can be used to disable all auto-assembly (so that only arrays ++explicitly listed in mdadm.conf or on the command line are assembled), ++or to disable assembly of certain metadata types which might be ++handled by other software. It can also be used to disable assembly of ++all foreign arrays - normally such arrays are assembled but given a ++non-deterministic name in ++.BR /dev/md/ . ++ ++The known metadata types are ++.BR 0.90 , ++.BR 1.x , ++.BR ddf , ++.BR imsm . ++ ++.B AUTO ++should be given at most once. Subsequent lines are silently ignored. ++Thus an earlier config file in a config directory will over-ride ++the setting in a later config file. ++ ++.TP ++.B POLICY ++This is used to specify what automatic behavior is allowed on devices ++newly appearing in the system and provides a way of marking spares that can ++be moved to other arrays as well as the migration domains. ++.I Domain ++can be defined through ++.I policy ++line by specifying a domain name for a number of paths from ++.BR /dev/disk/by-path/ . ++A device may belong to several domains. The domain of an array is a union ++of domains of all devices in that array. A spare can be automatically ++moved from one array to another if the set of the destination array's ++.I domains ++contains all the ++.I domains ++of the new disk or if both arrays have the same ++.IR spare-group . ++ ++To update hot plug configuration it is necessary to execute ++.B mdadm \-\-udev\-rules ++command after changing the config file ++ ++Keywords used in the ++.I POLICY ++line and supported values are: ++ ++.RS 4 ++.TP ++.B domain= ++any arbitrary string ++.TP ++.B metadata= ++0.9 1.x ddf or imsm ++.TP ++.B path= ++file glob matching anything from ++.B /dev/disk/by-path ++.TP ++.B type= ++either ++.B disk ++or ++.BR part . ++.TP ++.B action= ++include, re-add, spare, spare-same-slot, or force-spare ++.TP ++.B auto= ++yes, no, or homehost. ++ ++.P ++The ++.I action ++item determines the automatic behavior allowed for devices matching the ++.I path ++and ++.I type ++in the same line. If a device matches several lines with different ++.I actions ++then the most permissive will apply. The ordering of policy lines ++is irrelevant to the end result. ++.TP ++.B include ++allows adding a disk to an array if metadata on that disk matches that array ++.TP ++.B re\-add ++will include the device in the array if it appears to be a current member ++or a member that was recently removed and the array has a ++write-intent-bitmap to allow the ++.B re\-add ++functionality. ++.TP ++.B spare ++as above and additionally: if the device is bare it can ++become a spare if there is any array that it is a candidate for based ++on domains and metadata. ++.TP ++.B spare\-same\-slot ++as above and additionally if given slot was used by an array that went ++degraded recently and the device plugged in has no metadata then it will ++be automatically added to that array (or it's container) ++.TP ++.B force\-spare ++as above and the disk will become a spare in remaining cases ++.RE ++ ++.TP ++.B PART-POLICY ++This is similar to ++.B POLICY ++and accepts the same keyword assignments. It allows a consistent set ++of policies to applied to each of the partitions of a device. ++ ++A ++.B PART-POLICY ++line should set ++.I type=disk ++and identify the path to one or more disk devices. Each partition on ++these disks will be treated according to the ++.I action= ++setting from this line. If a ++.I domain ++is set in the line, then the domain associated with each patition will ++be based on the domain, but with ++.RB \(dq -part N\(dq ++appended, when N is the partition number for the partition that was ++found. ++ ++.TP ++.B SYSFS ++The ++.B SYSFS ++line lists custom values of MD device's sysfs attributes which will be ++stored in sysfs after the array is assembled. Multiple lines are allowed and each ++line has to contain the uuid or the name of the device to which it relates. ++.RS 4 ++.TP ++.B uuid= ++hexadecimal identifier of MD device. This has to match the uuid stored in the ++superblock. ++.TP ++.B name= ++name of the MD device as was given to ++.I mdadm ++when the array was created. It will be ignored if ++.B uuid ++is not empty. ++.RE ++ ++.TP ++.B MONITORDELAY ++The ++.B monitordelay ++line gives a delay in seconds ++.I mdadm ++shall wait before pooling md arrays ++when ++.I mdadm ++is running in ++.B \-\-monitor ++mode. ++.B \-d/\-\-delay ++command line argument takes precedence over the config file ++ ++.SH EXAMPLE ++DEVICE /dev/sd[bcdjkl]1 ++.br ++DEVICE /dev/hda1 /dev/hdb1 ++ ++# /dev/md0 is known by its UUID. ++.br ++ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 ++.br ++# /dev/md1 contains all devices with a minor number of ++.br ++# 1 in the superblock. ++.br ++ARRAY /dev/md1 superminor=1 ++.br ++# /dev/md2 is made from precisely these two devices ++.br ++ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 ++ ++# /dev/md4 and /dev/md5 are a spare-group and spares ++.br ++# can be moved between them ++.br ++ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df ++.br ++ spare\-group=group1 ++.br ++ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 ++.br ++ spare\-group=group1 ++.br ++# /dev/md/home is created if need to be a partitionable md array ++.br ++# any spare device number is allocated. ++.br ++ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b ++.br ++ auto=part ++.br ++# The name of this array contains a space. ++.br ++ARRAY /dev/md9 name='Data Storage' ++.sp ++POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* ++.br ++ action=spare ++.br ++POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* ++.br ++ action=include ++.br ++# One domain comprising of devices attached to specified paths is defined. ++.br ++# Bare device matching first path will be made an imsm spare on hot plug. ++.br ++# If more than one array is created on devices belonging to domain1 and ++.br ++# one of them becomes degraded, then any imsm spare matching any path for ++.br ++# given domain name can be migrated. ++.br ++MAILADDR root@mydomain.tld ++.br ++PROGRAM /usr/sbin/handle\-mdadm\-events ++.br ++CREATE group=system mode=0640 auto=part\-8 ++.br ++HOMEHOST ++.br ++AUTO +1.x homehost \-all ++.br ++SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 ++.br ++SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 ++sync_speed_max=1000000 ++.br ++MONITORDELAY 60 ++ ++.SH SEE ALSO ++.BR mdadm (8), ++.BR md (4). +-- +2.38.1 + diff --git a/0007-mdadm-Update-ReadMe.patch b/0007-mdadm-Update-ReadMe.patch new file mode 100644 index 0000000..a143a22 --- /dev/null +++ b/0007-mdadm-Update-ReadMe.patch @@ -0,0 +1,48 @@ +From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:05 +0100 +Subject: [PATCH 07/83] mdadm: Update ReadMe + +Instead of hardcoded config file path give reference to config manual. + +Add missing monitordelay and homecluster parameters. + +Signed-off-by: Lukasz Florczak +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/ReadMe.c b/ReadMe.c +index 81399765..8f873c48 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -613,7 +613,6 @@ char Help_incr[] = + ; + + char Help_config[] = +-"The /etc/mdadm.conf config file:\n\n" + " The config file contains, apart from blank lines and comment lines that\n" + " start with a hash(#), array lines, device lines, and various\n" + " configuration lines.\n" +@@ -636,10 +635,12 @@ char Help_config[] = + " than a device must match all of them to be considered.\n" + "\n" + " Other configuration lines include:\n" +-" mailaddr, mailfrom, program used for --monitor mode\n" +-" create, auto used when creating device names in /dev\n" +-" homehost, policy, part-policy used to guide policy in various\n" +-" situations\n" ++" mailaddr, mailfrom, program, monitordelay used for --monitor mode\n" ++" create, auto used when creating device names in /dev\n" ++" homehost, homecluster, policy, part-policy used to guide policy in various\n" ++" situations\n" ++"\n" ++"For more details see mdadm.conf(5).\n" + "\n" + ; + +-- +2.38.1 + diff --git a/0008-mdadm-Update-config-man-regarding-default-files-and-.patch b/0008-mdadm-Update-config-man-regarding-default-files-and-.patch new file mode 100644 index 0000000..0109e9a --- /dev/null +++ b/0008-mdadm-Update-config-man-regarding-default-files-and-.patch @@ -0,0 +1,203 @@ +From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:06 +0100 +Subject: [PATCH 08/83] mdadm: Update config man regarding default files and + multi-keyword behavior + +Simplify default and alternative config file and directory location references +from mdadm(8) as references to mdadm.conf(5). Add FILE section in config man +and explain order and conditions in which default and alternative config files +and directories are used. + +Update config man behavior regarding parsing order when multiple keywords/config +files are involved. + +Signed-off-by: Lukasz Florczak +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 30 +++++++++-------------- + mdadm.conf.5.in | 65 ++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 71 insertions(+), 24 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 8b21ffd4..0be02e4a 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts. + + .TP + .BR \-c ", " \-\-config= +-Specify the config file or directory. Default is to use +-.B {CONFFILE} +-and +-.BR {CONFFILE}.d , +-or if those are missing then +-.B {CONFFILE2} +-and +-.BR {CONFFILE2}.d . ++Specify the config file or directory. If not specified, default config file ++and default conf.d directory will be used. See ++.BR mdadm.conf (5) ++for more details. ++ + If the config file given is + .B "partitions" + then nothing will be read, but +@@ -2013,11 +2010,9 @@ The config file is only used if explicitly named with + .B \-\-config + or requested with (a possibly implicit) + .BR \-\-scan . +-In the later case, +-.B {CONFFILE} +-or +-.B {CONFFILE2} +-is used. ++In the later case, default config file is used. See ++.BR mdadm.conf (5) ++for more details. + + If + .B \-\-scan +@@ -3346,16 +3341,15 @@ on Monitor mode. + + .SS {CONFFILE} (or {CONFFILE2}) + +-The config file lists which devices may be scanned to see if +-they contain MD super block, and gives identifying information +-(e.g. UUID) about known MD arrays. See ++Default config file. See + .BR mdadm.conf (5) + for more details. + + .SS {CONFFILE}.d (or {CONFFILE2}.d) + +-A directory containing configuration files which are read in lexical +-order. ++Default directory containing configuration files. See ++.BR mdadm.conf (5) ++for more details. + + .SS {MAP_PATH} + When +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index 83edd008..dd331a6a 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -88,7 +88,8 @@ but only the major and minor device numbers. It scans + .I /dev + to find the name that matches the numbers. + +-If no DEVICE line is present, then "DEVICE partitions containers" is assumed. ++If no DEVICE line is present in any config file, ++then "DEVICE partitions containers" is assumed. + + For example: + .IP +@@ -272,6 +273,10 @@ catenated with spaces to form the address. + Note that this value cannot be set via the + .I mdadm + commandline. It is only settable via the config file. ++There should only be one ++.B MAILADDR ++line and it should have only one address. Any subsequent addresses ++are silently ignored. + + .TP + .B PROGRAM +@@ -286,7 +291,8 @@ device. + + There should only be one + .B program +-line and it should be give only one program. ++line and it should be given only one program. Any subsequent programs ++are silently ignored. + + + .TP +@@ -295,7 +301,14 @@ The + .B create + line gives default values to be used when creating arrays, new members + of arrays, and device entries for arrays. +-These include: ++ ++There should only be one ++.B create ++line. Any subsequent lines will override the previous settings. ++ ++Keywords used in the ++.I CREATE ++line and supported values are: + + .RS 4 + .TP +@@ -475,8 +488,8 @@ The known metadata types are + + .B AUTO + should be given at most once. Subsequent lines are silently ignored. +-Thus an earlier config file in a config directory will over-ride +-the setting in a later config file. ++Thus a later config file in a config directory will not overwrite ++the setting in an earlier config file. + + .TP + .B POLICY +@@ -594,6 +607,7 @@ The + line lists custom values of MD device's sysfs attributes which will be + stored in sysfs after the array is assembled. Multiple lines are allowed and each + line has to contain the uuid or the name of the device to which it relates. ++Lines are applied in reverse order. + .RS 4 + .TP + .B uuid= +@@ -621,7 +635,46 @@ is running in + .B \-\-monitor + mode. + .B \-d/\-\-delay +-command line argument takes precedence over the config file ++command line argument takes precedence over the config file. ++ ++If multiple ++.B MINITORDELAY ++lines are provided, only first non-zero value is considered. ++ ++.SH FILES ++ ++.SS {CONFFILE} ++ ++The default config file location, used when ++.I mdadm ++is running without --config option. ++ ++.SS {CONFFILE}.d ++ ++The default directory with config files. Used when ++.I mdadm ++is running without --config option, after successful reading of the ++.B {CONFFILE} ++default config file. Files in that directory ++are read in lexical order. ++ ++ ++.SS {CONFFILE2} ++ ++Alternative config file that is read, when ++.I mdadm ++is running without --config option and the ++.B {CONFFILE} ++default config file was not opened successfully. ++ ++.SS {CONFFILE2}.d ++ ++The alternative directory with config files. Used when ++.I mdadm ++is runninng without --config option, after reading the ++.B {CONFFILE2} ++alternative config file whether it was successful or not. Files in ++that directory are read in lexical order. + + .SH EXAMPLE + DEVICE /dev/sd[bcdjkl]1 +-- +2.38.1 + diff --git a/0009-mdadm-Update-config-manual.patch b/0009-mdadm-Update-config-manual.patch new file mode 100644 index 0000000..08599d5 --- /dev/null +++ b/0009-mdadm-Update-config-manual.patch @@ -0,0 +1,45 @@ +From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:07 +0100 +Subject: [PATCH 09/83] mdadm: Update config manual + +Add missing HOMECLUSTER keyword description. + +Signed-off-by: Lukasz Florczak +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.conf.5.in | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index dd331a6a..cd4e6a9d 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -439,6 +439,23 @@ from any possible local name. e.g. + .B /dev/md/1_1 + or + .BR /dev/md/home_0 . ++ ++.TP ++.B HOMECLUSTER ++The ++.B homcluster ++line gives a default value for the ++.B \-\-homecluster= ++option to mdadm. It specifies the cluster name for the md device. ++The md device can be assembled only on the cluster which matches ++the name specified. If ++.B homcluster ++is not provided, mdadm tries to detect the cluster name automatically. ++ ++There should only be one ++.B homecluster ++line. Any subsequent lines will be silently ignored. ++ + .TP + .B AUTO + A list of names of metadata format can be given, each preceded by a +-- +2.38.1 + diff --git a/0010-Create-Build-use-default_layout.patch b/0010-Create-Build-use-default_layout.patch new file mode 100644 index 0000000..7f9791b --- /dev/null +++ b/0010-Create-Build-use-default_layout.patch @@ -0,0 +1,153 @@ +From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 20 Jan 2022 13:18:32 +0100 +Subject: [PATCH 10/83] Create, Build: use default_layout() + +This code is duplicated for Build mode so make default_layout() extern +and use it. Simplify the function structure. + +It introduced change for Build mode, now for raid0 RAID0_ORIG_LAYOUT +will be returned same as for Create. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Build.c | 23 +------------------ + Create.c | 67 ++++++++++++++++++++++++++++++++++---------------------- + mdadm.h | 1 + + 3 files changed, 43 insertions(+), 48 deletions(-) + +diff --git a/Build.c b/Build.c +index 962c2e37..8d6f6f58 100644 +--- a/Build.c ++++ b/Build.c +@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist, + } + + if (s->layout == UnSet) +- switch(s->level) { +- default: /* no layout */ +- s->layout = 0; +- break; +- case 10: +- s->layout = 0x102; /* near=2, far=1 */ +- if (c->verbose > 0) +- pr_err("layout defaults to n1\n"); +- break; +- case 5: +- case 6: +- s->layout = map_name(r5layout, "default"); +- if (c->verbose > 0) +- pr_err("layout defaults to %s\n", map_num(r5layout, s->layout)); +- break; +- case LEVEL_FAULTY: +- s->layout = map_name(faultylayout, "default"); +- +- if (c->verbose > 0) +- pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout)); +- break; +- } ++ s->layout = default_layout(NULL, s->level, c->verbose); + + /* We need to create the device. It can have no name. */ + map_lock(&map); +diff --git a/Create.c b/Create.c +index 0ff1922d..9ea19de0 100644 +--- a/Create.c ++++ b/Create.c +@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk) + return 0; + } + +-static int default_layout(struct supertype *st, int level, int verbose) ++/** ++ * default_layout() - Get default layout for level. ++ * @st: metadata requested, could be NULL. ++ * @level: raid level requested. ++ * @verbose: verbose level. ++ * ++ * Try to ask metadata handler first, otherwise use global defaults. ++ * ++ * Return: Layout or &UnSet, return value meaning depends of level used. ++ */ ++int default_layout(struct supertype *st, int level, int verbose) + { + int layout = UnSet; ++ mapping_t *layout_map = NULL; ++ char *layout_name = NULL; + + if (st && st->ss->default_geometry) + st->ss->default_geometry(st, &level, &layout, NULL); + +- if (layout == UnSet) +- switch(level) { +- default: /* no layout */ +- layout = 0; +- break; +- case 0: +- layout = RAID0_ORIG_LAYOUT; +- break; +- case 10: +- layout = 0x102; /* near=2, far=1 */ +- if (verbose > 0) +- pr_err("layout defaults to n2\n"); +- break; +- case 5: +- case 6: +- layout = map_name(r5layout, "default"); +- if (verbose > 0) +- pr_err("layout defaults to %s\n", map_num(r5layout, layout)); +- break; +- case LEVEL_FAULTY: +- layout = map_name(faultylayout, "default"); ++ if (layout != UnSet) ++ return layout; + +- if (verbose > 0) +- pr_err("layout defaults to %s\n", map_num(faultylayout, layout)); +- break; +- } ++ switch (level) { ++ default: /* no layout */ ++ layout = 0; ++ break; ++ case 0: ++ layout = RAID0_ORIG_LAYOUT; ++ break; ++ case 10: ++ layout = 0x102; /* near=2, far=1 */ ++ layout_name = "n2"; ++ break; ++ case 5: ++ case 6: ++ layout_map = r5layout; ++ break; ++ case LEVEL_FAULTY: ++ layout_map = faultylayout; ++ break; ++ } ++ ++ if (layout_map) { ++ layout = map_name(layout_map, "default"); ++ layout_name = map_num(layout_map, layout); ++ } ++ if (layout_name && verbose > 0) ++ pr_err("layout defaults to %s\n", layout_name); + + return layout; + } +diff --git a/mdadm.h b/mdadm.h +index 26e7e5cd..cd72e711 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1512,6 +1512,7 @@ extern int get_linux_version(void); + extern int mdadm_version(char *version); + extern unsigned long long parse_size(char *size); + extern int parse_uuid(char *str, int uuid[4]); ++int default_layout(struct supertype *st, int level, int verbose); + extern int is_near_layout_10(int layout); + extern int parse_layout_10(char *layout); + extern int parse_layout_faulty(char *layout); +-- +2.38.1 + diff --git a/0011-mdadm-add-map_num_s.patch b/0011-mdadm-add-map_num_s.patch new file mode 100644 index 0000000..ee2c755 --- /dev/null +++ b/0011-mdadm-add-map_num_s.patch @@ -0,0 +1,382 @@ +From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 20 Jan 2022 13:18:33 +0100 +Subject: [PATCH 11/83] mdadm: add map_num_s() + +map_num() returns NULL if key is not defined. This patch adds +alternative, non NULL version for cases where NULL is not expected. + +There are many printf() calls where map_num() is called on variable +without NULL verification. It works, even if NULL is passed because +gcc is able to ignore NULL argument quietly but the behavior is +undefined. For safety reasons such usages will use map_num_s() now. +It is a potential point of regression. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Assemble.c | 6 ++---- + Create.c | 2 +- + Detail.c | 4 ++-- + Grow.c | 16 ++++++++-------- + Query.c | 4 ++-- + maps.c | 24 ++++++++++++++++++++++++ + mdadm.c | 20 ++++++++++---------- + mdadm.h | 2 +- + super-ddf.c | 6 +++--- + super-intel.c | 2 +- + super0.c | 2 +- + super1.c | 2 +- + sysfs.c | 9 +++++---- + 13 files changed, 61 insertions(+), 38 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 704b8293..9eac9ce0 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c, + struct assembly_array_info *arr) + { + int raid_disks = arr->preexist_cnt + arr->new_cnt; +- char *status_msg = map_num(assemble_statuses, status); ++ char *status_msg = map_num_s(assemble_statuses, status); + + if (c->export && result) + *result |= status; +@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c, + fprintf(stderr, " (%d new)", arr->new_cnt); + if (arr->exp_cnt) + fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt); +- if (status_msg) +- fprintf(stderr, " %s", status_msg); +- fprintf(stderr, ".\n"); ++ fprintf(stderr, " %s.\n", status_msg); + } + + static int name_matches(char *found, char *required, char *homehost, int require_homehost) +diff --git a/Create.c b/Create.c +index 9ea19de0..c84c1ac8 100644 +--- a/Create.c ++++ b/Create.c +@@ -83,7 +83,7 @@ int default_layout(struct supertype *st, int level, int verbose) + + if (layout_map) { + layout = map_name(layout_map, "default"); +- layout_name = map_num(layout_map, layout); ++ layout_name = map_num_s(layout_map, layout); + } + if (layout_name && verbose > 0) + pr_err("layout defaults to %s\n", layout_name); +diff --git a/Detail.c b/Detail.c +index 95d4cc70..ce7a8445 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c) + if (array.state & (1 << MD_SB_CLEAN)) { + if ((array.level == 0) || + (array.level == LEVEL_LINEAR)) +- arrayst = map_num(sysfs_array_states, +- sra->array_state); ++ arrayst = map_num_s(sysfs_array_states, ++ sra->array_state); + else + arrayst = "clean"; + } else { +diff --git a/Grow.c b/Grow.c +index 18c5719b..8a242b0f 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -547,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && + s->consistency_policy != CONSISTENCY_POLICY_PPL) { + pr_err("Operation not supported for consistency policy %s\n", +- map_num(consistency_policies, s->consistency_policy)); ++ map_num_s(consistency_policies, s->consistency_policy)); + return 1; + } + +@@ -578,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + + if (sra->consistency_policy == (unsigned)s->consistency_policy) { + pr_err("Consistency policy is already %s\n", +- map_num(consistency_policies, s->consistency_policy)); ++ map_num_s(consistency_policies, s->consistency_policy)); + ret = 1; + goto free_info; + } else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC && + sra->consistency_policy != CONSISTENCY_POLICY_PPL) { + pr_err("Current consistency policy is %s, cannot change to %s\n", +- map_num(consistency_policies, sra->consistency_policy), +- map_num(consistency_policies, s->consistency_policy)); ++ map_num_s(consistency_policies, sra->consistency_policy), ++ map_num_s(consistency_policies, s->consistency_policy)); + ret = 1; + goto free_info; + } +@@ -704,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + } + + ret = sysfs_set_str(sra, NULL, "consistency_policy", +- map_num(consistency_policies, +- s->consistency_policy)); ++ map_num_s(consistency_policies, ++ s->consistency_policy)); + if (ret) + pr_err("Failed to change array consistency policy\n"); + +@@ -2241,7 +2241,7 @@ size_change_error: + info.new_layout = UnSet; + if (info.array.level == 6 && info.new_level == UnSet) { + char l[40], *h; +- strcpy(l, map_num(r6layout, info.array.layout)); ++ strcpy(l, map_num_s(r6layout, info.array.layout)); + h = strrchr(l, '-'); + if (h && strcmp(h, "-6") == 0) { + *h = 0; +@@ -2266,7 +2266,7 @@ size_change_error: + info.new_layout = info.array.layout; + else if (info.array.level == 5 && info.new_level == 6) { + char l[40]; +- strcpy(l, map_num(r5layout, info.array.layout)); ++ strcpy(l, map_num_s(r5layout, info.array.layout)); + strcat(l, "-6"); + info.new_layout = map_name(r6layout, l); + } else { +diff --git a/Query.c b/Query.c +index 23fbf8aa..adcd231e 100644 +--- a/Query.c ++++ b/Query.c +@@ -93,7 +93,7 @@ int Query(char *dev) + else { + printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n", + dev, human_size_brief(larray_size,IEC), +- map_num(pers, level), raid_disks, ++ map_num_s(pers, level), raid_disks, + spare_disks, spare_disks == 1 ? "" : "s"); + } + st = guess_super(fd); +@@ -131,7 +131,7 @@ int Query(char *dev) + dev, + info.disk.number, info.array.raid_disks, + activity, +- map_num(pers, info.array.level), ++ map_num_s(pers, info.array.level), + mddev); + if (st->ss == &super0) + put_md_name(mddev); +diff --git a/maps.c b/maps.c +index a4fd2797..20fcf719 100644 +--- a/maps.c ++++ b/maps.c +@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = { + { NULL, ARRAY_UNKNOWN_STATE } + }; + ++/** ++ * map_num_s() - Safer alternative of map_num() function. ++ * @map: map to search. ++ * @num: key to match. ++ * ++ * Shall be used only if key existence is quaranted. ++ * ++ * Return: Pointer to name of the element. ++ */ ++char *map_num_s(mapping_t *map, int num) ++{ ++ char *ret = map_num(map, num); ++ ++ assert(ret); ++ return ret; ++} ++ ++/** ++ * map_num() - get element name by key. ++ * @map: map to search. ++ * @num: key to match. ++ * ++ * Return: Pointer to name of the element or NULL. ++ */ + char *map_num(mapping_t *map, int num) + { + while (map->name) { +diff --git a/mdadm.c b/mdadm.c +index 26299b2e..be40686c 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -280,8 +280,8 @@ int main(int argc, char *argv[]) + else + fprintf(stderr, "-%c", opt); + fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n", +- map_num(modes, newmode), +- map_num(modes, mode)); ++ map_num_s(modes, newmode), ++ map_num_s(modes, mode)); + exit(2); + } else if (!mode && newmode) { + mode = newmode; +@@ -544,7 +544,7 @@ int main(int argc, char *argv[]) + switch(s.level) { + default: + pr_err("layout not meaningful for %s arrays.\n", +- map_num(pers, s.level)); ++ map_num_s(pers, s.level)); + exit(2); + case UnSet: + pr_err("raid level must be given before layout.\n"); +@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[]) + if (option_index > 0) + pr_err(":option --%s not valid in %s mode\n", + long_options[option_index].name, +- map_num(modes, mode)); ++ map_num_s(modes, mode)); + else + pr_err("option -%c not valid in %s mode\n", +- opt, map_num(modes, mode)); ++ opt, map_num_s(modes, mode)); + exit(2); + + } +@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[]) + if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN && + s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { + pr_err("--write-journal is not supported with consistency policy: %s\n", +- map_num(consistency_policies, s.consistency_policy)); ++ map_num_s(consistency_policies, s.consistency_policy)); + exit(2); + } + } +@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[]) + s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { + if (s.level <= 0) { + pr_err("--consistency-policy not meaningful with level %s.\n", +- map_num(pers, s.level)); ++ map_num_s(pers, s.level)); + exit(2); + } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL && + !s.journaldisks) { + pr_err("--write-journal is required for consistency policy: %s\n", +- map_num(consistency_policies, s.consistency_policy)); ++ map_num_s(consistency_policies, s.consistency_policy)); + exit(2); + } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL && + s.level != 5) { +@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[]) + (!s.bitmap_file || + strcmp(s.bitmap_file, "none") == 0)) { + pr_err("--bitmap is required for consistency policy: %s\n", +- map_num(consistency_policies, s.consistency_policy)); ++ map_num_s(consistency_policies, s.consistency_policy)); + exit(2); + } else if (s.bitmap_file && + strcmp(s.bitmap_file, "none") != 0 && + s.consistency_policy != CONSISTENCY_POLICY_BITMAP && + s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { + pr_err("--bitmap is not compatible with consistency policy: %s\n", +- map_num(consistency_policies, s.consistency_policy)); ++ map_num_s(consistency_policies, s.consistency_policy)); + exit(2); + } + } +diff --git a/mdadm.h b/mdadm.h +index cd72e711..09915a00 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -770,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, + #endif + + #define SYSLOG_FACILITY LOG_DAEMON +- ++extern char *map_num_s(mapping_t *map, int num); + extern char *map_num(mapping_t *map, int num); + extern int map_name(mapping_t *map, char *name); + extern mapping_t r0layout[], r5layout[], r6layout[], +diff --git a/super-ddf.c b/super-ddf.c +index 3f304cdc..8cda23a7 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb) + printf("\n"); + printf(" unit[%d] : %d\n", i, be16_to_cpu(ve->unit)); + printf(" state[%d] : %s, %s%s\n", i, +- map_num(ddf_state, ve->state & 7), ++ map_num_s(ddf_state, ve->state & 7), + (ve->state & DDF_state_morphing) ? "Morphing, ": "", + (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent"); + printf(" init state[%d] : %s\n", i, +- map_num(ddf_init_state, ve->init_state&DDF_initstate_mask)); ++ map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask)); + printf(" access[%d] : %s\n", i, +- map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); ++ map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); + printf(" Name[%d] : %.16s\n", i, ve->name); + examine_vd(i, sb, ve->guid); + } +diff --git a/super-intel.c b/super-intel.c +index 6ff336ee..ba3bd41f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + free(dev); + free(dv); + pr_err("imsm does not support consistency policy %s\n", +- map_num(consistency_policies, s->consistency_policy)); ++ map_num_s(consistency_policies, s->consistency_policy)); + return 0; + } + +diff --git a/super0.c b/super0.c +index b79b97a9..61c9ec1d 100644 +--- a/super0.c ++++ b/super0.c +@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st) + { + mdp_super_t *sb = st->sb; + +- printf("MD_LEVEL=%s\n", map_num(pers, sb->level)); ++ printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level)); + printf("MD_DEVICES=%d\n", sb->raid_disks); + if (sb->minor_version >= 90) + printf("MD_UUID=%08x:%08x:%08x:%08x\n", +diff --git a/super1.c b/super1.c +index a12a5bc8..e3e2f954 100644 +--- a/super1.c ++++ b/super1.c +@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st) + int len = 32; + int layout; + +- printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level))); ++ printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level))); + printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks)); + for (i = 0; i < 32; i++) + if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { +diff --git a/sysfs.c b/sysfs.c +index 2995713d..0d98a65f 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) + if (info->array.level < 0) + return 0; /* FIXME */ + rv |= sysfs_set_str(info, NULL, "level", +- map_num(pers, info->array.level)); ++ map_num_s(pers, info->array.level)); + if (info->reshape_active && info->delta_disks != UnSet) + raid_disks -= info->delta_disks; + rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks); +@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers) + } + + if (info->consistency_policy == CONSISTENCY_POLICY_PPL) { +- if (sysfs_set_str(info, NULL, "consistency_policy", +- map_num(consistency_policies, +- info->consistency_policy))) { ++ char *policy = map_num_s(consistency_policies, ++ info->consistency_policy); ++ ++ if (sysfs_set_str(info, NULL, "consistency_policy", policy)) { + pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n"); + info->consistency_policy = CONSISTENCY_POLICY_RESYNC; + } +-- +2.38.1 + diff --git a/0013-mdmon-Stop-parsing-duplicate-options.patch b/0013-mdmon-Stop-parsing-duplicate-options.patch new file mode 100644 index 0000000..77324cf --- /dev/null +++ b/0013-mdmon-Stop-parsing-duplicate-options.patch @@ -0,0 +1,122 @@ +From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 13 May 2022 09:19:42 +0200 +Subject: [PATCH 13/83] mdmon: Stop parsing duplicate options + +Introduce new function is_duplicate_opt() to check if given option +was already used and prevent setting it again along with an error +message. + +Move parsing above in_initrd() check to be able to detect --offroot +option duplicates. + +Now help option is executed after parsing to prevent executing commands +like: 'mdmon --help --ndlksnlksajndfjksndafasj'. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + mdmon.c | 44 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 9 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 5570574b..c057da63 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -288,6 +288,15 @@ void usage(void) + exit(2); + } + ++static bool is_duplicate_opt(const int opt, const int set_val, const char *long_name) ++{ ++ if (opt == set_val) { ++ pr_err("--%s option duplicated!\n", long_name); ++ return true; ++ } ++ return false; ++} ++ + static int mdmon(char *devnm, int must_fork, int takeover); + + int main(int argc, char *argv[]) +@@ -299,6 +308,7 @@ int main(int argc, char *argv[]) + int all = 0; + int takeover = 0; + int dofork = 1; ++ bool help = false; + static struct option options[] = { + {"all", 0, NULL, 'a'}, + {"takeover", 0, NULL, 't'}, +@@ -308,37 +318,50 @@ int main(int argc, char *argv[]) + {NULL, 0, NULL, 0} + }; + +- if (in_initrd()) { +- /* +- * set first char of argv[0] to @. This is used by +- * systemd to signal that the task was launched from +- * initrd/initramfs and should be preserved during shutdown +- */ +- argv[0][0] = '@'; +- } +- + while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { + switch (opt) { + case 'a': ++ if (is_duplicate_opt(all, 1, "all")) ++ exit(1); + container_name = argv[optind-1]; + all = 1; + break; + case 't': ++ if (is_duplicate_opt(takeover, 1, "takeover")) ++ exit(1); + takeover = 1; + break; + case 'F': ++ if (is_duplicate_opt(dofork, 0, "foreground")) ++ exit(1); + dofork = 0; + break; + case OffRootOpt: ++ if (is_duplicate_opt(argv[0][0], '@', "offroot")) ++ exit(1); + argv[0][0] = '@'; + break; + case 'h': ++ if (is_duplicate_opt(help, true, "help")) ++ exit(1); ++ help = true; ++ break; + default: + usage(); + break; + } + } + ++ ++ if (in_initrd()) { ++ /* ++ * set first char of argv[0] to @. This is used by ++ * systemd to signal that the task was launched from ++ * initrd/initramfs and should be preserved during shutdown ++ */ ++ argv[0][0] = '@'; ++ } ++ + if (all == 0 && container_name == NULL) { + if (argv[optind]) + container_name = argv[optind]; +@@ -353,6 +376,9 @@ int main(int argc, char *argv[]) + if (strcmp(container_name, "/proc/mdstat") == 0) + all = 1; + ++ if (help) ++ usage(); ++ + if (all) { + struct mdstat_ent *mdstat, *e; + int container_len = strlen(container_name); +-- +2.38.1 + diff --git a/0014-Grow-block-n-on-external-volumes.patch b/0014-Grow-block-n-on-external-volumes.patch new file mode 100644 index 0000000..4e6a874 --- /dev/null +++ b/0014-Grow-block-n-on-external-volumes.patch @@ -0,0 +1,41 @@ +From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 19 May 2022 09:16:08 +0200 +Subject: [PATCH 14/83] Grow: block -n on external volumes. + +Performing --raid-devices on external metadata volume should be blocked +as it causes unwanted behaviour. + +Eg. Performing +mdadm -G /dev/md/volume -l10 -n4 +on r0_d2 inside 4 disk container, returns +mdadm: Need 2 spares to avoid degraded array, only have 0. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Grow.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/Grow.c b/Grow.c +index 8a242b0f..f6efbc48 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1892,6 +1892,14 @@ int Grow_reshape(char *devname, int fd, + + if (retval) { + pr_err("Cannot read superblock for %s\n", devname); ++ close(cfd); ++ free(subarray); ++ return 1; ++ } ++ ++ if (s->raiddisks && subarray) { ++ pr_err("--raid-devices operation can be performed on a container only\n"); ++ close(cfd); + free(subarray); + return 1; + } +-- +2.38.1 + diff --git a/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch b/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch new file mode 100644 index 0000000..51a9e0f --- /dev/null +++ b/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch @@ -0,0 +1,90 @@ +From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 12:11:25 +0200 +Subject: [PATCH 15/83] Incremental: Fix possible memory and resource leaks + +map allocated through map_by_uuid() is not freed if mdfd is invalid. +In addition mdfd is not closed, and mdinfo list is not freed too. + +Signed-off-by: Mateusz Grzonka +Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc +Signed-off-by: Jes Sorensen +--- + Incremental.c | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index a57fc323..4d0cd9d6 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1499,7 +1499,7 @@ static int Incremental_container(struct supertype *st, char *devname, + return 0; + } + for (ra = list ; ra ; ra = ra->next) { +- int mdfd; ++ int mdfd = -1; + char chosen_name[1024]; + struct map_ent *mp; + struct mddev_ident *match = NULL; +@@ -1514,6 +1514,12 @@ static int Incremental_container(struct supertype *st, char *devname, + + if (mp) { + mdfd = open_dev(mp->devnm); ++ if (!is_fd_valid(mdfd)) { ++ pr_err("failed to open %s: %s.\n", ++ mp->devnm, strerror(errno)); ++ rv = 2; ++ goto release; ++ } + if (mp->path) + strcpy(chosen_name, mp->path); + else +@@ -1573,21 +1579,25 @@ static int Incremental_container(struct supertype *st, char *devname, + c->autof, + trustworthy, + chosen_name, 0); ++ ++ if (!is_fd_valid(mdfd)) { ++ pr_err("create_mddev failed with chosen name %s: %s.\n", ++ chosen_name, strerror(errno)); ++ rv = 2; ++ goto release; ++ } + } +- if (only && (!mp || strcmp(mp->devnm, only) != 0)) +- continue; + +- if (mdfd < 0) { +- pr_err("failed to open %s: %s.\n", +- chosen_name, strerror(errno)); +- return 2; ++ if (only && (!mp || strcmp(mp->devnm, only) != 0)) { ++ close_fd(&mdfd); ++ continue; + } + + assemble_container_content(st, mdfd, ra, c, + chosen_name, &result); + map_free(map); + map = NULL; +- close(mdfd); ++ close_fd(&mdfd); + } + if (c->export && result) { + char sep = '='; +@@ -1610,7 +1620,11 @@ static int Incremental_container(struct supertype *st, char *devname, + } + printf("\n"); + } +- return 0; ++ ++release: ++ map_free(map); ++ sysfs_free(list); ++ return rv; + } + + static void run_udisks(char *arg1, char *arg2) +-- +2.38.1 + diff --git a/0016-Mdmonitor-Fix-segfault.patch b/0016-Mdmonitor-Fix-segfault.patch new file mode 100644 index 0000000..61c64ab --- /dev/null +++ b/0016-Mdmonitor-Fix-segfault.patch @@ -0,0 +1,98 @@ +From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Mon, 6 Jun 2022 12:32:12 +0200 +Subject: [PATCH 16/83] Mdmonitor: Fix segfault + +Mdadm with "--monitor" parameter requires md device +as an argument to be monitored. If given argument is +not a md device, error shall be returned. Previously +it was not checked and invalid argument caused +segmentation fault. This commit adds checking +that devices passed to mdmonitor are md devices. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Monitor.c | 10 +++++++++- + mdadm.h | 1 + + mdopen.c | 17 +++++++++++++++++ + 3 files changed, 27 insertions(+), 1 deletion(-) + +diff --git a/Monitor.c b/Monitor.c +index c0ab5412..4e5802b5 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -182,6 +182,7 @@ int Monitor(struct mddev_dev *devlist, + continue; + if (strcasecmp(mdlist->devname, "") == 0) + continue; ++ + st = xcalloc(1, sizeof *st); + if (mdlist->devname[0] == '/') + st->devname = xstrdup(mdlist->devname); +@@ -190,6 +191,8 @@ int Monitor(struct mddev_dev *devlist, + strcpy(strcpy(st->devname, "/dev/md/"), + mdlist->devname); + } ++ if (!is_mddev(mdlist->devname)) ++ return 1; + st->next = statelist; + st->devnm[0] = 0; + st->percent = RESYNC_UNKNOWN; +@@ -203,7 +206,12 @@ int Monitor(struct mddev_dev *devlist, + struct mddev_dev *dv; + + for (dv = devlist; dv; dv = dv->next) { +- struct state *st = xcalloc(1, sizeof *st); ++ struct state *st; ++ ++ if (!is_mddev(dv->devname)) ++ return 1; ++ ++ st = xcalloc(1, sizeof *st); + mdlist = conf_get_ident(dv->devname); + st->devname = xstrdup(dv->devname); + st->next = statelist; +diff --git a/mdadm.h b/mdadm.h +index 09915a00..d53df169 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1636,6 +1636,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy, + #define FOREIGN 2 + #define METADATA 3 + extern int open_mddev(char *dev, int report_errors); ++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); +diff --git a/mdopen.c b/mdopen.c +index 245be537..d18c9319 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -475,6 +475,23 @@ int open_mddev(char *dev, int report_errors) + return mdfd; + } + ++/** ++ * is_mddev() - check that file name passed is an md device. ++ * @dev: file name that has to be checked. ++ * Return: 1 if file passed is an md device, 0 if not. ++ */ ++int is_mddev(char *dev) ++{ ++ int fd = open_mddev(dev, 1); ++ ++ if (fd >= 0) { ++ close(fd); ++ return 1; ++ } ++ ++ return 0; ++} ++ + char *find_free_devnm(int use_partitions) + { + static char devnm[32]; +-- +2.38.1 + diff --git a/0017-Mdmonitor-Improve-logging-method.patch b/0017-Mdmonitor-Improve-logging-method.patch new file mode 100644 index 0000000..3c7eed2 --- /dev/null +++ b/0017-Mdmonitor-Improve-logging-method.patch @@ -0,0 +1,61 @@ +From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Mon, 6 Jun 2022 12:32:13 +0200 +Subject: [PATCH 17/83] Mdmonitor: Improve logging method + +Change logging, and as a result, mdmonitor in verbose +mode will report its configuration. + +Signed-off-by: Kinga Tanska +Signed-off-by: Oleksandr Shchirskyi +Signed-off-by: Jes Sorensen +--- + Monitor.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 4e5802b5..6ca1ebe5 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -136,24 +136,27 @@ int Monitor(struct mddev_dev *devlist, + struct mddev_ident *mdlist; + int delay_for_event = c->delay; + +- if (!mailaddr) { ++ if (!mailaddr) + mailaddr = conf_get_mailaddr(); +- if (mailaddr && ! c->scan) +- pr_err("Monitor using email address \"%s\" from config file\n", +- mailaddr); +- } +- mailfrom = conf_get_mailfrom(); + +- if (!alert_cmd) { ++ if (!alert_cmd) + alert_cmd = conf_get_program(); +- if (alert_cmd && !c->scan) +- pr_err("Monitor using program \"%s\" from config file\n", +- alert_cmd); +- } ++ ++ mailfrom = conf_get_mailfrom(); ++ + if (c->scan && !mailaddr && !alert_cmd && !dosyslog) { + pr_err("No mail address or alert command - not monitoring.\n"); + return 1; + } ++ ++ if (c->verbose) { ++ pr_err("Monitor is started with delay %ds\n", c->delay); ++ if (mailaddr) ++ pr_err("Monitor using email address %s\n", mailaddr); ++ if (alert_cmd) ++ pr_err("Monitor using program %s\n", alert_cmd); ++ } ++ + info.alert_cmd = alert_cmd; + info.mailaddr = mailaddr; + info.mailfrom = mailfrom; +-- +2.38.1 + diff --git a/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch new file mode 100644 index 0000000..24db49f --- /dev/null +++ b/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch @@ -0,0 +1,73 @@ +From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 11:59:34 +0200 +Subject: [PATCH 18/83] Fix possible NULL ptr dereferences and memory leaks + +In Assemble there was a NULL check for sra variable, +which effectively didn't stop the execution in every case. +That might have resulted in a NULL pointer dereference. + +Also in super-ddf, mu variable was set to NULL for some condition, +and then immidiately dereferenced. +Additionally some memory wasn't freed as well. + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Assemble.c | 7 ++++++- + super-ddf.c | 9 +++++++-- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9eac9ce0..4b213560 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1982,7 +1982,12 @@ int assemble_container_content(struct supertype *st, int mdfd, + } + + sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); +- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { ++ if (sra == NULL) { ++ pr_err("Failed to read sysfs parameters\n"); ++ return 1; ++ } ++ ++ if (strcmp(sra->text_version, content->text_version) != 0) { + if (content->array.major_version == -1 && + content->array.minor_version == -2 && + c->readonly && +diff --git a/super-ddf.c b/super-ddf.c +index 8cda23a7..abbc8b09 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -5125,13 +5125,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + */ + vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk, + &n_bvd, &vcl); +- if (vc == NULL) ++ if (vc == NULL) { ++ free(rv); + return NULL; ++ } + + mu = xmalloc(sizeof(*mu)); + if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) { + free(mu); +- mu = NULL; ++ free(rv); ++ return NULL; + } + + mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count; +@@ -5161,6 +5164,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + pr_err("BUG: can't find disk %d (%d/%d)\n", + di->disk.raid_disk, + di->disk.major, di->disk.minor); ++ free(mu); ++ free(rv); + return NULL; + } + vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum; +-- +2.38.1 + diff --git a/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch b/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch new file mode 100644 index 0000000..12dd070 --- /dev/null +++ b/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch @@ -0,0 +1,301 @@ +From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 12:00:09 +0200 +Subject: [PATCH 19/83] imsm: Remove possibility for get_imsm_dev to return + NULL + +Returning NULL from get_imsm_dev or __get_imsm_dev will cause segfault. +Guarantee that it never happens. + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + super-intel.c | 153 +++++++++++++++++++++++++------------------------- + 1 file changed, 78 insertions(+), 75 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index ba3bd41f..3788feb9 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -851,6 +851,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update) + return inf; + } + ++/** ++ * __get_imsm_dev() - Get device with index from imsm_super. ++ * @mpb: &imsm_super pointer, not NULL. ++ * @index: Device index. ++ * ++ * Function works as non-NULL, aborting in such a case, ++ * when NULL would be returned. ++ * ++ * Device index should be in range 0 up to num_raid_devs. ++ * Function assumes the index was already verified. ++ * Index must be valid, otherwise abort() is called. ++ * ++ * Return: Pointer to corresponding imsm_dev. ++ * ++ */ + static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) + { + int offset; +@@ -858,30 +873,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) + void *_mpb = mpb; + + if (index >= mpb->num_raid_devs) +- return NULL; ++ goto error; + + /* devices start after all disks */ + offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb; + +- for (i = 0; i <= index; i++) ++ for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0)) + if (i == index) + return _mpb + offset; +- else +- offset += sizeof_imsm_dev(_mpb + offset, 0); +- +- return NULL; ++error: ++ pr_err("cannot find imsm_dev with index %u in imsm_super\n", index); ++ abort(); + } + ++/** ++ * get_imsm_dev() - Get device with index from intel_super. ++ * @super: &intel_super pointer, not NULL. ++ * @index: Device index. ++ * ++ * Function works as non-NULL, aborting in such a case, ++ * when NULL would be returned. ++ * ++ * Device index should be in range 0 up to num_raid_devs. ++ * Function assumes the index was already verified. ++ * Index must be valid, otherwise abort() is called. ++ * ++ * Return: Pointer to corresponding imsm_dev. ++ * ++ */ + static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index) + { + struct intel_dev *dv; + + if (index >= super->anchor->num_raid_devs) +- return NULL; ++ goto error; ++ + for (dv = super->devlist; dv; dv = dv->next) + if (dv->index == index) + return dv->dev; +- return NULL; ++error: ++ pr_err("cannot find imsm_dev with index %u in intel_super\n", index); ++ abort(); + } + + static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr +@@ -4364,8 +4396,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 && +- dev_iter->vol.migr_state == 1 && ++ if (dev_iter->vol.migr_state == 1 && + dev_iter->vol.migr_type == MIGR_GEN_MIGR) { + /* This device is migrating */ + map0 = get_imsm_map(dev_iter, MAP_0); +@@ -4514,8 +4545,6 @@ static void clear_hi(struct intel_super *super) + } + for (i = 0; i < mpb->num_raid_devs; ++i) { + struct imsm_dev *dev = get_imsm_dev(super, i); +- if (!dev) +- return; + for (n = 0; n < 2; ++n) { + struct imsm_map *map = get_imsm_map(dev, n); + if (!map) +@@ -5836,7 +5865,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + struct imsm_dev *_dev = __get_imsm_dev(mpb, 0); + + _disk = __get_imsm_disk(mpb, dl->index); +- if (!_dev || !_disk) { ++ if (!_disk) { + pr_err("BUG mpb setup error\n"); + return 1; + } +@@ -6171,10 +6200,10 @@ static int write_super_imsm(struct supertype *st, int doclose) + for (i = 0; i < mpb->num_raid_devs; i++) { + struct imsm_dev *dev = __get_imsm_dev(mpb, i); + struct imsm_dev *dev2 = get_imsm_dev(super, i); +- if (dev && dev2) { +- imsm_copy_dev(dev, dev2); +- mpb_size += sizeof_imsm_dev(dev, 0); +- } ++ ++ imsm_copy_dev(dev, dev2); ++ mpb_size += sizeof_imsm_dev(dev, 0); ++ + if (is_gen_migration(dev2)) + clear_migration_record = 0; + } +@@ -9033,29 +9062,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed) + __u8 state; + + dev2 = get_imsm_dev(cont->sb, dev_idx); +- if (dev2) { +- state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); +- if (state == IMSM_T_STATE_FAILED) { +- map = get_imsm_map(dev2, MAP_0); +- if (!map) +- return 1; +- for (slot = 0; slot < map->num_members; slot++) { +- /* +- * Check if failed disks are deleted from intel +- * disk list or are marked to be deleted +- */ +- idx = get_imsm_disk_idx(dev2, slot, MAP_X); +- idisk = get_imsm_dl_disk(cont->sb, idx); +- /* +- * Do not rebuild the array if failed disks +- * from failed sub-array are not removed from +- * container. +- */ +- if (idisk && +- is_failed(&idisk->disk) && +- (idisk->action != DISK_REMOVE)) +- return 0; +- } ++ ++ state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); ++ if (state == IMSM_T_STATE_FAILED) { ++ map = get_imsm_map(dev2, MAP_0); ++ for (slot = 0; slot < map->num_members; slot++) { ++ /* ++ * Check if failed disks are deleted from intel ++ * disk list or are marked to be deleted ++ */ ++ idx = get_imsm_disk_idx(dev2, slot, MAP_X); ++ idisk = get_imsm_dl_disk(cont->sb, idx); ++ /* ++ * Do not rebuild the array if failed disks ++ * from failed sub-array are not removed from ++ * container. ++ */ ++ if (idisk && ++ is_failed(&idisk->disk) && ++ (idisk->action != DISK_REMOVE)) ++ return 0; + } + } + return 1; +@@ -10089,7 +10115,6 @@ static void imsm_process_update(struct supertype *st, + int victim = u->dev_idx; + struct active_array *a; + struct intel_dev **dp; +- struct imsm_dev *dev; + + /* sanity check that we are not affecting the uuid of + * active arrays, or deleting an active array +@@ -10105,8 +10130,7 @@ static void imsm_process_update(struct supertype *st, + * is active in the container, so checking + * mpb->num_raid_devs is just extra paranoia + */ +- dev = get_imsm_dev(super, victim); +- if (a || !dev || mpb->num_raid_devs == 1) { ++ if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) { + dprintf("failed to delete subarray-%d\n", victim); + break; + } +@@ -10140,7 +10164,7 @@ static void imsm_process_update(struct supertype *st, + if (a->info.container_member == target) + break; + dev = get_imsm_dev(super, u->dev_idx); +- if (a || !dev || !check_name(super, name, 1)) { ++ if (a || !check_name(super, name, 1)) { + dprintf("failed to rename subarray-%d\n", target); + break; + } +@@ -10169,10 +10193,6 @@ static void imsm_process_update(struct supertype *st, + struct imsm_update_rwh_policy *u = (void *)update->buf; + int target = u->dev_idx; + struct imsm_dev *dev = get_imsm_dev(super, target); +- if (!dev) { +- dprintf("could not find subarray-%d\n", target); +- break; +- } + + if (dev->rwh_policy != u->new_policy) { + dev->rwh_policy = u->new_policy; +@@ -11397,8 +11417,10 @@ static int imsm_create_metadata_update_for_migration( + { + struct intel_super *super = st->sb; + int update_memory_size; ++ int current_chunk_size; + struct imsm_update_reshape_migration *u; +- struct imsm_dev *dev; ++ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); ++ struct imsm_map *map = get_imsm_map(dev, MAP_0); + int previous_level = -1; + + dprintf("(enter) New Level = %i\n", geo->level); +@@ -11415,23 +11437,15 @@ static int imsm_create_metadata_update_for_migration( + u->new_disks[0] = -1; + u->new_chunksize = -1; + +- dev = get_imsm_dev(super, u->subdev); +- if (dev) { +- struct imsm_map *map; ++ current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2; + +- map = get_imsm_map(dev, MAP_0); +- if (map) { +- int current_chunk_size = +- __le16_to_cpu(map->blocks_per_strip) / 2; +- +- if (geo->chunksize != current_chunk_size) { +- u->new_chunksize = geo->chunksize / 1024; +- dprintf("imsm: chunk size change from %i to %i\n", +- current_chunk_size, u->new_chunksize); +- } +- previous_level = map->raid_level; +- } ++ if (geo->chunksize != current_chunk_size) { ++ u->new_chunksize = geo->chunksize / 1024; ++ dprintf("imsm: chunk size change from %i to %i\n", ++ current_chunk_size, u->new_chunksize); + } ++ previous_level = map->raid_level; ++ + if (geo->level == 5 && previous_level == 0) { + struct mdinfo *spares = NULL; + +@@ -12519,9 +12533,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st) + unsigned long long offset; + struct dl *d; + +- if (!dev) +- return -1; +- + if (dev->rwh_policy != RWH_BITMAP) + return 0; + +@@ -12567,16 +12578,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp, + return -1; + + dev = get_imsm_dev(super, vol_idx); +- +- if (!dev) { +- dprintf("cannot find the device for volume index %d\n", +- vol_idx); +- return -1; +- } + dev->rwh_policy = RWH_BITMAP; +- + *chunkp = calculate_bitmap_chunksize(st, dev); +- + return 0; + } + +-- +2.38.1 + diff --git a/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch b/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch new file mode 100644 index 0000000..f51c730 --- /dev/null +++ b/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch @@ -0,0 +1,85 @@ +From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 18 Apr 2022 13:44:23 -0400 +Subject: [PATCH 20/83] Revert "mdadm: fix coredump of mdadm --monitor -r" + +This reverts commit 546047688e1c64638f462147c755b58119cabdc8. + +The change from commit mdadm: fix coredump of mdadm +--monitor -r broke the printing of the return message when +passing -r to mdadm --manage, the removal of a device from +an array. + +If the current code reverts this commit, both issues are +still fixed. + +The original problem reported that the fix tried to address +was: The --monitor -r option requires a parameter, +otherwise a null pointer will be manipulated when +converting to integer data, and a core dump will appear. + +The original problem was really fixed with: +60815698c0a Refactor parse_num and use it to parse optarg. +Which added a check for NULL in 'optarg' before moving it +to the 'increments' variable. + +New issue: When trying to remove a device using the short +argument -r, instead of the long argument --remove, the +output is empty. The problem started when commit +546047688e1c was added. + +Steps to Reproduce: +1. create/assemble /dev/md0 device +2. mdadm --manage /dev/md0 -r /dev/vdxx + +Actual results: +Nothing, empty output, nothing happens, the device is still +connected to the array. + +The output should have stated "mdadm: hot remove failed +for /dev/vdxx: Device or resource busy", if the device was +still active. Or it should remove the device and print +a message: + +mdadm: set /dev/vdd faulty in /dev/md0 +mdadm: hot removed /dev/vdd from /dev/md0 + +The following commit should be reverted as it breaks +mdadm --manage -r. + +commit 546047688e1c64638f462147c755b58119cabdc8 +Author: Wu Guanghao +Date: Mon Aug 16 15:24:51 2021 +0800 +mdadm: fix coredump of mdadm --monitor -r + +-Nigel + +Signed-off-by: Nigel Croxon +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ReadMe.c b/ReadMe.c +index 8f873c48..bec1be9a 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -81,11 +81,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; + * found, it is started. + */ + +-char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k"; ++char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; + char short_bitmap_options[]= +- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; ++ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; + char short_bitmap_auto_options[]= +- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; ++ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; + + struct option long_options[] = { + {"manage", 0, 0, ManageOpt}, +-- +2.38.1 + diff --git a/0021-util-replace-ioctl-use-with-function.patch b/0021-util-replace-ioctl-use-with-function.patch new file mode 100644 index 0000000..56ee5e8 --- /dev/null +++ b/0021-util-replace-ioctl-use-with-function.patch @@ -0,0 +1,31 @@ +From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 21 Jun 2022 00:10:39 +0800 +Subject: [PATCH 21/83] util: replace ioctl use with function + +Replace using of ioctl calling to get md array info with +special function prepared to it. + +Signed-off-by: Kinga Tanska +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util.c b/util.c +index cc94f96e..38f0420e 100644 +--- a/util.c ++++ b/util.c +@@ -267,7 +267,7 @@ int md_array_active(int fd) + * GET_ARRAY_INFO doesn't provide access to the proper state + * information, so fallback to a basic check for raid_disks != 0 + */ +- ret = ioctl(fd, GET_ARRAY_INFO, &array); ++ ret = md_get_array_info(fd, &array); + } + + return !ret; +-- +2.38.1 + diff --git a/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch b/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch new file mode 100644 index 0000000..88bba83 --- /dev/null +++ b/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch @@ -0,0 +1,110 @@ +From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Tue, 21 Jun 2022 00:10:40 +0800 +Subject: [PATCH 22/83] mdadm/super1: restore commit 45a87c2f31335 to fix + clustered slot issue + +Commit 9d67f6496c71 ("mdadm:check the nodes when operate clustered +array") modified assignment logic for st->nodes in write_bitmap1(), +which introduced bitmap slot issue: + +load_super1 didn't set up supertype.nodes, which made spare disk only +have one slot info. Then it triggered kernel md_bitmap_load_sb to get +wrong bitmap slot data. + +For fixing this issue, there are two methods: + +1> revert the related code of commit 9d67f6496c71. and restore the code + from former commit 45a87c2f31335 ("super1: add more checks for + NodeNumUpdate option"). + st->nodes value would be 0 & 1 under current code logic. i.e. + When adding a spare disk, there is no place to init st->nodes, and + the value is ZERO. + +2> keep 9d67f6496c71, add additional ->nodes handling in load_super1(), + let load_super1 to set st->nodes when bitmap is BITMAP_MAJOR_CLUSTERED. + Under current mdadm code logic, load_super1 will be called many + times, any new code in load_super1 will cost mdadm running more time. + And more reason is I prefer as much as possible to limit clustered + code spreading in every corner. + +So I used method <1> to fix this issue. + +How to trigger: + +dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda +dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb +dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdc +mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb +mdadm -a /dev/md0 /dev/sdc +mdadm /dev/md0 --fail /dev/sda +mdadm /dev/md0 --remove /dev/sda +mdadm -Ss +mdadm -A /dev/md0 /dev/sdb /dev/sdc + +the output of current "mdadm -X /dev/sdc": +(there should be (by default) 4 slot info for correct output) +``` + Filename : /dev/sdc + Magic : 6d746962 + Version : 5 + UUID : a74642f8:a6b1fba8:58e1f8db:cfe7b082 + Events : 29 + Events Cleared : 0 + State : OK + Chunksize : 64 MB + Daemon : 5s flush period + Write Mode : Normal + Sync Size : 306176 (299.00 MiB 313.52 MB) + Bitmap : 5 bits (chunks), 5 dirty (100.0%) +``` + +And mdadm later operations will trigger kernel output error message: +(triggered by "mdadm -A /dev/md0 /dev/sdb /dev/sdc") +``` +kernel: md0: invalid bitmap file superblock: bad magic +kernel: md_bitmap_copy_from_slot can't get bitmap from slot 1 +kernel: md-cluster: Could not gather bitmaps from slot 1 +kernel: md0: invalid bitmap file superblock: bad magic +kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2 +kernel: md-cluster: Could not gather bitmaps from slot 2 +kernel: md0: invalid bitmap file superblock: bad magic +kernel: md_bitmap_copy_from_slot can't get bitmap from slot 3 +kernel: md-cluster: Could not gather bitmaps from slot 3 +kernel: md-cluster: failed to gather all resyn infos +kernel: md0: detected capacity change from 0 to 612352 +``` + +Acked-by: Coly Li +Signed-off-by: Heming Zhao +Signed-off-by: Jes Sorensen +--- + super1.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/super1.c b/super1.c +index e3e2f954..3a0c69fd 100644 +--- a/super1.c ++++ b/super1.c +@@ -2674,7 +2674,17 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update + } + + if (bms->version == BITMAP_MAJOR_CLUSTERED) { +- if (__cpu_to_le32(st->nodes) < bms->nodes) { ++ if (st->nodes == 1) { ++ /* the parameter for nodes is not valid */ ++ pr_err("Warning: cluster-md at least needs two nodes\n"); ++ return -EINVAL; ++ } else if (st->nodes == 0) { ++ /* ++ * parameter "--nodes" is not specified, (eg, add a disk to ++ * clustered raid) ++ */ ++ break; ++ } else if (__cpu_to_le32(st->nodes) < bms->nodes) { + /* + * Since the nodes num is not increased, no + * need to check the space enough or not, +-- +2.38.1 + diff --git a/0023-imsm-introduce-get_disk_slot_in_dev.patch b/0023-imsm-introduce-get_disk_slot_in_dev.patch new file mode 100644 index 0000000..ca1d015 --- /dev/null +++ b/0023-imsm-introduce-get_disk_slot_in_dev.patch @@ -0,0 +1,122 @@ +From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:41 +0800 +Subject: [PATCH 23/83] imsm: introduce get_disk_slot_in_dev() + +The routine was added to remove unnecessary get_imsm_dev() and +get_imsm_map() calls, used only to determine disk slot. + +Additionally, enum for IMSM return statues was added for further usage. + +Signed-off-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-intel.c | 47 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 36 insertions(+), 11 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 3788feb9..cd1f1e3d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -366,6 +366,18 @@ struct migr_record { + }; + ASSERT_SIZE(migr_record, 128) + ++/** ++ * enum imsm_status - internal IMSM return values representation. ++ * @STATUS_OK: function succeeded. ++ * @STATUS_ERROR: General error ocurred (not specified). ++ * ++ * Typedefed to imsm_status_t. ++ */ ++typedef enum imsm_status { ++ IMSM_STATUS_ERROR = -1, ++ IMSM_STATUS_OK = 0, ++} imsm_status_t; ++ + struct md_list { + /* usage marker: + * 1: load metadata +@@ -1183,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord) + map->disk_ord_tbl[slot] = __cpu_to_le32(ord); + } + +-static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) ++static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) + { + int slot; + __u32 ord; +@@ -1194,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) + return slot; + } + +- return -1; ++ return IMSM_STATUS_ERROR; + } + + static int get_imsm_raid_level(struct imsm_map *map) +@@ -1209,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map) + return map->raid_level; + } + ++/** ++ * get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev. ++ * @super: &intel_super pointer, not NULL. ++ * @dev_idx: imsm device index. ++ * @idx: disk index. ++ * ++ * Return: Slot on success, IMSM_STATUS_ERROR otherwise. ++ */ ++static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx, ++ const unsigned int idx) ++{ ++ struct imsm_dev *dev = get_imsm_dev(super, dev_idx); ++ struct imsm_map *map = get_imsm_map(dev, MAP_0); ++ ++ return get_imsm_disk_slot(map, idx); ++} ++ + static int cmp_extent(const void *av, const void *bv) + { + const struct extent *a = av; +@@ -1225,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super) + int memberships = 0; + int i; + +- for (i = 0; i < super->anchor->num_raid_devs; i++) { +- struct imsm_dev *dev = get_imsm_dev(super, i); +- struct imsm_map *map = get_imsm_map(dev, MAP_0); +- +- if (get_imsm_disk_slot(map, dl->index) >= 0) ++ for (i = 0; i < super->anchor->num_raid_devs; i++) ++ if (get_disk_slot_in_dev(super, i, dl->index) >= 0) + memberships++; +- } + + return memberships; + } +@@ -1941,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super) + + /* first map under migration */ + map = get_imsm_map(dev, MAP_0); ++ + if (map) + slot = get_imsm_disk_slot(map, super->disks->index); + if (map == NULL || slot > 1 || slot < 0) { +@@ -9655,10 +9681,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u, + /* count arrays using the victim in the metadata */ + found = 0; + for (a = active_array; a ; a = a->next) { +- dev = get_imsm_dev(super, a->info.container_member); +- map = get_imsm_map(dev, MAP_0); ++ int dev_idx = a->info.container_member; + +- if (get_imsm_disk_slot(map, victim) >= 0) ++ if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0) + found++; + } + +-- +2.38.1 + diff --git a/0024-imsm-use-same-slot-across-container.patch b/0024-imsm-use-same-slot-across-container.patch new file mode 100644 index 0000000..dc23b3c --- /dev/null +++ b/0024-imsm-use-same-slot-across-container.patch @@ -0,0 +1,252 @@ +From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:42 +0800 +Subject: [PATCH 24/83] imsm: use same slot across container + +Autolayout relies on drives order on super->disks list, but +it is not quaranted by readdir() in sysfs_read(). As a result +drive could be put in different slot in second volume. + +Make it consistent by reffering to first volume, if exists. + +Use enum imsm_status to unify error handling. + +Signed-off-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-intel.c | 169 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 108 insertions(+), 61 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index cd1f1e3d..deef7c87 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7522,11 +7522,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + return 1; + } + +-static int imsm_get_free_size(struct supertype *st, int raiddisks, +- unsigned long long size, int chunk, +- unsigned long long *freesize) ++/** ++ * imsm_get_free_size() - get the biggest, common free space from members. ++ * @super: &intel_super pointer, not NULL. ++ * @raiddisks: number of raid disks. ++ * @size: requested size, could be 0 (means max size). ++ * @chunk: requested chunk. ++ * @freesize: pointer for returned size value. ++ * ++ * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. ++ * ++ * @freesize is set to meaningful value, this can be @size, or calculated ++ * max free size. ++ * super->create_offset value is modified and set appropriately in ++ * merge_extends() for further creation. ++ */ ++static imsm_status_t imsm_get_free_size(struct intel_super *super, ++ const int raiddisks, ++ unsigned long long size, ++ const int chunk, ++ unsigned long long *freesize) + { +- struct intel_super *super = st->sb; + struct imsm_super *mpb = super->anchor; + struct dl *dl; + int i; +@@ -7570,12 +7586,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, + /* chunk is in K */ + minsize = chunk * 2; + +- if (cnt < raiddisks || +- (super->orom && used && used != raiddisks) || +- maxsize < minsize || +- maxsize == 0) { ++ if (cnt < raiddisks || (super->orom && used && used != raiddisks) || ++ maxsize < minsize || maxsize == 0) { + pr_err("not enough devices with space to create array.\n"); +- return 0; /* No enough free spaces large enough */ ++ return IMSM_STATUS_ERROR; + } + + if (size == 0) { +@@ -7588,37 +7602,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, + } + if (mpb->num_raid_devs > 0 && size && size != maxsize) + pr_err("attempting to create a second volume with size less then remaining space.\n"); +- cnt = 0; +- for (dl = super->disks; dl; dl = dl->next) +- if (dl->e) +- dl->raiddisk = cnt++; +- + *freesize = size; + + dprintf("imsm: imsm_get_free_size() returns : %llu\n", size); + +- return 1; ++ return IMSM_STATUS_OK; + } + +-static int reserve_space(struct supertype *st, int raiddisks, +- unsigned long long size, int chunk, +- unsigned long long *freesize) ++/** ++ * autolayout_imsm() - automatically layout a new volume. ++ * @super: &intel_super pointer, not NULL. ++ * @raiddisks: number of raid disks. ++ * @size: requested size, could be 0 (means max size). ++ * @chunk: requested chunk. ++ * @freesize: pointer for returned size value. ++ * ++ * We are being asked to automatically layout a new volume based on the current ++ * contents of the container. If the parameters can be satisfied autolayout_imsm ++ * will record the disks, start offset, and will return size of the volume to ++ * be created. See imsm_get_free_size() for details. ++ * add_to_super() and getinfo_super() detect when autolayout is in progress. ++ * If first volume exists, slots are set consistently to it. ++ * ++ * Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise. ++ * ++ * Disks are marked for creation via dl->raiddisk. ++ */ ++static imsm_status_t autolayout_imsm(struct intel_super *super, ++ const int raiddisks, ++ unsigned long long size, const int chunk, ++ unsigned long long *freesize) + { +- struct intel_super *super = st->sb; +- struct dl *dl; +- int cnt; +- int rv = 0; ++ int curr_slot = 0; ++ struct dl *disk; ++ int vol_cnt = super->anchor->num_raid_devs; ++ imsm_status_t rv; + +- rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize); +- if (rv) { +- cnt = 0; +- for (dl = super->disks; dl; dl = dl->next) +- if (dl->e) +- dl->raiddisk = cnt++; +- rv = 1; ++ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); ++ if (rv != IMSM_STATUS_OK) ++ return IMSM_STATUS_ERROR; ++ ++ for (disk = super->disks; disk; disk = disk->next) { ++ if (!disk->e) ++ continue; ++ ++ if (curr_slot == raiddisks) ++ break; ++ ++ if (vol_cnt == 0) { ++ disk->raiddisk = curr_slot; ++ } else { ++ int _slot = get_disk_slot_in_dev(super, 0, disk->index); ++ ++ if (_slot == -1) { ++ pr_err("Disk %s is not used in first volume, aborting\n", ++ disk->devname); ++ return IMSM_STATUS_ERROR; ++ } ++ disk->raiddisk = _slot; ++ } ++ curr_slot++; + } + +- return rv; ++ return IMSM_STATUS_OK; + } + + static int validate_geometry_imsm(struct supertype *st, int level, int layout, +@@ -7654,35 +7700,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + } + + if (!dev) { +- if (st->sb) { +- struct intel_super *super = st->sb; +- if (!validate_geometry_imsm_orom(st->sb, level, layout, +- raiddisks, chunk, size, +- verbose)) ++ struct intel_super *super = st->sb; ++ ++ /* ++ * Autolayout mode, st->sb and freesize must be set. ++ */ ++ if (!super || !freesize) { ++ pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); ++ return 1; ++ } ++ ++ if (!validate_geometry_imsm_orom(st->sb, level, layout, ++ raiddisks, chunk, size, ++ verbose)) ++ return 0; ++ ++ if (super->orom) { ++ imsm_status_t rv; ++ 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; +- /* we are being asked to automatically layout a +- * new volume based on the current contents of +- * the container. If the the parameters can be +- * satisfied reserve_space will record the disks, +- * start offset, and size of the volume to be +- * created. add_to_super and getinfo_super +- * detect when autolayout is in progress. +- */ +- /* assuming that freesize is always given when array is +- created */ +- if (super->orom && freesize) { +- int count; +- 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; +- } + } +- if (freesize) +- return reserve_space(st, raiddisks, size, +- *chunk, freesize); ++ ++ rv = autolayout_imsm(super, raiddisks, size, *chunk, ++ freesize); ++ if (rv != IMSM_STATUS_OK) ++ return 0; + } + return 1; + } +@@ -11538,7 +11584,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + unsigned long long current_size; + unsigned long long free_size; + unsigned long long max_size; +- int rv; ++ imsm_status_t rv; + + getinfo_super_imsm_volume(st, &info, NULL); + if (geo->level != info.array.level && geo->level >= 0 && +@@ -11657,9 +11703,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + } + /* check the maximum available size + */ +- rv = imsm_get_free_size(st, dev->vol.map->num_members, +- 0, chunk, &free_size); +- if (rv == 0) ++ rv = imsm_get_free_size(super, dev->vol.map->num_members, ++ 0, chunk, &free_size); ++ ++ if (rv != IMSM_STATUS_OK) + /* Cannot find maximum available space + */ + max_size = 0; +-- +2.38.1 + diff --git a/0025-imsm-block-changing-slots-during-creation.patch b/0025-imsm-block-changing-slots-during-creation.patch new file mode 100644 index 0000000..4c3b918 --- /dev/null +++ b/0025-imsm-block-changing-slots-during-creation.patch @@ -0,0 +1,122 @@ +From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:43 +0800 +Subject: [PATCH 25/83] imsm: block changing slots during creation + +If user specifies drives for array creation, then slot order across +volumes is not preserved. +Ideally, it should be checked in validate_geometry() but it is not +possible in current implementation (order is determined later). +Add verification in add_to_super_imsm_volume() and throw error if +mismatch is detected. +IMSM allows to use only same members within container. +This is not hardware dependency but metadata limitation. +Therefore, 09-imsm-overlap test is removed. Testing it is pointless. +After this patch, creation in this scenario is blocked. Offset +verification is covered in other tests. + +Signed-off-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-intel.c | 33 ++++++++++++++++++++++----------- + tests/09imsm-overlap | 28 ---------------------------- + 2 files changed, 22 insertions(+), 39 deletions(-) + delete mode 100644 tests/09imsm-overlap + +diff --git a/super-intel.c b/super-intel.c +index deef7c87..8ffe485c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + struct imsm_map *map; + struct dl *dl, *df; + int slot; ++ int autolayout = 0; ++ ++ if (!is_fd_valid(fd)) ++ autolayout = 1; + + dev = get_imsm_dev(super, super->current_vol); + map = get_imsm_map(dev, MAP_0); +@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + return 1; + } + +- if (!is_fd_valid(fd)) { +- /* we're doing autolayout so grab the pre-marked (in +- * validate_geometry) raid_disk +- */ +- for (dl = super->disks; dl; dl = dl->next) ++ for (dl = super->disks; dl ; dl = dl->next) { ++ if (autolayout) { + if (dl->raiddisk == dk->raid_disk) + break; +- } else { +- for (dl = super->disks; dl ; dl = dl->next) +- if (dl->major == dk->major && +- dl->minor == dk->minor) +- break; ++ } else if (dl->major == dk->major && dl->minor == dk->minor) ++ break; + } + + if (!dl) { +- pr_err("%s is not a member of the same container\n", devname); ++ if (!autolayout) ++ pr_err("%s is not a member of the same container.\n", ++ devname); + return 1; + } + ++ if (!autolayout && super->current_vol > 0) { ++ int _slot = get_disk_slot_in_dev(super, 0, dl->index); ++ ++ if (_slot != dk->raid_disk) { ++ pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n", ++ dl->devname, _slot, dk->raid_disk); ++ pr_err("Raid members are in different order than for the first volume, aborting.\n"); ++ return 1; ++ } ++ } ++ + if (mpb->num_disks == 0) + if (!get_dev_sector_size(dl->fd, dl->devname, + &super->sector_size)) +diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap +deleted file mode 100644 +index ff5d2093..00000000 +--- a/tests/09imsm-overlap ++++ /dev/null +@@ -1,28 +0,0 @@ +- +-. tests/env-imsm-template +- +-# create raid arrays with varying degress of overlap +-mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5 +-imsm_check container 6 +- +-size=1024 +-level=1 +-num_disks=2 +-mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size +-mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size +-mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size +-mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size +-mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size +- +-udevadm settle +- +-offset=0 +-imsm_check member $member0 $num_disks $level $size 1024 $offset +-offset=$((offset+size+4096)) +-imsm_check member $member1 $num_disks $level $size 1024 $offset +-offset=$((offset+size+4096)) +-imsm_check member $member2 $num_disks $level $size 1024 $offset +-offset=$((offset+size+4096)) +-imsm_check member $member3 $num_disks $level $size 1024 $offset +-offset=$((offset+size+4096)) +-imsm_check member $member4 $num_disks $level $size 1024 $offset +-- +2.38.1 + diff --git a/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch b/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch new file mode 100644 index 0000000..d593669 --- /dev/null +++ b/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch @@ -0,0 +1,177 @@ +From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Wed, 15 Jun 2022 14:28:39 +0200 +Subject: [PATCH 26/83] mdadm: block update=ppl for non raid456 levels + +Option ppl should be used only for raid levels 4, 5 and 6. Cancel update +for other levels. + +Applied globally for imsm and ddf format. + +Additionally introduce is_level456() helper function. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + Assemble.c | 11 +++++------ + Grow.c | 2 +- + Manage.c | 14 ++++++++++++-- + mdadm.h | 11 +++++++++++ + super0.c | 2 +- + super1.c | 3 +-- + 6 files changed, 31 insertions(+), 12 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 4b213560..6df6bfbc 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content, + * devices in RAID4 or last devices in RAID4/5/6. + */ + delta = devices[j].i.delta_disks; +- if (devices[j].i.array.level >= 4 && +- devices[j].i.array.level <= 6 && ++ if (is_level456(devices[j].i.array.level) && + i/2 >= content->array.raid_disks - delta) + /* OK */; + else if (devices[j].i.array.level == 4 && +@@ -1226,8 +1225,7 @@ static int start_array(int mdfd, + fprintf(stderr, ".\n"); + } + if (content->reshape_active && +- content->array.level >= 4 && +- content->array.level <= 6) { ++ is_level456(content->array.level)) { + /* might need to increase the size + * of the stripe cache - default is 256 + */ +@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd, + int start_reshape; + char *avail; + int err; +- int is_raid456, is_clean, all_disks; ++ int is_clean, all_disks; ++ bool is_raid456; + + if (sysfs_init(content, mdfd, NULL)) { + pr_err("Unable to initialize sysfs\n"); +@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + content->array.state |= 1; + } + +- is_raid456 = (content->array.level >= 4 && content->array.level <= 6); ++ is_raid456 = is_level456(content->array.level); + is_clean = content->array.state & 1; + + if (enough(content->array.level, content->array.raid_disks, +diff --git a/Grow.c b/Grow.c +index f6efbc48..8c520d42 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + } + + md_get_array_info(fd, &array); +- if (level == 0 && (array.level >= 4 && array.level <= 6)) { ++ if (level == 0 && is_level456(array.level)) { + /* To convert to RAID0 we need to fail and + * remove any non-data devices. */ + int found = 0; +diff --git a/Manage.c b/Manage.c +index f789e0c1..e5e6abe4 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + * - unfreeze reshape + * - wait on 'sync_completed' for that point to be reached. + */ +- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) && ++ if (mdi && is_level456(mdi->array.level) && + sysfs_attribute_available(mdi, NULL, "sync_action") && + sysfs_attribute_available(mdi, NULL, "reshape_direction") && + sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 && +@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + { + struct supertype supertype, *st = &supertype; + int fd, rv = 2; ++ struct mdinfo *info = NULL; + + memset(st, 0, sizeof(*st)); + +@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + if (mdmon_running(st->devnm)) + st->update_tail = &st->updates; + ++ info = st->ss->container_content(st, subarray); ++ ++ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { ++ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); ++ goto free_super; ++ } ++ + rv = st->ss->update_subarray(st, subarray, update, ident); + + if (rv) { +@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", + subarray, dev); + +- free_super: ++free_super: ++ if (info) ++ free(info); + st->ss->free_super(st); + close(fd); + +diff --git a/mdadm.h b/mdadm.h +index d53df169..974415b9 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -796,6 +796,17 @@ static inline int is_fd_valid(int fd) + return (fd > -1); + } + ++/** ++ * is_level456() - check whether given level is between inclusive 4 and 6. ++ * @level: level to check. ++ * ++ * Return: true if condition is met, false otherwise ++ */ ++static inline bool is_level456(int level) ++{ ++ return (level >= 4 && level <= 6); ++} ++ + /** + * close_fd() - verify, close and unset file descriptor. + * @fd: pointer to file descriptor. +diff --git a/super0.c b/super0.c +index 61c9ec1d..37f595ed 100644 +--- a/super0.c ++++ b/super0.c +@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + int parity = sb->level == 6 ? 2 : 1; + rv = 0; + +- if (sb->level >= 4 && sb->level <= 6 && ++ if (is_level456(sb->level) && + sb->reshape_position % ( + sb->new_chunk/512 * + (sb->raid_disks - sb->delta_disks - parity))) { +diff --git a/super1.c b/super1.c +index 3a0c69fd..71af860c 100644 +--- a/super1.c ++++ b/super1.c +@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + * So we reject a revert-reshape unless the + * alignment is good. + */ +- if (__le32_to_cpu(sb->level) >= 4 && +- __le32_to_cpu(sb->level) <= 6) { ++ if (is_level456(__le32_to_cpu(sb->level))) { + reshape_sectors = + __le64_to_cpu(sb->reshape_position); + reshape_chunk = __le32_to_cpu(sb->new_chunk); +-- +2.38.1 + diff --git a/0027-mdadm-Fix-array-size-mismatch-after-grow.patch b/0027-mdadm-Fix-array-size-mismatch-after-grow.patch new file mode 100644 index 0000000..02bdf9c --- /dev/null +++ b/0027-mdadm-Fix-array-size-mismatch-after-grow.patch @@ -0,0 +1,30 @@ +From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 22 Jul 2022 08:43:47 +0200 +Subject: [PATCH 27/83] mdadm: Fix array size mismatch after grow + +imsm_fix_size_mismatch() is invoked to fix the problem, but it couldn't +proceed due to migration check. This patch allows for intended behavior. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index 8ffe485c..76b947f5 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11854,7 +11854,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) + unsigned long long d_size = imsm_dev_size(dev); + int u_size; + +- if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR) ++ if (calc_size == d_size) + continue; + + /* There is a difference, confirm that imsm_dev_size is +-- +2.38.1 + diff --git a/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch b/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch new file mode 100644 index 0000000..08688dd --- /dev/null +++ b/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch @@ -0,0 +1,34 @@ +From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 22 Jul 2022 08:43:48 +0200 +Subject: [PATCH 28/83] mdadm: Remove dead code in imsm_fix_size_mismatch + +imsm_create_metadata_update_for_size_change() that returns u_size value +could return 0 in the past. As its behavior changed, and returned value +is always the size of imsm_update_size_change structure, check for +u_size is no longer needed. + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 76b947f5..4ddfcf94 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11869,10 +11869,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) + geo.size = d_size; + u_size = imsm_create_metadata_update_for_size_change(st, &geo, + &update); +- if (u_size < 1) { +- dprintf("imsm: Cannot prepare size change update\n"); +- goto exit; +- } + imsm_update_metadata_locally(st, update, u_size); + if (st->update_tail) { + append_metadata_update(st, update, u_size); +-- +2.38.1 + diff --git a/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch b/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch new file mode 100644 index 0000000..f337ff0 --- /dev/null +++ b/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch @@ -0,0 +1,40 @@ +From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 14 Jul 2022 09:02:10 +0200 +Subject: [PATCH 29/83] Monitor: use devname as char array instead of pointer + +Device name wasn't filled properly due to incorrect use of strcpy. +Strcpy was used twice. Firstly to fill devname with "/dev/md/" +and then to add chosen name. First strcpy result was overwritten by +second one (as a result instead of "/dev/md/" +was assigned). This commit changes this implementation to use snprintf +and devname with fixed size. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Monitor.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 6ca1ebe5..a5b11ae2 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -190,9 +190,11 @@ int Monitor(struct mddev_dev *devlist, + if (mdlist->devname[0] == '/') + st->devname = xstrdup(mdlist->devname); + else { +- st->devname = xmalloc(8+strlen(mdlist->devname)+1); +- strcpy(strcpy(st->devname, "/dev/md/"), +- mdlist->devname); ++ /* length of "/dev/md/" + device name + terminating byte */ ++ size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); ++ ++ st->devname = xcalloc(_len, sizeof(char)); ++ snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); + } + if (!is_mddev(mdlist->devname)) + return 1; +-- +2.38.1 + diff --git a/0030-Monitor-use-snprintf-to-fill-device-name.patch b/0030-Monitor-use-snprintf-to-fill-device-name.patch new file mode 100644 index 0000000..7d3b4bc --- /dev/null +++ b/0030-Monitor-use-snprintf-to-fill-device-name.patch @@ -0,0 +1,133 @@ +From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 14 Jul 2022 09:02:11 +0200 +Subject: [PATCH 30/83] Monitor: use snprintf to fill device name + +Safe string functions are propagated in Monitor.c. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Monitor.c | 37 ++++++++++++++----------------------- + 1 file changed, 14 insertions(+), 23 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index a5b11ae2..93f36ac0 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -33,8 +33,8 @@ + #endif + + struct state { +- char *devname; +- char devnm[32]; /* to sync with mdstat info */ ++ char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ ++ char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ + unsigned int utime; + int err; + char *spare_group; +@@ -45,9 +45,9 @@ struct state { + int devstate[MAX_DISKS]; + dev_t devid[MAX_DISKS]; + int percent; +- char parent_devnm[32]; /* For subarray, devnm of parent. +- * For others, "" +- */ ++ char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. ++ * For others, "" ++ */ + struct supertype *metadata; + struct state *subarray;/* for a container it is a link to first subarray + * for a subarray it is a link to next subarray +@@ -187,15 +187,8 @@ int Monitor(struct mddev_dev *devlist, + continue; + + st = xcalloc(1, sizeof *st); +- if (mdlist->devname[0] == '/') +- st->devname = xstrdup(mdlist->devname); +- else { +- /* length of "/dev/md/" + device name + terminating byte */ +- size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); +- +- st->devname = xcalloc(_len, sizeof(char)); +- snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); +- } ++ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), ++ "/dev/md/%s", basename(mdlist->devname)); + if (!is_mddev(mdlist->devname)) + return 1; + st->next = statelist; +@@ -218,7 +211,7 @@ int Monitor(struct mddev_dev *devlist, + + st = xcalloc(1, sizeof *st); + mdlist = conf_get_ident(dv->devname); +- st->devname = xstrdup(dv->devname); ++ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); + st->next = statelist; + st->devnm[0] = 0; + st->percent = RESYNC_UNKNOWN; +@@ -301,7 +294,6 @@ int Monitor(struct mddev_dev *devlist, + for (stp = &statelist; (st = *stp) != NULL; ) { + if (st->from_auto && st->err > 5) { + *stp = st->next; +- free(st->devname); + free(st->spare_group); + free(st); + } else +@@ -554,7 +546,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + goto disappeared; + + if (st->devnm[0] == 0) +- strcpy(st->devnm, fd2devnm(fd)); ++ snprintf(st->devnm, MD_NAME_MAX, "%s", fd2devnm(fd)); + + for (mse2 = mdstat; mse2; mse2 = mse2->next) + if (strcmp(mse2->devnm, st->devnm) == 0) { +@@ -684,7 +676,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + strncmp(mse->metadata_version, "external:", 9) == 0 && + is_subarray(mse->metadata_version+9)) { + char *sl; +- strcpy(st->parent_devnm, 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; +@@ -772,14 +764,13 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + continue; + } + +- st->devname = xstrdup(name); ++ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); + if ((fd = open(st->devname, O_RDONLY)) < 0 || + md_get_array_info(fd, &array) < 0) { + /* no such array */ + if (fd >= 0) + close(fd); + put_md_name(st->devname); +- free(st->devname); + if (st->metadata) { + st->metadata->ss->free_super(st->metadata); + free(st->metadata); +@@ -791,7 +782,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + st->next = *statelist; + st->err = 1; + st->from_auto = 1; +- strcpy(st->devnm, mse->devnm); ++ snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm); + st->percent = RESYNC_UNKNOWN; + st->expected_spares = -1; + if (mse->metadata_version && +@@ -799,8 +790,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + "external:", 9) == 0 && + is_subarray(mse->metadata_version+9)) { + char *sl; +- strcpy(st->parent_devnm, +- mse->metadata_version+10); ++ snprintf(st->parent_devnm, MD_NAME_MAX, ++ "%s", mse->metadata_version + 10); + sl = strchr(st->parent_devnm, '/'); + *sl = 0; + } else +-- +2.38.1 + diff --git a/0031-Makefile-Don-t-build-static-build-with-everything-an.patch b/0031-Makefile-Don-t-build-static-build-with-everything-an.patch new file mode 100644 index 0000000..de5e49e --- /dev/null +++ b/0031-Makefile-Don-t-build-static-build-with-everything-an.patch @@ -0,0 +1,42 @@ +From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:06 -0600 +Subject: [PATCH 31/83] Makefile: Don't build static build with everything and + everything-test + +Running the test suite requires building everything, but it seems to be +difficult to build the static version of mdadm now seeing there +is no readily available static udev library. + +The test suite doesn't need the static binary so just don't build it +with the everything or everything-test targets. + +Leave the mdadm.static and install-static targets in place in case +someone still has a use case for the static binary. + +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index bf126033..ec1f99ed 100644 +--- a/Makefile ++++ b/Makefile +@@ -182,9 +182,9 @@ check_rundir: + echo "***** or set CHECK_RUN_DIR=0"; exit 1; \ + fi + +-everything: all mdadm.static swap_super test_stripe raid6check \ ++everything: all swap_super test_stripe raid6check \ + mdadm.Os mdadm.O2 man +-everything-test: all mdadm.static swap_super test_stripe \ ++everything-test: all swap_super test_stripe \ + mdadm.Os mdadm.O2 man + # mdadm.uclibc doesn't work on x86-64 + # mdadm.tcc doesn't work.. +-- +2.38.1 + diff --git a/0032-DDF-Cleanup-validate_geometry_ddf_container.patch b/0032-DDF-Cleanup-validate_geometry_ddf_container.patch new file mode 100644 index 0000000..ec2954d --- /dev/null +++ b/0032-DDF-Cleanup-validate_geometry_ddf_container.patch @@ -0,0 +1,141 @@ +From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:07 -0600 +Subject: [PATCH 32/83] DDF: Cleanup validate_geometry_ddf_container() + +Move the function up so that the function declaration is not necessary +and remove the unused arguments to the function. + +No functional changes are intended but will help with a bug fix in the +next patch. + +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 88 ++++++++++++++++++++++++----------------------------- + 1 file changed, 39 insertions(+), 49 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index abbc8b09..9d867f69 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -503,13 +503,6 @@ struct ddf_super { + static int load_super_ddf_all(struct supertype *st, int fd, + void **sbp, char *devname); + static int get_svd_state(const struct ddf_super *, const struct vcl *); +-static int +-validate_geometry_ddf_container(struct supertype *st, +- int level, int layout, int raiddisks, +- int chunk, unsigned long long size, +- unsigned long long data_offset, +- char *dev, unsigned long long *freesize, +- int verbose); + + static int validate_geometry_ddf_bvd(struct supertype *st, + int level, int layout, int raiddisks, +@@ -3322,6 +3315,42 @@ static int reserve_space(struct supertype *st, int raiddisks, + return 1; + } + ++static int ++validate_geometry_ddf_container(struct supertype *st, ++ int level, int raiddisks, ++ unsigned long long data_offset, ++ char *dev, unsigned long long *freesize, ++ int verbose) ++{ ++ int fd; ++ unsigned long long ldsize; ++ ++ if (level != LEVEL_CONTAINER) ++ return 0; ++ if (!dev) ++ return 1; ++ ++ fd = dev_open(dev, O_RDONLY|O_EXCL); ++ if (fd < 0) { ++ if (verbose) ++ pr_err("ddf: Cannot open %s: %s\n", ++ dev, strerror(errno)); ++ return 0; ++ } ++ if (!get_dev_size(fd, dev, &ldsize)) { ++ close(fd); ++ return 0; ++ } ++ close(fd); ++ if (freesize) { ++ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); ++ if (*freesize == 0) ++ return 0; ++ } ++ ++ return 1; ++} ++ + static int validate_geometry_ddf(struct supertype *st, + int level, int layout, int raiddisks, + int *chunk, unsigned long long size, +@@ -3347,11 +3376,9 @@ static int validate_geometry_ddf(struct supertype *st, + level = LEVEL_CONTAINER; + if (level == LEVEL_CONTAINER) { + /* Must be a fresh device to add to a container */ +- return validate_geometry_ddf_container(st, level, layout, +- raiddisks, *chunk, +- size, data_offset, dev, +- freesize, +- verbose); ++ return validate_geometry_ddf_container(st, level, raiddisks, ++ data_offset, dev, ++ freesize, verbose); + } + + if (!dev) { +@@ -3449,43 +3476,6 @@ static int validate_geometry_ddf(struct supertype *st, + return 1; + } + +-static int +-validate_geometry_ddf_container(struct supertype *st, +- int level, int layout, int raiddisks, +- int chunk, unsigned long long size, +- unsigned long long data_offset, +- char *dev, unsigned long long *freesize, +- int verbose) +-{ +- int fd; +- unsigned long long ldsize; +- +- if (level != LEVEL_CONTAINER) +- return 0; +- if (!dev) +- return 1; +- +- fd = dev_open(dev, O_RDONLY|O_EXCL); +- if (fd < 0) { +- if (verbose) +- pr_err("ddf: Cannot open %s: %s\n", +- dev, strerror(errno)); +- return 0; +- } +- if (!get_dev_size(fd, dev, &ldsize)) { +- close(fd); +- return 0; +- } +- close(fd); +- if (freesize) { +- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); +- if (*freesize == 0) +- return 0; +- } +- +- return 1; +-} +- + static int validate_geometry_ddf_bvd(struct supertype *st, + int level, int layout, int raiddisks, + int *chunk, unsigned long long size, +-- +2.38.1 + diff --git a/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch b/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch new file mode 100644 index 0000000..3a53577 --- /dev/null +++ b/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch @@ -0,0 +1,49 @@ +From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:08 -0600 +Subject: [PATCH 33/83] DDF: Fix NULL pointer dereference in + validate_geometry_ddf() + +A relatively recent patch added a call to validate_geometry() in +Manage_add() that has level=LEVEL_CONTAINER and chunk=NULL. + +This causes some ddf tests to segfault which aborts the test suite. + +To fix this, avoid dereferencing chunk when the level is +LEVEL_CONTAINER or LEVEL_NONE. + +Fixes: 1f5d54a06df0 ("Manage: Call validate_geometry when adding drive to external container") +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 9d867f69..949e7d15 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3369,9 +3369,6 @@ static int validate_geometry_ddf(struct supertype *st, + * If given BVDs, we make an SVD, changing all the GUIDs in the process. + */ + +- if (*chunk == UnSet) +- *chunk = DEFAULT_CHUNK; +- + if (level == LEVEL_NONE) + level = LEVEL_CONTAINER; + if (level == LEVEL_CONTAINER) { +@@ -3381,6 +3378,9 @@ static int validate_geometry_ddf(struct supertype *st, + freesize, verbose); + } + ++ if (*chunk == UnSet) ++ *chunk = DEFAULT_CHUNK; ++ + if (!dev) { + mdu_array_info_t array = { + .level = level, +-- +2.38.1 + diff --git a/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch b/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch new file mode 100644 index 0000000..2695f67 --- /dev/null +++ b/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch @@ -0,0 +1,85 @@ +From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:09 -0600 +Subject: [PATCH 34/83] mdadm/Grow: Fix use after close bug by closing after + fork + +The test 07reshape-grow fails most of the time. But it succeeds around +1 in 5 times. When it does succeed, it causes the tests to die because +mdadm has segfaulted. + +The segfault was caused by mdadm attempting to repoen a file +descriptor that was already closed. The backtrace of the segfault +was: + + #0 __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:101 + #1 0x000056146e31d44b in devnm2devid (devnm=0x0) at util.c:956 + #2 0x000056146e31dab4 in open_dev_flags (devnm=0x0, flags=0) + at util.c:1072 + #3 0x000056146e31db22 in open_dev (devnm=0x0) at util.c:1079 + #4 0x000056146e3202e8 in reopen_mddev (mdfd=4) at util.c:2244 + #5 0x000056146e329f36 in start_array (mdfd=4, + mddev=0x7ffc55342450 "/dev/md0", content=0x7ffc55342860, + st=0x56146fc78660, ident=0x7ffc55342f70, best=0x56146fc6f5d0, + bestcnt=10, chosen_drive=0, devices=0x56146fc706b0, okcnt=5, + sparecnt=0, rebuilding_cnt=0, journalcnt=0, c=0x7ffc55342e90, + clean=1, avail=0x56146fc78720 "\001\001\001\001\001", + start_partial_ok=0, err_ok=0, was_forced=0) + at Assemble.c:1206 + #6 0x000056146e32c36e in Assemble (st=0x56146fc78660, + mddev=0x7ffc55342450 "/dev/md0", ident=0x7ffc55342f70, + devlist=0x56146fc6e2d0, c=0x7ffc55342e90) + at Assemble.c:1914 + #7 0x000056146e312ac9 in main (argc=11, argv=0x7ffc55343238) + at mdadm.c:1510 + +The file descriptor was closed early in Grow_continue(). The noted commit +moved the close() call to close the fd above the fork which caused the +parent process to return with a closed fd. + +This meant reshape_array() and Grow_continue() would return in the parent +with the fd forked. The fd would eventually be passed to reopen_mddev() +which returned an unhandled NULL from fd2devnm() which would then be +dereferenced in devnm2devid. + +Fix this by moving the close() call below the fork. This appears to +fix the 07revert-grow test. While we're at it, switch to using +close_fd() to invalidate the file descriptor. + +Fixes: 77b72fa82813 ("mdadm/Grow: prevent md's fd from being occupied during delayed time") +Cc: Alex Wu +Cc: BingJing Chang +Cc: Danny Shih +Cc: ChangSyun Peng +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Grow.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 8c520d42..97f22c75 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3514,7 +3514,6 @@ started: + return 0; + } + +- close(fd); + /* Now we just need to kick off the reshape and watch, while + * handling backups of the data... + * This is all done by a forked background process. +@@ -3535,6 +3534,9 @@ started: + break; + } + ++ /* Close unused file descriptor in the forked process */ ++ close_fd(&fd); ++ + /* If another array on the same devices is busy, the + * reshape will wait for them. This would mean that + * the first section that we suspend will stay suspended +-- +2.38.1 + diff --git a/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch b/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch new file mode 100644 index 0000000..ed09288 --- /dev/null +++ b/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch @@ -0,0 +1,36 @@ +From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:10 -0600 +Subject: [PATCH 35/83] monitor: Avoid segfault when calling NULL + get_bad_blocks + +Not all struct superswitch implement a get_bad_blocks() function, +yet mdmon seems to call it without checking for NULL and thus +occasionally segfaults in the test 10ddf-geometry. + +Fix this by checking for NULL before calling it. + +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + monitor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/monitor.c b/monitor.c +index b877e595..820a93d0 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -311,6 +311,9 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi) + struct md_bb *bb; + int i; + ++ if (!ss->get_bad_blocks) ++ return -1; ++ + /* + * Get a list of bad blocks for an array, then read list of + * acknowledged bad blocks from kernel and compare it against metadata +-- +2.38.1 + diff --git a/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch b/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch new file mode 100644 index 0000000..f091c64 --- /dev/null +++ b/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch @@ -0,0 +1,78 @@ +From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:11 -0600 +Subject: [PATCH 36/83] mdadm: Fix mdadm -r remove option regression + +The commit noted below globally adds a parameter to the -r option but missed +the fact that -r is used for another purpose: --remove. + +After that commit, a command such as: + + mdadm /dev/md0 -r /dev/loop0 + +will do nothing seeing the device parameter will be consumed as a +argument to the -r option; thus, there will only be one device +seen one the command line, devs_found will only be 1 and nothing will +happen. + +This caused the 01r5integ and 01raid6integ tests to hang indefinitely +as mdadm did not remove the failed device. With the device not removed, +it would not be readded. Then the loop waiting for the array status to +change would loop forever. + +This commit was recently reverted, but the legitimate fix for the +monitor operations was still not fixed. So add specific monitor +short ops to re-fix the --monitor -r option. + +Fixes: 546047688e1c ("mdadm: fix coredump of mdadm --monitor -r") +Fixes: 190dc029b141 ("Revert "mdadm: fix coredump of mdadm --monitor -r"") +Cc: Wu Guanghao +Cc: Mariusz Tkaczyk +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 1 + + mdadm.c | 1 + + mdadm.h | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/ReadMe.c b/ReadMe.c +index bec1be9a..7518a32a 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -82,6 +82,7 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; + */ + + char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; ++char short_monitor_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k:"; + char short_bitmap_options[]= + "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; + char short_bitmap_auto_options[]= +diff --git a/mdadm.c b/mdadm.c +index be40686c..d0c5e6de 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -227,6 +227,7 @@ int main(int argc, char *argv[]) + shortopt = short_bitmap_auto_options; + break; + case 'F': newmode = MONITOR; ++ shortopt = short_monitor_options; + break; + case 'G': newmode = GROW; + shortopt = short_bitmap_options; +diff --git a/mdadm.h b/mdadm.h +index 974415b9..163f4a49 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -419,6 +419,7 @@ enum mode { + }; + + extern char short_options[]; ++extern char short_monitor_options[]; + extern char short_bitmap_options[]; + extern char short_bitmap_auto_options[]; + extern struct option long_options[]; +-- +2.38.1 + diff --git a/0037-mdadm-Fix-optional-write-behind-parameter.patch b/0037-mdadm-Fix-optional-write-behind-parameter.patch new file mode 100644 index 0000000..60cafdb --- /dev/null +++ b/0037-mdadm-Fix-optional-write-behind-parameter.patch @@ -0,0 +1,42 @@ +From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:12 -0600 +Subject: [PATCH 37/83] mdadm: Fix optional --write-behind parameter + +The commit noted below changed the behaviour of --write-behind to +require an argument. This broke the 06wrmostly test with the error: + + mdadm: Invalid value for maximum outstanding write-behind writes: (null). + Must be between 0 and 16383. + +To fix this, check if optarg is NULL before parising it, as the origial +code did. + +Fixes: 60815698c0ac ("Refactor parse_num and use it to parse optarg.") +Cc: Mateusz Grzonka +Signed-off-by: Logan Gunthorpe +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + mdadm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index d0c5e6de..56722ed9 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1201,8 +1201,9 @@ int main(int argc, char *argv[]) + case O(BUILD, WriteBehind): + case O(CREATE, WriteBehind): + s.write_behind = DEFAULT_MAX_WRITE_BEHIND; +- if (parse_num(&s.write_behind, optarg) != 0 || +- s.write_behind < 0 || s.write_behind > 16383) { ++ if (optarg && ++ (parse_num(&s.write_behind, optarg) != 0 || ++ s.write_behind < 0 || s.write_behind > 16383)) { + pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", + optarg); + exit(2); +-- +2.38.1 + diff --git a/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch b/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch new file mode 100644 index 0000000..7794e18 --- /dev/null +++ b/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch @@ -0,0 +1,38 @@ +From 7539254342bc591717b0051734cc6c09c1b88640 Mon Sep 17 00:00:00 2001 +From: Sudhakar Panneerselvam +Date: Wed, 22 Jun 2022 14:25:13 -0600 +Subject: [PATCH 38/83] tests/00raid0: add a test that validates raid0 with + layout fails for 0.9 + +329dfc28debb disallows the creation of raid0 with layouts for 0.9 +metadata. This test confirms the new behavior. + +Signed-off-by: Sudhakar Panneerselvam +Signed-off-by: Himanshu Madhani +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/00raid0 | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/tests/00raid0 b/tests/00raid0 +index 8bc18985..e6b21cc4 100644 +--- a/tests/00raid0 ++++ b/tests/00raid0 +@@ -6,11 +6,9 @@ check raid0 + testdev $md0 3 $mdsize2_l 512 + mdadm -S $md0 + +-# now with version-0.90 superblock ++# verify raid0 with layouts fail for 0.90 + mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 +-check raid0 +-testdev $md0 4 $mdsize0 512 +-mdadm -S $md0 ++check opposite_result + + # now with no superblock + mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 +-- +2.38.1 + diff --git a/0039-tests-fix-raid0-tests-for-0.90-metadata.patch b/0039-tests-fix-raid0-tests-for-0.90-metadata.patch new file mode 100644 index 0000000..d897fb1 --- /dev/null +++ b/0039-tests-fix-raid0-tests-for-0.90-metadata.patch @@ -0,0 +1,99 @@ +From 14c2161edb77d7294199e8aa7daa9f9d1d0ad5d7 Mon Sep 17 00:00:00 2001 +From: Sudhakar Panneerselvam +Date: Wed, 22 Jun 2022 14:25:14 -0600 +Subject: [PATCH 39/83] tests: fix raid0 tests for 0.90 metadata + +Some of the test cases fail because raid0 creation fails with the error, +"0.90 metadata does not support layouts for RAID0" added by commit, +329dfc28debb. Fix some of the test cases by switching from raid0 to +linear level for 0.9 metadata where possible. + +Signed-off-by: Sudhakar Panneerselvam +Signed-off-by: Himanshu Madhani +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/00raid0 | 4 ++-- + tests/00readonly | 4 ++++ + tests/03r0assem | 6 +++--- + tests/04r0update | 4 ++-- + tests/04update-metadata | 2 +- + 5 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/tests/00raid0 b/tests/00raid0 +index e6b21cc4..9b8896cb 100644 +--- a/tests/00raid0 ++++ b/tests/00raid0 +@@ -20,8 +20,8 @@ mdadm -S $md0 + # now same again with different chunk size + for chunk in 4 32 256 + do +- mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 +- check raid0 ++ mdadm -CR $md0 -e0.90 -l linear --chunk $chunk -n3 $dev0 $dev1 $dev2 ++ check linear + testdev $md0 3 $mdsize0 $chunk + mdadm -S $md0 + +diff --git a/tests/00readonly b/tests/00readonly +index 28b0fa13..39202487 100644 +--- a/tests/00readonly ++++ b/tests/00readonly +@@ -4,6 +4,10 @@ for metadata in 0.9 1.0 1.1 1.2 + do + for level in linear raid0 raid1 raid4 raid5 raid6 raid10 + do ++ if [[ $metadata == "0.9" && $level == "raid0" ]]; ++ then ++ continue ++ fi + mdadm -CR $md0 -l $level -n 4 --metadata=$metadata \ + $dev1 $dev2 $dev3 $dev4 --assume-clean + check nosync +diff --git a/tests/03r0assem b/tests/03r0assem +index 6744e322..44df0645 100644 +--- a/tests/03r0assem ++++ b/tests/03r0assem +@@ -68,9 +68,9 @@ mdadm -S $md2 + ### Now for version 0... + + mdadm --zero-superblock $dev0 $dev1 $dev2 +-mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 +-check raid0 +-tst="testdev $md2 3 $mdsize0 512" ++mdadm -CR $md2 -llinear --metadata=0.90 -n3 $dev0 $dev1 $dev2 ++check linear ++tst="testdev $md2 3 $mdsize0 1" + $tst + + uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` +diff --git a/tests/04r0update b/tests/04r0update +index 73ee3b9f..b95efb06 100644 +--- a/tests/04r0update ++++ b/tests/04r0update +@@ -1,7 +1,7 @@ + + # create a raid0, re-assemble with a different super-minor +-mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 +-testdev $md0 3 $mdsize0 512 ++mdadm -CR -e 0.90 $md0 -llinear -n3 $dev0 $dev1 $dev2 ++testdev $md0 3 $mdsize0 1 + minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` + mdadm -S /dev/md0 + +diff --git a/tests/04update-metadata b/tests/04update-metadata +index 232fc1ff..08c14af7 100644 +--- a/tests/04update-metadata ++++ b/tests/04update-metadata +@@ -8,7 +8,7 @@ set -xe + + dlist="$dev0 $dev1 $dev2 $dev3" + +-for ls in raid0/4 linear/4 raid1/1 raid5/3 raid6/2 ++for ls in linear/4 raid1/1 raid5/3 raid6/2 + do + s=${ls#*/} l=${ls%/*} + mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist +-- +2.38.1 + diff --git a/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch b/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch new file mode 100644 index 0000000..12b291b --- /dev/null +++ b/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch @@ -0,0 +1,39 @@ +From de045db607b1ac4b70fc2a8878463e029c2ab1dc Mon Sep 17 00:00:00 2001 +From: Sudhakar Panneerselvam +Date: Wed, 22 Jun 2022 14:25:15 -0600 +Subject: [PATCH 40/83] tests/04update-metadata: avoid passing chunk size to + raid1 + +'04update-metadata' test fails with error, "specifying chunk size is +forbidden for this level" added by commit, 5b30a34aa4b5e. Hence, +correcting the test to ignore passing chunk size to raid1. + +Signed-off-by: Sudhakar Panneerselvam +Signed-off-by: Himanshu Madhani +[logang@deltatee.com: fix if/then style and dropped unrelated hunk] +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/04update-metadata | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/tests/04update-metadata b/tests/04update-metadata +index 08c14af7..2b72a303 100644 +--- a/tests/04update-metadata ++++ b/tests/04update-metadata +@@ -11,7 +11,11 @@ dlist="$dev0 $dev1 $dev2 $dev3" + for ls in linear/4 raid1/1 raid5/3 raid6/2 + do + s=${ls#*/} l=${ls%/*} +- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist ++ 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 +-- +2.38.1 + diff --git a/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch b/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch new file mode 100644 index 0000000..e6b9bba --- /dev/null +++ b/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch @@ -0,0 +1,31 @@ +From a2c832465fc75202e244327b2081231dfa974617 Mon Sep 17 00:00:00 2001 +From: Sudhakar Panneerselvam +Date: Wed, 22 Jun 2022 14:25:16 -0600 +Subject: [PATCH 41/83] tests/02lineargrow: clear the superblock at every + iteration + +This fixes 02lineargrow test as prior metadata causes --add operation +to misbehave. + +Signed-off-by: Sudhakar Panneerselvam +Signed-off-by: Himanshu Madhani +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/02lineargrow | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/02lineargrow b/tests/02lineargrow +index e05c219d..595bf9f2 100644 +--- a/tests/02lineargrow ++++ b/tests/02lineargrow +@@ -20,4 +20,6 @@ do + testdev $md0 3 $sz 1 + + mdadm -S $md0 ++ mdadm --zero /dev/loop2 ++ mdadm --zero /dev/loop3 + done +-- +2.38.1 + diff --git a/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch b/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch new file mode 100644 index 0000000..63f72dc --- /dev/null +++ b/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch @@ -0,0 +1,88 @@ +From a7bfcc716e235664dfb3b6c5a9590273e611ac72 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:17 -0600 +Subject: [PATCH 42/83] mdadm/test: Add a mode to repeat specified tests + +Many tests fail infrequently or rarely. To help find these, add +an option to run the tests multiple times by specifying --loop=N. + +If --loop=0 is specified, the test will be looped forever. + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + test | 36 ++++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 12 deletions(-) + +diff --git a/test b/test +index 711a3c7a..da6db5e0 100755 +--- a/test ++++ b/test +@@ -10,6 +10,7 @@ devlist= + + savelogs=0 + exitonerror=1 ++loop=1 + prefix='[0-9][0-9]' + + # use loop devices by default if doesn't specify --dev +@@ -117,6 +118,7 @@ do_help() { + --logdir=directory Directory to save all logfiles in + --save-logs Usually use with --logdir together + --keep-going | --no-error Don't stop on error, ie. run all tests ++ --loop=N Run tests N times (0 to run forever) + --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk + --disks= Provide a bunch of physical devices for test + --volgroup=name LVM volume group for LVM test +@@ -211,6 +213,9 @@ parse_args() { + --keep-going | --no-error ) + exitonerror=0 + ;; ++ --loop=* ) ++ loop="${i##*=}" ++ ;; + --disable-multipath ) + unset MULTIPATH + ;; +@@ -263,19 +268,26 @@ main() { + echo "Testing on linux-$(uname -r) kernel" + [ "$savelogs" == "1" ] && + echo "Saving logs to $logdir" +- if [ "x$TESTLIST" != "x" ] +- then +- for script in ${TESTLIST[@]} +- do +- do_test $testdir/$script +- done +- else +- for script in $testdir/$prefix $testdir/$prefix*[^~] +- do +- do_test $script +- done +- fi + ++ while true; do ++ if [ "x$TESTLIST" != "x" ] ++ then ++ for script in ${TESTLIST[@]} ++ do ++ do_test $testdir/$script ++ done ++ else ++ for script in $testdir/$prefix $testdir/$prefix*[^~] ++ do ++ do_test $script ++ done ++ fi ++ ++ let loop=$loop-1 ++ if [ "$loop" == "0" ]; then ++ break ++ fi ++ done + exit 0 + } + +-- +2.38.1 + diff --git a/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch b/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch new file mode 100644 index 0000000..52fd3e9 --- /dev/null +++ b/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch @@ -0,0 +1,120 @@ +From 28520bf114b3b0515a48ff44fff4ecbe9ed6dfad Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:18 -0600 +Subject: [PATCH 43/83] mdadm/test: Mark and ignore broken test failures + +Add functionality to continue if a test marked as broken fails. + +To mark a test as broken, a file with the same name but with the suffix +'.broken' should exist. The first line in the file will be printed with +a KNOWN BROKEN message; the rest of the file can describe the how the +test is broken. + +Also adds --skip-broken and --skip-always-broken to skip all the tests +that have a .broken file or to skip all tests whose .broken file's first +line contains the keyword always. + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + test | 37 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +diff --git a/test b/test +index da6db5e0..61d9ee83 100755 +--- a/test ++++ b/test +@@ -10,6 +10,8 @@ devlist= + + savelogs=0 + exitonerror=1 ++ctrl_c_error=0 ++skipbroken=0 + loop=1 + prefix='[0-9][0-9]' + +@@ -36,6 +38,7 @@ die() { + + ctrl_c() { + exitonerror=1 ++ ctrl_c_error=1 + } + + # mdadm always adds --quiet, and we want to see any unexpected messages +@@ -80,8 +83,21 @@ mdadm() { + do_test() { + _script=$1 + _basename=`basename $_script` ++ _broken=0 ++ + if [ -f "$_script" ] + then ++ if [ -f "${_script}.broken" ]; then ++ _broken=1 ++ _broken_msg=$(head -n1 "${_script}.broken" | tr -d '\n') ++ if [ "$skipbroken" == "all" ]; then ++ return ++ elif [ "$skipbroken" == "always" ] && ++ [[ "$_broken_msg" == *always* ]]; then ++ return ++ fi ++ fi ++ + rm -f $targetdir/stderr + # this might have been reset: restore the default. + echo 2000 > /proc/sys/dev/raid/speed_limit_max +@@ -98,10 +114,15 @@ do_test() { + else + save_log fail + _fail=1 ++ if [ "$_broken" == "1" ]; then ++ echo " (KNOWN BROKEN TEST: $_broken_msg)" ++ fi + fi + [ "$savelogs" == "1" ] && + mv -f $targetdir/log $logdir/$_basename.log +- [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1 ++ [ "$ctrl_c_error" == "1" ] && exit 1 ++ [ "$_fail" == "1" -a "$exitonerror" == "1" \ ++ -a "$_broken" == "0" ] && exit 1 + fi + } + +@@ -119,6 +140,8 @@ do_help() { + --save-logs Usually use with --logdir together + --keep-going | --no-error Don't stop on error, ie. run all tests + --loop=N Run tests N times (0 to run forever) ++ --skip-broken Skip tests that are known to be broken ++ --skip-always-broken Skip tests that are known to always fail + --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk + --disks= Provide a bunch of physical devices for test + --volgroup=name LVM volume group for LVM test +@@ -216,6 +239,12 @@ parse_args() { + --loop=* ) + loop="${i##*=}" + ;; ++ --skip-broken ) ++ skipbroken=all ++ ;; ++ --skip-always-broken ) ++ skipbroken=always ++ ;; + --disable-multipath ) + unset MULTIPATH + ;; +@@ -279,7 +308,11 @@ main() { + else + for script in $testdir/$prefix $testdir/$prefix*[^~] + do +- do_test $script ++ case $script in ++ *.broken) ;; ++ *) ++ do_test $script ++ esac + done + fi + +-- +2.38.1 + diff --git a/0044-tests-Add-broken-files-for-all-broken-tests.patch b/0044-tests-Add-broken-files-for-all-broken-tests.patch new file mode 100644 index 0000000..2484e1b --- /dev/null +++ b/0044-tests-Add-broken-files-for-all-broken-tests.patch @@ -0,0 +1,447 @@ +From daa86d6634761796ada1f535c13e47fdd3cc95eb Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:19 -0600 +Subject: [PATCH 44/83] tests: Add broken files for all broken tests + +Each broken file contains the rough frequency of brokeness as well +as a brief explanation of what happens when it breaks. Estimates +of failure rates are not statistically significant and can vary +run to run. + +This is really just a view from my window. Tests were done on a +small VM with the default loop devices, not real hardware. We've +seen different kernel configurations can cause bugs to appear as well +(ie. different block schedulers). It may also be that different race +conditions will be seen on machines with different performance +characteristics. + +These annotations were done with the kernel currently in md/md-next: + + facef3b96c5b ("md: Notify sysfs sync_completed in md_reap_sync_thread()") + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/01r5integ.broken | 7 ++++ + tests/01raid6integ.broken | 7 ++++ + tests/04r5swap.broken | 7 ++++ + tests/07autoassemble.broken | 8 ++++ + tests/07autodetect.broken | 5 +++ + tests/07changelevelintr.broken | 9 +++++ + tests/07changelevels.broken | 9 +++++ + tests/07reshape5intr.broken | 45 ++++++++++++++++++++++ + tests/07revert-grow.broken | 31 +++++++++++++++ + tests/07revert-shrink.broken | 9 +++++ + tests/07testreshape5.broken | 12 ++++++ + tests/09imsm-assemble.broken | 6 +++ + tests/09imsm-create-fail-rebuild.broken | 5 +++ + tests/09imsm-overlap.broken | 7 ++++ + tests/10ddf-assemble-missing.broken | 6 +++ + tests/10ddf-fail-create-race.broken | 7 ++++ + tests/10ddf-fail-two-spares.broken | 5 +++ + tests/10ddf-incremental-wrong-order.broken | 9 +++++ + tests/14imsm-r1_2d-grow-r1_3d.broken | 5 +++ + tests/14imsm-r1_2d-takeover-r0_2d.broken | 6 +++ + tests/18imsm-r10_4d-takeover-r0_2d.broken | 5 +++ + tests/18imsm-r1_2d-takeover-r0_1d.broken | 6 +++ + tests/19raid6auto-repair.broken | 5 +++ + tests/19raid6repair.broken | 5 +++ + 24 files changed, 226 insertions(+) + create mode 100644 tests/01r5integ.broken + create mode 100644 tests/01raid6integ.broken + create mode 100644 tests/04r5swap.broken + create mode 100644 tests/07autoassemble.broken + create mode 100644 tests/07autodetect.broken + create mode 100644 tests/07changelevelintr.broken + create mode 100644 tests/07changelevels.broken + create mode 100644 tests/07reshape5intr.broken + create mode 100644 tests/07revert-grow.broken + create mode 100644 tests/07revert-shrink.broken + create mode 100644 tests/07testreshape5.broken + create mode 100644 tests/09imsm-assemble.broken + create mode 100644 tests/09imsm-create-fail-rebuild.broken + create mode 100644 tests/09imsm-overlap.broken + create mode 100644 tests/10ddf-assemble-missing.broken + create mode 100644 tests/10ddf-fail-create-race.broken + create mode 100644 tests/10ddf-fail-two-spares.broken + create mode 100644 tests/10ddf-incremental-wrong-order.broken + create mode 100644 tests/14imsm-r1_2d-grow-r1_3d.broken + create mode 100644 tests/14imsm-r1_2d-takeover-r0_2d.broken + create mode 100644 tests/18imsm-r10_4d-takeover-r0_2d.broken + create mode 100644 tests/18imsm-r1_2d-takeover-r0_1d.broken + create mode 100644 tests/19raid6auto-repair.broken + create mode 100644 tests/19raid6repair.broken + +diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken +new file mode 100644 +index 00000000..20737637 +--- /dev/null ++++ b/tests/01r5integ.broken +@@ -0,0 +1,7 @@ ++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 +diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken +new file mode 100644 +index 00000000..1df735f0 +--- /dev/null ++++ b/tests/01raid6integ.broken +@@ -0,0 +1,7 @@ ++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 +diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken +new file mode 100644 +index 00000000..e38987db +--- /dev/null ++++ b/tests/04r5swap.broken +@@ -0,0 +1,7 @@ ++always fails ++ ++Fails with errors: ++ ++ mdadm: /dev/loop0 has no superblock - assembly aborted ++ ++ ERROR: no recovery happening +diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken +new file mode 100644 +index 00000000..8be09407 +--- /dev/null ++++ b/tests/07autoassemble.broken +@@ -0,0 +1,8 @@ ++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 +diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken +new file mode 100644 +index 00000000..294954a1 +--- /dev/null ++++ b/tests/07autodetect.broken +@@ -0,0 +1,5 @@ ++always fails ++ ++Fails with error: ++ ++ ERROR: no resync happening +diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken +new file mode 100644 +index 00000000..284b4906 +--- /dev/null ++++ b/tests/07changelevelintr.broken +@@ -0,0 +1,9 @@ ++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 +diff --git a/tests/07changelevels.broken b/tests/07changelevels.broken +new file mode 100644 +index 00000000..9b930d93 +--- /dev/null ++++ b/tests/07changelevels.broken +@@ -0,0 +1,9 @@ ++always fails ++ ++Fails with errors: ++ ++ mdadm: /dev/loop0 is smaller than given size. 18976K < 19968K + metadata ++ mdadm: /dev/loop1 is smaller than given size. 18976K < 19968K + metadata ++ mdadm: /dev/loop2 is smaller than given size. 18976K < 19968K + metadata ++ ++ ERROR: /dev/md0 isn't a block device. +diff --git a/tests/07reshape5intr.broken b/tests/07reshape5intr.broken +new file mode 100644 +index 00000000..efe52a66 +--- /dev/null ++++ b/tests/07reshape5intr.broken +@@ -0,0 +1,45 @@ ++always fails ++ ++This patch, recently added to md-next causes the test to always fail: ++ ++7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex ++held") ++ ++The new error is simply: ++ ++ ERROR: no reshape happening ++ ++Before the patch, the error seen is below. ++ ++-- ++ ++fails infrequently ++ ++Fails roughly 1 in 4 runs with errors: ++ ++ mdadm: Merging with already-assembled /dev/md/0 ++ mdadm: cannot re-read metadata from /dev/loop6 - aborting ++ ++ ERROR: no reshape happening ++ ++Also have seen a random deadlock: ++ ++ INFO: task mdadm:109702 blocked for more than 30 seconds. ++ Not tainted 5.18.0-rc3-eid-vmlocalyes-dbg-00095-g3c2b5427979d #2040 ++ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. ++ task:mdadm state:D stack: 0 pid:109702 ppid: 1 flags:0x00004000 ++ Call Trace: ++ ++ __schedule+0x67e/0x13b0 ++ schedule+0x82/0x110 ++ mddev_suspend+0x2e1/0x330 ++ suspend_lo_store+0xbd/0x140 ++ md_attr_store+0xcb/0x130 ++ sysfs_kf_write+0x89/0xb0 ++ kernfs_fop_write_iter+0x202/0x2c0 ++ new_sync_write+0x222/0x330 ++ vfs_write+0x3bc/0x4d0 ++ ksys_write+0xd9/0x180 ++ __x64_sys_write+0x43/0x50 ++ do_syscall_64+0x3b/0x90 ++ entry_SYSCALL_64_after_hwframe+0x44/0xae +diff --git a/tests/07revert-grow.broken b/tests/07revert-grow.broken +new file mode 100644 +index 00000000..9b6db86f +--- /dev/null ++++ b/tests/07revert-grow.broken +@@ -0,0 +1,31 @@ ++always fails ++ ++This patch, recently added to md-next causes the test to always fail: ++ ++7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex held") ++ ++The errors are: ++ ++ mdadm: No active reshape to revert on /dev/loop0 ++ ERROR: active raid5 not found ++ ++Before the patch, the error seen is below. ++ ++-- ++ ++fails rarely ++ ++Fails about 1 in every 30 runs with errors: ++ ++ mdadm: Merging with already-assembled /dev/md/0 ++ mdadm: backup file /tmp/md-backup inaccessible: No such file or directory ++ mdadm: failed to add /dev/loop1 to /dev/md/0: Invalid argument ++ mdadm: failed to add /dev/loop2 to /dev/md/0: Invalid argument ++ mdadm: failed to add /dev/loop3 to /dev/md/0: Invalid argument ++ mdadm: failed to add /dev/loop0 to /dev/md/0: Invalid argument ++ mdadm: /dev/md/0 assembled from 1 drive - need all 5 to start it ++ (use --run to insist). ++ ++ grep: /sys/block/md*/md/sync_action: No such file or directory ++ ++ ERROR: active raid5 not found +diff --git a/tests/07revert-shrink.broken b/tests/07revert-shrink.broken +new file mode 100644 +index 00000000..c33c39ec +--- /dev/null ++++ b/tests/07revert-shrink.broken +@@ -0,0 +1,9 @@ ++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 53760 ++ ++ ERROR: active raid5 not found +diff --git a/tests/07testreshape5.broken b/tests/07testreshape5.broken +new file mode 100644 +index 00000000..a8ce03e4 +--- /dev/null ++++ b/tests/07testreshape5.broken +@@ -0,0 +1,12 @@ ++always fails ++ ++Test seems to run 'test_stripe' at $dir directory, but $dir is never ++set. If $dir is adjusted to $PWD, the test still fails with: ++ ++ mdadm: /dev/loop2 is not suitable for this array. ++ mdadm: create aborted ++ ++ return 1 ++ ++ cmp -s -n 8192 /dev/md0 /tmp/RandFile ++ ++ echo cmp failed ++ cmp failed ++ ++ exit 2 +diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken +new file mode 100644 +index 00000000..a6d4d5cf +--- /dev/null ++++ b/tests/09imsm-assemble.broken +@@ -0,0 +1,6 @@ ++fails infrequently ++ ++Fails roughly 1 in 10 runs with errors: ++ ++ mdadm: /dev/loop2 is still in use, cannot remove. ++ /dev/loop2 removal from /dev/md/container should have succeeded +diff --git a/tests/09imsm-create-fail-rebuild.broken b/tests/09imsm-create-fail-rebuild.broken +new file mode 100644 +index 00000000..40c4b294 +--- /dev/null ++++ b/tests/09imsm-create-fail-rebuild.broken +@@ -0,0 +1,5 @@ ++always fails ++ ++Fails with error: ++ ++ **Error**: Array size mismatch - expected 3072, actual 16384 +diff --git a/tests/09imsm-overlap.broken b/tests/09imsm-overlap.broken +new file mode 100644 +index 00000000..e7ccab76 +--- /dev/null ++++ b/tests/09imsm-overlap.broken +@@ -0,0 +1,7 @@ ++always fails ++ ++Fails with errors: ++ ++ **Error**: Offset mismatch - expected 15360, actual 0 ++ **Error**: Offset mismatch - expected 15360, actual 0 ++ /dev/md/vol3 failed check +diff --git a/tests/10ddf-assemble-missing.broken b/tests/10ddf-assemble-missing.broken +new file mode 100644 +index 00000000..bfd8d103 +--- /dev/null ++++ b/tests/10ddf-assemble-missing.broken +@@ -0,0 +1,6 @@ ++always fails ++ ++Fails with errors: ++ ++ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 ++ ERROR: unexpected number of online disks on /dev/loop10 +diff --git a/tests/10ddf-fail-create-race.broken b/tests/10ddf-fail-create-race.broken +new file mode 100644 +index 00000000..6c0df023 +--- /dev/null ++++ b/tests/10ddf-fail-create-race.broken +@@ -0,0 +1,7 @@ ++usually fails ++ ++Fails about 9 out of 10 times with many errors: ++ ++ mdadm: cannot open MISSING: No such file or directory ++ ERROR: non-degraded array found ++ ERROR: disk 0 not marked as failed in meta data +diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken +new file mode 100644 +index 00000000..eeea56d9 +--- /dev/null ++++ b/tests/10ddf-fail-two-spares.broken +@@ -0,0 +1,5 @@ ++fails infrequently ++ ++Fails roughly 1 in 3 with error: ++ ++ ERROR: /dev/md/vol1 should be optimal in meta data +diff --git a/tests/10ddf-incremental-wrong-order.broken b/tests/10ddf-incremental-wrong-order.broken +new file mode 100644 +index 00000000..a5af3bab +--- /dev/null ++++ b/tests/10ddf-incremental-wrong-order.broken +@@ -0,0 +1,9 @@ ++always fails ++ ++Fails with errors: ++ ERROR: sha1sum of /dev/md/vol0 has changed ++ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 ++ ERROR: unexpected number of online disks on /dev/loop10 ++ ERROR: /dev/md/vol0 has unexpected state on /dev/loop8 ++ ERROR: unexpected number of online disks on /dev/loop8 ++ ERROR: sha1sum of /dev/md/vol0 has changed +diff --git a/tests/14imsm-r1_2d-grow-r1_3d.broken b/tests/14imsm-r1_2d-grow-r1_3d.broken +new file mode 100644 +index 00000000..4ef1d406 +--- /dev/null ++++ b/tests/14imsm-r1_2d-grow-r1_3d.broken +@@ -0,0 +1,5 @@ ++always fails ++ ++Fails with error: ++ ++ mdadm/tests/func.sh: line 325: dvsize/chunk: division by 0 (error token is "chunk") +diff --git a/tests/14imsm-r1_2d-takeover-r0_2d.broken b/tests/14imsm-r1_2d-takeover-r0_2d.broken +new file mode 100644 +index 00000000..89cd4e57 +--- /dev/null ++++ b/tests/14imsm-r1_2d-takeover-r0_2d.broken +@@ -0,0 +1,6 @@ ++always fails ++ ++Fails with error: ++ ++ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token ++ is "chunk") +diff --git a/tests/18imsm-r10_4d-takeover-r0_2d.broken b/tests/18imsm-r10_4d-takeover-r0_2d.broken +new file mode 100644 +index 00000000..a27399f5 +--- /dev/null ++++ b/tests/18imsm-r10_4d-takeover-r0_2d.broken +@@ -0,0 +1,5 @@ ++fails rarely ++ ++Fails about 1 run in 100 with message: ++ ++ ERROR: size is wrong for /dev/md/vol0: 2 * 5120 (chunk=128) = 20480, not 0 +diff --git a/tests/18imsm-r1_2d-takeover-r0_1d.broken b/tests/18imsm-r1_2d-takeover-r0_1d.broken +new file mode 100644 +index 00000000..aa1982e6 +--- /dev/null ++++ b/tests/18imsm-r1_2d-takeover-r0_1d.broken +@@ -0,0 +1,6 @@ ++always fails ++ ++Fails with error: ++ ++ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token ++ is "chunk") +diff --git a/tests/19raid6auto-repair.broken b/tests/19raid6auto-repair.broken +new file mode 100644 +index 00000000..e91a1425 +--- /dev/null ++++ b/tests/19raid6auto-repair.broken +@@ -0,0 +1,5 @@ ++always fails ++ ++Fails with: ++ ++ "should detect errors" +diff --git a/tests/19raid6repair.broken b/tests/19raid6repair.broken +new file mode 100644 +index 00000000..e91a1425 +--- /dev/null ++++ b/tests/19raid6repair.broken +@@ -0,0 +1,5 @@ ++always fails ++ ++Fails with: ++ ++ "should detect errors" +-- +2.38.1 + diff --git a/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch b/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch new file mode 100644 index 0000000..74bf834 --- /dev/null +++ b/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch @@ -0,0 +1,316 @@ +From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Fri, 12 Aug 2022 16:36:02 +0200 +Subject: [PATCH 45/83] mdadm: Replace obsolete usleep with nanosleep + +According to POSIX.1-2001, usleep is considered obsolete. +Replace it with a wrapper that uses nanosleep, as recommended in man. +Add handy macros for conversions between msec, usec and nsec. + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Assemble.c | 2 +- + Grow.c | 4 ++-- + Manage.c | 10 +++++----- + managemon.c | 8 ++++---- + mdadm.h | 4 ++++ + mdmon.c | 4 ++-- + super-intel.c | 6 +++--- + util.c | 42 +++++++++++++++++++++++++++++++++--------- + 8 files changed, 54 insertions(+), 26 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 6df6bfbc..be2160b4 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1947,7 +1947,7 @@ out: + break; + close(mdfd); + } +- usleep(usecs); ++ sleep_for(0, USEC_TO_NSEC(usecs), true); + usecs <<= 1; + } + } +diff --git a/Grow.c b/Grow.c +index 97f22c75..5780635a 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -954,7 +954,7 @@ int start_reshape(struct mdinfo *sra, int already_running, + err = sysfs_set_str(sra, NULL, "sync_action", + "reshape"); + if (err) +- sleep(1); ++ sleep_for(1, 0, true); + } while (err && errno == EBUSY && cnt-- > 0); + } + return err; +@@ -5058,7 +5058,7 @@ int Grow_continue_command(char *devname, int fd, + } + st->ss->getinfo_super(st, content, NULL); + if (!content->reshape_active) +- sleep(3); ++ sleep_for(3, 0, true); + else + break; + } while (cnt-- > 0); +diff --git a/Manage.c b/Manage.c +index e5e6abe4..a142f8bd 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -244,7 +244,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + "array_state", + "inactive")) < 0 && + errno == EBUSY) { +- usleep(200000); ++ sleep_for(0, MSEC_TO_NSEC(200), true); + count--; + } + if (err) { +@@ -328,7 +328,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) { + /* must be in the critical section - wait a bit */ + delay -= 1; +- usleep(100000); ++ sleep_for(0, MSEC_TO_NSEC(100), true); + } + + if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0) +@@ -405,7 +405,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + * quite started yet. Wait a bit and + * check 'sync_action' to see. + */ +- usleep(10000); ++ sleep_for(0, MSEC_TO_NSEC(10), true); + sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf)); + if (strncmp(buf, "reshape", 7) != 0) + break; +@@ -447,7 +447,7 @@ done: + count = 25; err = 0; + while (count && fd >= 0 && + (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { +- usleep(200000); ++ sleep_for(0, MSEC_TO_NSEC(200), true); + count --; + } + if (fd >= 0 && err) { +@@ -1105,7 +1105,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + ret = sysfs_unique_holder(devnm, rdev); + if (ret < 2) + break; +- usleep(100 * 1000); /* 100ms */ ++ sleep_for(0, MSEC_TO_NSEC(100), true); + } while (--count > 0); + + if (ret == 0) { +diff --git a/managemon.c b/managemon.c +index 0e9bdf00..a7bfa8f6 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -207,7 +207,7 @@ static void replace_array(struct supertype *container, + remove_old(); + while (pending_discard) { + while (discard_this == NULL) +- sleep(1); ++ sleep_for(1, 0, true); + remove_old(); + } + pending_discard = old; +@@ -568,7 +568,7 @@ static void manage_member(struct mdstat_ent *mdstat, + updates = NULL; + while (update_queue_pending || update_queue) { + check_update_queue(container); +- usleep(15*1000); ++ sleep_for(0, MSEC_TO_NSEC(15), true); + } + replace_array(container, a, newa); + if (sysfs_set_str(&a->info, NULL, +@@ -822,7 +822,7 @@ static void handle_message(struct supertype *container, struct metadata_update * + if (msg->len <= 0) + while (update_queue_pending || update_queue) { + check_update_queue(container); +- usleep(15*1000); ++ sleep_for(0, MSEC_TO_NSEC(15), true); + } + + if (msg->len == 0) { /* ping_monitor */ +@@ -836,7 +836,7 @@ static void handle_message(struct supertype *container, struct metadata_update * + wakeup_monitor(); + + while (monitor_loop_cnt - cnt < 0) +- usleep(10 * 1000); ++ sleep_for(0, MSEC_TO_NSEC(10), true); + } else if (msg->len == -1) { /* ping_manager */ + struct mdstat_ent *mdstat = mdstat_read(1, 0); + +diff --git a/mdadm.h b/mdadm.h +index 163f4a49..add9c0b6 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1720,6 +1720,10 @@ extern int cluster_get_dlmlock(void); + extern int cluster_release_dlmlock(void); + extern void set_dlm_hooks(void); + ++#define MSEC_TO_NSEC(msec) ((msec) * 1000000) ++#define USEC_TO_NSEC(usec) ((usec) * 1000) ++extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); ++ + #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) + #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) + #define ROUND_UP_PTR(ptr, base) ((typeof(ptr)) \ +diff --git a/mdmon.c b/mdmon.c +index c057da63..e9d035eb 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -99,7 +99,7 @@ static int clone_monitor(struct supertype *container) + if (rc) + return rc; + while (mon_tid == -1) +- usleep(10); ++ sleep_for(0, USEC_TO_NSEC(10), true); + pthread_attr_destroy(&attr); + + mgr_tid = syscall(SYS_gettid); +@@ -209,7 +209,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) + rv = kill(pid, SIGUSR1); + if (rv < 0) + break; +- usleep(200000); ++ sleep_for(0, MSEC_TO_NSEC(200), true); + } + } + +diff --git a/super-intel.c b/super-intel.c +index 4ddfcf94..4d82af3d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5275,7 +5275,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d + /* retry the load if we might have raced against mdmon */ + if (err == 3 && devnm && mdmon_running(devnm)) + for (retry = 0; retry < 3; retry++) { +- usleep(3000); ++ sleep_for(0, MSEC_TO_NSEC(3), true); + err = load_and_parse_mpb(dfd, s, NULL, keep_fd); + if (err != 3) + break; +@@ -5377,7 +5377,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) + + if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) { + for (retry = 0; retry < 3; retry++) { +- usleep(3000); ++ sleep_for(0, MSEC_TO_NSEC(3), true); + rv = load_and_parse_mpb(fd, super, devname, 0); + if (rv != 3) + break; +@@ -12084,7 +12084,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) + close(fd); + return 1; + } +- usleep(30000); ++ sleep_for(0, MSEC_TO_NSEC(30), true); + } else + break; + } while (retry--); +diff --git a/util.c b/util.c +index 38f0420e..ca48d976 100644 +--- a/util.c ++++ b/util.c +@@ -166,7 +166,7 @@ retry: + pr_err("error %d when get PW mode on lock %s\n", errno, str); + /* let's try several times if EAGAIN happened */ + if (dlm_lock_res->lksb.sb_status == EAGAIN && retry_count < 10) { +- sleep(10); ++ sleep_for(10, 0, true); + retry_count++; + goto retry; + } +@@ -1085,7 +1085,7 @@ int open_dev_excl(char *devnm) + int i; + int flags = O_RDWR; + dev_t devid = devnm2devid(devnm); +- long delay = 1000; ++ unsigned int delay = 1; // miliseconds + + sprintf(buf, "%d:%d", major(devid), minor(devid)); + for (i = 0; i < 25; i++) { +@@ -1098,8 +1098,8 @@ int open_dev_excl(char *devnm) + } + if (errno != EBUSY) + return fd; +- usleep(delay); +- if (delay < 200000) ++ sleep_for(0, MSEC_TO_NSEC(delay), true); ++ if (delay < 200) + delay *= 2; + } + return -1; +@@ -1123,7 +1123,7 @@ void wait_for(char *dev, int fd) + { + int i; + struct stat stb_want; +- long delay = 1000; ++ unsigned int delay = 1; // miliseconds + + if (fstat(fd, &stb_want) != 0 || + (stb_want.st_mode & S_IFMT) != S_IFBLK) +@@ -1135,8 +1135,8 @@ void wait_for(char *dev, int fd) + (stb.st_mode & S_IFMT) == S_IFBLK && + (stb.st_rdev == stb_want.st_rdev)) + return; +- usleep(delay); +- if (delay < 200000) ++ sleep_for(0, MSEC_TO_NSEC(delay), true); ++ if (delay < 200) + delay *= 2; + } + if (i == 25) +@@ -1821,7 +1821,7 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force) + while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && + errno == EBUSY && + cnt-- > 0) +- usleep(10000); ++ sleep_for(0, MSEC_TO_NSEC(10), true); + + return ret; + } +@@ -1834,7 +1834,7 @@ int sys_hot_remove_disk(int statefd, int force) + while ((ret = write(statefd, "remove", 6)) == -1 && + errno == EBUSY && + cnt-- > 0) +- usleep(10000); ++ sleep_for(0, MSEC_TO_NSEC(10), true); + return ret == 6 ? 0 : -1; + } + +@@ -2375,3 +2375,27 @@ out: + close(fd_zero); + return ret; + } ++ ++/** ++ * sleep_for() - Sleeps for specified time. ++ * @sec: Seconds to sleep for. ++ * @nsec: Nanoseconds to sleep for, has to be less than one second. ++ * @wake_after_interrupt: If set, wake up if interrupted. ++ * ++ * Function immediately returns if error different than EINTR occurs. ++ */ ++void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) ++{ ++ struct timespec delay = {.tv_sec = sec, .tv_nsec = nsec}; ++ ++ assert(nsec < MSEC_TO_NSEC(1000)); ++ ++ do { ++ errno = 0; ++ nanosleep(&delay, &delay); ++ if (errno != 0 && errno != EINTR) { ++ pr_err("Error sleeping for %us %ldns: %s\n", sec, nsec, strerror(errno)); ++ return; ++ } ++ } while (!wake_after_interrupt && errno == EINTR); ++} +-- +2.38.1 + diff --git a/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch b/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch new file mode 100644 index 0000000..5872416 --- /dev/null +++ b/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch @@ -0,0 +1,36 @@ +From 39b381252c32275079344d30de18b76fda4bba26 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 27 Jul 2022 15:52:45 -0600 +Subject: [PATCH 46/83] tests/00readonly: Run udevadm settle before setting ro + +In some recent kernel versions, 00readonly fails with: + + mdadm: failed to set readonly for /dev/md0: Device or resource busy + ERROR: array is not read-only! + +This was traced down to a race condition with udev holding a reference +to the block device at the same time as trying to set it read only. + +To fix this, call udevadm settle before setting the array read only. + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + tests/00readonly | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/00readonly b/tests/00readonly +index 39202487..afe243b3 100644 +--- a/tests/00readonly ++++ b/tests/00readonly +@@ -12,6 +12,7 @@ do + $dev1 $dev2 $dev3 $dev4 --assume-clean + check nosync + check $level ++ udevadm settle + mdadm -ro $md0 + check readonly + state=$(cat /sys/block/md0/md/array_state) +-- +2.38.1 + diff --git a/0047-tests-add-test-for-names.patch b/0047-tests-add-test-for-names.patch new file mode 100644 index 0000000..03aee00 --- /dev/null +++ b/0047-tests-add-test-for-names.patch @@ -0,0 +1,119 @@ +From b7671c82010ffc04dfaecff2dd19ef8b2283e2b6 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 19 Jul 2022 14:48:21 +0200 +Subject: [PATCH 47/83] tests: add test for names + +Current behavior is not documented and tested. This test is a base for +future improvements. It is enough to test it only with native metadata, +because it is generic code. Generated properties are passed to metadata +handler. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + tests/00createnames | 93 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 93 insertions(+) + create mode 100644 tests/00createnames + +diff --git a/tests/00createnames b/tests/00createnames +new file mode 100644 +index 00000000..64b81b92 +--- /dev/null ++++ b/tests/00createnames +@@ -0,0 +1,93 @@ ++set -x -e ++ ++# Test how and --name= are handled for create mode. ++# We need to check three properties, generated from those parameters: ++# - devnode name ++# - link in /dev/md/ (MD_DEVNAME property from --detail --export) ++# - name in metadata (MD_NAME property from --examine --export) ++ ++function _verify() { ++ local DEVNODE_NAME="$1" ++ local WANTED_LINK="$2" ++ local WANTED_NAME="$3" ++ ++ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" ++ if [[ "$?" != "0" ]]; then ++ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." ++ exit 1 ++ fi ++ ++ if [[ "$WANTED_LINK" != "empty" ]]; then ++ local EXPECTED="MD_DEVNAME=$WANTED_LINK" ++ if [[ "$RES" != "$EXPECTED" ]]; then ++ echo "$RES doesn't match $EXPECTED." ++ exit 1 ++ fi ++ fi ++ ++ ++ local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" ++ if [[ "$?" != "0" ]]; then ++ echo "Cannot get metadata from $dev0." ++ exit 1 ++ fi ++ ++ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" ++ if [[ "$RES" != "$EXPECTED" ]]; then ++ echo "$RES doesn't match $EXPECTED." ++ exit 1 ++ fi ++} ++ ++function _create() { ++ local DEVNAME=$1 ++ local NAME=$2 ++ ++ if [[ -z "$NAME" ]]; then ++ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force ++ else ++ mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force ++ fi ++ ++ if [[ "$?" != "0" ]]; then ++ echo "Cannot create device." ++ exit 1 ++ fi ++} ++ ++# The most trivial case. ++_create "/dev/md/name" ++_verify "/dev/md127" "name" "name" ++mdadm -S "/dev/md127" ++ ++_create "name" ++_verify "/dev/md127" "name" "name" ++mdadm -S "/dev/md127" ++ ++# Use 'mdX' as name. ++_create "/dev/md/md0" ++_verify "/dev/md127" "md0" "md0" ++mdadm -S "/dev/md127" ++ ++_create "md0" ++_verify "/dev/md127" "md0" "md0" ++mdadm -S "/dev/md127" ++ ++# is used to create MD_DEVNAME but, name is used to create MD_NAME. ++_create "/dev/md/devnode" "name" ++_verify "/dev/md127" "devnode" "name" ++mdadm -S "/dev/md127" ++ ++_create "devnode" "name" ++_verify "/dev/md127" "devnode" "name" ++mdadm -S "/dev/md127" ++ ++# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. ++_create "/dev/md0" ++_verify "/dev/md0" "empty" "0" ++mdadm -S "/dev/md0" ++ ++# Devnode points to /dev/ directory and name is set. ++_create "/dev/md0" "name" ++_verify "/dev/md0" "empty" "name" ++mdadm -S "/dev/md0" +-- +2.38.1 + diff --git a/0048-mdadm-remove-symlink-option.patch b/0048-mdadm-remove-symlink-option.patch new file mode 100644 index 0000000..1956e2b --- /dev/null +++ b/0048-mdadm-remove-symlink-option.patch @@ -0,0 +1,176 @@ +From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 19 Jul 2022 14:48:22 +0200 +Subject: [PATCH 48/83] mdadm: remove symlink option + +The option is not used. Remove it from code. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 1 - + config.c | 7 +------ + mdadm.8.in | 9 --------- + mdadm.c | 20 -------------------- + mdadm.conf.5.in | 15 --------------- + mdadm.h | 2 -- + 6 files changed, 1 insertion(+), 53 deletions(-) + +diff --git a/ReadMe.c b/ReadMe.c +index 7518a32a..7f94847e 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -147,7 +147,6 @@ struct option long_options[] = { + {"nofailfast",0, 0, NoFailFast}, + {"re-add", 0, 0, ReAdd}, + {"homehost", 1, 0, HomeHost}, +- {"symlinks", 1, 0, Symlinks}, + {"data-offset",1, 0, DataOffset}, + {"nodes",1, 0, Nodes}, /* also for --assemble */ + {"home-cluster",1, 0, ClusterName}, +diff --git a/config.c b/config.c +index 9c725457..dc1620c1 100644 +--- a/config.c ++++ b/config.c +@@ -194,7 +194,6 @@ struct mddev_dev *load_containers(void) + + struct createinfo createinfo = { + .autof = 2, /* by default, create devices with standard names */ +- .symlinks = 1, + .names = 0, /* By default, stick with numbered md devices. */ + .bblist = 1, /* Use a bad block list by default */ + #ifdef DEBIAN +@@ -310,11 +309,7 @@ static void createline(char *line) + if (!createinfo.supertype) + pr_err("metadata format %s unknown, ignoring\n", + w+9); +- } else if (strncasecmp(w, "symlinks=yes", 12) == 0) +- createinfo.symlinks = 1; +- else if (strncasecmp(w, "symlinks=no", 11) == 0) +- createinfo.symlinks = 0; +- else if (strncasecmp(w, "names=yes", 12) == 0) ++ } else if (strncasecmp(w, "names=yes", 12) == 0) + createinfo.names = 1; + else if (strncasecmp(w, "names=no", 11) == 0) + createinfo.names = 0; +diff --git a/mdadm.8.in b/mdadm.8.in +index 0be02e4a..f2736226 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -1048,11 +1048,6 @@ simultaneously. If not specified, this defaults to 4. + Specify journal device for the RAID-4/5/6 array. The journal device + should be a SSD with reasonable lifetime. + +-.TP +-.BR \-\-symlinks +-Auto creation of symlinks in /dev to /dev/md, option --symlinks must +-be 'no' or 'yes' and work with --create and --build. +- + .TP + .BR \-k ", " \-\-consistency\-policy= + Specify how the array maintains consistency in case of unexpected shutdown. +@@ -1405,10 +1400,6 @@ Reshape can be continued later using the + .B \-\-continue + option for the grow command. + +-.TP +-.BR \-\-symlinks +-See this option under Create and Build options. +- + .SH For Manage mode: + + .TP +diff --git a/mdadm.c b/mdadm.c +index 56722ed9..180f7a9c 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -59,7 +59,6 @@ int main(int argc, char *argv[]) + struct mddev_dev *dv; + mdu_array_info_t array; + int devs_found = 0; +- char *symlinks = NULL; + int grow_continue = 0; + /* autof indicates whether and how to create device node. + * bottom 3 bits are style. Rest (when shifted) are number of parts +@@ -663,13 +662,6 @@ int main(int argc, char *argv[]) + case O(ASSEMBLE,Auto): /* auto-creation of device node */ + c.autof = parse_auto(optarg, "--auto flag", 0); + continue; +- +- case O(CREATE,Symlinks): +- case O(BUILD,Symlinks): +- case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */ +- symlinks = optarg; +- continue; +- + case O(BUILD,'f'): /* force honouring '-n 1' */ + case O(BUILD,Force): /* force honouring '-n 1' */ + case O(GROW,'f'): /* ditto */ +@@ -1325,18 +1317,6 @@ int main(int argc, char *argv[]) + exit(2); + } + +- if (symlinks) { +- struct createinfo *ci = conf_get_create_info(); +- +- if (strcasecmp(symlinks, "yes") == 0) +- ci->symlinks = 1; +- else if (strcasecmp(symlinks, "no") == 0) +- ci->symlinks = 0; +- else { +- pr_err("option --symlinks must be 'no' or 'yes'\n"); +- exit(2); +- } +- } + /* Ok, got the option parsing out of the way + * hopefully it's mostly right but there might be some stuff + * missing +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index cd4e6a9d..bc2295c2 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -338,21 +338,6 @@ missing device entries should be created. + The name of the metadata format to use if none is explicitly given. + This can be useful to impose a system-wide default of version-1 superblocks. + +-.TP +-.B symlinks=no +-Normally when creating devices in +-.B /dev/md/ +-.I mdadm +-will create a matching symlink from +-.B /dev/ +-with a name starting +-.B md +-or +-.BR md_ . +-Give +-.B symlinks=no +-to suppress this symlink creation. +- + .TP + .B names=yes + Since Linux 2.6.29 it has been possible to create +diff --git a/mdadm.h b/mdadm.h +index add9c0b6..93e72786 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -394,7 +394,6 @@ struct createinfo { + int gid; + int autof; + int mode; +- int symlinks; + int names; + int bblist; + struct supertype *supertype; +@@ -442,7 +441,6 @@ enum special_options { + BackupFile, + HomeHost, + AutoHomeHost, +- Symlinks, + AutoDetect, + Waitclean, + DetailPlatform, +-- +2.38.1 + diff --git a/0049-mdadm-move-data_offset-to-struct-shape.patch b/0049-mdadm-move-data_offset-to-struct-shape.patch new file mode 100644 index 0000000..5dca508 --- /dev/null +++ b/0049-mdadm-move-data_offset-to-struct-shape.patch @@ -0,0 +1,232 @@ +From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 19 Jul 2022 14:48:23 +0200 +Subject: [PATCH 49/83] mdadm: move data_offset to struct shape + +Data offset is a shape property so move it there to remove additional +parameter from some functions. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Create.c | 16 ++++++++-------- + Grow.c | 7 +++---- + mdadm.c | 20 +++++++++----------- + mdadm.h | 5 ++--- + 4 files changed, 22 insertions(+), 26 deletions(-) + +diff --git a/Create.c b/Create.c +index c84c1ac8..e06ec2ae 100644 +--- a/Create.c ++++ b/Create.c +@@ -95,7 +95,7 @@ int Create(struct supertype *st, char *mddev, + char *name, int *uuid, + int subdevs, struct mddev_dev *devlist, + struct shape *s, +- struct context *c, unsigned long long data_offset) ++ struct context *c) + { + /* + * Create a new raid array. +@@ -288,7 +288,7 @@ int Create(struct supertype *st, char *mddev, + newsize = s->size * 2; + if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, + &s->chunk, s->size*2, +- data_offset, NULL, ++ s->data_offset, NULL, + &newsize, s->consistency_policy, + c->verbose >= 0)) + return 1; +@@ -323,10 +323,10 @@ int Create(struct supertype *st, char *mddev, + info.array.working_disks = 0; + dnum = 0; + for (dv = devlist; dv; dv = dv->next) +- if (data_offset == VARIABLE_OFFSET) ++ if (s->data_offset == VARIABLE_OFFSET) + dv->data_offset = INVALID_SECTORS; + else +- dv->data_offset = data_offset; ++ dv->data_offset = s->data_offset; + + for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) { + char *dname = dv->devname; +@@ -342,7 +342,7 @@ int Create(struct supertype *st, char *mddev, + missing_disks ++; + continue; + } +- if (data_offset == VARIABLE_OFFSET) { ++ if (s->data_offset == VARIABLE_OFFSET) { + doff = strchr(dname, ':'); + if (doff) { + *doff++ = 0; +@@ -350,7 +350,7 @@ int Create(struct supertype *st, char *mddev, + } else + dv->data_offset = INVALID_SECTORS; + } else +- dv->data_offset = data_offset; ++ dv->data_offset = s->data_offset; + + dfd = open(dname, O_RDONLY); + if (dfd < 0) { +@@ -535,7 +535,7 @@ int Create(struct supertype *st, char *mddev, + if (!st->ss->validate_geometry(st, s->level, s->layout, + s->raiddisks, + &s->chunk, minsize*2, +- data_offset, ++ s->data_offset, + NULL, NULL, + s->consistency_policy, 0)) { + pr_err("devices too large for RAID level %d\n", s->level); +@@ -754,7 +754,7 @@ int Create(struct supertype *st, char *mddev, + } + } + if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid, +- data_offset)) ++ s->data_offset)) + goto abort_locked; + + total_slots = info.array.nr_disks; +diff --git a/Grow.c b/Grow.c +index 5780635a..868bdc3a 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1775,7 +1775,6 @@ static int reshape_container(char *container, char *devname, + + int Grow_reshape(char *devname, int fd, + struct mddev_dev *devlist, +- unsigned long long data_offset, + struct context *c, struct shape *s) + { + /* Make some changes in the shape of an array. +@@ -1821,7 +1820,7 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- if (data_offset != INVALID_SECTORS && array.level != 10 && ++ if (s->data_offset != INVALID_SECTORS && array.level != 10 && + (array.level < 4 || array.level > 6)) { + pr_err("--grow --data-offset not yet supported\n"); + return 1; +@@ -2179,7 +2178,7 @@ size_change_error: + if ((s->level == UnSet || s->level == array.level) && + (s->layout_str == NULL) && + (s->chunk == 0 || s->chunk == array.chunk_size) && +- data_offset == INVALID_SECTORS && ++ s->data_offset == INVALID_SECTORS && + (s->raiddisks == 0 || s->raiddisks == array.raid_disks)) { + /* Nothing more to do */ + if (!changed && c->verbose >= 0) +@@ -2379,7 +2378,7 @@ size_change_error: + } + sync_metadata(st); + rv = reshape_array(container, fd, devname, st, &info, c->force, +- devlist, data_offset, c->backup_file, ++ devlist, s->data_offset, c->backup_file, + c->verbose, 0, 0, 0); + frozen = 0; + } +diff --git a/mdadm.c b/mdadm.c +index 180f7a9c..845e4466 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -49,7 +49,6 @@ int main(int argc, char *argv[]) + int i; + + unsigned long long array_size = 0; +- unsigned long long data_offset = INVALID_SECTORS; + struct mddev_ident ident; + char *configfile = NULL; + int devmode = 0; +@@ -79,6 +78,7 @@ int main(int argc, char *argv[]) + .layout = UnSet, + .bitmap_chunk = UnSet, + .consistency_policy = CONSISTENCY_POLICY_UNKNOWN, ++ .data_offset = INVALID_SECTORS, + }; + + char sys_hostname[256]; +@@ -479,15 +479,15 @@ int main(int argc, char *argv[]) + + case O(CREATE,DataOffset): + case O(GROW,DataOffset): +- if (data_offset != INVALID_SECTORS) { ++ if (s.data_offset != INVALID_SECTORS) { + pr_err("data-offset may only be specified one. Second value is %s.\n", optarg); + exit(2); + } + if (mode == CREATE && strcmp(optarg, "variable") == 0) +- data_offset = VARIABLE_OFFSET; ++ s.data_offset = VARIABLE_OFFSET; + else +- data_offset = parse_size(optarg); +- if (data_offset == INVALID_SECTORS) { ++ s.data_offset = parse_size(optarg); ++ if (s.data_offset == INVALID_SECTORS) { + pr_err("invalid data-offset: %s\n", + optarg); + exit(2); +@@ -1416,7 +1416,7 @@ int main(int argc, char *argv[]) + exit(1); + } + +- if (c.backup_file && data_offset != INVALID_SECTORS) { ++ if (c.backup_file && s.data_offset != INVALID_SECTORS) { + pr_err("--backup-file and --data-offset are incompatible\n"); + exit(2); + } +@@ -1587,8 +1587,7 @@ int main(int argc, char *argv[]) + + rv = Create(ss, devlist->devname, + ident.name, ident.uuid_set ? ident.uuid : NULL, +- devs_found-1, devlist->next, +- &s, &c, data_offset); ++ devs_found - 1, devlist->next, &s, &c); + break; + case MISC: + if (devmode == 'E') { +@@ -1706,10 +1705,9 @@ int main(int argc, char *argv[]) + c.verbose); + else if (s.size > 0 || s.raiddisks || s.layout_str || + s.chunk != 0 || s.level != UnSet || +- data_offset != INVALID_SECTORS) { ++ s.data_offset != INVALID_SECTORS) { + rv = Grow_reshape(devlist->devname, mdfd, +- devlist->next, +- data_offset, &c, &s); ++ devlist->next, &c, &s); + } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { + rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); + } else if (array_size == 0) +diff --git a/mdadm.h b/mdadm.h +index 93e72786..adb7cdaa 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -595,6 +595,7 @@ struct shape { + int assume_clean; + int write_behind; + unsigned long long size; ++ unsigned long long data_offset; + int consistency_policy; + }; + +@@ -1431,7 +1432,6 @@ extern int Grow_addbitmap(char *devname, int fd, + struct context *c, struct shape *s); + extern int Grow_reshape(char *devname, int fd, + struct mddev_dev *devlist, +- unsigned long long data_offset, + struct context *c, struct shape *s); + extern int Grow_restart(struct supertype *st, struct mdinfo *info, + int *fdlist, int cnt, char *backup_file, int verbose); +@@ -1462,8 +1462,7 @@ extern int Create(struct supertype *st, char *mddev, + char *name, int *uuid, + int subdevs, struct mddev_dev *devlist, + struct shape *s, +- struct context *c, +- unsigned long long data_offset); ++ struct context *c); + + extern int Detail(char *dev, struct context *c); + extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); +-- +2.38.1 + diff --git a/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch new file mode 100644 index 0000000..c319da2 --- /dev/null +++ b/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch @@ -0,0 +1,162 @@ +From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 27 Jul 2022 15:52:46 -0600 +Subject: [PATCH 50/83] mdadm: Don't open md device for CREATE and ASSEMBLE + +The mdadm command tries to open the md device for most modes, first +thing, no matter what. When running to create or assemble an array, +in most cases, the md device will not exist, the open call will fail +and everything will proceed correctly. + +However, when running tests, a create or assembly command may be run +shortly after stopping an array and the old md device file may still +be around. Then, if create_on_open is set in the kernel, a new md +device will be created when mdadm does its initial open. + +When mdadm gets around to creating the new device with the new_array +parameter it issues this error: + + mdadm: Fail to create md0 when using + /sys/module/md_mod/parameters/new_array, fallback to creation via node + +This is because an mddev was already created by the kernel with the +earlier open() call and thus the new one being created will fail with +EEXIST. The mdadm command will still successfully be created due to +falling back to the node creation method. However, the error message +itself will fail any test that's running it. + +This issue is a race condition that is very rare, but a recent change +in the kernel caused this to happen more frequently: about 1 in 50 +times. + +To fix this, don't bother trying to open the md device for CREATE, +ASSEMBLE and BUILD commands, as the file descriptor will never be used +anyway even if it is successfully openned. The mdfd has not been used +for these commands since: + + 7f91af49ad09 ("Delay creation of array devices for assemble/build/create") + +The checks that were done on the open device can be changed to being +done with stat. + +Side note: it would be nice to disable create_on_open as well to help +solve this, but it seems the work for this was never finished. By default, +mdadm will create using the old node interface when a name is specified +unless the user specifically puts names=yes in a config file, which +doesn't seem to be common or desirable to require this.. + +Signed-off-by: Logan Gunthorpe +Signed-off-by: Jes Sorensen +--- + lib.c | 12 ++++++++++++ + mdadm.c | 40 ++++++++++++++++++++-------------------- + mdadm.h | 1 + + 3 files changed, 33 insertions(+), 20 deletions(-) + +diff --git a/lib.c b/lib.c +index 7e3e3d47..e395b28d 100644 +--- a/lib.c ++++ b/lib.c +@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st) + return devid2devnm(st->st_rdev); + } + ++bool stat_is_md_dev(struct stat *st) ++{ ++ if ((S_IFMT & st->st_mode) != S_IFBLK) ++ return false; ++ if (major(st->st_rdev) == MD_MAJOR) ++ return true; ++ if (major(st->st_rdev) == (unsigned)get_mdp_major()) ++ return true; ++ ++ return false; ++} ++ + char *fd2devnm(int fd) + { + struct stat stb; +diff --git a/mdadm.c b/mdadm.c +index 845e4466..972adb52 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1329,6 +1329,9 @@ int main(int argc, char *argv[]) + + if (mode == MANAGE || mode == BUILD || mode == CREATE || + mode == GROW || (mode == ASSEMBLE && ! c.scan)) { ++ struct stat stb; ++ int ret; ++ + if (devs_found < 1) { + pr_err("an md device must be given in this mode\n"); + exit(2); +@@ -1341,6 +1344,12 @@ int main(int argc, char *argv[]) + mdfd = open_mddev(devlist->devname, 1); + if (mdfd < 0) + exit(1); ++ ++ ret = fstat(mdfd, &stb); ++ if (ret) { ++ pr_err("fstat failed on %s.\n", devlist->devname); ++ exit(1); ++ } + } else { + char *bname = basename(devlist->devname); + +@@ -1348,30 +1357,21 @@ int main(int argc, char *argv[]) + pr_err("Name %s is too long.\n", devlist->devname); + exit(1); + } +- /* non-existent device is OK */ +- mdfd = open_mddev(devlist->devname, 0); +- } +- if (mdfd == -2) { +- pr_err("device %s exists but is not an md array.\n", devlist->devname); +- exit(1); +- } +- if ((int)ident.super_minor == -2) { +- struct stat stb; +- if (mdfd < 0) { ++ ++ ret = stat(devlist->devname, &stb); ++ if (ident.super_minor == -2 && ret != 0) { + pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", +- devlist->devname); ++ devlist->devname); ++ exit(1); ++ } ++ ++ if (!ret && !stat_is_md_dev(&stb)) { ++ pr_err("device %s exists but is not an md array.\n", devlist->devname); + exit(1); + } +- fstat(mdfd, &stb); +- ident.super_minor = minor(stb.st_rdev); +- } +- if (mdfd >= 0 && mode != MANAGE && mode != GROW) { +- /* We don't really want this open yet, we just might +- * have wanted to check some things +- */ +- close(mdfd); +- mdfd = -1; + } ++ if (ident.super_minor == -2) ++ ident.super_minor = minor(stb.st_rdev); + } + + if (s.raiddisks) { +diff --git a/mdadm.h b/mdadm.h +index adb7cdaa..8208b81e 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1672,6 +1672,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 + extern char *stat2kname(struct stat *st); + extern char *fd2kname(int fd); + extern char *stat2devnm(struct stat *st); ++bool stat_is_md_dev(struct stat *st); + extern char *fd2devnm(int fd); + extern void udev_block(char *devnm); + extern void udev_unblock(void); +-- +2.38.1 + diff --git a/0051-Grow-Split-Grow_reshape-into-helper-function.patch b/0051-Grow-Split-Grow_reshape-into-helper-function.patch new file mode 100644 index 0000000..8fe5894 --- /dev/null +++ b/0051-Grow-Split-Grow_reshape-into-helper-function.patch @@ -0,0 +1,231 @@ +From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 28 Jul 2022 20:20:53 +0800 +Subject: [PATCH 51/83] Grow: Split Grow_reshape into helper function + +Grow_reshape should be split into helper functions given its size. +- Add helper function for preparing reshape on external metadata. +- Close cfd file descriptor. + +Signed-off-by: Mateusz Kusiak +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Grow.c | 125 ++++++++++++++++++++++++++++++-------------------------- + mdadm.h | 1 + + util.c | 14 +++++++ + 3 files changed, 81 insertions(+), 59 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 868bdc3a..0f07a894 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname, + char *backup_file, int verbose, + int forked, int restart, int freeze_reshape); + ++/** ++ * prepare_external_reshape() - prepares update on external metadata if supported. ++ * @devname: Device name. ++ * @subarray: Subarray. ++ * @st: Supertype. ++ * @container: Container. ++ * @cfd: Container file descriptor. ++ * ++ * Function checks that the requested reshape is supported on external metadata, ++ * and performs an initial check that the container holds the pre-requisite ++ * spare devices (mdmon owns final validation). ++ * ++ * Return: 0 on success, else 1 ++ */ ++static int prepare_external_reshape(char *devname, char *subarray, ++ struct supertype *st, char *container, ++ const int cfd) ++{ ++ struct mdinfo *cc = NULL; ++ struct mdinfo *content = NULL; ++ ++ if (st->ss->load_container(st, cfd, NULL)) { ++ pr_err("Cannot read superblock for %s\n", devname); ++ return 1; ++ } ++ ++ if (!st->ss->container_content) ++ return 1; ++ ++ cc = st->ss->container_content(st, subarray); ++ for (content = cc; content ; content = content->next) { ++ /* ++ * check if reshape is allowed based on metadata ++ * indications stored in content.array.status ++ */ ++ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) || ++ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) { ++ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n", ++ devname, container); ++ goto error; ++ } ++ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) { ++ pr_err("Operation not supported when ppl consistency policy is enabled\n"); ++ goto error; ++ } ++ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) { ++ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n"); ++ goto error; ++ } ++ } ++ sysfs_free(cc); ++ if (mdmon_running(container)) ++ st->update_tail = &st->updates; ++ return 0; ++error: ++ sysfs_free(cc); ++ return 1; ++} ++ + int Grow_reshape(char *devname, int fd, + struct mddev_dev *devlist, + struct context *c, struct shape *s) +@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd, + struct supertype *st; + char *subarray = NULL; + +- int frozen; ++ int frozen = 0; + int changed = 0; + char *container = NULL; + int cfd = -1; +@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd, + int added_disks; + + struct mdinfo info; +- struct mdinfo *sra; ++ struct mdinfo *sra = NULL; + + if (md_get_array_info(fd, &array) < 0) { + pr_err("%s is not an active md array - aborting\n", +@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd, + } + } + +- /* in the external case we need to check that the requested reshape is +- * supported, and perform an initial check that the container holds the +- * pre-requisite spare devices (mdmon owns final validation) +- */ + if (st->ss->external) { +- int retval; +- + if (subarray) { + container = st->container_devnm; + cfd = open_dev_excl(st->container_devnm); +@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- retval = st->ss->load_container(st, cfd, NULL); +- +- if (retval) { +- pr_err("Cannot read superblock for %s\n", devname); +- close(cfd); ++ rv = prepare_external_reshape(devname, subarray, st, ++ container, cfd); ++ if (rv > 0) { + free(subarray); +- return 1; ++ close(cfd); ++ goto release; + } + + if (s->raiddisks && subarray) { +@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd, + free(subarray); + return 1; + } +- +- /* check if operation is supported for metadata handler */ +- if (st->ss->container_content) { +- struct mdinfo *cc = NULL; +- struct mdinfo *content = NULL; +- +- cc = st->ss->container_content(st, subarray); +- for (content = cc; content ; content = content->next) { +- int allow_reshape = 1; +- +- /* check if reshape is allowed based on metadata +- * indications stored in content.array.status +- */ +- if (content->array.state & +- (1 << MD_SB_BLOCK_VOLUME)) +- allow_reshape = 0; +- if (content->array.state & +- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE)) +- allow_reshape = 0; +- if (!allow_reshape) { +- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n", +- devname, container); +- sysfs_free(cc); +- free(subarray); +- return 1; +- } +- if (content->consistency_policy == +- CONSISTENCY_POLICY_PPL) { +- pr_err("Operation not supported when ppl consistency policy is enabled\n"); +- sysfs_free(cc); +- free(subarray); +- return 1; +- } +- if (content->consistency_policy == +- CONSISTENCY_POLICY_BITMAP) { +- pr_err("Operation not supported when write-intent bitmap is enabled\n"); +- sysfs_free(cc); +- free(subarray); +- return 1; +- } +- } +- sysfs_free(cc); +- } +- if (mdmon_running(container)) +- st->update_tail = &st->updates; + } + + added_disks = 0; +diff --git a/mdadm.h b/mdadm.h +index 8208b81e..941a5f38 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev); + extern bool is_dev_alive(char *path); + extern int get_mdp_major(void); + extern int get_maj_min(char *dev, int *major, int *minor); ++extern bool is_bit_set(int *val, unsigned char index); + extern int dev_open(char *dev, int flags); + extern int open_dev(char *devnm); + extern void reopen_mddev(int mdfd); +diff --git a/util.c b/util.c +index ca48d976..26ffdcea 100644 +--- a/util.c ++++ b/util.c +@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor) + *e == 0); + } + ++/** ++ * is_bit_set() - get bit value by index. ++ * @val: value. ++ * @index: index of the bit (LSB numbering). ++ * ++ * Return: bit value. ++ */ ++bool is_bit_set(int *val, unsigned char index) ++{ ++ if ((*val) & (1 << index)) ++ return true; ++ return false; ++} ++ + int dev_open(char *dev, int flags) + { + /* like 'open', but if 'dev' matches %d:%d, create a temp +-- +2.38.1 + diff --git a/0052-Assemble-check-if-device-is-container-before-schedul.patch b/0052-Assemble-check-if-device-is-container-before-schedul.patch new file mode 100644 index 0000000..52d08b8 --- /dev/null +++ b/0052-Assemble-check-if-device-is-container-before-schedul.patch @@ -0,0 +1,36 @@ +From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 19 Aug 2022 02:55:46 +0200 +Subject: [PATCH 52/83] Assemble: check if device is container before + scheduling force-clean update + +Up to now using assemble with force flag making each array as clean. +Force-clean should not be done for the container. This commit add +check if device is different than container before cleaning. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Assemble.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index be2160b4..1dd82a8c 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1809,10 +1809,9 @@ try_again: + } + #endif + } +- if (c->force && !clean && ++ if (c->force && !clean && content->array.level != LEVEL_CONTAINER && + !enough(content->array.level, content->array.raid_disks, +- content->array.layout, clean, +- avail)) { ++ content->array.layout, clean, avail)) { + change += st->ss->update_super(st, content, "force-array", + devices[chosen_drive].devname, c->verbose, + 0, NULL); +-- +2.38.1 + diff --git a/0053-super1-report-truncated-device.patch b/0053-super1-report-truncated-device.patch new file mode 100644 index 0000000..35cbd4b --- /dev/null +++ b/0053-super1-report-truncated-device.patch @@ -0,0 +1,112 @@ +From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 26 Aug 2022 08:55:56 +1000 +Subject: [PATCH 53/83] super1: report truncated device + +When the metadata is at the start of the device, it is possible that it +describes a device large than the one it is actually stored on. When +this happens, report it loudly in --examine. + +.... + Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL + State : clean TRUNCATED DEVICE +.... + +Also report in --assemble so that the failure which the kernel will +report will be explained. + +mdadm: Device /dev/sdb is not large enough for data described in superblock +mdadm: no RAID superblock on /dev/sdb +mdadm: /dev/sdb has no superblock - assembly aborted + +Scenario can be demonstrated as follows: + +mdadm: Note: this array has metadata at the start and + may not be suitable as a boot device. If you plan to + store '/boot' on this device please ensure that + your boot-loader understands md/v1.x metadata, or use + --metadata=0.90 +mdadm: Defaulting to version 1.2 metadata +mdadm: array /dev/md/test started. +mdadm: stopped /dev/md/test + Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL + State : clean TRUNCATED DEVICE + Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL + State : clean TRUNCATED DEVICE + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + super1.c | 35 ++++++++++++++++++++++++++++------- + 1 file changed, 28 insertions(+), 7 deletions(-) + +diff --git a/super1.c b/super1.c +index 71af860c..58345e68 100644 +--- a/super1.c ++++ b/super1.c +@@ -406,12 +406,18 @@ static void examine_super1(struct supertype *st, char *homehost) + + st->ss->getinfo_super(st, &info, NULL); + if (info.space_after != 1 && +- !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) +- printf(" Unused Space : before=%llu sectors, after=%llu sectors\n", +- info.space_before, info.space_after); +- +- printf(" State : %s\n", +- (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); ++ !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { ++ printf(" Unused Space : before=%llu sectors, ", ++ info.space_before); ++ if (info.space_after < INT64_MAX) ++ printf("after=%llu sectors\n", info.space_after); ++ else ++ printf("after=-%llu sectors DEVICE TOO SMALL\n", ++ UINT64_MAX - info.space_after); ++ } ++ printf(" State : %s%s\n", ++ (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", ++ (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); + printf(" Device UUID : "); + for (i=0; i<16; i++) { + if ((i&3)==0 && i != 0) +@@ -2206,6 +2212,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) + tst.ss = &super1; + for (tst.minor_version = 0; tst.minor_version <= 2; + tst.minor_version++) { ++ tst.ignore_hw_compat = st->ignore_hw_compat; + switch(load_super1(&tst, fd, devname)) { + case 0: super = tst.sb; + if (bestvers == -1 || +@@ -2312,7 +2319,6 @@ static int load_super1(struct supertype *st, int fd, char *devname) + free(super); + return 2; + } +- st->sb = super; + + bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); + +@@ -2322,6 +2328,21 @@ static int load_super1(struct supertype *st, int fd, char *devname) + if (st->data_offset == INVALID_SECTORS) + st->data_offset = __le64_to_cpu(super->data_offset); + ++ if (st->minor_version >= 1 && ++ st->ignore_hw_compat == 0 && ++ (dsize < (__le64_to_cpu(super->data_offset) + ++ __le64_to_cpu(super->size)) ++ || ++ dsize < (__le64_to_cpu(super->data_offset) + ++ __le64_to_cpu(super->data_size)))) { ++ if (devname) ++ pr_err("Device %s is not large enough for data described in superblock\n", ++ devname); ++ free(super); ++ return 2; ++ } ++ st->sb = super; ++ + /* Now check on the bitmap superblock */ + if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) + return 0; +-- +2.38.1 + diff --git a/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch b/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch new file mode 100644 index 0000000..c37276f --- /dev/null +++ b/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch @@ -0,0 +1,616 @@ +From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Fri, 12 Aug 2022 16:52:12 +0200 +Subject: [PATCH 54/83] mdadm: Correct typos, punctuation and grammar in man + +Signed-off-by: Mateusz Grzonka +Reviewed-by: Wol +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 178 ++++++++++++++++++++++++++--------------------------- + 1 file changed, 88 insertions(+), 90 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index f2736226..70c79d1e 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -158,7 +158,7 @@ adding new spares and removing faulty devices. + .B Misc + This is an 'everything else' mode that supports operations on active + arrays, operations on component devices such as erasing old superblocks, and +-information gathering operations. ++information-gathering operations. + .\"This mode allows operations on independent devices such as examine MD + .\"superblocks, erasing old superblocks and stopping active arrays. + +@@ -231,12 +231,12 @@ mode to be assumed. + + .TP + .BR \-h ", " \-\-help +-Display general help message or, after one of the above options, a ++Display a general help message or, after one of the above options, a + mode-specific help message. + + .TP + .B \-\-help\-options +-Display more detailed help about command line parsing and some commonly ++Display more detailed help about command-line parsing and some commonly + used options. + + .TP +@@ -266,7 +266,7 @@ the exact meaning of this option in different contexts. + + .TP + .BR \-c ", " \-\-config= +-Specify the config file or directory. If not specified, default config file ++Specify the config file or directory. If not specified, the default config file + and default conf.d directory will be used. See + .BR mdadm.conf (5) + for more details. +@@ -379,7 +379,7 @@ When creating an array, the + .B homehost + will be recorded in the metadata. For version-1 superblocks, it will + be prefixed to the array name. For version-0.90 superblocks, part of +-the SHA1 hash of the hostname will be stored in the later half of the ++the SHA1 hash of the hostname will be stored in the latter half of the + UUID. + + When reporting information about an array, any array which is tagged +@@ -388,7 +388,7 @@ for the given homehost will be reported as such. + When using Auto-Assemble, only arrays tagged for the given homehost + will be allowed to use 'local' names (i.e. not ending in '_' followed + by a digit string). See below under +-.BR "Auto Assembly" . ++.BR "Auto-Assembly" . + + The special name "\fBany\fP" can be used as a wild card. If an array + is created with +@@ -403,7 +403,7 @@ When + .I mdadm + needs to print the name for a device it normally finds the name in + .B /dev +-which refers to the device and is shortest. When a path component is ++which refers to the device and is the shortest. When a path component is + given with + .B \-\-prefer + .I mdadm +@@ -478,9 +478,9 @@ still be larger than any replacement. + + This option can be used with + .B \-\-create +-for determining initial size of an array. For external metadata, ++for determining the initial size of an array. For external metadata, + it can be used on a volume, but not on a container itself. +-Setting initial size of ++Setting the initial size of + .B RAID 0 + array is only valid for external metadata. + +@@ -545,20 +545,20 @@ Clustered arrays do not support this parameter yet. + + .TP + .BR \-c ", " \-\-chunk= +-Specify chunk size of kilobytes. The default when creating an ++Specify chunk size in kilobytes. The default when creating an + array is 512KB. To ensure compatibility with earlier versions, the + default when building an array with no persistent metadata is 64KB. + This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10. + + RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power +-of 2. In any case it must be a multiple of 4KB. ++of 2, with minimal chunk size being 4KB. + + A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, + Megabytes, Gigabytes or Terabytes respectively. + + .TP + .BR \-\-rounding= +-Specify rounding factor for a Linear array. The size of each ++Specify the rounding factor for a Linear array. The size of each + component will be rounded down to a multiple of this size. + This is a synonym for + .B \-\-chunk +@@ -655,7 +655,8 @@ option to set subsequent failure modes. + and "flush" will clear any persistent faults. + + The layout options for RAID10 are one of 'n', 'o' or 'f' followed +-by a small number. The default is 'n2'. The supported options are: ++by a small number signifying the number of copies of each datablock. ++The default is 'n2'. The supported options are: + + .I 'n' + signals 'near' copies. Multiple copies of one data block are at +@@ -673,7 +674,7 @@ signals 'far' copies + (multiple copies have very different offsets). + See md(4) for more detail about 'near', 'offset', and 'far'. + +-The number is the number of copies of each datablock. 2 is normal, 3 ++As for the number of copies of each data block, 2 is normal, 3 + can be useful. This number can be at most equal to the number of + devices in the array. It does not need to divide evenly into that + number (e.g. it is perfectly legal to have an 'n2' layout for an array +@@ -684,7 +685,7 @@ A bug introduced in Linux 3.14 means that RAID0 arrays + started using a different layout. This could lead to + data corruption. Since Linux 5.4 (and various stable releases that received + backports), the kernel will not accept such an array unless +-a layout is explictly set. It can be set to ++a layout is explicitly set. It can be set to + .RB ' original ' + or + .RB ' alternate '. +@@ -760,13 +761,13 @@ or by selecting a different consistency policy with + + .TP + .BR \-\-bitmap\-chunk= +-Set the chunksize of the bitmap. Each bit corresponds to that many ++Set the chunk size of the bitmap. Each bit corresponds to that many + Kilobytes of storage. +-When using a file based bitmap, the default is to use the smallest +-size that is at-least 4 and requires no more than 2^21 chunks. ++When using a file-based bitmap, the default is to use the smallest ++size that is at least 4 and requires no more than 2^21 chunks. + When using an + .B internal +-bitmap, the chunksize defaults to 64Meg, or larger if necessary to ++bitmap, the chunk size defaults to 64Meg, or larger if necessary to + fit the bitmap into the available space. + + A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, +@@ -840,7 +841,7 @@ can be used with that command to avoid the automatic resync. + .BR \-\-backup\-file= + This is needed when + .B \-\-grow +-is used to increase the number of raid-devices in a RAID5 or RAID6 if ++is used to increase the number of raid devices in a RAID5 or RAID6 if + there are no spare devices available, or to shrink, change RAID level + or layout. See the GROW MODE section below on RAID\-DEVICES CHANGES. + The file must be stored on a separate device, not on the RAID array +@@ -879,7 +880,7 @@ When creating an array, + .B \-\-data\-offset + can be specified as + .BR variable . +-In the case each member device is expected to have a offset appended ++In the case each member device is expected to have an offset appended + to the name, separated by a colon. This makes it possible to recreate + exactly an array which has varying data offsets (as can happen when + different versions of +@@ -943,7 +944,7 @@ Insist that + .I mdadm + accept the geometry and layout specified without question. Normally + .I mdadm +-will not allow creation of an array with only one device, and will try ++will not allow the creation of an array with only one device, and will try + to create a RAID5 array with one missing drive (as this makes the + initial resync work faster). With + .BR \-\-force , +@@ -1004,7 +1005,7 @@ number added, e.g. + If the md device name is in a 'standard' format as described in DEVICE + NAMES, then it will be created, if necessary, with the appropriate + device number based on that name. If the device name is not in one of these +-formats, then a unused device number will be allocated. The device ++formats, then an unused device number will be allocated. The device + number will be considered unused if there is no active array for that + number, and there is no entry in /dev for that number and with a + non-standard name. Names that are not in 'standard' format are only +@@ -1032,25 +1033,25 @@ then + .B \-\-add + can be used to add some extra devices to be included in the array. + In most cases this is not needed as the extra devices can be added as +-spares first, and then the number of raid-disks can be changed. +-However for RAID0, it is not possible to add spares. So to increase ++spares first, and then the number of raid disks can be changed. ++However, for RAID0 it is not possible to add spares. So to increase + the number of devices in a RAID0, it is necessary to set the new + number of devices, and to add the new devices, in the same command. + + .TP + .BR \-\-nodes +-Only works when the array is for clustered environment. It specifies ++Only works when the array is created for a clustered environment. It specifies + the maximum number of nodes in the cluster that will use this device + simultaneously. If not specified, this defaults to 4. + + .TP + .BR \-\-write-journal + Specify journal device for the RAID-4/5/6 array. The journal device +-should be a SSD with reasonable lifetime. ++should be an SSD with a reasonable lifetime. + + .TP + .BR \-k ", " \-\-consistency\-policy= +-Specify how the array maintains consistency in case of unexpected shutdown. ++Specify how the array maintains consistency in the case of an unexpected shutdown. + Only relevant for RAID levels with redundancy. + Currently supported options are: + .RS +@@ -1058,7 +1059,7 @@ Currently supported options are: + .TP + .B resync + Full resync is performed and all redundancy is regenerated when the array is +-started after unclean shutdown. ++started after an unclean shutdown. + + .TP + .B bitmap +@@ -1067,8 +1068,8 @@ Resync assisted by a write-intent bitmap. Implicitly selected when using + + .TP + .B journal +-For RAID levels 4/5/6, journal device is used to log transactions and replay +-after unclean shutdown. Implicitly selected when using ++For RAID levels 4/5/6, the journal device is used to log transactions and replay ++after an unclean shutdown. Implicitly selected when using + .BR \-\-write\-journal . + + .TP +@@ -1237,7 +1238,7 @@ This can be useful if + reports a different "Preferred Minor" to + .BR \-\-detail . + In some cases this update will be performed automatically +-by the kernel driver. In particular the update happens automatically ++by the kernel driver. In particular, the update happens automatically + at the first write to an array with redundancy (RAID level 1 or + greater) on a 2.6 (or later) kernel. + +@@ -1277,7 +1278,7 @@ For version-1 superblocks, this involves updating the name. + The + .B home\-cluster + option will change the cluster name as recorded in the superblock and +-bitmap. This option only works for clustered environment. ++bitmap. This option only works for a clustered environment. + + The + .B resync +@@ -1390,10 +1391,10 @@ This option should be used with great caution. + + .TP + .BR \-\-freeze\-reshape +-Option is intended to be used in start-up scripts during initrd boot phase. +-When array under reshape is assembled during initrd phase, this option +-stops reshape after reshape critical section is being restored. This happens +-before file system pivot operation and avoids loss of file system context. ++This option is intended to be used in start-up scripts during the initrd boot phase. ++When the array under reshape is assembled during the initrd phase, this option ++stops the reshape after the reshape-critical section has been restored. This happens ++before the file system pivot operation and avoids loss of filesystem context. + Losing file system context would cause reshape to be broken. + + Reshape can be continued later using the +@@ -1437,9 +1438,9 @@ re\-add a device that was previously removed from an array. + If the metadata on the device reports that it is a member of the + array, and the slot that it used is still vacant, then the device will + be added back to the array in the same position. This will normally +-cause the data for that device to be recovered. However based on the ++cause the data for that device to be recovered. However, based on the + event count on the device, the recovery may only require sections that +-are flagged a write-intent bitmap to be recovered or may not require ++are flagged by a write-intent bitmap to be recovered or may not require + any recovery at all. + + When used on an array that has no metadata (i.e. it was built with +@@ -1447,13 +1448,12 @@ When used on an array that has no metadata (i.e. it was built with + it will be assumed that bitmap-based recovery is enough to make the + device fully consistent with the array. + +-When used with v1.x metadata, + .B \-\-re\-add +-can be accompanied by ++can also be accompanied by + .BR \-\-update=devicesize , + .BR \-\-update=bbl ", or" + .BR \-\-update=no\-bbl . +-See the description of these option when used in Assemble mode for an ++See descriptions of these options when used in Assemble mode for an + explanation of their use. + + If the device name given is +@@ -1480,7 +1480,7 @@ Add a device as a spare. This is similar to + except that it does not attempt + .B \-\-re\-add + first. The device will be added as a spare even if it looks like it +-could be an recent member of the array. ++could be a recent member of the array. + + .TP + .BR \-r ", " \-\-remove +@@ -1497,12 +1497,12 @@ and names like + .B set-A + can be given to + .BR \-\-remove . +-The first causes all failed device to be removed. The second causes ++The first causes all failed devices to be removed. The second causes + any device which is no longer connected to the system (i.e an 'open' + returns + .BR ENXIO ) + to be removed. +-The third will remove a set as describe below under ++The third will remove a set as described below under + .BR \-\-fail . + + .TP +@@ -1519,7 +1519,7 @@ For RAID10 arrays where the number of copies evenly divides the number + of devices, the devices can be conceptually divided into sets where + each set contains a single complete copy of the data on the array. + Sometimes a RAID10 array will be configured so that these sets are on +-separate controllers. In this case all the devices in one set can be ++separate controllers. In this case, all the devices in one set can be + failed by giving a name like + .B set\-A + or +@@ -1549,9 +1549,9 @@ This can follow a list of + .B \-\-replace + devices. The devices listed after + .B \-\-with +-will be preferentially used to replace the devices listed after ++will preferentially be used to replace the devices listed after + .BR \-\-replace . +-These device must already be spare devices in the array. ++These devices must already be spare devices in the array. + + .TP + .BR \-\-write\-mostly +@@ -1574,8 +1574,8 @@ the device is found or :missing in case the device is not found. + + .TP + .BR \-\-add-journal +-Add journal to an existing array, or recreate journal for RAID-4/5/6 array +-that lost a journal device. To avoid interrupting on-going write opertions, ++Add a journal to an existing array, or recreate journal for a RAID-4/5/6 array ++that lost a journal device. To avoid interrupting ongoing write operations, + .B \-\-add-journal + only works for array in Read-Only state. + +@@ -1631,9 +1631,9 @@ Print details of one or more md devices. + .TP + .BR \-\-detail\-platform + Print details of the platform's RAID capabilities (firmware / hardware +-topology) for a given metadata format. If used without argument, mdadm ++topology) for a given metadata format. If used without an argument, mdadm + will scan all controllers looking for their capabilities. Otherwise, mdadm +-will only look at the controller specified by the argument in form of an ++will only look at the controller specified by the argument in the form of an + absolute filepath or a link, e.g. + .IR /sys/devices/pci0000:00/0000:00:1f.2 . + +@@ -1742,8 +1742,8 @@ the block where the superblock would be is overwritten even if it + doesn't appear to be valid. + + .B Note: +-Be careful to call \-\-zero\-superblock with clustered raid, make sure +-array isn't used or assembled in other cluster node before execute it. ++Be careful when calling \-\-zero\-superblock with clustered raid. Make sure ++the array isn't used or assembled in another cluster node before executing it. + + .TP + .B \-\-kill\-subarray= +@@ -1790,7 +1790,7 @@ For each md device given, or each device in /proc/mdstat if + is given, arrange for the array to be marked clean as soon as possible. + .I mdadm + will return with success if the array uses external metadata and we +-successfully waited. For native arrays this returns immediately as the ++successfully waited. For native arrays, this returns immediately as the + kernel handles dirty-clean transitions at shutdown. No action is taken + if safe-mode handling is disabled. + +@@ -1830,7 +1830,7 @@ uses to help track which arrays are currently being assembled. + + .TP + .BR \-\-run ", " \-R +-Run any array assembled as soon as a minimal number of devices are ++Run any array assembled as soon as a minimal number of devices is + available, rather than waiting until all expected devices are present. + + .TP +@@ -1860,7 +1860,7 @@ Only used with \-\-fail. The 'path' given will be recorded so that if + a new device appears at the same location it can be automatically + added to the same array. This allows the failed device to be + automatically replaced by a new device without metadata if it appears +-at specified path. This option is normally only set by a ++at specified path. This option is normally only set by an + .I udev + script. + +@@ -1961,7 +1961,7 @@ Usage: + .PP + This usage assembles one or more RAID arrays from pre-existing components. + For each array, mdadm needs to know the md device, the identity of the +-array, and a number of component-devices. These can be found in a number of ways. ++array, and the number of component devices. These can be found in a number of ways. + + In the first usage example (without the + .BR \-\-scan ) +@@ -2001,7 +2001,7 @@ The config file is only used if explicitly named with + .B \-\-config + or requested with (a possibly implicit) + .BR \-\-scan . +-In the later case, default config file is used. See ++In the latter case, the default config file is used. See + .BR mdadm.conf (5) + for more details. + +@@ -2039,14 +2039,14 @@ detects that udev is not configured, it will create the devices in + .B /dev + itself. + +-In Linux kernels prior to version 2.6.28 there were two distinctly +-different types of md devices that could be created: one that could be ++In Linux kernels prior to version 2.6.28 there were two distinct ++types of md devices that could be created: one that could be + partitioned using standard partitioning tools and one that could not. +-Since 2.6.28 that distinction is no longer relevant as both type of ++Since 2.6.28 that distinction is no longer relevant as both types of + devices can be partitioned. + .I mdadm + will normally create the type that originally could not be partitioned +-as it has a well defined major number (9). ++as it has a well-defined major number (9). + + Prior to 2.6.28, it is important that mdadm chooses the correct type + of array device to use. This can be controlled with the +@@ -2066,7 +2066,7 @@ can also be given in the configuration file as a word starting + .B auto= + on the ARRAY line for the relevant array. + +-.SS Auto Assembly ++.SS Auto-Assembly + When + .B \-\-assemble + is used with +@@ -2122,11 +2122,11 @@ See + .IR mdadm.conf (5) + for further details. + +-Note: Auto assembly cannot be used for assembling and activating some ++Note: Auto-assembly cannot be used for assembling and activating some + arrays which are undergoing reshape. In particular as the + .B backup\-file +-cannot be given, any reshape which requires a backup-file to continue +-cannot be started by auto assembly. An array which is growing to more ++cannot be given, any reshape which requires a backup file to continue ++cannot be started by auto-assembly. An array which is growing to more + devices and has passed the critical section can be assembled using + auto-assembly. + +@@ -2233,7 +2233,7 @@ When creating a partition based array, using + .I mdadm + with version-1.x metadata, the partition type should be set to + .B 0xDA +-(non fs-data). This type selection allows for greater precision since ++(non fs-data). This type of selection allows for greater precision since + using any other [RAID auto-detect (0xFD) or a GNU/Linux partition (0x83)], + might create problems in the event of array recovery through a live cdrom. + +@@ -2249,7 +2249,7 @@ when creating a v0.90 array will silently override any + setting. + .\"If the + .\".B \-\-size +-.\"option is given, it is not necessary to list any component-devices in this command. ++.\"option is given, it is not necessary to list any component devices in this command. + .\"They can be added later, before a + .\".B \-\-run. + .\"If no +@@ -2263,7 +2263,7 @@ requested with the + .B \-\-bitmap + option or a different consistency policy is selected with the + .B \-\-consistency\-policy +-option. In any case space for a bitmap will be reserved so that one ++option. In any case, space for a bitmap will be reserved so that one + can be added later with + .BR "\-\-grow \-\-bitmap=internal" . + +@@ -2313,7 +2313,7 @@ will firstly mark + as faulty in + .B /dev/md0 + and will then remove it from the array and finally add it back +-in as a spare. However only one md array can be affected by a single ++in as a spare. However, only one md array can be affected by a single + command. + + When a device is added to an active array, mdadm checks to see if it +@@ -2458,14 +2458,14 @@ config file to be examined. + If the device contains RAID metadata, a file will be created in the + .I directory + and the metadata will be written to it. The file will be the same +-size as the device and have the metadata written in the file at the +-same locate that it exists in the device. However the file will be "sparse" so ++size as the device and will have the metadata written at the ++same location as it exists in the device. However, the file will be "sparse" so + that only those blocks containing metadata will be allocated. The + total space used will be small. + +-The file name used in the ++The filename used in the + .I directory +-will be the base name of the device. Further if any links appear in ++will be the base name of the device. Further, if any links appear in + .I /dev/disk/by-id + which point to the device, then hard links to the file will be created + in +@@ -2567,7 +2567,7 @@ and if the destination array has a failed drive but no spares. + + If any devices are listed on the command line, + .I mdadm +-will only monitor those devices. Otherwise all arrays listed in the ++will only monitor those devices, otherwise, all arrays listed in the + configuration file will be monitored. Further, if + .B \-\-scan + is given, then any other md devices that appear in +@@ -2624,10 +2624,10 @@ check, repair). (syslog priority: Warning) + .BI Rebuild NN + Where + .I NN +-is a two-digit number (ie. 05, 48). This indicates that rebuild +-has passed that many percent of the total. The events are generated +-with fixed increment since 0. Increment size may be specified with +-a commandline option (default is 20). (syslog priority: Warning) ++is a two-digit number (eg. 05, 48). This indicates that the rebuild ++has reached that percentage of the total. The events are generated ++at a fixed increment from 0. The increment size may be specified with ++a command-line option (the default is 20). (syslog priority: Warning) + + .TP + .B RebuildFinished +@@ -2735,8 +2735,8 @@ When + detects that an array in a spare group has fewer active + devices than necessary for the complete array, and has no spare + devices, it will look for another array in the same spare group that +-has a full complement of working drive and a spare. It will then +-attempt to remove the spare from the second drive and add it to the ++has a full complement of working drives and a spare. It will then ++attempt to remove the spare from the second array and add it to the + first. + If the removal succeeds but the adding fails, then it is added back to + the original array. +@@ -2750,10 +2750,8 @@ and then follow similar steps as above if a matching spare is found. + .SH GROW MODE + The GROW mode is used for changing the size or shape of an active + array. +-For this to work, the kernel must support the necessary change. +-Various types of growth are being added during 2.6 development. + +-Currently the supported changes include ++During the kernel 2.6 era the following changes were added: + .IP \(bu 4 + change the "size" attribute for RAID1, RAID4, RAID5 and RAID6. + .IP \(bu 4 +@@ -2796,8 +2794,8 @@ use more than half of a spare device for backup space. + + .SS SIZE CHANGES + Normally when an array is built the "size" is taken from the smallest +-of the drives. If all the small drives in an arrays are, one at a +-time, removed and replaced with larger drives, then you could have an ++of the drives. If all the small drives in an arrays are, over time, ++removed and replaced with larger drives, then you could have an + array of large drives with only a small amount used. In this + situation, changing the "size" with "GROW" mode will allow the extra + space to start being used. If the size is increased in this way, a +@@ -2812,7 +2810,7 @@ after growing, or to reduce its size + .B prior + to shrinking the array. + +-Also the size of an array cannot be changed while it has an active ++Also, the size of an array cannot be changed while it has an active + bitmap. If an array has a bitmap, it must be removed before the size + can be changed. Once the change is complete a new bitmap can be created. + +@@ -2892,7 +2890,7 @@ long time. A + is required. If the array is not simultaneously being grown or + shrunk, so that the array size will remain the same - for example, + reshaping a 3-drive RAID5 into a 4-drive RAID6 - the backup file will +-be used not just for a "cricital section" but throughout the reshape ++be used not just for a "critical section" but throughout the reshape + operation, as described below under LAYOUT CHANGES. + + .SS CHUNK-SIZE AND LAYOUT CHANGES +@@ -2910,7 +2908,7 @@ slowly. + If the reshape is interrupted for any reason, this backup file must be + made available to + .B "mdadm --assemble" +-so the array can be reassembled. Consequently the file cannot be ++so the array can be reassembled. Consequently, the file cannot be + stored on the device being reshaped. + + +-- +2.38.1 + diff --git a/0055-Manage-Block-unsafe-member-failing.patch b/0055-Manage-Block-unsafe-member-failing.patch new file mode 100644 index 0000000..290c56f --- /dev/null +++ b/0055-Manage-Block-unsafe-member-failing.patch @@ -0,0 +1,91 @@ +From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Aug 2022 11:47:21 +0200 +Subject: [PATCH 55/83] Manage: Block unsafe member failing + +Kernel may or may not block mdadm from removing member device if it +will cause arrays failed state. It depends on raid personality +implementation in kernel. +Add verification on requested removal path (#mdadm --set-faulty +command). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Manage.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 52 insertions(+), 1 deletion(-) + +diff --git a/Manage.c b/Manage.c +index a142f8bd..b1d0e630 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1285,6 +1285,50 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, + return -1; + } + ++/** ++ * is_remove_safe() - Check if remove is safe. ++ * @array: Array info. ++ * @fd: Array file descriptor. ++ * @devname: Name of device to remove. ++ * @verbose: Verbose. ++ * ++ * The function determines if array will be operational ++ * after removing &devname. ++ * ++ * Return: True if array will be operational, false otherwise. ++ */ ++bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose) ++{ ++ dev_t devid = devnm2devid(devname + 5); ++ struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE); ++ ++ if (!mdi) { ++ if (verbose) ++ pr_err("Failed to read sysfs attributes for %s\n", devname); ++ return false; ++ } ++ ++ char *avail = xcalloc(array->raid_disks, sizeof(char)); ++ ++ for (mdi = mdi->devs; mdi; mdi = mdi->next) { ++ if (mdi->disk.raid_disk < 0) ++ continue; ++ if (!(mdi->disk.state & (1 << MD_DISK_SYNC))) ++ continue; ++ if (makedev(mdi->disk.major, mdi->disk.minor) == devid) ++ continue; ++ avail[mdi->disk.raid_disk] = 1; ++ } ++ sysfs_free(mdi); ++ ++ bool is_enough = enough(array->level, array->raid_disks, ++ array->layout, (array->state & 1), ++ avail); ++ ++ free(avail); ++ return is_enough; ++} ++ + int Manage_subdevs(char *devname, int fd, + struct mddev_dev *devlist, int verbose, int test, + char *update, int force) +@@ -1598,7 +1642,14 @@ int Manage_subdevs(char *devname, int fd, + break; + + case 'f': /* set faulty */ +- /* FIXME check current member */ ++ 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); ++ goto abort; ++ } ++ + if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || + (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, + rdev))) { +-- +2.38.1 + diff --git a/0056-Monitor-Fix-statelist-memory-leaks.patch b/0056-Monitor-Fix-statelist-memory-leaks.patch new file mode 100644 index 0000000..ad36a25 --- /dev/null +++ b/0056-Monitor-Fix-statelist-memory-leaks.patch @@ -0,0 +1,112 @@ +From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 1 Sep 2022 11:20:31 +0200 +Subject: [PATCH 56/83] Monitor: Fix statelist memory leaks + +Free statelist in error path in Monitor initialization. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + Monitor.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 93f36ac0..b4e954c6 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + int test, struct alert_info *info); + static void try_spare_migration(struct state *statelist, struct alert_info *info); + static void link_containers_with_subarrays(struct state *list); ++static void free_statelist(struct state *statelist); + #ifndef NO_LIBUDEV + static int check_udev_activity(void); + #endif +@@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist, + */ + + struct state *statelist = NULL; +- struct state *st2; + int finished = 0; + struct mdstat_ent *mdstat = NULL; + char *mailfrom; +@@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist, + continue; + if (strcasecmp(mdlist->devname, "") == 0) + continue; ++ if (!is_mddev(mdlist->devname)) { ++ free_statelist(statelist); ++ return 1; ++ } + + st = xcalloc(1, sizeof *st); + snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), + "/dev/md/%s", basename(mdlist->devname)); +- if (!is_mddev(mdlist->devname)) +- return 1; + st->next = statelist; + st->devnm[0] = 0; + st->percent = RESYNC_UNKNOWN; +@@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist, + for (dv = devlist; dv; dv = dv->next) { + struct state *st; + +- if (!is_mddev(dv->devname)) ++ if (!is_mddev(dv->devname)) { ++ free_statelist(statelist); + return 1; ++ } + + st = xcalloc(1, sizeof *st); + mdlist = conf_get_ident(dv->devname); +@@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist, + for (stp = &statelist; (st = *stp) != NULL; ) { + if (st->from_auto && st->err > 5) { + *stp = st->next; +- free(st->spare_group); ++ if (st->spare_group) ++ free(st->spare_group); ++ + free(st); + } else + stp = &st->next; + } + } +- for (st2 = statelist; st2; st2 = statelist) { +- statelist = st2->next; +- free(st2); +- } ++ ++ free_statelist(statelist); + + if (pidfile) + unlink(pidfile); +@@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list) + } + } + ++/** ++ * free_statelist() - Frees statelist. ++ * @statelist: statelist to free ++ */ ++static void free_statelist(struct state *statelist) ++{ ++ struct state *tmp = NULL; ++ ++ while (statelist) { ++ if (statelist->spare_group) ++ free(statelist->spare_group); ++ ++ tmp = statelist; ++ statelist = statelist->next; ++ free(tmp); ++ } ++} ++ + #ifndef NO_LIBUDEV + /* function: check_udev_activity + * Description: Function waits for udev to finish +-- +2.38.1 + diff --git a/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch b/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch new file mode 100644 index 0000000..79a3262 --- /dev/null +++ b/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch @@ -0,0 +1,64 @@ +From ea7a02a3294aae223e1329aed5da7f4aa3ac05c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= +Date: Wed, 31 Aug 2022 19:57:29 +0200 +Subject: [PATCH 57/83] mdadm: added support for Intel Alderlake RST on VMD + platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Alderlake RST on VMD uses RstVmdV UEFI variable name, so detect it. + +Signed-off-by: Oldřich Jedlička +Reviewed-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + platform-intel.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 5a8729e7..757f0b1b 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -512,7 +512,8 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) + #define AHCI_PROP "RstSataV" + #define AHCI_SSATA_PROP "RstsSatV" + #define AHCI_TSATA_PROP "RsttSatV" +-#define VMD_PROP "RstUefiV" ++#define VROC_VMD_PROP "RstUefiV" ++#define RST_VMD_PROP "RstVmdV" + + #define VENDOR_GUID \ + EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) +@@ -605,6 +606,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) + struct orom_entry *ret; + static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP, + AHCI_TSATA_PROP}; ++ static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP}; + unsigned long i; + + if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) +@@ -636,10 +638,16 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) + + break; + case SYS_DEV_VMD: +- if (!read_efi_variable(&orom, sizeof(orom), VMD_PROP, +- VENDOR_GUID)) +- break; +- return NULL; ++ for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { ++ if (!read_efi_variable(&orom, sizeof(orom), ++ vmd_efivars[i], VENDOR_GUID)) ++ break; ++ } ++ ++ if (i == ARRAY_SIZE(vmd_efivars)) ++ return NULL; ++ ++ break; + default: + return NULL; + } +-- +2.38.1 + diff --git a/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch b/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch new file mode 100644 index 0000000..6e1a179 --- /dev/null +++ b/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch @@ -0,0 +1,111 @@ +From ea109700563d93704ebdc540c7770d874369f667 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 9 Sep 2022 15:50:33 +0200 +Subject: [PATCH 58/83] mdadm: Add Documentation entries to systemd services + +Add documentation section. +Copied from Debian. + +Cc: Felix Lechner +Signed-off-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 1 + + systemd/mdadm-last-resort@.service | 1 + + systemd/mdcheck_continue.service | 3 ++- + systemd/mdcheck_start.service | 1 + + systemd/mdmon@.service | 1 + + systemd/mdmonitor-oneshot.service | 1 + + systemd/mdmonitor.service | 1 + + 7 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 9fdc8ec7..64b8254a 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -8,6 +8,7 @@ + [Unit] + Description=Manage MD Reshape on /dev/%I + DefaultDependencies=no ++Documentation=man:mdadm(8) + + [Service] + ExecStart=BINDIR/mdadm --grow --continue /dev/%I +diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service +index efeb3f63..e9381125 100644 +--- a/systemd/mdadm-last-resort@.service ++++ b/systemd/mdadm-last-resort@.service +@@ -2,6 +2,7 @@ + Description=Activate md array %I even though degraded + DefaultDependencies=no + ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action ++Documentation=man:mdadm(8) + + [Service] + Type=oneshot +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index 854317f1..f5324905 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -7,7 +7,8 @@ + + [Unit] + Description=MD array scrubbing - continuation +-ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* ++ConditionPathExistsGlob=/var/lib/mdcheck/MD_UUID_* ++Documentation=man:mdadm(8) + + [Service] + Type=oneshot +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index 3bb3d130..703a6583 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -8,6 +8,7 @@ + [Unit] + Description=MD array scrubbing + Wants=mdcheck_continue.timer ++Documentation=man:mdadm(8) + + [Service] + Type=oneshot +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index 77533958..97a1acd9 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -9,6 +9,7 @@ + Description=MD Metadata Monitor on /dev/%I + DefaultDependencies=no + Before=initrd-switch-root.target ++Documentation=man:mdmon(8) + + [Service] + # mdmon should never complain due to lack of a platform, +diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service +index 373955a2..ba86b44e 100644 +--- a/systemd/mdmonitor-oneshot.service ++++ b/systemd/mdmonitor-oneshot.service +@@ -7,6 +7,7 @@ + + [Unit] + Description=Reminder for degraded MD arrays ++Documentation=man:mdadm(8) + + [Service] + Environment=MDADM_MONITOR_ARGS=--scan +diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service +index 46f7b880..9c364785 100644 +--- a/systemd/mdmonitor.service ++++ b/systemd/mdmonitor.service +@@ -8,6 +8,7 @@ + [Unit] + Description=MD array monitor + DefaultDependencies=no ++Documentation=man:mdadm(8) + + [Service] + Environment= MDADM_MONITOR_ARGS=--scan +-- +2.38.1 + diff --git a/0059-ReadMe-fix-command-line-help.patch b/0059-ReadMe-fix-command-line-help.patch new file mode 100644 index 0000000..837a339 --- /dev/null +++ b/0059-ReadMe-fix-command-line-help.patch @@ -0,0 +1,32 @@ +From f7cbd810b639eb946ba1b3bddb1faefb9696de42 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 9 Sep 2022 15:50:34 +0200 +Subject: [PATCH 59/83] ReadMe: fix command-line help + +Make command-line help consistent with manual page. +Copied from Debian. + +Cc: Felix Lechner +Signed-off-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ReadMe.c b/ReadMe.c +index 7f94847e..50a5e36d 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -477,7 +477,7 @@ char Help_assemble[] = + ; + + char Help_manage[] = +-"Usage: mdadm arraydevice options component devices...\n" ++"Usage: mdadm [mode] arraydevice [options] \n" + "\n" + "This usage is for managing the component devices within an array.\n" + "The --manage option is not needed and is assumed if the first argument\n" +-- +2.38.1 + diff --git a/0060-mdadm-replace-container-level-checking-with-inline.patch b/0060-mdadm-replace-container-level-checking-with-inline.patch new file mode 100644 index 0000000..7b2b6b2 --- /dev/null +++ b/0060-mdadm-replace-container-level-checking-with-inline.patch @@ -0,0 +1,257 @@ +From 6f2af6a48c541f207cb727a31fb86de2cd04fc21 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 2 Sep 2022 08:49:23 +0200 +Subject: [PATCH 60/83] mdadm: replace container level checking with inline + +To unify all containers checks in code, is_container() function is +added and propagated. + +Signed-off-by: Kinga Tanska +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Assemble.c | 7 +++---- + Create.c | 6 +++--- + Grow.c | 6 +++--- + Incremental.c | 4 ++-- + mdadm.h | 14 ++++++++++++++ + super-ddf.c | 6 +++--- + super-intel.c | 4 ++-- + super0.c | 2 +- + super1.c | 2 +- + sysfs.c | 2 +- + 10 files changed, 33 insertions(+), 20 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 1dd82a8c..8b0af0c9 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1120,7 +1120,7 @@ static int start_array(int mdfd, + i/2, mddev); + } + +- if (content->array.level == LEVEL_CONTAINER) { ++ if (is_container(content->array.level)) { + sysfs_rules_apply(mddev, content); + if (c->verbose >= 0) { + pr_err("Container %s has been assembled with %d drive%s", +@@ -1549,8 +1549,7 @@ try_again: + */ + trustworthy = LOCAL; + +- if (name[0] == 0 && +- content->array.level == LEVEL_CONTAINER) { ++ if (!name[0] && is_container(content->array.level)) { + name = content->text_version; + trustworthy = METADATA; + } +@@ -1809,7 +1808,7 @@ try_again: + } + #endif + } +- if (c->force && !clean && content->array.level != LEVEL_CONTAINER && ++ if (c->force && !clean && !is_container(content->array.level) && + !enough(content->array.level, content->array.raid_disks, + content->array.layout, clean, avail)) { + change += st->ss->update_super(st, content, "force-array", +diff --git a/Create.c b/Create.c +index e06ec2ae..953e7372 100644 +--- a/Create.c ++++ b/Create.c +@@ -487,7 +487,7 @@ int Create(struct supertype *st, char *mddev, + st->minor_version >= 1) + /* metadata at front */ + warn |= check_partitions(fd, dname, 0, 0); +- else if (s->level == 1 || s->level == LEVEL_CONTAINER || ++ else if (s->level == 1 || is_container(s->level) || + (s->level == 0 && s->raiddisks == 1)) + /* partitions could be meaningful */ + warn |= check_partitions(fd, dname, freesize*2, s->size*2); +@@ -997,7 +997,7 @@ int Create(struct supertype *st, char *mddev, + * again returns container info. + */ + st->ss->getinfo_super(st, &info_new, NULL); +- if (st->ss->external && s->level != LEVEL_CONTAINER && ++ if (st->ss->external && !is_container(s->level) && + !same_uuid(info_new.uuid, info.uuid, 0)) { + map_update(&map, fd2devnm(mdfd), + info_new.text_version, +@@ -1040,7 +1040,7 @@ int Create(struct supertype *st, char *mddev, + map_unlock(&map); + free(infos); + +- if (s->level == LEVEL_CONTAINER) { ++ if (is_container(s->level)) { + /* No need to start. But we should signal udev to + * create links */ + sysfs_uevent(&info, "change"); +diff --git a/Grow.c b/Grow.c +index 0f07a894..e362403a 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2175,7 +2175,7 @@ size_change_error: + devname, s->size); + } + changed = 1; +- } else if (array.level != LEVEL_CONTAINER) { ++ } else if (!is_container(array.level)) { + s->size = get_component_size(fd)/2; + if (s->size == 0) + s->size = array.size; +@@ -2231,7 +2231,7 @@ size_change_error: + info.component_size = s->size*2; + info.new_level = s->level; + info.new_chunk = s->chunk * 1024; +- if (info.array.level == LEVEL_CONTAINER) { ++ if (is_container(info.array.level)) { + info.delta_disks = UnSet; + info.array.raid_disks = s->raiddisks; + } else if (s->raiddisks) +@@ -2344,7 +2344,7 @@ size_change_error: + printf("layout for %s set to %d\n", + devname, array.layout); + } +- } else if (array.level == LEVEL_CONTAINER) { ++ } else if (is_container(array.level)) { + /* This change is to be applied to every array in the + * container. This is only needed when the metadata imposes + * restraints of the various arrays in the container. +diff --git a/Incremental.c b/Incremental.c +index 4d0cd9d6..5a5f4c4c 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -244,7 +244,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + c->autof = ci->autof; + + name_to_use = info.name; +- if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) { ++ if (name_to_use[0] == 0 && is_container(info.array.level)) { + name_to_use = info.text_version; + trustworthy = METADATA; + } +@@ -472,7 +472,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + + /* 7/ Is there enough devices to possibly start the array? */ + /* 7a/ if not, finish with success. */ +- if (info.array.level == LEVEL_CONTAINER) { ++ if (is_container(info.array.level)) { + char devnm[32]; + /* Try to assemble within the container */ + sysfs_uevent(sra, "change"); +diff --git a/mdadm.h b/mdadm.h +index 941a5f38..3673494e 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1924,3 +1924,17 @@ enum r0layout { + * This is true for native and DDF, IMSM allows 16. + */ + #define MD_NAME_MAX 32 ++ ++/** ++ * is_container() - check if @level is &LEVEL_CONTAINER ++ * @level: level value ++ * ++ * return: ++ * 1 if level is equal to &LEVEL_CONTAINER, 0 otherwise. ++ */ ++static inline int is_container(const int level) ++{ ++ if (level == LEVEL_CONTAINER) ++ return 1; ++ return 0; ++} +diff --git a/super-ddf.c b/super-ddf.c +index 949e7d15..9d1e3b94 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3325,7 +3325,7 @@ validate_geometry_ddf_container(struct supertype *st, + int fd; + unsigned long long ldsize; + +- if (level != LEVEL_CONTAINER) ++ if (!is_container(level)) + return 0; + if (!dev) + return 1; +@@ -3371,7 +3371,7 @@ static int validate_geometry_ddf(struct supertype *st, + + if (level == LEVEL_NONE) + level = LEVEL_CONTAINER; +- if (level == LEVEL_CONTAINER) { ++ if (is_container(level)) { + /* Must be a fresh device to add to a container */ + return validate_geometry_ddf_container(st, level, raiddisks, + data_offset, dev, +@@ -3488,7 +3488,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + struct dl *dl; + unsigned long long maxsize; + /* ddf/bvd supports lots of things, but not containers */ +- if (level == LEVEL_CONTAINER) { ++ if (is_container(level)) { + if (verbose) + pr_err("DDF cannot create a container within an container\n"); + return 0; +diff --git a/super-intel.c b/super-intel.c +index 4d82af3d..b0565610 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6727,7 +6727,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, + struct intel_super *super = NULL; + int rv = 0; + +- if (level != LEVEL_CONTAINER) ++ if (!is_container(level)) + return 0; + if (!dev) + return 1; +@@ -7692,7 +7692,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + * if given unused devices create a container + * if given given devices in a container create a member volume + */ +- if (level == LEVEL_CONTAINER) ++ if (is_container(level)) + /* Must be a fresh device to add to a container */ + return validate_geometry_imsm_container(st, level, raiddisks, + data_offset, dev, +diff --git a/super0.c b/super0.c +index 37f595ed..93876e2e 100644 +--- a/super0.c ++++ b/super0.c +@@ -1273,7 +1273,7 @@ static int validate_geometry0(struct supertype *st, int level, + if (get_linux_version() < 3001000) + tbmax = 2; + +- if (level == LEVEL_CONTAINER) { ++ if (is_container(level)) { + if (verbose) + pr_err("0.90 metadata does not support containers\n"); + return 0; +diff --git a/super1.c b/super1.c +index 58345e68..0b505a7e 100644 +--- a/super1.c ++++ b/super1.c +@@ -2830,7 +2830,7 @@ static int validate_geometry1(struct supertype *st, int level, + unsigned long long overhead; + int fd; + +- if (level == LEVEL_CONTAINER) { ++ if (is_container(level)) { + if (verbose) + pr_err("1.x metadata does not support containers\n"); + return 0; +diff --git a/sysfs.c b/sysfs.c +index 0d98a65f..ca1d888f 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -763,7 +763,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) + + rv = sysfs_set_num(sra, sd, "offset", sd->data_offset); + rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2); +- if (sra->array.level != LEVEL_CONTAINER) { ++ if (!is_container(sra->array.level)) { + if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) { + rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector); + rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size); +-- +2.38.1 + diff --git a/0061-Mdmonitor-Omit-non-md-devices.patch b/0061-Mdmonitor-Omit-non-md-devices.patch new file mode 100644 index 0000000..062ecdf --- /dev/null +++ b/0061-Mdmonitor-Omit-non-md-devices.patch @@ -0,0 +1,58 @@ +From 8b668d4aa3305af5963162b7499b128bd71f8f29 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Thu, 22 Sep 2022 08:29:50 +0200 +Subject: [PATCH 61/83] Mdmonitor: Omit non-md devices + +Fix segfault commit [1] introduced check whether given device is +mddevice, but it happend to terminate Mdmonitor if at least one of given +devices didn't fulfill that condition. In result Mdmonitor service was +no longer started on boot (with --scan option) when config contained some +non-existent array entry. + +This commit introduces ommiting non-md devices so scan option can still +be used when config is wrong and allow Mdmonitor service to run on boot. + +Giving a list of devices to monitor containing non-existing or +non-md devices will result in monitoring only confirmed mddevices. + +[1] https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=e702f392959d1c2ad2089e595b52235ed97b4e18 + +Signed-off-by: Lukasz Florczak +Signed-off-by: Jes Sorensen +--- + Monitor.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index b4e954c6..7d7dc4d2 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -185,10 +185,8 @@ int Monitor(struct mddev_dev *devlist, + continue; + if (strcasecmp(mdlist->devname, "") == 0) + continue; +- if (!is_mddev(mdlist->devname)) { +- free_statelist(statelist); +- return 1; +- } ++ if (!is_mddev(mdlist->devname)) ++ continue; + + st = xcalloc(1, sizeof *st); + snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), +@@ -208,10 +206,8 @@ int Monitor(struct mddev_dev *devlist, + for (dv = devlist; dv; dv = dv->next) { + struct state *st; + +- if (!is_mddev(dv->devname)) { +- free_statelist(statelist); +- return 1; +- } ++ if (!is_mddev(dv->devname)) ++ continue; + + st = xcalloc(1, sizeof *st); + mdlist = conf_get_ident(dv->devname); +-- +2.38.1 + diff --git a/0062-Mdmonitor-Split-alert-into-separate-functions.patch b/0062-Mdmonitor-Split-alert-into-separate-functions.patch new file mode 100644 index 0000000..c7562e7 --- /dev/null +++ b/0062-Mdmonitor-Split-alert-into-separate-functions.patch @@ -0,0 +1,233 @@ +From 3698867194f27fdd7824b8bdd172d619a2c087cc Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Wed, 7 Sep 2022 14:56:49 +0200 +Subject: [PATCH 62/83] Mdmonitor: Split alert() into separate functions + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Monitor.c | 186 ++++++++++++++++++++++++++++-------------------------- + 1 file changed, 95 insertions(+), 91 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 7d7dc4d2..0036e8cd 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -66,7 +66,7 @@ struct alert_info { + static int make_daemon(char *pidfile); + static int check_one_sharer(int scan); + static void write_autorebuild_pid(void); +-static void alert(char *event, char *dev, char *disc, struct alert_info *info); ++static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); + static int check_array(struct state *st, struct mdstat_ent *mdstat, + int test, struct alert_info *info, + int increments, char *prefer); +@@ -407,111 +407,115 @@ static void write_autorebuild_pid() + } + } + +-static void alert(char *event, char *dev, char *disc, struct alert_info *info) ++static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) ++{ ++ int pid = fork(); ++ ++ switch (pid) { ++ default: ++ waitpid(pid, NULL, 0); ++ break; ++ case -1: ++ pr_err("Cannot fork to execute alert command"); ++ break; ++ case 0: ++ execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); ++ exit(2); ++ } ++} ++ ++static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) ++{ ++ FILE *mp, *mdstat; ++ char hname[256]; ++ char buf[BUFSIZ]; ++ int n; ++ ++ mp = popen(Sendmail, "w"); ++ if (!mp) { ++ pr_err("Cannot open pipe stream for sendmail.\n"); ++ return; ++ } ++ ++ gethostname(hname, sizeof(hname)); ++ signal(SIGPIPE, SIG_IGN); ++ if (info->mailfrom) ++ fprintf(mp, "From: %s\n", info->mailfrom); ++ else ++ fprintf(mp, "From: %s monitoring \n", Name); ++ fprintf(mp, "To: %s\n", info->mailaddr); ++ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); ++ fprintf(mp, "This is an automatically generated mail message. \n"); ++ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); ++ ++ if (disc && disc[0] != ' ') ++ fprintf(mp, ++ "It could be related to component device %s.\n\n", disc); ++ if (disc && disc[0] == ' ') ++ fprintf(mp, "Extra information:%s.\n\n", disc); ++ ++ mdstat = fopen("/proc/mdstat", "r"); ++ if (!mdstat) { ++ pr_err("Cannot open /proc/mdstat\n"); ++ pclose(mp); ++ return; ++ } ++ ++ fprintf(mp, "The /proc/mdstat file currently contains the following:\n\n"); ++ while ((n = fread(buf, 1, sizeof(buf), mdstat)) > 0) ++ n = fwrite(buf, 1, n, mp); ++ fclose(mdstat); ++ pclose(mp); ++} ++ ++static void log_event_to_syslog(const char *event, const char *dev, const char *disc) + { + int priority; ++ /* Log at a different severity depending on the event. ++ * ++ * These are the critical events: */ ++ if (strncmp(event, "Fail", 4) == 0 || ++ strncmp(event, "Degrade", 7) == 0 || ++ strncmp(event, "DeviceDisappeared", 17) == 0) ++ priority = LOG_CRIT; ++ /* Good to know about, but are not failures: */ ++ else if (strncmp(event, "Rebuild", 7) == 0 || ++ strncmp(event, "MoveSpare", 9) == 0 || ++ strncmp(event, "Spares", 6) != 0) ++ priority = LOG_WARNING; ++ /* Everything else: */ ++ else ++ priority = LOG_INFO; + ++ if (disc && disc[0] != ' ') ++ syslog(priority, ++ "%s event detected on md device %s, component device %s", event, dev, disc); ++ else if (disc) ++ syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); ++ else ++ syslog(priority, "%s event detected on md device %s", event, dev); ++} ++ ++static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) ++{ + if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { + time_t now = time(0); + + printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, + event, dev, disc?disc:"unknown device"); + } +- if (info->alert_cmd) { +- int pid = fork(); +- switch(pid) { +- default: +- waitpid(pid, NULL, 0); +- break; +- case -1: +- break; +- case 0: +- execl(info->alert_cmd, info->alert_cmd, +- event, dev, disc, NULL); +- exit(2); +- } +- } ++ if (info->alert_cmd) ++ execute_alert_cmd(event, dev, disc, info); ++ + if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || + strncmp(event, "Test", 4) == 0 || + strncmp(event, "Spares", 6) == 0 || + strncmp(event, "Degrade", 7) == 0)) { +- FILE *mp = popen(Sendmail, "w"); +- if (mp) { +- FILE *mdstat; +- char hname[256]; +- +- gethostname(hname, sizeof(hname)); +- signal_s(SIGPIPE, SIG_IGN); +- +- if (info->mailfrom) +- fprintf(mp, "From: %s\n", info->mailfrom); +- else +- fprintf(mp, "From: %s monitoring \n", +- Name); +- fprintf(mp, "To: %s\n", info->mailaddr); +- fprintf(mp, "Subject: %s event on %s:%s\n\n", +- event, dev, hname); +- +- fprintf(mp, +- "This is an automatically generated mail message from %s\n", Name); +- fprintf(mp, "running on %s\n\n", hname); +- +- fprintf(mp, +- "A %s event had been detected on md device %s.\n\n", event, dev); +- +- if (disc && disc[0] != ' ') +- fprintf(mp, +- "It could be related to component device %s.\n\n", disc); +- if (disc && disc[0] == ' ') +- fprintf(mp, "Extra information:%s.\n\n", disc); +- +- fprintf(mp, "Faithfully yours, etc.\n"); +- +- mdstat = fopen("/proc/mdstat", "r"); +- if (mdstat) { +- char buf[8192]; +- int n; +- fprintf(mp, +- "\nP.S. The /proc/mdstat file currently contains the following:\n\n"); +- while ((n = fread(buf, 1, sizeof(buf), +- mdstat)) > 0) +- n = fwrite(buf, 1, n, mp); +- fclose(mdstat); +- } +- pclose(mp); +- } ++ send_event_email(event, dev, disc, info); + } + +- /* log the event to syslog maybe */ +- if (info->dosyslog) { +- /* Log at a different severity depending on the event. +- * +- * These are the critical events: */ +- if (strncmp(event, "Fail", 4) == 0 || +- strncmp(event, "Degrade", 7) == 0 || +- strncmp(event, "DeviceDisappeared", 17) == 0) +- priority = LOG_CRIT; +- /* Good to know about, but are not failures: */ +- else if (strncmp(event, "Rebuild", 7) == 0 || +- strncmp(event, "MoveSpare", 9) == 0 || +- strncmp(event, "Spares", 6) != 0) +- priority = LOG_WARNING; +- /* Everything else: */ +- else +- priority = LOG_INFO; +- +- if (disc && disc[0] != ' ') +- syslog(priority, +- "%s event detected on md device %s, component device %s", event, dev, disc); +- else if (disc) +- syslog(priority, +- "%s event detected on md device %s: %s", +- event, dev, disc); +- else +- syslog(priority, +- "%s event detected on md device %s", +- event, dev); +- } ++ if (info->dosyslog) ++ log_event_to_syslog(event, dev, disc); + } + + static int check_array(struct state *st, struct mdstat_ent *mdstat, +-- +2.38.1 + diff --git a/0063-Monitor-block-if-monitor-modes-are-combined.patch b/0063-Monitor-block-if-monitor-modes-are-combined.patch new file mode 100644 index 0000000..d993d9d --- /dev/null +++ b/0063-Monitor-block-if-monitor-modes-are-combined.patch @@ -0,0 +1,41 @@ +From f40ac0e7e6043361ad12e9db97c07e56c3977cf6 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 19 Dec 2022 11:21:57 +0100 +Subject: [PATCH 63/83] Monitor: block if monitor modes are combined. + +Block monitoring start if --scan mode and MD devices list are combined. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + Monitor.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/Monitor.c b/Monitor.c +index 0036e8cd..188cb8be 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -123,7 +123,7 @@ int Monitor(struct mddev_dev *devlist, + * and if we can get_disk_info and find a name + * Then we hot-remove and hot-add to the other array + * +- * If devlist is NULL, then we can monitor everything because --scan ++ * If devlist is NULL, then we can monitor everything if --scan + * was given. We get an initial list from config file and add anything + * that appears in /proc/mdstat + */ +@@ -136,6 +136,11 @@ int Monitor(struct mddev_dev *devlist, + struct mddev_ident *mdlist; + int delay_for_event = c->delay; + ++ if (devlist && c->scan) { ++ pr_err("Devices list and --scan option cannot be combined - not monitoring.\n"); ++ return 1; ++ } ++ + if (!mailaddr) + mailaddr = conf_get_mailaddr(); + +-- +2.38.1 + diff --git a/0064-Update-mdadm-Monitor-manual.patch b/0064-Update-mdadm-Monitor-manual.patch new file mode 100644 index 0000000..15f52e1 --- /dev/null +++ b/0064-Update-mdadm-Monitor-manual.patch @@ -0,0 +1,119 @@ +From 725e37cd14866906ba28c970394b9f7a4cd97413 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 19 Dec 2022 11:21:58 +0100 +Subject: [PATCH 64/83] Update mdadm Monitor manual. + +- describe monitor work modes, +- clarify the turning off condition, +- describe the mdmonitor.service as a prefered management way. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 71 ++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 21 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 70c79d1e..64f71ed1 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -2548,13 +2548,33 @@ Usage: + .I options... devices... + + .PP +-This usage causes ++Monitor option can work in two modes: ++.IP \(bu 4 ++system wide mode, follow all md devices based on ++.B /proc/mdstat, ++.IP \(bu 4 ++follow only specified MD devices in command line. ++.PP ++ ++.B \-\-scan - ++indicates system wide mode. Option causes the ++.I monitor ++to track all md devices that appear in ++.B /proc/mdstat. ++If it is not set, then at least one ++.B device ++must be specified. ++ ++Monitor usage causes + .I mdadm + to periodically poll a number of md arrays and to report on any events + noticed. +-.I mdadm +-will never exit once it decides that there are arrays to be checked, +-so it should normally be run in the background. ++ ++In both modes, ++.I monitor ++will work as long as there is an active array with redundancy and it is defined to follow (for ++.B \-\-scan ++every array is followed). + + As well as reporting events, + .I mdadm +@@ -2565,15 +2585,6 @@ or + .B domain + and if the destination array has a failed drive but no spares. + +-If any devices are listed on the command line, +-.I mdadm +-will only monitor those devices, otherwise, all arrays listed in the +-configuration file will be monitored. Further, if +-.B \-\-scan +-is given, then any other md devices that appear in +-.B /proc/mdstat +-will also be monitored. +- + The result of monitoring the arrays is the generation of events. + These events are passed to a separate program (if specified) and may + be mailed to a given E-mail address. +@@ -2586,16 +2597,34 @@ device if relevant (such as a component device that has failed). + + If + .B \-\-scan +-is given, then a program or an E-mail address must be specified on the +-command line or in the config file. If neither are available, then ++is given, then a ++.B program ++or an ++.B e-mail ++address must be specified on the ++command line or in the config file. If neither are available, then + .I mdadm + will not monitor anything. +-Without +-.B \-\-scan, +-.I mdadm +-will continue monitoring as long as something was found to monitor. If +-no program or email is given, then each event is reported to +-.BR stdout . ++For devices given directly in command line, without ++.B program ++or ++.B email ++specified, each event is reported to ++.BR stdout. ++ ++Note: For systems where ++.If mdadm monitor ++is configured via systemd, ++.B mdmonitor(mdmonitor.service) ++should be configured. The service is designed to be primary solution for array monitoring, ++it is configured to work in system wide mode. ++It is automatically started and stopped according to current state and types of MD arrays in system. ++The service may require additional configuration, like ++.B e-mail ++or ++.B delay. ++That should be done in ++.B mdadm.conf. + + The different events are: + +-- +2.38.1 + diff --git a/0065-Grow-fix-possible-memory-leak.patch b/0065-Grow-fix-possible-memory-leak.patch new file mode 100644 index 0000000..07d9fb6 --- /dev/null +++ b/0065-Grow-fix-possible-memory-leak.patch @@ -0,0 +1,38 @@ +From 434b3b9bb96a76dc12f693b64cf23b581781e20b Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Tue, 20 Dec 2022 12:07:51 +0100 +Subject: [PATCH 65/83] Grow: fix possible memory leak. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + Grow.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index e362403a..b73ec2ae 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -432,6 +432,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && + (strcmp(s->bitmap_file, "clustered") == 0)) { + pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); ++ free(mdi); + return 1; + } + fd2 = dev_open(dv, O_RDWR); +@@ -453,8 +454,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + pr_err("failed to load super-block.\n"); + } + close(fd2); +- if (rv) ++ if (rv) { ++ free(mdi); + return 1; ++ } + } + if (offset_setable) { + st->ss->getinfo_super(st, mdi, NULL); +-- +2.38.1 + diff --git a/0066-mdadm-create-ident_init.patch b/0066-mdadm-create-ident_init.patch new file mode 100644 index 0000000..32d374b --- /dev/null +++ b/0066-mdadm-create-ident_init.patch @@ -0,0 +1,148 @@ +From 7fcbfd7c620e2dcd3b539d18e93cb503ee3a8a62 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 21 Dec 2022 12:50:17 +0100 +Subject: [PATCH 66/83] mdadm: create ident_init() + +Add a wrapper for repeated initializations in mdadm.c and config.c. +Move includes up. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + config.c | 45 +++++++++++++++++++++++++++++---------------- + mdadm.c | 16 ++-------------- + mdadm.h | 7 +++++-- + 3 files changed, 36 insertions(+), 32 deletions(-) + +diff --git a/config.c b/config.c +index dc1620c1..eeedd0c6 100644 +--- a/config.c ++++ b/config.c +@@ -119,6 +119,34 @@ int match_keyword(char *word) + return -1; + } + ++/** ++ * ident_init() - Set defaults. ++ * @ident: ident pointer, not NULL. ++ */ ++inline void ident_init(struct mddev_ident *ident) ++{ ++ assert(ident); ++ ++ ident->assembled = false; ++ ident->autof = 0; ++ ident->bitmap_fd = -1; ++ ident->bitmap_file = NULL; ++ ident->container = NULL; ++ ident->devices = NULL; ++ ident->devname = NULL; ++ ident->level = UnSet; ++ ident->member = NULL; ++ ident->name[0] = 0; ++ ident->next = NULL; ++ ident->raid_disks = UnSet; ++ ident->spare_group = NULL; ++ ident->spare_disks = 0; ++ ident->st = NULL; ++ ident->super_minor = UnSet; ++ ident->uuid[0] = 0; ++ ident->uuid_set = 0; ++} ++ + struct conf_dev { + struct conf_dev *next; + char *name; +@@ -363,22 +391,7 @@ void arrayline(char *line) + struct mddev_ident mis; + struct mddev_ident *mi; + +- mis.uuid_set = 0; +- mis.super_minor = UnSet; +- mis.level = UnSet; +- mis.raid_disks = UnSet; +- mis.spare_disks = 0; +- mis.devices = NULL; +- mis.devname = NULL; +- mis.spare_group = NULL; +- mis.autof = 0; +- mis.next = NULL; +- mis.st = NULL; +- mis.bitmap_fd = -1; +- mis.bitmap_file = NULL; +- mis.name[0] = 0; +- mis.container = NULL; +- mis.member = NULL; ++ ident_init(&mis); + + for (w = dl_next(line); w != line; w = dl_next(w)) { + if (w[0] == '/' || strchr(w, '=') == NULL) { +diff --git a/mdadm.c b/mdadm.c +index 972adb52..74fdec31 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -107,25 +107,13 @@ int main(int argc, char *argv[]) + + srandom(time(0) ^ getpid()); + +- ident.uuid_set = 0; +- ident.level = UnSet; +- ident.raid_disks = UnSet; +- ident.super_minor = UnSet; +- ident.devices = 0; +- ident.spare_group = NULL; +- ident.autof = 0; +- ident.st = NULL; +- ident.bitmap_fd = -1; +- ident.bitmap_file = NULL; +- ident.name[0] = 0; +- ident.container = NULL; +- ident.member = NULL; +- + if (get_linux_version() < 2006015) { + pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); + exit(1); + } + ++ ident_init(&ident); ++ + while ((option_index = -1), + (opt = getopt_long(argc, argv, shortopt, long_options, + &option_index)) != -1) { +diff --git a/mdadm.h b/mdadm.h +index 3673494e..23ffe977 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); + # endif + #endif + ++#include + #include + #include ++#include + #include + #include + #include +@@ -1552,6 +1554,8 @@ extern void enable_fds(int devices); + extern void manage_fork_fds(int close_all); + extern int continue_via_systemd(char *devnm, char *service_name); + ++extern void ident_init(struct mddev_ident *ident); ++ + extern int parse_auto(char *str, char *msg, int config); + extern struct mddev_ident *conf_get_ident(char *dev); + extern struct mddev_dev *conf_get_devs(void); +@@ -1779,8 +1783,7 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler) + #define dprintf_cont(fmt, arg...) \ + ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) + #endif +-#include +-#include ++ + static inline int xasprintf(char **strp, const char *fmt, ...) { + va_list ap; + int ret; +-- +2.38.1 + diff --git a/0067-mdadm-Add-option-validation-for-update-subarray.patch b/0067-mdadm-Add-option-validation-for-update-subarray.patch new file mode 100644 index 0000000..faa7113 --- /dev/null +++ b/0067-mdadm-Add-option-validation-for-update-subarray.patch @@ -0,0 +1,287 @@ +From 2568ce89ea5c26225e8984733adc2ea7559d853a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:15 +0100 +Subject: [PATCH 67/83] mdadm: Add option validation for --update-subarray + +Subset of options available for "--update" is not same as for "--update-subarray". +Define maps and enum for update options and use them instead of direct comparisons. +Add proper error message. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + ReadMe.c | 31 +++++++++++++++++ + maps.c | 31 +++++++++++++++++ + mdadm.c | 104 +++++++++++++++++-------------------------------------- + mdadm.h | 32 ++++++++++++++++- + 4 files changed, 124 insertions(+), 74 deletions(-) + +diff --git a/ReadMe.c b/ReadMe.c +index 50a5e36d..bd8d50d2 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -655,3 +655,34 @@ char *mode_help[mode_count] = { + [GROW] = Help_grow, + [INCREMENTAL] = Help_incr, + }; ++ ++/** ++ * fprint_update_options() - Print valid update options depending on the mode. ++ * @outf: File (output stream) ++ * @update_mode: Used to distinguish update and update_subarray ++ */ ++void fprint_update_options(FILE *outf, enum update_opt update_mode) ++{ ++ int counter = UOPT_NAME, breakpoint = UOPT_HELP; ++ mapping_t *map = update_options; ++ ++ if (!outf) ++ return; ++ if (update_mode == UOPT_SUBARRAY_ONLY) { ++ breakpoint = UOPT_SUBARRAY_ONLY; ++ fprintf(outf, "Valid --update options for update-subarray are:\n\t"); ++ } else ++ fprintf(outf, "Valid --update options are:\n\t"); ++ while (map->num) { ++ if (map->num >= breakpoint) ++ break; ++ fprintf(outf, "'%s', ", map->name); ++ if (counter % 5 == 0) ++ fprintf(outf, "\n\t"); ++ counter++; ++ map++; ++ } ++ if ((counter - 1) % 5) ++ fprintf(outf, "\n"); ++ fprintf(outf, "\r"); ++} +diff --git a/maps.c b/maps.c +index 20fcf719..b586679a 100644 +--- a/maps.c ++++ b/maps.c +@@ -165,6 +165,37 @@ mapping_t sysfs_array_states[] = { + { "broken", ARRAY_BROKEN }, + { NULL, ARRAY_UNKNOWN_STATE } + }; ++/** ++ * mapping_t update_options - stores supported update options. ++ */ ++mapping_t update_options[] = { ++ { "name", UOPT_NAME }, ++ { "ppl", UOPT_PPL }, ++ { "no-ppl", UOPT_NO_PPL }, ++ { "bitmap", UOPT_BITMAP }, ++ { "no-bitmap", UOPT_NO_BITMAP }, ++ { "sparc2.2", UOPT_SPARC22 }, ++ { "super-minor", UOPT_SUPER_MINOR }, ++ { "summaries", UOPT_SUMMARIES }, ++ { "resync", UOPT_RESYNC }, ++ { "uuid", UOPT_UUID }, ++ { "homehost", UOPT_HOMEHOST }, ++ { "home-cluster", UOPT_HOME_CLUSTER }, ++ { "nodes", UOPT_NODES }, ++ { "devicesize", UOPT_DEVICESIZE }, ++ { "bbl", UOPT_BBL }, ++ { "no-bbl", UOPT_NO_BBL }, ++ { "force-no-bbl", UOPT_FORCE_NO_BBL }, ++ { "metadata", UOPT_METADATA }, ++ { "revert-reshape", UOPT_REVERT_RESHAPE }, ++ { "layout-original", UOPT_LAYOUT_ORIGINAL }, ++ { "layout-alternate", UOPT_LAYOUT_ALTERNATE }, ++ { "layout-unspecified", UOPT_LAYOUT_UNSPECIFIED }, ++ { "byteorder", UOPT_BYTEORDER }, ++ { "help", UOPT_HELP }, ++ { "?", UOPT_HELP }, ++ { NULL, UOPT_UNDEFINED} ++}; + + /** + * map_num_s() - Safer alternative of map_num() function. +diff --git a/mdadm.c b/mdadm.c +index 74fdec31..f5f505fe 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -100,7 +100,7 @@ int main(int argc, char *argv[]) + char *dump_directory = NULL; + + int print_help = 0; +- FILE *outf; ++ FILE *outf = NULL; + + int mdfd = -1; + int locked = 0; +@@ -723,7 +723,11 @@ int main(int argc, char *argv[]) + continue; + + case O(ASSEMBLE,'U'): /* update the superblock */ +- case O(MISC,'U'): ++ case O(MISC,'U'): { ++ enum update_opt updateopt = map_name(update_options, c.update); ++ enum update_opt print_mode = UOPT_HELP; ++ const char *error_addon = "update option"; ++ + if (c.update) { + pr_err("Can only update one aspect of superblock, both %s and %s given.\n", + c.update, optarg); +@@ -733,83 +737,37 @@ int main(int argc, char *argv[]) + pr_err("Only subarrays can be updated in misc mode\n"); + exit(2); + } ++ + c.update = optarg; +- if (strcmp(c.update, "sparc2.2") == 0) +- continue; +- if (strcmp(c.update, "super-minor") == 0) +- continue; +- if (strcmp(c.update, "summaries") == 0) +- continue; +- if (strcmp(c.update, "resync") == 0) +- continue; +- if (strcmp(c.update, "uuid") == 0) +- continue; +- if (strcmp(c.update, "name") == 0) +- continue; +- if (strcmp(c.update, "homehost") == 0) +- continue; +- if (strcmp(c.update, "home-cluster") == 0) +- continue; +- if (strcmp(c.update, "nodes") == 0) +- continue; +- if (strcmp(c.update, "devicesize") == 0) +- continue; +- if (strcmp(c.update, "bitmap") == 0) +- continue; +- if (strcmp(c.update, "no-bitmap") == 0) +- continue; +- if (strcmp(c.update, "bbl") == 0) +- continue; +- if (strcmp(c.update, "no-bbl") == 0) +- continue; +- if (strcmp(c.update, "force-no-bbl") == 0) +- continue; +- if (strcmp(c.update, "ppl") == 0) +- continue; +- if (strcmp(c.update, "no-ppl") == 0) +- continue; +- if (strcmp(c.update, "metadata") == 0) +- continue; +- if (strcmp(c.update, "revert-reshape") == 0) +- continue; +- if (strcmp(c.update, "layout-original") == 0 || +- strcmp(c.update, "layout-alternate") == 0 || +- strcmp(c.update, "layout-unspecified") == 0) +- continue; +- if (strcmp(c.update, "byteorder") == 0) { ++ ++ if (devmode == UpdateSubarray) { ++ print_mode = UOPT_SUBARRAY_ONLY; ++ error_addon = "update-subarray option"; ++ ++ if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) ++ updateopt = UOPT_UNDEFINED; ++ } ++ ++ switch (updateopt) { ++ case UOPT_UNDEFINED: ++ pr_err("'--update=%s' is invalid %s. ", ++ c.update, error_addon); ++ outf = stderr; ++ case UOPT_HELP: ++ if (!outf) ++ outf = stdout; ++ fprint_update_options(outf, print_mode); ++ exit(outf == stdout ? 0 : 2); ++ case UOPT_BYTEORDER: + if (ss) { + pr_err("must not set metadata type with --update=byteorder.\n"); + exit(2); + } +- for(i = 0; !ss && superlist[i]; i++) +- ss = superlist[i]->match_metadata_desc( +- "0.swap"); +- if (!ss) { +- pr_err("INTERNAL ERROR cannot find 0.swap\n"); +- exit(2); +- } +- +- continue; ++ default: ++ break; + } +- if (strcmp(c.update,"?") == 0 || +- strcmp(c.update, "help") == 0) { +- outf = stdout; +- fprintf(outf, "%s: ", Name); +- } else { +- outf = stderr; +- fprintf(outf, +- "%s: '--update=%s' is invalid. ", +- Name, c.update); +- } +- fprintf(outf, "Valid --update options are:\n" +- " 'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n" +- " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n" +- " 'bitmap', 'no-bitmap', 'metadata', 'revert-reshape'\n" +- " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n" +- " 'layout-original', 'layout-alternate', 'layout-unspecified'\n" +- ); +- exit(outf == stdout ? 0 : 2); +- ++ continue; ++ } + case O(MANAGE,'U'): + /* update=devicesize is allowed with --re-add */ + if (devmode != 'A') { +diff --git a/mdadm.h b/mdadm.h +index 23ffe977..51f1db2d 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -497,6 +497,36 @@ enum special_options { + ConsistencyPolicy, + }; + ++enum update_opt { ++ UOPT_NAME = 1, ++ UOPT_PPL, ++ UOPT_NO_PPL, ++ UOPT_BITMAP, ++ UOPT_NO_BITMAP, ++ UOPT_SUBARRAY_ONLY, ++ UOPT_SPARC22, ++ UOPT_SUPER_MINOR, ++ UOPT_SUMMARIES, ++ UOPT_RESYNC, ++ UOPT_UUID, ++ UOPT_HOMEHOST, ++ UOPT_HOME_CLUSTER, ++ UOPT_NODES, ++ UOPT_DEVICESIZE, ++ UOPT_BBL, ++ UOPT_NO_BBL, ++ UOPT_FORCE_NO_BBL, ++ UOPT_METADATA, ++ UOPT_REVERT_RESHAPE, ++ UOPT_LAYOUT_ORIGINAL, ++ UOPT_LAYOUT_ALTERNATE, ++ UOPT_LAYOUT_UNSPECIFIED, ++ UOPT_BYTEORDER, ++ UOPT_HELP, ++ UOPT_UNDEFINED ++}; ++extern void fprint_update_options(FILE *outf, enum update_opt update_mode); ++ + enum prefix_standard { + JEDEC, + IEC +@@ -777,7 +807,7 @@ extern char *map_num(mapping_t *map, int num); + extern int map_name(mapping_t *map, char *name); + extern mapping_t r0layout[], r5layout[], r6layout[], + pers[], modes[], faultylayout[]; +-extern mapping_t consistency_policies[], sysfs_array_states[]; ++extern mapping_t consistency_policies[], sysfs_array_states[], update_options[]; + + extern char *map_dev_preferred(int major, int minor, int create, + char *prefer); +-- +2.38.1 + diff --git a/0068-Fix-update-subarray-on-active-volume.patch b/0068-Fix-update-subarray-on-active-volume.patch new file mode 100644 index 0000000..7c1c4bc --- /dev/null +++ b/0068-Fix-update-subarray-on-active-volume.patch @@ -0,0 +1,54 @@ +From db10eab68e652f141169b7240e057d110d626c3d Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:16 +0100 +Subject: [PATCH 68/83] Fix --update-subarray on active volume + +Options: bitmap, ppl and name should not be updated when array is active. +Those features are mutually exclusive and share the same data area in IMSM (danger of overwriting by kernel). +Remove check for active subarrays from super-intel. +Since ddf is not supported, apply it globally for all options. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Manage.c | 7 +++++++ + super-intel.c | 5 ----- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/Manage.c b/Manage.c +index b1d0e630..5a9ea316 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1745,6 +1745,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + goto free_super; + } + ++ if (is_subarray_active(subarray, st->devnm)) { ++ if (verbose >= 0) ++ pr_err("Subarray %s in %s is active, cannot update %s\n", ++ subarray, dev, update); ++ goto free_super; ++ } ++ + if (mdmon_running(st->devnm)) + st->update_tail = &st->updates; + +diff --git a/super-intel.c b/super-intel.c +index b0565610..5f93f3d3 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7914,11 +7914,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + char *ep; + int vol; + +- if (is_subarray_active(subarray, st->devnm)) { +- pr_err("Unable to update name of active subarray\n"); +- return 2; +- } +- + if (!check_name(super, name, 0)) + return 2; + +-- +2.38.1 + diff --git a/0069-Add-code-specific-update-options-to-enum.patch b/0069-Add-code-specific-update-options-to-enum.patch new file mode 100644 index 0000000..57386f5 --- /dev/null +++ b/0069-Add-code-specific-update-options-to-enum.patch @@ -0,0 +1,77 @@ +From 2257de106cbf17a7f1df33a10cfd2be0d5a064cb Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:17 +0100 +Subject: [PATCH 69/83] Add code specific update options to enum. + +Some of update options aren't taken from user input, but are hard-coded +as strings. +Include those options in enum. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + maps.c | 21 +++++++++++++++++++++ + mdadm.h | 15 +++++++++++++++ + 2 files changed, 36 insertions(+) + +diff --git a/maps.c b/maps.c +index b586679a..c59036f1 100644 +--- a/maps.c ++++ b/maps.c +@@ -194,6 +194,27 @@ mapping_t update_options[] = { + { "byteorder", UOPT_BYTEORDER }, + { "help", UOPT_HELP }, + { "?", UOPT_HELP }, ++ /* ++ * Those enries are temporary and will be removed in this patchset. ++ * ++ * Before update_super:update can be changed to enum, ++ * all update_super sub-functions must be adapted first. ++ * Update options will be passed as string (as it is for now), ++ * and then mapped, so all options must be handled temporarily. ++ * ++ * Those options code specific and should not be accessible for user. ++ */ ++ { "force-one", UOPT_SPEC_FORCE_ONE }, ++ { "force-array", UOPT_SPEC_FORCE_ARRAY }, ++ { "assemble", UOPT_SPEC_ASSEMBLE }, ++ { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, ++ { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, ++ { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, ++ { "writemostly", UOPT_SPEC_WRITEMOSTLY }, ++ { "readwrite", UOPT_SPEC_READWRITE }, ++ { "failfast", UOPT_SPEC_FAILFAST }, ++ { "nofailfast", UOPT_SPEC_NOFAILFAST }, ++ { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, + { NULL, UOPT_UNDEFINED} + }; + +diff --git a/mdadm.h b/mdadm.h +index 51f1db2d..31db25f5 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -523,6 +523,21 @@ enum update_opt { + UOPT_LAYOUT_UNSPECIFIED, + UOPT_BYTEORDER, + UOPT_HELP, ++ UOPT_USER_ONLY, ++ /* ++ * Code specific options, cannot be set by the user ++ */ ++ UOPT_SPEC_FORCE_ONE, ++ UOPT_SPEC_FORCE_ARRAY, ++ UOPT_SPEC_ASSEMBLE, ++ UOPT_SPEC_LINEAR_GROW_NEW, ++ UOPT_SPEC_LINEAR_GROW_UPDATE, ++ UOPT_SPEC__RESHAPE_PROGRESS, ++ UOPT_SPEC_WRITEMOSTLY, ++ UOPT_SPEC_READWRITE, ++ 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.38.1 + diff --git a/0070-super-ddf-Remove-update_super_ddf.patch b/0070-super-ddf-Remove-update_super_ddf.patch new file mode 100644 index 0000000..7a6d213 --- /dev/null +++ b/0070-super-ddf-Remove-update_super_ddf.patch @@ -0,0 +1,106 @@ +From 35aa44c549290e22f285896684c704acb53b7717 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:18 +0100 +Subject: [PATCH 70/83] super-ddf: Remove update_super_ddf. + +This is not supported by ddf. +It hides errors by returning success status for some updates. +Remove update_super_dff(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 70 ----------------------------------------------------- + 1 file changed, 70 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 9d1e3b94..309812df 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -2139,75 +2139,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha + } + } + +-static int update_super_ddf(struct supertype *st, struct mdinfo *info, +- char *update, +- char *devname, int verbose, +- int uuid_set, char *homehost) +-{ +- /* For 'assemble' and 'force' we need to return non-zero if any +- * change was made. For others, the return value is ignored. +- * Update options are: +- * force-one : This device looks a bit old but needs to be included, +- * update age info appropriately. +- * assemble: clear any 'faulty' flag to allow this device to +- * be assembled. +- * force-array: Array is degraded but being forced, mark it clean +- * if that will be needed to assemble it. +- * +- * newdev: not used ???? +- * grow: Array has gained a new device - this is currently for +- * linear only +- * resync: mark as dirty so a resync will happen. +- * uuid: Change the uuid of the array to match what is given +- * homehost: update the recorded homehost +- * name: update the name - preserving the homehost +- * _reshape_progress: record new reshape_progress position. +- * +- * Following are not relevant for this version: +- * sparc2.2 : update from old dodgey metadata +- * super-minor: change the preferred_minor number +- * summaries: update redundant counters. +- */ +- int rv = 0; +-// struct ddf_super *ddf = st->sb; +-// struct vd_config *vd = find_vdcr(ddf, info->container_member); +-// struct virtual_entry *ve = find_ve(ddf); +- +- /* we don't need to handle "force-*" or "assemble" as +- * there is no need to 'trick' the kernel. When the metadata is +- * first updated to activate the array, all the implied modifications +- * will just happen. +- */ +- +- if (strcmp(update, "grow") == 0) { +- /* FIXME */ +- } else if (strcmp(update, "resync") == 0) { +-// info->resync_checkpoint = 0; +- } else if (strcmp(update, "homehost") == 0) { +- /* homehost is stored in controller->vendor_data, +- * or it is when we are the vendor +- */ +-// if (info->vendor_is_local) +-// strcpy(ddf->controller.vendor_data, homehost); +- rv = -1; +- } else if (strcmp(update, "name") == 0) { +- /* name is stored in virtual_entry->name */ +-// memset(ve->name, ' ', 16); +-// strncpy(ve->name, info->name, 16); +- rv = -1; +- } else if (strcmp(update, "_reshape_progress") == 0) { +- /* We don't support reshape yet */ +- } else if (strcmp(update, "assemble") == 0 ) { +- /* Do nothing, just succeed */ +- rv = 0; +- } else +- rv = -1; +- +-// update_all_csum(ddf); +- +- return rv; +-} +- + static void make_header_guid(char *guid) + { + be32 stamp; +@@ -5211,7 +5142,6 @@ struct superswitch super_ddf = { + .match_home = match_home_ddf, + .uuid_from_super= uuid_from_super_ddf, + .getinfo_super = getinfo_super_ddf, +- .update_super = update_super_ddf, + + .avail_size = avail_size_ddf, + +-- +2.38.1 + diff --git a/0071-super0-refactor-the-code-for-enum.patch b/0071-super0-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..f01c534 --- /dev/null +++ b/0071-super0-refactor-the-code-for-enum.patch @@ -0,0 +1,212 @@ +From 0a9e39383d3bf63e1f5cf10f64200083a1af8091 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:19 +0100 +Subject: [PATCH 71/83] super0: refactor the code for enum + +It prepares update_super0 for change context->update to enum. +Change if else statements to switch. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + super0.c | 102 ++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 63 insertions(+), 39 deletions(-) + +diff --git a/super0.c b/super0.c +index 93876e2e..d9f5bff4 100644 +--- a/super0.c ++++ b/super0.c +@@ -502,19 +502,39 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + int rv = 0; + int uuid[4]; + mdp_super_t *sb = st->sb; ++ enum update_opt update_enum = map_name(update_options, update); + +- if (strcmp(update, "homehost") == 0 && +- homehost) { +- /* note that 'homehost' is special as it is really ++ if (update_enum == UOPT_HOMEHOST && homehost) { ++ /* ++ * note that 'homehost' is special as it is really + * a "uuid" update. + */ + uuid_set = 0; +- update = "uuid"; ++ update_enum = UOPT_UUID; + info->uuid[0] = sb->set_uuid0; + info->uuid[1] = sb->set_uuid1; + } + +- if (strcmp(update, "sparc2.2")==0 ) { ++ switch (update_enum) { ++ case UOPT_UUID: ++ if (!uuid_set && homehost) { ++ char buf[20]; ++ memcpy(info->uuid+2, ++ sha1_buffer(homehost, strlen(homehost), buf), ++ 8); ++ } ++ sb->set_uuid0 = info->uuid[0]; ++ sb->set_uuid1 = info->uuid[1]; ++ sb->set_uuid2 = info->uuid[2]; ++ sb->set_uuid3 = info->uuid[3]; ++ if (sb->state & (1<uuid, uuid, 16); ++ } ++ break; ++ case UOPT_SPARC22: { + /* 2.2 sparc put the events in the wrong place + * So we copy the tail of the superblock + * up 4 bytes before continuing +@@ -527,12 +547,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + if (verbose >= 0) + pr_err("adjusting superblock of %s for 2.2/sparc compatibility.\n", + devname); +- } else if (strcmp(update, "super-minor") ==0) { ++ break; ++ } ++ case UOPT_SUPER_MINOR: + sb->md_minor = info->array.md_minor; + if (verbose > 0) + pr_err("updating superblock of %s with minor number %d\n", + devname, info->array.md_minor); +- } else if (strcmp(update, "summaries") == 0) { ++ break; ++ case UOPT_SUMMARIES: { + unsigned int i; + /* set nr_disks, active_disks, working_disks, + * failed_disks, spare_disks based on disks[] +@@ -559,7 +582,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + sb->spare_disks++; + } else if (i >= sb->raid_disks && sb->disks[i].number == 0) + sb->disks[i].state = 0; +- } else if (strcmp(update, "force-one")==0) { ++ break; ++ } ++ case UOPT_SPEC_FORCE_ONE: { + /* Not enough devices for a working array, so + * bring this one up-to-date. + */ +@@ -569,7 +594,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + if (sb->events_hi != ehi || + sb->events_lo != elo) + rv = 1; +- } else if (strcmp(update, "force-array")==0) { ++ break; ++ } ++ case UOPT_SPEC_FORCE_ARRAY: + /* degraded array and 'force' requested, so + * maybe need to mark it 'clean' + */ +@@ -579,7 +606,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + sb->state |= (1 << MD_SB_CLEAN); + rv = 1; + } +- } else if (strcmp(update, "assemble")==0) { ++ break; ++ case UOPT_SPEC_ASSEMBLE: { + int d = info->disk.number; + int wonly = sb->disks[d].state & (1<disks[d].state & (1<reshape_position = info->reshape_progress; + rv = 1; + } +- } else if (strcmp(update, "linear-grow-new") == 0) { ++ break; ++ } ++ case UOPT_SPEC_LINEAR_GROW_NEW: + memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); + sb->disks[info->disk.number].number = info->disk.number; + sb->disks[info->disk.number].major = info->disk.major; +@@ -617,7 +647,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; + sb->disks[info->disk.number].state = info->disk.state; + sb->this_disk = sb->disks[info->disk.number]; +- } else if (strcmp(update, "linear-grow-update") == 0) { ++ break; ++ case UOPT_SPEC_LINEAR_GROW_UPDATE: + sb->raid_disks = info->array.raid_disks; + sb->nr_disks = info->array.nr_disks; + sb->active_disks = info->array.active_disks; +@@ -628,29 +659,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + sb->disks[info->disk.number].minor = info->disk.minor; + sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; + sb->disks[info->disk.number].state = info->disk.state; +- } else if (strcmp(update, "resync") == 0) { +- /* make sure resync happens */ ++ break; ++ case UOPT_RESYNC: ++ /* ++ * make sure resync happens ++ */ + sb->state &= ~(1<recovery_cp = 0; +- } else if (strcmp(update, "uuid") == 0) { +- if (!uuid_set && homehost) { +- char buf[20]; +- char *hash = sha1_buffer(homehost, +- strlen(homehost), +- buf); +- memcpy(info->uuid+2, hash, 8); +- } +- sb->set_uuid0 = info->uuid[0]; +- sb->set_uuid1 = info->uuid[1]; +- sb->set_uuid2 = info->uuid[2]; +- sb->set_uuid3 = info->uuid[3]; +- if (sb->state & (1<uuid, uuid, 16); +- } +- } else if (strcmp(update, "metadata") == 0) { ++ break; ++ case UOPT_METADATA: + /* Create some v1.0 metadata to match ours but make the + * ctime bigger. Also update info->array.*_version. + * We need to arrange that store_super writes out +@@ -670,7 +687,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + uuid_from_super0(st, info->uuid); + st->other = super1_make_v0(st, info, st->sb); + } +- } else if (strcmp(update, "revert-reshape") == 0) { ++ break; ++ case UOPT_REVERT_RESHAPE: + rv = -2; + if (sb->minor_version <= 90) + pr_err("No active reshape to revert on %s\n", +@@ -702,16 +720,22 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + sb->new_chunk = sb->chunk_size; + sb->chunk_size = tmp; + } +- } else if (strcmp(update, "no-bitmap") == 0) { ++ break; ++ case UOPT_NO_BITMAP: + sb->state &= ~(1<reshape_position = info->reshape_progress; +- else if (strcmp(update, "writemostly")==0) ++ break; ++ case UOPT_SPEC_WRITEMOSTLY: + sb->state |= (1<state &= ~(1<sb_csum = calc_sb0_csum(sb); + return rv; +-- +2.38.1 + diff --git a/0072-super1-refactor-the-code-for-enum.patch b/0072-super1-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..bd164b8 --- /dev/null +++ b/0072-super1-refactor-the-code-for-enum.patch @@ -0,0 +1,302 @@ +From 7e8daba8b7937716dce8ea28298a4e2e72cb829e Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:20 +0100 +Subject: [PATCH 72/83] super1: refactor the code for enum + +It prepares update_super1 for change context->update to enum. +Change if else statements into switch. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + super1.c | 152 +++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 91 insertions(+), 61 deletions(-) + +diff --git a/super1.c b/super1.c +index 0b505a7e..b0a97016 100644 +--- a/super1.c ++++ b/super1.c +@@ -1218,30 +1218,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + int rv = 0; + struct mdp_superblock_1 *sb = st->sb; + bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); ++ enum update_opt update_enum = map_name(update_options, update); + +- if (strcmp(update, "homehost") == 0 && +- homehost) { +- /* Note that 'homehost' is special as it is really ++ if (update_enum == UOPT_HOMEHOST && homehost) { ++ /* ++ * Note that 'homehost' is special as it is really + * a "name" update. + */ + char *c; +- update = "name"; ++ update_enum = UOPT_NAME; + c = strchr(sb->set_name, ':'); + if (c) +- strncpy(info->name, c+1, 31 - (c-sb->set_name)); ++ snprintf(info->name, sizeof(info->name), "%s", c+1); + else +- strncpy(info->name, sb->set_name, 32); +- info->name[32] = 0; ++ snprintf(info->name, sizeof(info->name), "%s", sb->set_name); + } + +- if (strcmp(update, "force-one")==0) { ++ switch (update_enum) { ++ case UOPT_NAME: { ++ int namelen; ++ ++ if (!info->name[0]) ++ snprintf(info->name, sizeof(info->name), "%d", info->array.md_minor); ++ memset(sb->set_name, 0, sizeof(sb->set_name)); ++ ++ namelen = strnlen(homehost, MD_NAME_MAX) + 1 + strnlen(info->name, MD_NAME_MAX); ++ if (homehost && ++ strchr(info->name, ':') == NULL && ++ namelen < MD_NAME_MAX) { ++ strcpy(sb->set_name, homehost); ++ strcat(sb->set_name, ":"); ++ strcat(sb->set_name, info->name); ++ } else { ++ namelen = min((int)strnlen(info->name, MD_NAME_MAX), ++ (int)sizeof(sb->set_name) - 1); ++ memcpy(sb->set_name, info->name, namelen); ++ memset(&sb->set_name[namelen], '\0', ++ sizeof(sb->set_name) - namelen); ++ } ++ break; ++ } ++ case UOPT_SPEC_FORCE_ONE: + /* Not enough devices for a working array, + * so bring this one up-to-date + */ + if (sb->events != __cpu_to_le64(info->events)) + rv = 1; + sb->events = __cpu_to_le64(info->events); +- } else if (strcmp(update, "force-array")==0) { ++ break; ++ case UOPT_SPEC_FORCE_ARRAY: + /* Degraded array and 'force' requests to + * maybe need to mark it 'clean'. + */ +@@ -1254,7 +1279,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + rv = 1; + sb->resync_offset = MaxSector; + } +- } else if (strcmp(update, "assemble")==0) { ++ break; ++ case UOPT_SPEC_ASSEMBLE: { + int d = info->disk.number; + int want; + if (info->disk.state & (1<reshape_progress); + rv = 1; + } +- } else if (strcmp(update, "linear-grow-new") == 0) { ++ break; ++ } ++ case UOPT_SPEC_LINEAR_GROW_NEW: { + int i; + int fd; + int max = __le32_to_cpu(sb->max_dev); +@@ -1330,7 +1358,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + ds - __le64_to_cpu(sb->data_offset)); + } + } +- } else if (strcmp(update, "linear-grow-update") == 0) { ++ break; ++ } ++ case UOPT_SPEC_LINEAR_GROW_UPDATE: { + int max = __le32_to_cpu(sb->max_dev); + int i = info->disk.number; + if (max > MAX_DEVS || i > MAX_DEVS) +@@ -1342,19 +1372,20 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->raid_disks = __cpu_to_le32(info->array.raid_disks); + sb->dev_roles[info->disk.number] = + __cpu_to_le16(info->disk.raid_disk); +- } else if (strcmp(update, "resync") == 0) { +- /* make sure resync happens */ +- sb->resync_offset = 0ULL; +- } else if (strcmp(update, "uuid") == 0) { ++ break; ++ } ++ case UOPT_UUID: + copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); + + if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) + memcpy(bms->uuid, sb->set_uuid, 16); +- } else if (strcmp(update, "no-bitmap") == 0) { ++ break; ++ case UOPT_NO_BITMAP: + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); + if (bms->version == BITMAP_MAJOR_CLUSTERED && !IsBitmapDirty(devname)) + sb->resync_offset = MaxSector; +- } else if (strcmp(update, "bbl") == 0) { ++ break; ++ case UOPT_BBL: { + /* only possible if there is room after the bitmap, or if + * there is no bitmap + */ +@@ -1383,14 +1414,12 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + bb_offset = bitmap_offset + bm_sectors; + while (bb_offset < (long)sb_offset + 8 + 32*2 && + bb_offset + 8+8 <= (long)data_offset) +- /* too close to bitmap, and room to grow */ + bb_offset += 8; + if (bb_offset + 8 <= (long)data_offset) { + sb->bblog_size = __cpu_to_le16(8); + sb->bblog_offset = __cpu_to_le32(bb_offset); + } + } else { +- /* 1.0 - Put bbl just before super block */ + if (bm_sectors && bitmap_offset < 0) + space = -bitmap_offset - bm_sectors; + else +@@ -1401,7 +1430,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->bblog_offset = __cpu_to_le32((unsigned)-8); + } + } +- } else if (strcmp(update, "no-bbl") == 0) { ++ break; ++ } ++ case UOPT_NO_BBL: + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) + pr_err("Cannot remove active bbl from %s\n",devname); + else { +@@ -1409,12 +1440,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->bblog_shift = 0; + sb->bblog_offset = 0; + } +- } else if (strcmp(update, "force-no-bbl") == 0) { ++ break; ++ case UOPT_FORCE_NO_BBL: + sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_BAD_BLOCKS); + sb->bblog_size = 0; + sb->bblog_shift = 0; + sb->bblog_offset = 0; +- } else if (strcmp(update, "ppl") == 0) { ++ break; ++ case UOPT_PPL: { + unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); + unsigned long long data_offset = __le64_to_cpu(sb->data_offset); + unsigned long long data_size = __le64_to_cpu(sb->data_size); +@@ -1464,37 +1497,26 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->ppl.offset = __cpu_to_le16(offset); + sb->ppl.size = __cpu_to_le16(space); + sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); +- } else if (strcmp(update, "no-ppl") == 0) { ++ break; ++ } ++ case UOPT_NO_PPL: + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | + MD_FEATURE_MUTLIPLE_PPLS); +- } else if (strcmp(update, "name") == 0) { +- if (info->name[0] == 0) +- sprintf(info->name, "%d", info->array.md_minor); +- memset(sb->set_name, 0, sizeof(sb->set_name)); +- if (homehost && +- strchr(info->name, ':') == NULL && +- strlen(homehost)+1+strlen(info->name) < 32) { +- strcpy(sb->set_name, homehost); +- strcat(sb->set_name, ":"); +- strcat(sb->set_name, info->name); +- } else { +- int namelen; +- +- namelen = min((int)strlen(info->name), +- (int)sizeof(sb->set_name) - 1); +- memcpy(sb->set_name, info->name, namelen); +- memset(&sb->set_name[namelen], '\0', +- sizeof(sb->set_name) - namelen); +- } +- } else if (strcmp(update, "devicesize") == 0 && +- __le64_to_cpu(sb->super_offset) < +- __le64_to_cpu(sb->data_offset)) { +- /* set data_size to device size less data_offset */ ++ break; ++ case UOPT_DEVICESIZE: ++ if (__le64_to_cpu(sb->super_offset) >= ++ __le64_to_cpu(sb->data_offset)) ++ break; ++ /* ++ * set data_size to device size less data_offset ++ */ + struct misc_dev_info *misc = (struct misc_dev_info*) + (st->sb + MAX_SB_SIZE + BM_SUPER_SIZE); + sb->data_size = __cpu_to_le64( + misc->device_size - __le64_to_cpu(sb->data_offset)); +- } else if (strncmp(update, "revert-reshape", 14) == 0) { ++ break; ++ case UOPT_SPEC_REVERT_RESHAPE_NOBACKUP: ++ case UOPT_REVERT_RESHAPE: + rv = -2; + if (!(sb->feature_map & + __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) +@@ -1512,7 +1534,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + * If that couldn't happen, the "-nobackup" version + * will be used. + */ +- if (strcmp(update, "revert-reshape-nobackup") == 0 && ++ if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && + sb->reshape_position == 0 && + (__le32_to_cpu(sb->delta_disks) > 0 || + (__le32_to_cpu(sb->delta_disks) == 0 && +@@ -1575,32 +1597,40 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + } + done:; + } +- } else if (strcmp(update, "_reshape_progress") == 0) ++ break; ++ case UOPT_SPEC__RESHAPE_PROGRESS: + sb->reshape_position = __cpu_to_le64(info->reshape_progress); +- else if (strcmp(update, "writemostly") == 0) ++ break; ++ case UOPT_SPEC_WRITEMOSTLY: + sb->devflags |= WriteMostly1; +- else if (strcmp(update, "readwrite") == 0) ++ break; ++ case UOPT_SPEC_READWRITE: + sb->devflags &= ~WriteMostly1; +- else if (strcmp(update, "failfast") == 0) ++ break; ++ case UOPT_SPEC_FAILFAST: + sb->devflags |= FailFast1; +- else if (strcmp(update, "nofailfast") == 0) ++ break; ++ case UOPT_SPEC_NOFAILFAST: + sb->devflags &= ~FailFast1; +- else if (strcmp(update, "layout-original") == 0 || +- strcmp(update, "layout-alternate") == 0 || +- strcmp(update, "layout-unspecified") == 0) { ++ break; ++ case UOPT_LAYOUT_ORIGINAL: ++ case UOPT_LAYOUT_ALTERNATE: ++ case UOPT_LAYOUT_UNSPECIFIED: + if (__le32_to_cpu(sb->level) != 0) { + pr_err("%s: %s only supported for RAID0\n", +- devname?:"", update); ++ devname ?: "", map_num(update_options, update_enum)); + rv = -1; +- } else if (strcmp(update, "layout-unspecified") == 0) { ++ } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); + sb->layout = 0; + } else { + sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); +- sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); ++ sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); + } +- } else ++ break; ++ default: + rv = -1; ++ } + + sb->sb_csum = calc_sb_1_csum(sb); + +-- +2.38.1 + diff --git a/0073-super-intel-refactor-the-code-for-enum.patch b/0073-super-intel-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..6756297 --- /dev/null +++ b/0073-super-intel-refactor-the-code-for-enum.patch @@ -0,0 +1,106 @@ +From 4345e135c4c7dd04bb15bad140dfc4747f677738 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:21 +0100 +Subject: [PATCH 73/83] super-intel: refactor the code for enum + +It prepares super-intel for change context->update to enum. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 37 +++++++++++++++++++++++++------------ + 1 file changed, 25 insertions(+), 12 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 5f93f3d3..85fb7f17 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -3930,7 +3930,8 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, + + mpb = super->anchor; + +- if (strcmp(update, "uuid") == 0) { ++ switch (map_name(update_options, update)) { ++ case UOPT_UUID: + /* We take this to mean that the family_num should be updated. + * However that is much smaller than the uuid so we cannot really + * allow an explicit uuid to be given. And it is hard to reliably +@@ -3954,10 +3955,14 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, + } + if (rv == 0) + mpb->orig_family_num = info->uuid[0]; +- } else if (strcmp(update, "assemble") == 0) ++ break; ++ case UOPT_SPEC_ASSEMBLE: + rv = 0; +- else ++ break; ++ default: + rv = -1; ++ break; ++ } + + /* successful update? recompute checksum */ + if (rv == 0) +@@ -7889,17 +7894,25 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) + return 0; + } + +-static int get_rwh_policy_from_update(char *update) ++/** ++ * get_rwh_policy_from_update() - Get the rwh policy for update option. ++ * @update: Update option. ++ */ ++static int get_rwh_policy_from_update(enum update_opt update) + { +- if (strcmp(update, "ppl") == 0) ++ switch (update) { ++ case UOPT_PPL: + return RWH_MULTIPLE_DISTRIBUTED; +- else if (strcmp(update, "no-ppl") == 0) ++ case UOPT_NO_PPL: + return RWH_MULTIPLE_OFF; +- else if (strcmp(update, "bitmap") == 0) ++ case UOPT_BITMAP: + return RWH_BITMAP; +- else if (strcmp(update, "no-bitmap") == 0) ++ case UOPT_NO_BITMAP: + return RWH_OFF; +- return -1; ++ default: ++ break; ++ } ++ return UOPT_UNDEFINED; + } + + static int update_subarray_imsm(struct supertype *st, char *subarray, +@@ -7909,7 +7922,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + struct intel_super *super = st->sb; + struct imsm_super *mpb = super->anchor; + +- if (strcmp(update, "name") == 0) { ++ if (map_name(update_options, update) == UOPT_NAME) { + char *name = ident->name; + char *ep; + int vol; +@@ -7943,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + } + super->updates_pending++; + } +- } else if (get_rwh_policy_from_update(update) != -1) { ++ } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { + int new_policy; + char *ep; + int vol = strtoul(subarray, &ep, 10); +@@ -7951,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + if (*ep != '\0' || vol >= super->anchor->num_raid_devs) + return 2; + +- new_policy = get_rwh_policy_from_update(update); ++ new_policy = get_rwh_policy_from_update(map_name(update_options, update)); + + if (st->update_tail) { + struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); +-- +2.38.1 + diff --git a/0074-Change-update-to-enum-in-update_super-and-update_sub.patch b/0074-Change-update-to-enum-in-update_super-and-update_sub.patch new file mode 100644 index 0000000..c9e186e --- /dev/null +++ b/0074-Change-update-to-enum-in-update_super-and-update_sub.patch @@ -0,0 +1,424 @@ +From 03312b5240438ffc3b63114bdc87e911222f01e5 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:22 +0100 +Subject: [PATCH 74/83] Change update to enum in update_super and + update_subarray + +Use already existing enum, change update_super and update_subarray +update to enum globally. +Refactor function references also. +Remove code specific options from update_options. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Assemble.c | 14 +++++++++----- + Examine.c | 2 +- + Grow.c | 9 +++++---- + Manage.c | 14 ++++++++------ + maps.c | 21 --------------------- + mdadm.h | 12 +++++++++--- + super-intel.c | 16 ++++++++-------- + super0.c | 9 ++++----- + super1.c | 17 ++++++++--------- + 9 files changed, 52 insertions(+), 62 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 8b0af0c9..dba910cd 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -695,12 +695,16 @@ static int load_devices(struct devs *devices, char *devmap, + } else if (strcmp(c->update, "revert-reshape") == 0 && + c->invalid_backup) + err = tst->ss->update_super(tst, content, +- "revert-reshape-nobackup", ++ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, + devname, c->verbose, + ident->uuid_set, + c->homehost); + else +- err = tst->ss->update_super(tst, content, c->update, ++ /* ++ * Mapping is temporary, will be removed in this patchset ++ */ ++ err = tst->ss->update_super(tst, content, ++ map_name(update_options, c->update), + devname, c->verbose, + ident->uuid_set, + c->homehost); +@@ -960,7 +964,7 @@ static int force_array(struct mdinfo *content, + continue; + } + content->events = devices[most_recent].i.events; +- tst->ss->update_super(tst, content, "force-one", ++ tst->ss->update_super(tst, content, UOPT_SPEC_FORCE_ONE, + devices[chosen_drive].devname, c->verbose, + 0, NULL); + +@@ -1788,7 +1792,7 @@ try_again: + if (!(devices[j].i.array.state & 1)) + clean = 0; + +- if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, ++ if (st->ss->update_super(st, &devices[j].i, UOPT_SPEC_ASSEMBLE, NULL, + c->verbose, 0, NULL)) { + if (c->force) { + if (c->verbose >= 0) +@@ -1811,7 +1815,7 @@ try_again: + if (c->force && !clean && !is_container(content->array.level) && + !enough(content->array.level, content->array.raid_disks, + content->array.layout, clean, avail)) { +- change += st->ss->update_super(st, content, "force-array", ++ change += st->ss->update_super(st, content, UOPT_SPEC_FORCE_ARRAY, + devices[chosen_drive].devname, c->verbose, + 0, NULL); + was_forced = 1; +diff --git a/Examine.c b/Examine.c +index 9574a3cc..c9605a60 100644 +--- a/Examine.c ++++ b/Examine.c +@@ -117,7 +117,7 @@ int Examine(struct mddev_dev *devlist, + } + + if (c->SparcAdjust) +- st->ss->update_super(st, NULL, "sparc2.2", ++ st->ss->update_super(st, NULL, UOPT_SPARC22, + devlist->devname, 0, 0, NULL); + /* Ok, its good enough to try, though the checksum could be wrong */ + +diff --git a/Grow.c b/Grow.c +index b73ec2ae..82d5d2ea 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -196,7 +196,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + info.disk.minor = minor(rdev); + info.disk.raid_disk = d; + info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); +- if (st->ss->update_super(st, &info, "linear-grow-new", newdev, ++ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_NEW, newdev, + 0, 0, NULL) != 0) { + pr_err("Preparing new metadata failed on %s\n", newdev); + close(nfd); +@@ -254,7 +254,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + info.array.active_disks = nd+1; + info.array.working_disks = nd+1; + +- if (st->ss->update_super(st, &info, "linear-grow-update", dv, ++ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_UPDATE, dv, + 0, 0, NULL) != 0) { + pr_err("Updating metadata failed on %s\n", dv); + close(fd2); +@@ -668,7 +668,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + goto free_info; + } + +- ret = st->ss->update_super(st, sra, "ppl", ++ ret = st->ss->update_super(st, sra, UOPT_PPL, + devname, + c->verbose, 0, NULL); + if (ret) { +@@ -4950,7 +4950,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, + continue; + st->ss->getinfo_super(st, &dinfo, NULL); + dinfo.reshape_progress = info->reshape_progress; +- st->ss->update_super(st, &dinfo, "_reshape_progress", ++ st->ss->update_super(st, &dinfo, ++ UOPT_SPEC__RESHAPE_PROGRESS, + NULL,0, 0, NULL); + st->ss->store_super(st, fdlist[j]); + st->ss->free_super(st); +diff --git a/Manage.c b/Manage.c +index 5a9ea316..87b8aa0c 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -605,6 +605,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + struct mdinfo mdi; + int duuid[4]; + int ouuid[4]; ++ enum update_opt update_enum = map_name(update_options, update); + + dev_st->ss->getinfo_super(dev_st, &mdi, NULL); + dev_st->ss->uuid_from_super(dev_st, ouuid); +@@ -666,23 +667,23 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + + if (dv->writemostly == FlagSet) + rv = dev_st->ss->update_super( +- dev_st, NULL, "writemostly", ++ dev_st, NULL, UOPT_SPEC_WRITEMOSTLY, + devname, verbose, 0, NULL); + if (dv->writemostly == FlagClear) + rv = dev_st->ss->update_super( +- dev_st, NULL, "readwrite", ++ dev_st, NULL, UOPT_SPEC_READWRITE, + devname, verbose, 0, NULL); + if (dv->failfast == FlagSet) + rv = dev_st->ss->update_super( +- dev_st, NULL, "failfast", ++ dev_st, NULL, UOPT_SPEC_FAILFAST, + devname, verbose, 0, NULL); + if (dv->failfast == FlagClear) + rv = dev_st->ss->update_super( +- dev_st, NULL, "nofailfast", ++ dev_st, NULL, UOPT_SPEC_NOFAILFAST, + devname, verbose, 0, NULL); + if (update) + rv = dev_st->ss->update_super( +- dev_st, NULL, update, ++ dev_st, NULL, update_enum, + devname, verbose, 0, NULL); + if (rv == 0) + rv = dev_st->ss->store_super(dev_st, tfd); +@@ -1731,6 +1732,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + struct supertype supertype, *st = &supertype; + int fd, rv = 2; + struct mdinfo *info = NULL; ++ enum update_opt update_enum = map_name(update_options, update); + + memset(st, 0, sizeof(*st)); + +@@ -1762,7 +1764,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + goto free_super; + } + +- rv = st->ss->update_subarray(st, subarray, update, ident); ++ rv = st->ss->update_subarray(st, subarray, update_enum, ident); + + if (rv) { + if (verbose >= 0) +diff --git a/maps.c b/maps.c +index c59036f1..b586679a 100644 +--- a/maps.c ++++ b/maps.c +@@ -194,27 +194,6 @@ mapping_t update_options[] = { + { "byteorder", UOPT_BYTEORDER }, + { "help", UOPT_HELP }, + { "?", UOPT_HELP }, +- /* +- * Those enries are temporary and will be removed in this patchset. +- * +- * Before update_super:update can be changed to enum, +- * all update_super sub-functions must be adapted first. +- * Update options will be passed as string (as it is for now), +- * and then mapped, so all options must be handled temporarily. +- * +- * Those options code specific and should not be accessible for user. +- */ +- { "force-one", UOPT_SPEC_FORCE_ONE }, +- { "force-array", UOPT_SPEC_FORCE_ARRAY }, +- { "assemble", UOPT_SPEC_ASSEMBLE }, +- { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, +- { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, +- { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, +- { "writemostly", UOPT_SPEC_WRITEMOSTLY }, +- { "readwrite", UOPT_SPEC_READWRITE }, +- { "failfast", UOPT_SPEC_FAILFAST }, +- { "nofailfast", UOPT_SPEC_NOFAILFAST }, +- { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, + { NULL, UOPT_UNDEFINED} + }; + +diff --git a/mdadm.h b/mdadm.h +index 31db25f5..5dc94390 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1011,7 +1011,7 @@ extern struct superswitch { + * it will resume going in the opposite direction. + */ + int (*update_super)(struct supertype *st, struct mdinfo *info, +- char *update, ++ enum update_opt update, + char *devname, int verbose, + int uuid_set, char *homehost); + +@@ -1137,9 +1137,15 @@ extern struct superswitch { + /* Permit subarray's to be deleted from inactive containers */ + int (*kill_subarray)(struct supertype *st, + char *subarray_id); /* optional */ +- /* Permit subarray's to be modified */ ++ /** ++ * update_subarray() - Permit subarray to be modified. ++ * @st: Supertype. ++ * @subarray: Subarray name. ++ * @update: Update option. ++ * @ident: Optional identifiers. ++ */ + int (*update_subarray)(struct supertype *st, char *subarray, +- char *update, struct mddev_ident *ident); /* optional */ ++ enum update_opt update, struct mddev_ident *ident); + /* Check if reshape is supported for this external format. + * st is obtained from super_by_fd() where st->subarray[0] is + * initialized to indicate if reshape is being performed at the +diff --git a/super-intel.c b/super-intel.c +index 85fb7f17..1f5f6eda 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -3893,8 +3893,8 @@ struct mdinfo *getinfo_super_disks_imsm(struct supertype *st) + } + + static int update_super_imsm(struct supertype *st, struct mdinfo *info, +- char *update, char *devname, int verbose, +- int uuid_set, char *homehost) ++ enum update_opt update, char *devname, ++ int verbose, int uuid_set, char *homehost) + { + /* For 'assemble' and 'force' we need to return non-zero if any + * change was made. For others, the return value is ignored. +@@ -3930,7 +3930,7 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, + + mpb = super->anchor; + +- switch (map_name(update_options, update)) { ++ switch (update) { + case UOPT_UUID: + /* We take this to mean that the family_num should be updated. + * However that is much smaller than the uuid so we cannot really +@@ -6538,7 +6538,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + if (mdmon_running(st->container_devnm)) + st->update_tail = &st->updates; + +- if (st->ss->update_subarray(st, subarray, "ppl", NULL)) { ++ if (st->ss->update_subarray(st, subarray, UOPT_PPL, NULL)) { + pr_err("Failed to update subarray %s\n", + subarray); + } else { +@@ -7916,13 +7916,13 @@ static int get_rwh_policy_from_update(enum update_opt update) + } + + static int update_subarray_imsm(struct supertype *st, char *subarray, +- char *update, struct mddev_ident *ident) ++ enum update_opt update, struct mddev_ident *ident) + { + /* update the subarray currently referenced by ->current_vol */ + struct intel_super *super = st->sb; + struct imsm_super *mpb = super->anchor; + +- if (map_name(update_options, update) == UOPT_NAME) { ++ if (update == UOPT_NAME) { + char *name = ident->name; + char *ep; + int vol; +@@ -7956,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + } + super->updates_pending++; + } +- } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { ++ } else if (get_rwh_policy_from_update(update) != UOPT_UNDEFINED) { + int new_policy; + char *ep; + int vol = strtoul(subarray, &ep, 10); +@@ -7964,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + if (*ep != '\0' || vol >= super->anchor->num_raid_devs) + return 2; + +- new_policy = get_rwh_policy_from_update(map_name(update_options, update)); ++ new_policy = get_rwh_policy_from_update(update); + + if (st->update_tail) { + struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); +diff --git a/super0.c b/super0.c +index d9f5bff4..a7c5f813 100644 +--- a/super0.c ++++ b/super0.c +@@ -491,7 +491,7 @@ static struct mdinfo *container_content0(struct supertype *st, char *subarray) + } + + static int update_super0(struct supertype *st, struct mdinfo *info, +- char *update, ++ enum update_opt update, + char *devname, int verbose, + int uuid_set, char *homehost) + { +@@ -502,20 +502,19 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + int rv = 0; + int uuid[4]; + mdp_super_t *sb = st->sb; +- enum update_opt update_enum = map_name(update_options, update); + +- if (update_enum == UOPT_HOMEHOST && homehost) { ++ if (update == UOPT_HOMEHOST && homehost) { + /* + * note that 'homehost' is special as it is really + * a "uuid" update. + */ + uuid_set = 0; +- update_enum = UOPT_UUID; ++ update = UOPT_UUID; + info->uuid[0] = sb->set_uuid0; + info->uuid[1] = sb->set_uuid1; + } + +- switch (update_enum) { ++ switch (update) { + case UOPT_UUID: + if (!uuid_set && homehost) { + char buf[20]; +diff --git a/super1.c b/super1.c +index b0a97016..f7020320 100644 +--- a/super1.c ++++ b/super1.c +@@ -1208,7 +1208,7 @@ static struct mdinfo *container_content1(struct supertype *st, char *subarray) + } + + static int update_super1(struct supertype *st, struct mdinfo *info, +- char *update, char *devname, int verbose, ++ enum update_opt update, char *devname, int verbose, + int uuid_set, char *homehost) + { + /* NOTE: for 'assemble' and 'force' we need to return non-zero +@@ -1218,15 +1218,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + int rv = 0; + struct mdp_superblock_1 *sb = st->sb; + bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); +- enum update_opt update_enum = map_name(update_options, update); + +- if (update_enum == UOPT_HOMEHOST && homehost) { ++ if (update == UOPT_HOMEHOST && homehost) { + /* + * Note that 'homehost' is special as it is really + * a "name" update. + */ + char *c; +- update_enum = UOPT_NAME; ++ update = UOPT_NAME; + c = strchr(sb->set_name, ':'); + if (c) + snprintf(info->name, sizeof(info->name), "%s", c+1); +@@ -1234,7 +1233,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + snprintf(info->name, sizeof(info->name), "%s", sb->set_name); + } + +- switch (update_enum) { ++ switch (update) { + case UOPT_NAME: { + int namelen; + +@@ -1534,7 +1533,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + * If that couldn't happen, the "-nobackup" version + * will be used. + */ +- if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && ++ if (update == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && + sb->reshape_position == 0 && + (__le32_to_cpu(sb->delta_disks) > 0 || + (__le32_to_cpu(sb->delta_disks) == 0 && +@@ -1618,14 +1617,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + case UOPT_LAYOUT_UNSPECIFIED: + if (__le32_to_cpu(sb->level) != 0) { + pr_err("%s: %s only supported for RAID0\n", +- devname ?: "", map_num(update_options, update_enum)); ++ devname ?: "", map_num(update_options, update)); + rv = -1; +- } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { ++ } else if (update == UOPT_LAYOUT_UNSPECIFIED) { + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); + sb->layout = 0; + } else { + sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); +- sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); ++ sb->layout = __cpu_to_le32(update == UOPT_LAYOUT_ORIGINAL ? 1 : 2); + } + break; + default: +-- +2.38.1 + diff --git a/0075-Manage-Incremental-code-refactor-string-to-enum.patch b/0075-Manage-Incremental-code-refactor-string-to-enum.patch new file mode 100644 index 0000000..d4b20ff --- /dev/null +++ b/0075-Manage-Incremental-code-refactor-string-to-enum.patch @@ -0,0 +1,279 @@ +From f2e8393bd7223c419aaa33c45feeb5c75440b986 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:23 +0100 +Subject: [PATCH 75/83] Manage&Incremental: code refactor, string to enum + +Prepare Manage and Incremental for later changing context->update to enum. +Change update from string to enum in multiple functions and pass enum +where already possible. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Grow.c | 8 ++++---- + Incremental.c | 8 ++++---- + Manage.c | 35 +++++++++++++++++------------------ + mdadm.c | 23 ++++++++++++++++++----- + mdadm.h | 4 ++-- + 5 files changed, 45 insertions(+), 33 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 82d5d2ea..8f5cf07d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -605,12 +605,12 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + } + + if (subarray) { +- char *update; ++ enum update_opt update; + + if (s->consistency_policy == CONSISTENCY_POLICY_PPL) +- update = "ppl"; ++ update = UOPT_PPL; + else +- update = "no-ppl"; ++ update = UOPT_NO_PPL; + + sprintf(container_dev, "/dev/%s", st->container_devnm); + +@@ -3243,7 +3243,7 @@ static int reshape_array(char *container, int fd, char *devname, + * level and frozen, we can safely add them. + */ + if (devlist) { +- if (Manage_subdevs(devname, fd, devlist, verbose, 0, NULL, 0)) ++ if (Manage_subdevs(devname, fd, devlist, verbose, 0, UOPT_UNDEFINED, 0)) + goto release; + } + +diff --git a/Incremental.c b/Incremental.c +index 5a5f4c4c..ff3548c0 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1025,7 +1025,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + close(dfd); + *dfdp = -1; + rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist, +- -1, 0, NULL, 0); ++ -1, 0, UOPT_UNDEFINED, 0); + close(mdfd); + } + if (verbose > 0) { +@@ -1666,7 +1666,7 @@ static void remove_from_member_array(struct mdstat_ent *memb, + + if (subfd >= 0) { + rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, +- 0, NULL, 0); ++ 0, UOPT_UNDEFINED, 0); + if (rv & 2) { + if (sysfs_init(&mmdi, -1, memb->devnm)) + pr_err("unable to initialize sysfs for: %s\n", +@@ -1758,7 +1758,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + free_mdstat(mdstat); + } else { + rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, +- verbose, 0, NULL, 0); ++ verbose, 0, UOPT_UNDEFINED, 0); + if (rv & 2) { + /* Failed due to EBUSY, try to stop the array. + * Give udisks a chance to unmount it first. +@@ -1770,7 +1770,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + + devlist.disposition = 'r'; + rv = Manage_subdevs(ent->devnm, mdfd, &devlist, +- verbose, 0, NULL, 0); ++ verbose, 0, UOPT_UNDEFINED, 0); + end: + close(mdfd); + free_mdstat(ent); +diff --git a/Manage.c b/Manage.c +index 87b8aa0c..594e3d2c 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -598,14 +598,12 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) + + int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + struct supertype *dev_st, struct supertype *tst, +- unsigned long rdev, +- char *update, char *devname, int verbose, +- mdu_array_info_t *array) ++ unsigned long rdev, enum update_opt update, ++ char *devname, int verbose, mdu_array_info_t *array) + { + struct mdinfo mdi; + int duuid[4]; + int ouuid[4]; +- enum update_opt update_enum = map_name(update_options, update); + + dev_st->ss->getinfo_super(dev_st, &mdi, NULL); + dev_st->ss->uuid_from_super(dev_st, ouuid); +@@ -683,7 +681,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + devname, verbose, 0, NULL); + if (update) + rv = dev_st->ss->update_super( +- dev_st, NULL, update_enum, ++ dev_st, NULL, update, + devname, verbose, 0, NULL); + if (rv == 0) + rv = dev_st->ss->store_super(dev_st, tfd); +@@ -715,8 +713,8 @@ skip_re_add: + 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, +- char *update, unsigned long rdev, unsigned long long array_size, +- int raid_slot) ++ enum update_opt update, unsigned long rdev, ++ unsigned long long array_size, int raid_slot) + { + unsigned long long ldsize; + struct supertype *dev_st; +@@ -1332,7 +1330,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + + int Manage_subdevs(char *devname, int fd, + struct mddev_dev *devlist, int verbose, int test, +- char *update, int force) ++ enum update_opt update, int force) + { + /* Do something to each dev. + * devmode can be +@@ -1727,12 +1725,13 @@ int autodetect(void) + return rv; + } + +-int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int verbose) ++int Update_subarray(char *dev, char *subarray, enum update_opt update, ++ struct mddev_ident *ident, int verbose) + { + struct supertype supertype, *st = &supertype; + int fd, rv = 2; + struct mdinfo *info = NULL; +- enum update_opt update_enum = map_name(update_options, update); ++ char *update_verb = map_num(update_options, update); + + memset(st, 0, sizeof(*st)); + +@@ -1750,7 +1749,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + if (is_subarray_active(subarray, st->devnm)) { + if (verbose >= 0) + pr_err("Subarray %s in %s is active, cannot update %s\n", +- subarray, dev, update); ++ subarray, dev, update_verb); + goto free_super; + } + +@@ -1759,23 +1758,23 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident + + info = st->ss->container_content(st, subarray); + +- if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { ++ if (update == UOPT_PPL && !is_level456(info->array.level)) { + pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); + goto free_super; + } + +- rv = st->ss->update_subarray(st, subarray, update_enum, ident); ++ rv = st->ss->update_subarray(st, subarray, update, ident); + + if (rv) { + if (verbose >= 0) + pr_err("Failed to update %s of subarray-%s in %s\n", +- update, subarray, dev); ++ update_verb, subarray, dev); + } else if (st->update_tail) + flush_metadata_updates(st); + else + st->ss->sync_metadata(st); + +- if (rv == 0 && strcmp(update, "name") == 0 && verbose >= 0) ++ if (rv == 0 && update == UOPT_NAME && verbose >= 0) + pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", + subarray, dev); + +@@ -1816,10 +1815,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + sprintf(devname, "%d:%d", major(devid), minor(devid)); + + devlist.disposition = 'r'; +- if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { ++ if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, UOPT_UNDEFINED, 0) == 0) { + devlist.disposition = 'a'; + if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, +- NULL, 0) == 0) { ++ UOPT_UNDEFINED, 0) == 0) { + /* make sure manager is aware of changes */ + ping_manager(to_devname); + ping_manager(from_devname); +@@ -1829,7 +1828,7 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + } + else + Manage_subdevs(from_devname, fd2, &devlist, +- -1, 0, NULL, 0); ++ -1, 0, UOPT_UNDEFINED, 0); + } + close(fd1); + close(fd2); +diff --git a/mdadm.c b/mdadm.c +index f5f505fe..d06e2820 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1402,10 +1402,22 @@ int main(int argc, char *argv[]) + /* readonly, add/remove, readwrite, runstop */ + if (c.readonly > 0) + rv = Manage_ro(devlist->devname, mdfd, c.readonly); +- if (!rv && devs_found>1) +- rv = Manage_subdevs(devlist->devname, mdfd, +- devlist->next, c.verbose, c.test, +- c.update, c.force); ++ if (!rv && devs_found > 1) { ++ /* ++ * This is temporary and will be removed in next patches ++ * Null c.update will cause segfault ++ */ ++ if (c.update) ++ rv = Manage_subdevs(devlist->devname, mdfd, ++ devlist->next, c.verbose, c.test, ++ map_name(update_options, c.update), ++ c.force); ++ else ++ rv = Manage_subdevs(devlist->devname, mdfd, ++ devlist->next, c.verbose, c.test, ++ UOPT_UNDEFINED, ++ c.force); ++ } + if (!rv && c.readonly < 0) + rv = Manage_ro(devlist->devname, mdfd, c.readonly); + if (!rv && c.runstop > 0) +@@ -1931,7 +1943,8 @@ static int misc_list(struct mddev_dev *devlist, + continue; + } + rv |= Update_subarray(dv->devname, c->subarray, +- c->update, ident, c->verbose); ++ map_name(update_options, c->update), ++ ident, c->verbose); + continue; + case Dump: + rv |= Dump_metadata(dv->devname, dump_directory, c, ss); +diff --git a/mdadm.h b/mdadm.h +index 5dc94390..924f4b63 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1478,7 +1478,7 @@ extern int Manage_stop(char *devname, int fd, int quiet, + int will_retry); + extern int Manage_subdevs(char *devname, int fd, + struct mddev_dev *devlist, int verbose, int test, +- char *update, int force); ++ enum update_opt update, int force); + extern int autodetect(void); + extern int Grow_Add_device(char *devname, int fd, char *newdev); + extern int Grow_addbitmap(char *devname, int fd, +@@ -1532,7 +1532,7 @@ extern int Monitor(struct mddev_dev *devlist, + + extern int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl); + extern int Kill_subarray(char *dev, char *subarray, int verbose); +-extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet); ++extern int Update_subarray(char *dev, char *subarray, enum update_opt update, struct mddev_ident *ident, int quiet); + extern int Wait(char *dev); + extern int WaitClean(char *dev, int verbose); + extern int SetAction(char *dev, char *action); +-- +2.38.1 + diff --git a/0076-Change-char-to-enum-in-context-update-refactor-code.patch b/0076-Change-char-to-enum-in-context-update-refactor-code.patch new file mode 100644 index 0000000..a18f8d1 --- /dev/null +++ b/0076-Change-char-to-enum-in-context-update-refactor-code.patch @@ -0,0 +1,289 @@ +From 3a87fa67112dc2c2c3664aeecd0b49cb4b6ceaa9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:24 +0100 +Subject: [PATCH 76/83] Change char* to enum in context->update & refactor code + +Storing update option in string is bad for frequent comparisons and +error prone. +Replace char array with enum so already existing enum is passed around +instead of string. +Adapt code to changes. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Assemble.c | 40 +++++++++++++++++----------------------- + mdadm.c | 52 +++++++++++++++++++--------------------------------- + mdadm.h | 2 +- + 3 files changed, 37 insertions(+), 57 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index dba910cd..49804941 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -135,17 +135,17 @@ static int ident_matches(struct mddev_ident *ident, + struct mdinfo *content, + struct supertype *tst, + char *homehost, int require_homehost, +- char *update, char *devname) ++ enum update_opt update, char *devname) + { + +- if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) && ++ if (ident->uuid_set && update != UOPT_UUID && + same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 && + memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) { + if (devname) + pr_err("%s has wrong uuid.\n", devname); + return 0; + } +- if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && ++ if (ident->name[0] && update != UOPT_NAME && + name_matches(content->name, ident->name, homehost, require_homehost)==0) { + if (devname) + pr_err("%s has wrong name.\n", devname); +@@ -648,11 +648,10 @@ static int load_devices(struct devs *devices, char *devmap, + int err; + fstat(mdfd, &stb2); + +- if (strcmp(c->update, "uuid") == 0 && !ident->uuid_set) ++ if (c->update == UOPT_UUID && !ident->uuid_set) + random_uuid((__u8 *)ident->uuid); + +- if (strcmp(c->update, "ppl") == 0 && +- ident->bitmap_fd >= 0) { ++ if (c->update == UOPT_PPL && ident->bitmap_fd >= 0) { + pr_err("PPL is not compatible with bitmap\n"); + close(mdfd); + free(devices); +@@ -684,34 +683,30 @@ static int load_devices(struct devs *devices, char *devmap, + strcpy(content->name, ident->name); + content->array.md_minor = minor(stb2.st_rdev); + +- if (strcmp(c->update, "byteorder") == 0) ++ if (c->update == UOPT_BYTEORDER) + err = 0; +- else if (strcmp(c->update, "home-cluster") == 0) { ++ else if (c->update == UOPT_HOME_CLUSTER) { + tst->cluster_name = c->homecluster; + err = tst->ss->write_bitmap(tst, dfd, NameUpdate); +- } else if (strcmp(c->update, "nodes") == 0) { ++ } else if (c->update == UOPT_NODES) { + tst->nodes = c->nodes; + err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate); +- } else if (strcmp(c->update, "revert-reshape") == 0 && +- c->invalid_backup) ++ } else if (c->update == UOPT_REVERT_RESHAPE && c->invalid_backup) + err = tst->ss->update_super(tst, content, + UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, + devname, c->verbose, + ident->uuid_set, + c->homehost); + else +- /* +- * Mapping is temporary, will be removed in this patchset +- */ + err = tst->ss->update_super(tst, content, +- map_name(update_options, c->update), ++ c->update, + devname, c->verbose, + ident->uuid_set, + c->homehost); + if (err < 0) { + if (err == -1) + pr_err("--update=%s not understood for %s metadata\n", +- c->update, tst->ss->name); ++ map_num(update_options, c->update), tst->ss->name); + tst->ss->free_super(tst); + free(tst); + close(mdfd); +@@ -721,7 +716,7 @@ static int load_devices(struct devs *devices, char *devmap, + *stp = st; + return -1; + } +- if (strcmp(c->update, "uuid")==0 && ++ if (c->update == UOPT_UUID && + !ident->uuid_set) { + ident->uuid_set = 1; + memcpy(ident->uuid, content->uuid, 16); +@@ -730,7 +725,7 @@ static int load_devices(struct devs *devices, char *devmap, + pr_err("Could not re-write superblock on %s.\n", + devname); + +- if (strcmp(c->update, "uuid")==0 && ++ if (c->update == UOPT_UUID && + ident->bitmap_fd >= 0 && !bitmap_done) { + if (bitmap_update_uuid(ident->bitmap_fd, + content->uuid, +@@ -1188,8 +1183,7 @@ static int start_array(int mdfd, + pr_err("%s: Need a backup file to complete reshape of this array.\n", + mddev); + pr_err("Please provided one with \"--backup-file=...\"\n"); +- if (c->update && +- strcmp(c->update, "revert-reshape") == 0) ++ if (c->update == UOPT_REVERT_RESHAPE) + pr_err("(Don't specify --update=revert-reshape again, that part succeeded.)\n"); + return 1; + } +@@ -1487,7 +1481,7 @@ try_again: + */ + if (map_lock(&map)) + pr_err("failed to get exclusive lock on mapfile - continue anyway...\n"); +- if (c->update && strcmp(c->update,"uuid") == 0) ++ if (c->update == UOPT_UUID) + mp = NULL; + else + mp = map_by_uuid(&map, content->uuid); +@@ -1634,7 +1628,7 @@ try_again: + goto out; + } + +- if (c->update && strcmp(c->update, "byteorder")==0) ++ if (c->update == UOPT_BYTEORDER) + st->minor_version = 90; + + st->ss->getinfo_super(st, content, NULL); +@@ -1902,7 +1896,7 @@ try_again: + /* First, fill in the map, so that udev can find our name + * as soon as we become active. + */ +- if (c->update && strcmp(c->update, "metadata")==0) { ++ if (c->update == UOPT_METADATA) { + content->array.major_version = 1; + content->array.minor_version = 0; + strcpy(content->text_version, "1.0"); +diff --git a/mdadm.c b/mdadm.c +index d06e2820..57e8e6fa 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -724,13 +724,12 @@ int main(int argc, char *argv[]) + + case O(ASSEMBLE,'U'): /* update the superblock */ + case O(MISC,'U'): { +- enum update_opt updateopt = map_name(update_options, c.update); + enum update_opt print_mode = UOPT_HELP; + const char *error_addon = "update option"; + + if (c.update) { + pr_err("Can only update one aspect of superblock, both %s and %s given.\n", +- c.update, optarg); ++ map_num(update_options, c.update), optarg); + exit(2); + } + if (mode == MISC && !c.subarray) { +@@ -738,20 +737,20 @@ int main(int argc, char *argv[]) + exit(2); + } + +- c.update = optarg; ++ c.update = map_name(update_options, optarg); + + if (devmode == UpdateSubarray) { + print_mode = UOPT_SUBARRAY_ONLY; + error_addon = "update-subarray option"; + +- if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) +- updateopt = UOPT_UNDEFINED; ++ if (c.update > UOPT_SUBARRAY_ONLY && c.update < UOPT_HELP) ++ c.update = UOPT_UNDEFINED; + } + +- switch (updateopt) { ++ switch (c.update) { + case UOPT_UNDEFINED: + pr_err("'--update=%s' is invalid %s. ", +- c.update, error_addon); ++ optarg, error_addon); + outf = stderr; + case UOPT_HELP: + if (!outf) +@@ -776,14 +775,14 @@ int main(int argc, char *argv[]) + } + if (c.update) { + pr_err("Can only update one aspect of superblock, both %s and %s given.\n", +- c.update, optarg); ++ map_num(update_options, c.update), optarg); + exit(2); + } +- c.update = optarg; +- if (strcmp(c.update, "devicesize") != 0 && +- strcmp(c.update, "bbl") != 0 && +- strcmp(c.update, "force-no-bbl") != 0 && +- strcmp(c.update, "no-bbl") != 0) { ++ c.update = map_name(update_options, optarg); ++ if (c.update != UOPT_DEVICESIZE && ++ c.update != UOPT_BBL && ++ c.update != UOPT_NO_BBL && ++ c.update != UOPT_FORCE_NO_BBL) { + pr_err("only 'devicesize', 'bbl', 'no-bbl', and 'force-no-bbl' can be updated with --re-add\n"); + exit(2); + } +@@ -1357,7 +1356,7 @@ int main(int argc, char *argv[]) + } + } + +- if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) { ++ if (c.update && c.update == UOPT_NODES && c.nodes == 0) { + pr_err("Please specify nodes number with --nodes\n"); + exit(1); + } +@@ -1402,22 +1401,10 @@ int main(int argc, char *argv[]) + /* readonly, add/remove, readwrite, runstop */ + if (c.readonly > 0) + rv = Manage_ro(devlist->devname, mdfd, c.readonly); +- if (!rv && devs_found > 1) { +- /* +- * This is temporary and will be removed in next patches +- * Null c.update will cause segfault +- */ +- if (c.update) +- rv = Manage_subdevs(devlist->devname, mdfd, +- devlist->next, c.verbose, c.test, +- map_name(update_options, c.update), +- c.force); +- else +- rv = Manage_subdevs(devlist->devname, mdfd, +- devlist->next, c.verbose, c.test, +- UOPT_UNDEFINED, +- c.force); +- } ++ if (!rv && devs_found > 1) ++ rv = Manage_subdevs(devlist->devname, mdfd, ++ devlist->next, c.verbose, ++ c.test, c.update, c.force); + if (!rv && c.readonly < 0) + rv = Manage_ro(devlist->devname, mdfd, c.readonly); + if (!rv && c.runstop > 0) +@@ -1937,14 +1924,13 @@ static int misc_list(struct mddev_dev *devlist, + rv |= Kill_subarray(dv->devname, c->subarray, c->verbose); + continue; + case UpdateSubarray: +- if (c->update == NULL) { ++ if (!c->update) { + pr_err("-U/--update must be specified with --update-subarray\n"); + rv |= 1; + continue; + } + rv |= Update_subarray(dv->devname, c->subarray, +- map_name(update_options, c->update), +- ident, c->verbose); ++ c->update, ident, c->verbose); + continue; + case Dump: + rv |= Dump_metadata(dv->devname, dump_directory, c, ss); +diff --git a/mdadm.h b/mdadm.h +index 924f4b63..13f8b4cb 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -616,7 +616,7 @@ struct context { + int export; + int test; + char *subarray; +- char *update; ++ enum update_opt update; + int scan; + int SparcAdjust; + int autof; +-- +2.38.1 + diff --git a/0077-mdmon-fix-segfault.patch b/0077-mdmon-fix-segfault.patch new file mode 100644 index 0000000..980ceda --- /dev/null +++ b/0077-mdmon-fix-segfault.patch @@ -0,0 +1,86 @@ +From 9b429fc0a4ffd7028b3b336589d38e32fb9045dc Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:46:21 +0100 +Subject: [PATCH 77/83] mdmon: fix segfault + +Mdmon crashes if stat2devnm returns null. +Use open_mddev to check if device is mddevice and get name using +fd2devnm. +Refactor container name handling. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + Makefile | 2 +- + mdmon.c | 26 ++++++++++++-------------- + 2 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/Makefile b/Makefile +index ec1f99ed..5eac1a4e 100644 +--- a/Makefile ++++ b/Makefile +@@ -160,7 +160,7 @@ SRCS = $(patsubst %.o,%.c,$(OBJS)) + + INCL = mdadm.h part.h bitmap.h + +-MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \ ++MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o config.o mapfile.o mdopen.o\ + policy.o lib.o \ + Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ + super-mbr.o super-gpt.o \ +diff --git a/mdmon.c b/mdmon.c +index e9d035eb..ecf52dc8 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -363,14 +363,14 @@ int main(int argc, char *argv[]) + } + + if (all == 0 && container_name == NULL) { +- if (argv[optind]) +- container_name = argv[optind]; ++ if (argv[optind]) { ++ container_name = get_md_name(argv[optind]); ++ if (!container_name) ++ container_name = argv[optind]; ++ } + } + +- if (container_name == NULL) +- usage(); +- +- if (argc - optind > 1) ++ if (container_name == NULL || argc - optind > 1) + usage(); + + if (strcmp(container_name, "/proc/mdstat") == 0) +@@ -402,21 +402,19 @@ int main(int argc, char *argv[]) + free_mdstat(mdstat); + + return status; +- } else if (strncmp(container_name, "md", 2) == 0) { +- int id = devnm2devid(container_name); +- if (id) +- devnm = container_name; + } else { +- struct stat st; ++ int mdfd = open_mddev(container_name, 1); + +- if (stat(container_name, &st) == 0) +- devnm = xstrdup(stat2devnm(&st)); ++ if (mdfd < 0) ++ return 1; ++ devnm = fd2devnm(mdfd); ++ close(mdfd); + } + + if (!devnm) { + pr_err("%s is not a valid md device name\n", + container_name); +- exit(1); ++ return 1; + } + return mdmon(devnm, dofork && do_fork(), takeover); + } +-- +2.38.1 + diff --git a/0078-util-remove-obsolete-code-from-get_md_name.patch b/0078-util-remove-obsolete-code-from-get_md_name.patch new file mode 100644 index 0000000..b371d39 --- /dev/null +++ b/0078-util-remove-obsolete-code-from-get_md_name.patch @@ -0,0 +1,116 @@ +From b938519e7719c992dae2d61c796c45fe49e6b71b Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:46:22 +0100 +Subject: [PATCH 78/83] util: remove obsolete code from get_md_name + +get_md_name() is used only with mdstat entries. +Remove dead code and simplyfy function. + +Remove redundadnt checks from mdmon.c + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Jes Sorensen +--- + mdmon.c | 8 +++----- + util.c | 51 +++++++++++++++++---------------------------------- + 2 files changed, 20 insertions(+), 39 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index ecf52dc8..60ba3182 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -366,7 +366,7 @@ int main(int argc, char *argv[]) + if (argv[optind]) { + container_name = get_md_name(argv[optind]); + if (!container_name) +- container_name = argv[optind]; ++ return 1; + } + } + +@@ -403,11 +403,9 @@ int main(int argc, char *argv[]) + + return status; + } else { +- int mdfd = open_mddev(container_name, 1); +- +- if (mdfd < 0) +- return 1; ++ int mdfd = open_mddev(container_name, 0); + devnm = fd2devnm(mdfd); ++ + close(mdfd); + } + +diff --git a/util.c b/util.c +index 26ffdcea..9cd89fa4 100644 +--- a/util.c ++++ b/util.c +@@ -968,47 +968,30 @@ dev_t devnm2devid(char *devnm) + return 0; + } + ++/** ++ * get_md_name() - Get main dev node of the md device. ++ * @devnm: Md device name or path. ++ * ++ * Function checks if the full name was passed and returns md name ++ * if it is the MD device. ++ * ++ * Return: Main dev node of the md device or NULL if not found. ++ */ + char *get_md_name(char *devnm) + { +- /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ +- /* if dev < 0, want /dev/md/d%d or find mdp in /proc/devices ... */ +- +- static char devname[50]; ++ static char devname[NAME_MAX]; + struct stat stb; +- dev_t rdev = devnm2devid(devnm); +- char *dn; + +- if (rdev == 0) +- return 0; +- if (strncmp(devnm, "md_", 3) == 0) { +- snprintf(devname, sizeof(devname), "/dev/md/%s", +- devnm + 3); +- if (stat(devname, &stb) == 0 && +- (S_IFMT&stb.st_mode) == S_IFBLK && (stb.st_rdev == rdev)) +- return devname; +- } +- snprintf(devname, sizeof(devname), "/dev/%s", devnm); +- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && +- (stb.st_rdev == rdev)) +- return devname; ++ if (strncmp(devnm, "/dev/", 5) == 0) ++ snprintf(devname, sizeof(devname), "%s", devnm); ++ else ++ snprintf(devname, sizeof(devname), "/dev/%s", devnm); + +- snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2); +- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && +- (stb.st_rdev == rdev)) ++ if (!is_mddev(devname)) ++ return NULL; ++ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK) + return devname; + +- dn = map_dev(major(rdev), minor(rdev), 0); +- if (dn) +- return dn; +- snprintf(devname, sizeof(devname), "/dev/.tmp.%s", devnm); +- if (mknod(devname, S_IFBLK | 0600, rdev) == -1) +- if (errno != EEXIST) +- return NULL; +- +- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && +- (stb.st_rdev == rdev)) +- return devname; +- unlink(devname); + return NULL; + } + +-- +2.38.1 + diff --git a/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch b/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch new file mode 100644 index 0000000..f888a09 --- /dev/null +++ b/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch @@ -0,0 +1,54 @@ +From 24d329fc97a64ec185ef27e59730f3f058c09029 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 5 Jan 2023 00:29:20 +0800 +Subject: [PATCH 79/83] mdadm/udev: Don't handle change event on raw devices + +The raw devices are ready when add event happpens and the raid +can be assembled. So there is no need to handle change events. +And it can cause some inconvenient problems. + +For example, the OS is installed on md0(/root) and md1(/home). +md0 and md1 are created on partitions. When it wants to re-install +OS, anaconda can't clear the storage configure. It deletes one +partition and does some jobs. The change event happens. Now +the raid device is assembled again. It can't delete the other +partitions. + +So in this patch, we don't handle change event on raw devices +anymore. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + udev-md-raid-assembly.rules | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules +index 39b4344b..d4a7f0a5 100644 +--- a/udev-md-raid-assembly.rules ++++ b/udev-md-raid-assembly.rules +@@ -11,6 +11,11 @@ SUBSYSTEM!="block", GOTO="md_inc_end" + ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end" + + # handle potential components of arrays (the ones supported by md) ++# For member devices which are md/dm devices, we don't need to ++# handle add event. Because md/dm devices need to do some init jobs. ++# Then the change event happens. ++# When adding md/dm devices, ID_FS_TYPE can only be linux_raid_member ++# after change event happens. + ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc" + + # "noiswmd" on kernel command line stops mdadm from handling +@@ -28,6 +33,9 @@ GOTO="md_inc_end" + + LABEL="md_inc" + ++# Bare disks are ready when add event happens, the raid can be assembled. ++ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end" ++ + # remember you can limit what gets auto/incrementally assembled by + # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' + ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" +-- +2.38.1 + diff --git a/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch b/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch new file mode 100644 index 0000000..e2c1179 --- /dev/null +++ b/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch @@ -0,0 +1,33 @@ +From b3e7b7eb1dfedd7cbd9a3800e884941f67d94c96 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Dec 2022 06:50:42 +0100 +Subject: [PATCH 80/83] Manage: do not check array state when drive is removed + +Array state doesn't need to be checked when drive is +removed, but until now clean state was required. Result +of the is_remove_safe() function will be independent +from array state. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Manage.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 594e3d2c..4d6e54b1 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1321,8 +1321,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + sysfs_free(mdi); + + bool is_enough = enough(array->level, array->raid_disks, +- array->layout, (array->state & 1), +- avail); ++ array->layout, 1, avail); + + free(avail); + return is_enough; +-- +2.38.1 + diff --git a/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch b/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch new file mode 100644 index 0000000..4e0169c --- /dev/null +++ b/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch @@ -0,0 +1,59 @@ +From 461fae7e7809670d286cc19aac5bfa861c29f93a Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Dec 2022 06:50:43 +0100 +Subject: [PATCH 81/83] incremental, manage: do not verify if remove is safe + +Function is_remove_safe() was introduced to verify if removing +member device won't cause failed state of the array. This +verification should be used only with set-faulty command. Add +special mode indicating that Incremental removal was executed. +If this mode is used do not execute is_remove_safe() routine. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + Incremental.c | 2 +- + Manage.c | 7 ++++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index ff3548c0..09b94b9f 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1744,7 +1744,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + + memset(&devlist, 0, sizeof(devlist)); + devlist.devname = devname; +- devlist.disposition = 'f'; ++ devlist.disposition = 'I'; + /* for a container, we must fail each member array */ + if (ent->metadata_version && + strncmp(ent->metadata_version, "external:", 9) == 0) { +diff --git a/Manage.c b/Manage.c +index 4d6e54b1..6184d3f7 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1494,8 +1494,9 @@ int Manage_subdevs(char *devname, int fd, + /* Assume this is a kernel-internal name like 'sda1' */ + int found = 0; + char dname[55]; +- if (dv->disposition != 'r' && dv->disposition != 'f') { +- pr_err("%s only meaningful with -r or -f, not -%c\n", ++ if (dv->disposition != 'r' && dv->disposition != 'f' && ++ dv->disposition != 'I') { ++ pr_err("%s only meaningful with -r, -f or -I, not -%c\n", + dv->devname, dv->disposition); + goto abort; + } +@@ -1647,7 +1648,7 @@ int Manage_subdevs(char *devname, int fd, + close(sysfd); + goto abort; + } +- ++ case 'I': /* incremental fail */ + if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || + (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, + rdev))) { +-- +2.38.1 + diff --git a/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch b/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch new file mode 100644 index 0000000..0035c89 --- /dev/null +++ b/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch @@ -0,0 +1,52 @@ +From 071f839ea549e2a384cd13bba445245cd87e48b1 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 28 Oct 2022 04:51:17 +0200 +Subject: [PATCH 82/83] super-intel: make freesize not required for chunk size + migration + +Freesize is needed to be set for migrations where size of RAID could +be changed - expand. It tells how many free space is determined for +members. In chunk size migartion freesize is not needed to be set, +pointer shouldn't be checked if exists. This commit moves check to +condition which contains size calculations, instead of checking it +always at the first step. +Fix return value when superblock is not set. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + super-intel.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 1f5f6eda..89fac626 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7719,11 +7719,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + struct intel_super *super = st->sb; + + /* +- * Autolayout mode, st->sb and freesize must be set. ++ * Autolayout mode, st->sb must be set. + */ +- if (!super || !freesize) { +- pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); +- return 1; ++ if (!super) { ++ pr_vrb("superblock must be set for autolayout, aborting\n"); ++ return 0; + } + + if (!validate_geometry_imsm_orom(st->sb, level, layout, +@@ -7731,7 +7731,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + verbose)) + return 0; + +- if (super->orom) { ++ if (super->orom && freesize) { + imsm_status_t rv; + int count = count_volumes(super->hba, super->orom->dpa, + verbose); +-- +2.38.1 + diff --git a/0083-manage-move-comment-with-function-description.patch b/0083-manage-move-comment-with-function-description.patch new file mode 100644 index 0000000..091854f --- /dev/null +++ b/0083-manage-move-comment-with-function-description.patch @@ -0,0 +1,105 @@ +From 36a707824eb1dafbb990f5daf1cbbe0e37dbbefb Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 5 Jan 2023 06:31:25 +0100 +Subject: [PATCH 83/83] manage: move comment with function description + +Move the function description from the function body to outside +to obey kernel coding style. + +Signed-off-by: Kinga Tanska +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Manage.c | 72 ++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 44 insertions(+), 28 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 6184d3f7..fde6aba3 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1327,38 +1327,54 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + return is_enough; + } + ++/** ++ * Manage_subdevs() - Execute operation depending on devmode. ++ * ++ * @devname: name of the device. ++ * @fd: file descriptor. ++ * @devlist: list of sub-devices to manage. ++ * @verbose: verbose level. ++ * @test: test flag. ++ * @update: type of update. ++ * @force: force flag. ++ * ++ * This function executes operation defined by devmode ++ * for each dev from devlist. ++ * Devmode can be: ++ * 'a' - add the device ++ * 'S' - add the device as a spare - don't try re-add ++ * 'j' - add the device as a journal device ++ * 'A' - re-add the device ++ * 'r' - remove the device: HOT_REMOVE_DISK ++ * device can be 'faulty' or 'detached' in which case all ++ * matching devices are removed. ++ * 'f' - set the device faulty SET_DISK_FAULTY ++ * device can be 'detached' in which case any device that ++ * is inaccessible will be marked faulty. ++ * 'I' - remove device by using incremental fail ++ * which is executed when device is removed surprisingly. ++ * 'R' - mark this device as wanting replacement. ++ * 'W' - this device is added if necessary and activated as ++ * a replacement for a previous 'R' device. ++ * ----- ++ * 'w' - 'W' will be changed to 'w' when it is paired with ++ * a 'R' device. If a 'W' is found while walking the list ++ * it must be unpaired, and is an error. ++ * 'M' - this is created by a 'missing' target. It is a slight ++ * variant on 'A' ++ * 'F' - Another variant of 'A', where the device was faulty ++ * so must be removed from the array first. ++ * 'c' - confirm the device as found (for clustered environments) ++ * ++ * For 'f' and 'r', the device can also be a kernel-internal ++ * name such as 'sdb'. ++ * ++ * Return: 0 on success, otherwise 1 or 2. ++ */ + int Manage_subdevs(char *devname, int fd, + struct mddev_dev *devlist, int verbose, int test, + enum update_opt update, int force) + { +- /* Do something to each dev. +- * devmode can be +- * 'a' - add the device +- * 'S' - add the device as a spare - don't try re-add +- * 'j' - add the device as a journal device +- * 'A' - re-add the device +- * 'r' - remove the device: HOT_REMOVE_DISK +- * device can be 'faulty' or 'detached' in which case all +- * matching devices are removed. +- * 'f' - set the device faulty SET_DISK_FAULTY +- * device can be 'detached' in which case any device that +- * is inaccessible will be marked faulty. +- * 'R' - mark this device as wanting replacement. +- * 'W' - this device is added if necessary and activated as +- * a replacement for a previous 'R' device. +- * ----- +- * 'w' - 'W' will be changed to 'w' when it is paired with +- * a 'R' device. If a 'W' is found while walking the list +- * it must be unpaired, and is an error. +- * 'M' - this is created by a 'missing' target. It is a slight +- * variant on 'A' +- * 'F' - Another variant of 'A', where the device was faulty +- * so must be removed from the array first. +- * 'c' - confirm the device as found (for clustered environments) +- * +- * For 'f' and 'r', the device can also be a kernel-internal +- * name such as 'sdb'. +- */ + mdu_array_info_t array; + unsigned long long array_size; + struct mddev_dev *dv; +-- +2.38.1 + diff --git a/mdadm-udev.patch b/mdadm-udev.patch new file mode 100644 index 0000000..a9d4d93 --- /dev/null +++ b/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/mdadm.rules b/mdadm.rules deleted file mode 100644 index 682e9e8..0000000 --- a/mdadm.rules +++ /dev/null @@ -1,67 +0,0 @@ -# This file causes block devices with Linux RAID (mdadm) signatures to -# automatically cause mdadm to be run. -# See udev(8) for syntax - -# 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), but we must process change events as well -# on any dm devices (like LUKS partitions or LVM logical volumes) and on -# md devices because both of these first get added, then get brought live -# and trigger a change event. The reason we don't process change events -# on bare hard disks is because if you stop all arrays on a disk, then -# run fdisk on the disk to change the partitions, when fdisk exits it -# triggers a change event, and we want to wait until all the fdisks on -# all member disks are done before we do anything. Unfortunately, we have -# no way of knowing that, so we just have to let those arrays be brought -# up manually after fdisk has been run on all of the disks. - -# First, process all add events (md and dm devices will not really do -# anything here, just regular disks, and this also won't get any imsm -# array members either) -SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \ - IMPORT{program}="/sbin/mdadm -I $env{DEVNAME} --export $devnode --offroot $${DEVLINKS}" -SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \ - ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \ - ENV{ID_FS_TYPE}=="linux_raid_member", \ - RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}" -SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \ - ENV{ID_FS_TYPE}=="linux_raid_member", \ - RUN+="/sbin/mdadm -If $name" - -# Next, check to make sure the BIOS raid stuff wasn't turned off via cmdline -IMPORT{cmdline}="noiswmd" -IMPORT{cmdline}="nodmraid" -ENV{noiswmd}=="?*", GOTO="md_imsm_inc_end" -ENV{nodmraid}=="?*", GOTO="md_imsm_inc_end" -SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="isw_raid_member", \ - RUN+="/sbin/mdadm -I $env{DEVNAME}" -SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \ - ENV{ID_FS_TYPE}=="isw_raid_member", \ - RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}" -SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \ - ENV{ID_FS_TYPE}=="isw_raid_member", \ - RUN+="/sbin/mdadm -If $name" -LABEL="md_imsm_inc_end" - -# Next make sure that this isn't a dm device we should skip for some reason -ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="dm_change_end" -ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="dm_change_end" -ENV{DM_SUSPENDED}=="1", GOTO="dm_change_end" -KERNEL=="dm-*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \ - ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}" -LABEL="dm_change_end" - -# Finally catch any nested md raid arrays. If we brought up an md raid -# array that's part of another md raid array, it won't be ready to be used -# until the change event that occurs when it becomes live -KERNEL=="md*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \ - ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}" - -LABEL="md_end" diff --git a/mdadm.spec b/mdadm.spec index 06886b6..e03694c 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,26 +1,108 @@ Name: mdadm Version: 4.2 -Release: 3%{?dist} +Release: 4%{?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.rules -Source3: mdadm-raid-check-sysconfig -Source4: mdmonitor.service -Source5: mdadm.conf -Source6: mdadm_event.conf -Source7: raid-check.timer -Source8: raid-check.service +Source2: mdadm-raid-check-sysconfig +Source3: mdmonitor.service +Source4: mdadm.conf +Source5: mdadm_event.conf +Source6: raid-check.timer +Source7: raid-check.service -# Build without -Werror. -Patch00: disable-Werror.patch +Patch000: 0001-Unify-error-message.patch +Patch001: 0002-mdadm-Fix-double-free.patch +Patch002: 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch +Patch003: 0004-udev-adapt-rules-to-systemd-v247.patch +Patch004: 0005-Replace-error-prone-signal-with-sigaction.patch +Patch005: 0006-mdadm-Respect-config-file-location-in-man.patch +Patch006: 0007-mdadm-Update-ReadMe.patch +Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch +Patch008: 0009-mdadm-Update-config-manual.patch +Patch009: 0010-Create-Build-use-default_layout.patch +Patch010: 0011-mdadm-add-map_num_s.patch +# patch0012 is deleted because of needing KillMode=none +Patch011: 0013-mdmon-Stop-parsing-duplicate-options.patch +Patch012: 0014-Grow-block-n-on-external-volumes.patch +Patch013: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch +Patch014: 0016-Mdmonitor-Fix-segfault.patch +Patch015: 0017-Mdmonitor-Improve-logging-method.patch +Patch016: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +Patch017: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +Patch018: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +Patch019: 0021-util-replace-ioctl-use-with-function.patch +Patch020: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +Patch021: 0023-imsm-introduce-get_disk_slot_in_dev.patch +Patch022: 0024-imsm-use-same-slot-across-container.patch +Patch023: 0025-imsm-block-changing-slots-during-creation.patch +Patch024: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch +Patch025: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch +Patch026: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +Patch027: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch +Patch028: 0030-Monitor-use-snprintf-to-fill-device-name.patch +Patch029: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch +Patch030: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch +Patch031: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +Patch032: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +Patch033: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +Patch034: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch +Patch035: 0037-mdadm-Fix-optional-write-behind-parameter.patch +Patch036: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch +Patch037: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch +Patch038: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch +Patch039: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch +Patch040: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch +Patch041: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch +Patch042: 0044-tests-Add-broken-files-for-all-broken-tests.patch +Patch043: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +Patch044: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch +Patch045: 0047-tests-add-test-for-names.patch +Patch046: 0048-mdadm-remove-symlink-option.patch +Patch047: 0049-mdadm-move-data_offset-to-struct-shape.patch +Patch048: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +Patch049: 0051-Grow-Split-Grow_reshape-into-helper-function.patch +Patch050: 0052-Assemble-check-if-device-is-container-before-schedul.patch +Patch051: 0053-super1-report-truncated-device.patch +Patch052: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +Patch053: 0055-Manage-Block-unsafe-member-failing.patch +Patch054: 0056-Monitor-Fix-statelist-memory-leaks.patch +Patch055: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +Patch056: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch +Patch057: 0059-ReadMe-fix-command-line-help.patch +Patch058: 0060-mdadm-replace-container-level-checking-with-inline.patch +Patch059: 0061-Mdmonitor-Omit-non-md-devices.patch +Patch060: 0062-Mdmonitor-Split-alert-into-separate-functions.patch +Patch061: 0063-Monitor-block-if-monitor-modes-are-combined.patch +Patch062: 0064-Update-mdadm-Monitor-manual.patch +Patch063: 0065-Grow-fix-possible-memory-leak.patch +Patch064: 0066-mdadm-create-ident_init.patch +Patch065: 0067-mdadm-Add-option-validation-for-update-subarray.patch +Patch066: 0068-Fix-update-subarray-on-active-volume.patch +Patch067: 0069-Add-code-specific-update-options-to-enum.patch +Patch068: 0070-super-ddf-Remove-update_super_ddf.patch +Patch069: 0071-super0-refactor-the-code-for-enum.patch +Patch070: 0072-super1-refactor-the-code-for-enum.patch +Patch071: 0073-super-intel-refactor-the-code-for-enum.patch +Patch072: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch +Patch073: 0075-Manage-Incremental-code-refactor-string-to-enum.patch +Patch074: 0076-Change-char-to-enum-in-context-update-refactor-code.patch +Patch075: 0077-mdmon-fix-segfault.patch +Patch076: 0078-util-remove-obsolete-code-from-get_md_name.patch +Patch077: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +Patch078: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch +Patch079: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch +Patch080: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch +Patch081: 0083-manage-move-comment-with-function-description.patch # Fedora customization patches -Patch97: mdadm-3.3-udev.patch +Patch97: mdadm-udev.patch Patch98: mdadm-2.5.2-static.patch +# Build without -Werror. +Patch99: disable-Werror.patch BuildRequires: make BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel @@ -45,25 +127,24 @@ make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR %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}%{_udevrulesdir}/65-md-incremental.rules -install -Dp -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/raid-check +install -Dp -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/raid-check mkdir -p -m 710 %{buildroot}/run/mdadm # systemd mkdir -p %{buildroot}%{_unitdir} -install -m644 %{SOURCE4} %{buildroot}%{_unitdir} +install -m644 %{SOURCE3} %{buildroot}%{_unitdir} +install -m644 %{SOURCE6} %{buildroot}%{_unitdir} install -m644 %{SOURCE7} %{buildroot}%{_unitdir} -install -m644 %{SOURCE8} %{buildroot}%{_unitdir} # tmpfile mkdir -p %{buildroot}%{_tmpfilesdir} -install -m 0644 %{SOURCE5} %{buildroot}%{_tmpfilesdir}/%{name}.conf +install -m 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf mkdir -p %{buildroot}%{_localstatedir}/run/ install -d -m 0710 %{buildroot}/run/%{name}/ # abrt mkdir -p %{buildroot}/etc/libreport/events.d -install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d +install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d %post %systemd_post mdmonitor.service raid-check.timer @@ -89,6 +170,10 @@ install -m644 %{SOURCE6} %{buildroot}/etc/libreport/events.d /etc/libreport/events.d/* %changelog +* 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 From a91fbc1088a22bb4524b3a807d1a5f3c82f9bfaa Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Wed, 12 Apr 2023 20:46:33 +0800 Subject: [PATCH 07/22] Update to latest upstream and fix mdcheck service bug Now mdcheck service can't be run successfully. We need to put mdcheck in to the right place (/usr/share/mdadm/mdcheck) and it needs to remove the dependency of mdadm_env.sh which is fixed in patch 76c224c6c. And there is a history problem. It needed KillMode=none before, so it removed the upstream patch 52c67fcdd. Now this problem has been fixed, so we can do the backport more easilly now. We don't need to remove the upstream patch here again. Resolves: bz#2175540 Signed-off-by: Xiao Ni --- ...move-KillMode-none-from-service-file.patch | 69 +++ ...temd-remove-KillMode-none-from-servi.patch | 54 +++ ...hange-bitmap-type-from-none-to-clust.patch | 45 ++ ...-Fix-NULL-dereference-in-super_by_fd.patch | 76 +++ 0087-Mdmonitor-Make-alert_info-global.patch | 369 ++++++++++++++ ...vents-to-alert-using-enums-instead-o.patch | 313 ++++++++++++ 0089-Mdmonitor-Add-helper-functions.patch | 406 ++++++++++++++++ ...etermine-whether-directories-or-file.patch | 83 ++++ ...nitor-Refactor-write_autorebuild_pid.patch | 110 +++++ ...or-check_one_sharer-for-better-error.patch | 139 ++++++ ...er-code-lines-in-parse_layout_faulty.patch | 41 ++ ...c-fix-memleak-in-parse_layout_faulty.patch | 32 ++ 0095-Detail.c-fix-memleak-in-Detail.patch | 31 ++ ...l.c-fix-double-free-in-load_imsm_mpb.patch | 63 +++ ...ix-memleak-in-find_disk_attached_hba.patch | 39 ++ ...ix-memleak-in-get_vd_num_of_subarray.patch | 46 ++ ...t_locked-instead-of-return-1-in-erro.patch | 36 ++ ...emove-safe_mode_delay-local-variable.patch | 64 +++ ...-Create-Factor-out-add_disks-helpers.patch | 452 ++++++++++++++++++ 0102-mdadm-Introduce-pr_info.patch | 72 +++ ...dm-Add-write-zeros-option-for-Create.patch | 346 ++++++++++++++ ...ro-Introduce-test-to-exercise-write-.patch | 44 ++ ...e-Add-write-zeroes-option-to-manpage.patch | 56 +++ ...sing-_Alignof-when-using-C11-or-newe.patch | 53 ++ ...-etc-initrd-release-to-detect-initrd.patch | 41 ++ ...n-t-test-both-all-and-container_name.patch | 47 ++ ...-systemd-unit-file-to-use-foreground.patch | 33 ++ ...-mdmon-Remove-need-for-KillMode-none.patch | 55 +++ ...dmon-Improve-switchroot-interactions.patch | 166 +++++++ ...mdopen-always-try-create_named_array.patch | 40 ++ ...vements-for-IMSM_NO_PLATFORM-testing.patch | 172 +++++++ ...adm-systemd-remove-KillMode-none-fro.patch | 29 ++ ...ing-for-container-in-update_metadata.patch | 38 ++ ...ull-pointer-for-incremental-in-mdadm.patch | 43 ++ ...-truncation-check-for-journal-device.patch | 33 ++ 0118-Fix-some-cases-eyesore-formatting.patch | 433 +++++++++++++++++ ...ump-minimum-kernel-version-to-2.6.32.patch | 136 ++++++ ...g-files-in-mdcheck_start-continue-se.patch | 42 ++ mdadm.spec | 197 +++++--- mdcheck | 166 +++++++ 40 files changed, 4634 insertions(+), 76 deletions(-) create mode 100644 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch create mode 100644 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch create mode 100644 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch create mode 100644 0086-Fix-NULL-dereference-in-super_by_fd.patch create mode 100644 0087-Mdmonitor-Make-alert_info-global.patch create mode 100644 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch create mode 100644 0089-Mdmonitor-Add-helper-functions.patch create mode 100644 0090-Add-helpers-to-determine-whether-directories-or-file.patch create mode 100644 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch create mode 100644 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch create mode 100644 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch create mode 100644 0094-util.c-fix-memleak-in-parse_layout_faulty.patch create mode 100644 0095-Detail.c-fix-memleak-in-Detail.patch create mode 100644 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch create mode 100644 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch create mode 100644 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch create mode 100644 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch create mode 100644 0100-Create-remove-safe_mode_delay-local-variable.patch create mode 100644 0101-Create-Factor-out-add_disks-helpers.patch create mode 100644 0102-mdadm-Introduce-pr_info.patch create mode 100644 0103-mdadm-Add-write-zeros-option-for-Create.patch create mode 100644 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch create mode 100644 0105-manpage-Add-write-zeroes-option-to-manpage.patch create mode 100644 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch create mode 100644 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch create mode 100644 0108-mdmon-don-t-test-both-all-and-container_name.patch create mode 100644 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch create mode 100644 0110-mdmon-Remove-need-for-KillMode-none.patch create mode 100644 0111-mdmon-Improve-switchroot-interactions.patch create mode 100644 0112-mdopen-always-try-create_named_array.patch create mode 100644 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch create mode 100644 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch create mode 100644 0115-Create-Fix-checking-for-container-in-update_metadata.patch create mode 100644 0116-Fix-null-pointer-for-incremental-in-mdadm.patch create mode 100644 0117-super1-fix-truncation-check-for-journal-device.patch create mode 100644 0118-Fix-some-cases-eyesore-formatting.patch create mode 100644 0119-Bump-minimum-kernel-version-to-2.6.32.patch create mode 100644 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch create mode 100644 mdcheck diff --git a/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch b/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch new file mode 100644 index 0000000..ae67325 --- /dev/null +++ b/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch @@ -0,0 +1,69 @@ +From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Tue, 15 Feb 2022 21:34:15 +0800 +Subject: [PATCH 012/120] mdadm/systemd: remove KillMode=none from service file + +For mdadm's systemd configuration, current systemd KillMode is "none" in +following service files, +- mdadm-grow-continue@.service +- mdmon@.service + +This "none" mode is strongly againsted by systemd developers (see man 5 +systemd.kill for "KillMode=" section), and is considering to remove in +future systemd version. + +As systemd developer explained in disuccsion, the systemd kill process +is, +1. send the signal specified by KillSignal= to the list of processes (if + any), TERM is the default +2. wait until either the target of process(es) exit or a timeout expires +3. if the timeout expires send the signal specified by FinalKillSignal=, + KILL is the default + +For "control-group", all remaining processes will receive the SIGTERM +signal (by default) and if there are still processes after a period f +time, they will get the SIGKILL signal. + +For "mixed", only the main process will receive the SIGTERM signal, and +if there are still processes after a period of time, all remaining +processes (including the main one) will receive the SIGKILL signal. + +From the above comment, currently KillMode=control-group is a proper +kill mode. Since control-gropu is the default kill mode, the fix can be +simply removing KillMode=none line from the service file, then the +default mode will take effect. + +Signed-off-by: Coly Li +Cc: Benjamin Brunner +Cc: Franck Bui +Cc: Jes Sorensen +Cc: Mariusz Tkaczyk +Cc: Neil Brown +Cc: Xiao Ni +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 1 - + systemd/mdmon@.service | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 5c667d2a..9fdc8ec7 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I + StandardInput=null + StandardOutput=null + StandardError=null +-KillMode=none +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index 85a3a7c5..77533958 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -25,4 +25,3 @@ Type=forking + # it out) and systemd will remove it when transitioning from + # initramfs to rootfs. + #PIDFile=/run/mdadm/%I.pid +-KillMode=none +-- +2.38.1 + diff --git a/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch b/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch new file mode 100644 index 0000000..d824449 --- /dev/null +++ b/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch @@ -0,0 +1,54 @@ +From 28a083955c6f58f8e582734c8c82aff909a7d461 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 2 Feb 2023 08:56:31 +0100 +Subject: [PATCH 084/120] Revert "mdadm/systemd: remove KillMode=none from + service file" + +This reverts commit 52c67fcdd6dadc4138ecad73e65599551804d445. + +The functionality is marked as deprecated but we don't have alternative +solution yet. Shutdown hangs if OS is installed on external array: + +task:umount state:D stack: 0 pid: 6285 ppid: flags:0x00004084 +Call Trace: +__schedule+0x2d1/0x830 +? finish_wait+0x80/0x80 +schedule+0x35/0xa0 +md_write_start+0x14b/0x220 +? finish_wait+0x80/0x80 +raid1_make_request+0x3c/0x90 [raid1] +md_handle_request+0x128/0x1b0 +md_make_request+0x5b/0xb0 +generic_make_request_no_check+0x202/0x330 +submit_bio+0x3c/0x160 + +Use it until new solution is implemented. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 1 + + systemd/mdmon@.service | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 64b8254a..9ccadca3 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -15,3 +15,4 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I + StandardInput=null + StandardOutput=null + StandardError=null ++KillMode=none +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index 97a1acd9..cb6482d9 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -26,3 +26,4 @@ Type=forking + # it out) and systemd will remove it when transitioning from + # initramfs to rootfs. + #PIDFile=/run/mdadm/%I.pid ++KillMode=none +-- +2.38.1 + diff --git a/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch b/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch new file mode 100644 index 0000000..0bc1069 --- /dev/null +++ b/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch @@ -0,0 +1,45 @@ +From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Thu, 23 Feb 2023 22:39:39 +0800 +Subject: [PATCH 085/120] Grow: fix can't change bitmap type from none to + clustered. + +Commit a042210648ed ("disallow create or grow clustered bitmap with +writemostly set") introduced this bug. We should use 'true' logic not +'== 0' to deny setting up clustered array under WRITEMOSTLY condition. + +How to trigger + +``` +~/mdadm # ./mdadm -Ss && ./mdadm --zero-superblock /dev/sd{a,b} +~/mdadm # ./mdadm -C /dev/md0 -l mirror -b clustered -e 1.2 -n 2 \ +/dev/sda /dev/sdb --assume-clean +mdadm: array /dev/md0 started. +~/mdadm # ./mdadm --grow /dev/md0 --bitmap=none +~/mdadm # ./mdadm --grow /dev/md0 --bitmap=clustered +mdadm: /dev/md0 disks marked write-mostly are not supported with clustered bitmap +``` + +Signed-off-by: Heming Zhao +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Grow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 8f5cf07d..bb5fe45c 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -429,7 +429,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + dv = map_dev(disk.major, disk.minor, 1); + if (!dv) + continue; +- if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && ++ if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) && + (strcmp(s->bitmap_file, "clustered") == 0)) { + pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); + free(mdi); +-- +2.38.1 + diff --git a/0086-Fix-NULL-dereference-in-super_by_fd.patch b/0086-Fix-NULL-dereference-in-super_by_fd.patch new file mode 100644 index 0000000..95cb79a --- /dev/null +++ b/0086-Fix-NULL-dereference-in-super_by_fd.patch @@ -0,0 +1,76 @@ +From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001 +From: Li Xiao Keng +Date: Mon, 27 Feb 2023 11:12:07 +0800 +Subject: [PATCH 086/120] Fix NULL dereference in super_by_fd + +When we create 100 partitions (major is 259 not 254) in a raid device, +mdadm may coredump: + +Core was generated by `/usr/sbin/mdadm --detail --export /dev/md1p7'. +Program terminated with signal SIGSEGV, Segmentation fault. +#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 +74 VPCMPEQ (%rdi), %ymm0, %ymm1 +(gdb) bt +#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 +#1 0x00007fbb9a7e4139 in __strcpy_chk (dest=dest@entry=0x55d55d6a13ac "", src=0x0, destlen=destlen@entry=32) at strcpy_chk.c:28 +#2 0x000055d55ba1766d in strcpy (__src=, __dest=0x55d55d6a13ac "") at /usr/include/bits/string_fortified.h:79 +#3 super_by_fd (fd=fd@entry=3, subarrayp=subarrayp@entry=0x7fff44dfcc48) at util.c:1289 +#4 0x000055d55ba273a6 in Detail (dev=0x7fff44dfef0b "/dev/md1p7", c=0x7fff44dfe440) at Detail.c:101 +#5 0x000055d55ba0de61 in misc_list (c=, ss=, dump_directory=, ident=, devlist=) at mdadm.c:1959 +#6 main (argc=, argv=) at mdadm.c:1629 + +The direct cause is fd2devnm returning NULL, so add a check. + +Signed-off-by: Li Xiao Keng +Signed-off-by: Wu Guang Hao +Acked-by: Coly Li +Acked-by: Coly Li > +Signed-off-by: Jes Sorensen +--- + mapfile.c | 4 ++++ + util.c | 7 ++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/mapfile.c b/mapfile.c +index 6b2207dd..ac351768 100644 +--- a/mapfile.c ++++ b/mapfile.c +@@ -292,6 +292,10 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) + struct map_ent *map_by_devnm(struct map_ent **map, char *devnm) + { + struct map_ent *mp; ++ ++ if (!devnm) ++ return NULL; ++ + if (!*map) + map_read(map); + +diff --git a/util.c b/util.c +index 9cd89fa4..8c7f3fd5 100644 +--- a/util.c ++++ b/util.c +@@ -1160,6 +1160,11 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + int i; + char *subarray = NULL; + char container[32] = ""; ++ char *devnm = NULL; ++ ++ devnm = fd2devnm(fd); ++ if (!devnm) ++ return NULL; + + sra = sysfs_read(fd, NULL, GET_VERSION); + +@@ -1205,7 +1210,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + if (subarrayp) + *subarrayp = subarray; + strcpy(st->container_devnm, container); +- strcpy(st->devnm, fd2devnm(fd)); ++ strncpy(st->devnm, devnm, MD_NAME_MAX - 1); + } else + free(subarray); + +-- +2.38.1 + diff --git a/0087-Mdmonitor-Make-alert_info-global.patch b/0087-Mdmonitor-Make-alert_info-global.patch new file mode 100644 index 0000000..c8da02b --- /dev/null +++ b/0087-Mdmonitor-Make-alert_info-global.patch @@ -0,0 +1,369 @@ +From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:26:59 +0100 +Subject: [PATCH 087/120] Mdmonitor: Make alert_info global + +Move information about --test flag and hostname into alert_info. + +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Monitor.c | 124 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 61 insertions(+), 63 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 188cb8be..9ef4dab8 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -58,21 +58,20 @@ struct state { + }; + + struct alert_info { ++ char hostname[HOST_NAME_MAX]; + char *mailaddr; + char *mailfrom; + char *alert_cmd; + int dosyslog; +-}; ++ int test; ++} info; + static int make_daemon(char *pidfile); + static int check_one_sharer(int scan); + static void write_autorebuild_pid(void); +-static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); +-static int check_array(struct state *st, struct mdstat_ent *mdstat, +- int test, struct alert_info *info, +- int increments, char *prefer); +-static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, +- int test, struct alert_info *info); +-static void try_spare_migration(struct state *statelist, struct alert_info *info); ++static void alert(const char *event, const char *dev, const char *disc); ++static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); ++static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); ++static void try_spare_migration(struct state *statelist); + static void link_containers_with_subarrays(struct state *list); + static void free_statelist(struct state *statelist); + #ifndef NO_LIBUDEV +@@ -132,7 +131,6 @@ int Monitor(struct mddev_dev *devlist, + int finished = 0; + struct mdstat_ent *mdstat = NULL; + char *mailfrom; +- struct alert_info info; + struct mddev_ident *mdlist; + int delay_for_event = c->delay; + +@@ -166,6 +164,13 @@ int Monitor(struct mddev_dev *devlist, + info.mailaddr = mailaddr; + info.mailfrom = mailfrom; + info.dosyslog = dosyslog; ++ info.test = c->test; ++ ++ if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { ++ pr_err("Cannot get hostname.\n"); ++ return 1; ++ } ++ info.hostname[sizeof(info.hostname) - 1] = '\0'; + + if (share){ + if (check_one_sharer(c->scan)) +@@ -241,8 +246,7 @@ int Monitor(struct mddev_dev *devlist, + mdstat = mdstat_read(oneshot ? 0 : 1, 0); + + for (st = statelist; st; st = st->next) { +- if (check_array(st, mdstat, c->test, &info, +- increments, c->prefer)) ++ if (check_array(st, mdstat, increments, c->prefer)) + anydegraded = 1; + /* for external arrays, metadata is filled for + * containers only +@@ -255,15 +259,14 @@ int Monitor(struct mddev_dev *devlist, + + /* now check if there are any new devices found in mdstat */ + if (c->scan) +- new_found = add_new_arrays(mdstat, &statelist, c->test, +- &info); ++ new_found = add_new_arrays(mdstat, &statelist); + + /* If an array has active < raid && spare == 0 && spare_group != NULL + * Look for another array with spare > 0 and active == raid and same spare_group + * if found, choose a device and hotremove/hotadd + */ + if (share && anydegraded) +- try_spare_migration(statelist, &info); ++ try_spare_migration(statelist); + if (!new_found) { + if (oneshot) + break; +@@ -294,7 +297,7 @@ int Monitor(struct mddev_dev *devlist, + mdstat_close(); + } + } +- c->test = 0; ++ info.test = 0; + + for (stp = &statelist; (st = *stp) != NULL; ) { + if (st->from_auto && st->err > 5) { +@@ -412,7 +415,7 @@ static void write_autorebuild_pid() + } + } + +-static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) ++static void execute_alert_cmd(const char *event, const char *dev, const char *disc) + { + int pid = fork(); + +@@ -424,15 +427,14 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di + pr_err("Cannot fork to execute alert command"); + break; + case 0: +- execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); ++ execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); + exit(2); + } + } + +-static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) ++static void send_event_email(const char *event, const char *dev, const char *disc) + { + FILE *mp, *mdstat; +- char hname[256]; + char buf[BUFSIZ]; + int n; + +@@ -442,14 +444,13 @@ static void send_event_email(const char *event, const char *dev, const char *dis + return; + } + +- gethostname(hname, sizeof(hname)); + signal(SIGPIPE, SIG_IGN); +- if (info->mailfrom) +- fprintf(mp, "From: %s\n", info->mailfrom); ++ if (info.mailfrom) ++ fprintf(mp, "From: %s\n", info.mailfrom); + else + fprintf(mp, "From: %s monitoring \n", Name); +- fprintf(mp, "To: %s\n", info->mailaddr); +- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); ++ fprintf(mp, "To: %s\n", info.mailaddr); ++ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); + fprintf(mp, "This is an automatically generated mail message. \n"); + fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); + +@@ -501,37 +502,36 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * + syslog(priority, "%s event detected on md device %s", event, dev); + } + +-static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) ++static void alert(const char *event, const char *dev, const char *disc) + { +- if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { ++ if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { + time_t now = time(0); + + printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, + event, dev, disc?disc:"unknown device"); + } +- if (info->alert_cmd) +- execute_alert_cmd(event, dev, disc, info); ++ if (info.alert_cmd) ++ execute_alert_cmd(event, dev, disc); + +- if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || ++ if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || + strncmp(event, "Test", 4) == 0 || + strncmp(event, "Spares", 6) == 0 || + strncmp(event, "Degrade", 7) == 0)) { +- send_event_email(event, dev, disc, info); ++ send_event_email(event, dev, disc); + } + +- if (info->dosyslog) ++ if (info.dosyslog) + log_event_to_syslog(event, dev, disc); + } + + static int check_array(struct state *st, struct mdstat_ent *mdstat, +- int test, struct alert_info *ainfo, + int increments, char *prefer) + { + /* Update the state 'st' to reflect any changes shown in mdstat, + * or found by directly examining the array, and return + * '1' if the array is degraded, or '0' if it is optimal (or dead). + */ +- struct { int state, major, minor; } info[MAX_DISKS]; ++ struct { int state, major, minor; } disks_info[MAX_DISKS]; + struct mdinfo *sra = NULL; + mdu_array_info_t array; + struct mdstat_ent *mse = NULL, *mse2; +@@ -545,8 +545,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + int is_container = 0; + unsigned long redundancy_only_flags = 0; + +- if (test) +- alert("TestMessage", dev, NULL, ainfo); ++ if (info.test) ++ alert("TestMessage", dev, NULL); + + retval = 0; + +@@ -595,7 +595,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + */ + if (sra->array.level == 0 || sra->array.level == -1) { + if (!st->err && !st->from_config) +- alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); ++ alert("DeviceDisappeared", dev, " Wrong-Level"); + st->err++; + goto out; + } +@@ -612,7 +612,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->percent = RESYNC_NONE; + new_array = 1; + if (!is_container) +- alert("NewArray", st->devname, NULL, ainfo); ++ alert("NewArray", st->devname, NULL); + } + + if (st->utime == array.utime && st->failed == sra->array.failed_disks && +@@ -625,14 +625,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + if (st->utime == 0 && /* new array */ + mse->pattern && strchr(mse->pattern, '_') /* degraded */) +- alert("DegradedArray", dev, NULL, ainfo); ++ alert("DegradedArray", dev, NULL); + + if (st->utime == 0 && /* new array */ st->expected_spares > 0 && + sra->array.spare_disks < st->expected_spares) +- alert("SparesMissing", dev, NULL, ainfo); ++ alert("SparesMissing", dev, NULL); + if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && + mse->percent >= 0) +- alert("RebuildStarted", dev, NULL, ainfo); ++ alert("RebuildStarted", dev, NULL); + if (st->percent >= 0 && mse->percent >= 0 && + (mse->percent / increments) > (st->percent / increments)) { + char percentalert[18]; +@@ -647,7 +647,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + snprintf(percentalert, sizeof(percentalert), + "Rebuild%02d", mse->percent); + +- alert(percentalert, dev, NULL, ainfo); ++ alert(percentalert, dev, NULL); + } + + if (mse->percent == RESYNC_NONE && st->percent >= 0) { +@@ -660,9 +660,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + snprintf(cnt, sizeof(cnt), + " mismatches found: %d (on raid level %d)", + sra->mismatch_cnt, sra->array.level); +- alert("RebuildFinished", dev, cnt, ainfo); ++ alert("RebuildFinished", dev, cnt); + } else +- alert("RebuildFinished", dev, NULL, ainfo); ++ alert("RebuildFinished", dev, NULL); + } + st->percent = mse->percent; + +@@ -671,13 +671,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + mdu_disk_info_t disc; + disc.number = i; + if (md_get_disk_info(fd, &disc) >= 0) { +- info[i].state = disc.state; +- info[i].major = disc.major; +- info[i].minor = disc.minor; ++ disks_info[i].state = disc.state; ++ disks_info[i].major = disc.major; ++ disks_info[i].minor = disc.minor; + if (disc.major || disc.minor) + remaining_disks --; + } else +- info[i].major = info[i].minor = 0; ++ disks_info[i].major = disks_info[i].minor = 0; + } + last_disk = i; + +@@ -700,13 +700,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + int change; + char *dv = NULL; + disc.number = i; +- if (i < last_disk && (info[i].major || info[i].minor)) { +- newstate = info[i].state; +- dv = map_dev_preferred(info[i].major, info[i].minor, 1, ++ if (i < last_disk && (disks_info[i].major || disks_info[i].minor)) { ++ newstate = disks_info[i].state; ++ dv = map_dev_preferred(disks_info[i].major, disks_info[i].minor, 1, + prefer); + disc.state = newstate; +- disc.major = info[i].major; +- disc.minor = info[i].minor; ++ disc.major = disks_info[i].major; ++ disc.minor = disks_info[i].minor; + } else + newstate = (1 << MD_DISK_REMOVED); + +@@ -716,14 +716,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + change = newstate ^ st->devstate[i]; + if (st->utime && change && !st->err && !new_array) { + if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) +- alert("Fail", dev, dv, ainfo); ++ alert("Fail", dev, dv); + else if ((newstate & (1 << MD_DISK_FAULTY)) && + (disc.major || disc.minor) && + st->devid[i] == makedev(disc.major, + disc.minor)) +- alert("FailSpare", dev, dv, ainfo); ++ alert("FailSpare", dev, dv); + else if ((newstate&change) & (1 << MD_DISK_SYNC)) +- alert("SpareActive", dev, dv, ainfo); ++ alert("SpareActive", dev, dv); + } + st->devstate[i] = newstate; + st->devid[i] = makedev(disc.major, disc.minor); +@@ -747,13 +747,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + + disappeared: + if (!st->err && !is_container) +- alert("DeviceDisappeared", dev, NULL, ainfo); ++ alert("DeviceDisappeared", dev, NULL); + st->err++; + goto out; + } + +-static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, +- int test, struct alert_info *info) ++static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + { + struct mdstat_ent *mse; + int new_found = 0; +@@ -806,8 +805,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + } else + st->parent_devnm[0] = 0; + *statelist = st; +- if (test) +- alert("TestMessage", st->devname, NULL, info); ++ if (info.test) ++ alert("TestMessage", st->devname, NULL); + new_found = 1; + } + return new_found; +@@ -971,7 +970,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to, + return dev; + } + +-static void try_spare_migration(struct state *statelist, struct alert_info *info) ++static void try_spare_migration(struct state *statelist) + { + struct state *from; + struct state *st; +@@ -1030,8 +1029,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info + if (devid > 0 && + move_spare(from->devname, to->devname, + devid)) { +- alert("MoveSpare", to->devname, +- from->devname, info); ++ alert("MoveSpare", to->devname, from->devname); + break; + } + } +-- +2.38.1 + diff --git a/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch b/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch new file mode 100644 index 0000000..c5f2b97 --- /dev/null +++ b/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch @@ -0,0 +1,313 @@ +From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:00 +0100 +Subject: [PATCH 088/120] Mdmonitor: Pass events to alert() using enums instead + of strings + +Add events enum, and mapping_t struct, that maps them to strings, so +that enums are passed around instead of strings. + +Signed-off-by: Mateusz Grzonka +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Monitor.c | 136 +++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 83 insertions(+), 53 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 9ef4dab8..029e9efd 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -32,6 +32,8 @@ + #include + #endif + ++#define EVENT_NAME_MAX 32 ++ + struct state { + char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ + char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ +@@ -65,10 +67,43 @@ struct alert_info { + int dosyslog; + int test; + } info; ++ ++enum event { ++ EVENT_SPARE_ACTIVE = 0, ++ EVENT_NEW_ARRAY, ++ EVENT_MOVE_SPARE, ++ EVENT_TEST_MESSAGE, ++ EVENT_REBUILD_STARTED, ++ EVENT_REBUILD, ++ EVENT_REBUILD_FINISHED, ++ EVENT_SPARES_MISSING, ++ EVENT_DEVICE_DISAPPEARED, ++ EVENT_FAIL, ++ EVENT_FAIL_SPARE, ++ EVENT_DEGRADED_ARRAY, ++ EVENT_UNKNOWN ++}; ++ ++mapping_t events_map[] = { ++ {"SpareActive", EVENT_SPARE_ACTIVE}, ++ {"NewArray", EVENT_NEW_ARRAY}, ++ {"MoveSpare", EVENT_MOVE_SPARE}, ++ {"TestMessage", EVENT_TEST_MESSAGE}, ++ {"RebuildStarted", EVENT_REBUILD_STARTED}, ++ {"Rebuild", EVENT_REBUILD}, ++ {"RebuildFinished", EVENT_REBUILD_FINISHED}, ++ {"SparesMissing", EVENT_SPARES_MISSING}, ++ {"DeviceDisappeared", EVENT_DEVICE_DISAPPEARED}, ++ {"Fail", EVENT_FAIL}, ++ {"FailSpare", EVENT_FAIL_SPARE}, ++ {"DegradedArray", EVENT_DEGRADED_ARRAY}, ++ {NULL, EVENT_UNKNOWN} ++}; ++ + static int make_daemon(char *pidfile); + static int check_one_sharer(int scan); + static void write_autorebuild_pid(void); +-static void alert(const char *event, const char *dev, const char *disc); ++static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); + static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); + static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); + static void try_spare_migration(struct state *statelist); +@@ -415,7 +450,7 @@ static void write_autorebuild_pid() + } + } + +-static void execute_alert_cmd(const char *event, const char *dev, const char *disc) ++static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) + { + int pid = fork(); + +@@ -427,12 +462,12 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di + pr_err("Cannot fork to execute alert command"); + break; + case 0: +- execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); ++ execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); + exit(2); + } + } + +-static void send_event_email(const char *event, const char *dev, const char *disc) ++static void send_event_email(const char *event_name, const char *dev, const char *disc) + { + FILE *mp, *mdstat; + char buf[BUFSIZ]; +@@ -450,9 +485,9 @@ static void send_event_email(const char *event, const char *dev, const char *dis + else + fprintf(mp, "From: %s monitoring \n", Name); + fprintf(mp, "To: %s\n", info.mailaddr); +- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); ++ fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); + fprintf(mp, "This is an automatically generated mail message. \n"); +- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); ++ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); + + if (disc && disc[0] != ' ') + fprintf(mp, +@@ -474,20 +509,20 @@ static void send_event_email(const char *event, const char *dev, const char *dis + pclose(mp); + } + +-static void log_event_to_syslog(const char *event, const char *dev, const char *disc) ++static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) + { + int priority; + /* Log at a different severity depending on the event. + * + * These are the critical events: */ +- if (strncmp(event, "Fail", 4) == 0 || +- strncmp(event, "Degrade", 7) == 0 || +- strncmp(event, "DeviceDisappeared", 17) == 0) ++ if (event_enum == EVENT_FAIL || ++ event_enum == EVENT_DEGRADED_ARRAY || ++ event_enum == EVENT_DEVICE_DISAPPEARED) + priority = LOG_CRIT; + /* Good to know about, but are not failures: */ +- else if (strncmp(event, "Rebuild", 7) == 0 || +- strncmp(event, "MoveSpare", 9) == 0 || +- strncmp(event, "Spares", 6) != 0) ++ else if (event_enum == EVENT_REBUILD || ++ event_enum == EVENT_MOVE_SPARE || ++ event_enum == EVENT_SPARES_MISSING) + priority = LOG_WARNING; + /* Everything else: */ + else +@@ -495,33 +530,37 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * + + if (disc && disc[0] != ' ') + syslog(priority, +- "%s event detected on md device %s, component device %s", event, dev, disc); ++ "%s event detected on md device %s, component device %s", ++ event_name, dev, disc); + else if (disc) +- syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); ++ syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); + else +- syslog(priority, "%s event detected on md device %s", event, dev); ++ syslog(priority, "%s event detected on md device %s", event_name, dev); + } + +-static void alert(const char *event, const char *dev, const char *disc) ++static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) + { +- if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { +- time_t now = time(0); ++ char event_name[EVENT_NAME_MAX]; + +- printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, +- event, dev, disc?disc:"unknown device"); ++ if (event_enum == EVENT_REBUILD) { ++ snprintf(event_name, sizeof(event_name), "%s%02d", ++ map_num_s(events_map, EVENT_REBUILD), progress); ++ } else { ++ snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); + } ++ + if (info.alert_cmd) +- execute_alert_cmd(event, dev, disc); ++ execute_alert_cmd(event_name, dev, disc); + +- if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || +- strncmp(event, "Test", 4) == 0 || +- strncmp(event, "Spares", 6) == 0 || +- strncmp(event, "Degrade", 7) == 0)) { +- send_event_email(event, dev, disc); ++ if (info.mailaddr && (event_enum == EVENT_FAIL || ++ event_enum == EVENT_TEST_MESSAGE || ++ event_enum == EVENT_SPARES_MISSING || ++ event_enum == EVENT_DEGRADED_ARRAY)) { ++ send_event_email(event_name, dev, disc); + } + + if (info.dosyslog) +- log_event_to_syslog(event, dev, disc); ++ log_event_to_syslog(event_enum, event_name, dev, disc); + } + + static int check_array(struct state *st, struct mdstat_ent *mdstat, +@@ -546,7 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + unsigned long redundancy_only_flags = 0; + + if (info.test) +- alert("TestMessage", dev, NULL); ++ alert(EVENT_TEST_MESSAGE, 0, dev, NULL); + + retval = 0; + +@@ -595,7 +634,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + */ + if (sra->array.level == 0 || sra->array.level == -1) { + if (!st->err && !st->from_config) +- alert("DeviceDisappeared", dev, " Wrong-Level"); ++ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); + st->err++; + goto out; + } +@@ -612,7 +651,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->percent = RESYNC_NONE; + new_array = 1; + if (!is_container) +- alert("NewArray", st->devname, NULL); ++ alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); + } + + if (st->utime == array.utime && st->failed == sra->array.failed_disks && +@@ -625,29 +664,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + if (st->utime == 0 && /* new array */ + mse->pattern && strchr(mse->pattern, '_') /* degraded */) +- alert("DegradedArray", dev, NULL); ++ alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); + + if (st->utime == 0 && /* new array */ st->expected_spares > 0 && + sra->array.spare_disks < st->expected_spares) +- alert("SparesMissing", dev, NULL); ++ alert(EVENT_SPARES_MISSING, 0, dev, NULL); + if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && + mse->percent >= 0) +- alert("RebuildStarted", dev, NULL); ++ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); + if (st->percent >= 0 && mse->percent >= 0 && + (mse->percent / increments) > (st->percent / increments)) { +- char percentalert[18]; +- /* +- * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) +- */ +- + if((mse->percent / increments) == 0) +- snprintf(percentalert, sizeof(percentalert), +- "RebuildStarted"); ++ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); + else +- snprintf(percentalert, sizeof(percentalert), +- "Rebuild%02d", mse->percent); +- +- alert(percentalert, dev, NULL); ++ alert(EVENT_REBUILD, mse->percent, dev, NULL); + } + + if (mse->percent == RESYNC_NONE && st->percent >= 0) { +@@ -660,9 +690,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + snprintf(cnt, sizeof(cnt), + " mismatches found: %d (on raid level %d)", + sra->mismatch_cnt, sra->array.level); +- alert("RebuildFinished", dev, cnt); ++ alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); + } else +- alert("RebuildFinished", dev, NULL); ++ alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); + } + st->percent = mse->percent; + +@@ -716,14 +746,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + change = newstate ^ st->devstate[i]; + if (st->utime && change && !st->err && !new_array) { + if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) +- alert("Fail", dev, dv); ++ alert(EVENT_FAIL, 0, dev, dv); + else if ((newstate & (1 << MD_DISK_FAULTY)) && + (disc.major || disc.minor) && + st->devid[i] == makedev(disc.major, + disc.minor)) +- alert("FailSpare", dev, dv); ++ alert(EVENT_FAIL_SPARE, 0, dev, dv); + else if ((newstate&change) & (1 << MD_DISK_SYNC)) +- alert("SpareActive", dev, dv); ++ alert(EVENT_SPARE_ACTIVE, 0, dev, dv); + } + st->devstate[i] = newstate; + st->devid[i] = makedev(disc.major, disc.minor); +@@ -747,7 +777,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + + disappeared: + if (!st->err && !is_container) +- alert("DeviceDisappeared", dev, NULL); ++ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); + st->err++; + goto out; + } +@@ -806,7 +836,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + st->parent_devnm[0] = 0; + *statelist = st; + if (info.test) +- alert("TestMessage", st->devname, NULL); ++ alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); + new_found = 1; + } + return new_found; +@@ -1029,7 +1059,7 @@ static void try_spare_migration(struct state *statelist) + if (devid > 0 && + move_spare(from->devname, to->devname, + devid)) { +- alert("MoveSpare", to->devname, from->devname); ++ alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); + break; + } + } +-- +2.38.1 + diff --git a/0089-Mdmonitor-Add-helper-functions.patch b/0089-Mdmonitor-Add-helper-functions.patch new file mode 100644 index 0000000..b8fc968 --- /dev/null +++ b/0089-Mdmonitor-Add-helper-functions.patch @@ -0,0 +1,406 @@ +From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:01 +0100 +Subject: [PATCH 089/120] Mdmonitor: Add helper functions + +Add functions: +- is_email_event(), +- get_syslog_event_priority(), +- sprint_event_message(), +with kernel style comments containing more detailed descriptions. + +Also update event syslog priorities to be consistent with man. MoveSpare event was described in man as priority info, while implemented as warning. Move event data into a struct, so that it is passed between different functions if needed. +Sort function declarations alphabetically and remove redundant alert() declaration. + +Signed-off-by: Mateusz Grzonka +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Monitor.c | 228 +++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 158 insertions(+), 70 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 029e9efd..39598ba0 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -73,10 +73,12 @@ enum event { + EVENT_NEW_ARRAY, + EVENT_MOVE_SPARE, + EVENT_TEST_MESSAGE, ++ __SYSLOG_PRIORITY_WARNING, + EVENT_REBUILD_STARTED, + EVENT_REBUILD, + EVENT_REBUILD_FINISHED, + EVENT_SPARES_MISSING, ++ __SYSLOG_PRIORITY_CRITICAL, + EVENT_DEVICE_DISAPPEARED, + EVENT_FAIL, + EVENT_FAIL_SPARE, +@@ -100,18 +102,31 @@ mapping_t events_map[] = { + {NULL, EVENT_UNKNOWN} + }; + +-static int make_daemon(char *pidfile); +-static int check_one_sharer(int scan); +-static void write_autorebuild_pid(void); +-static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); +-static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); ++struct event_data { ++ enum event event_enum; ++ /* ++ * @event_name: Rebuild event name must be in form "RebuildXX", where XX is rebuild progress. ++ */ ++ char event_name[EVENT_NAME_MAX]; ++ char message[BUFSIZ]; ++ const char *description; ++ const char *dev; ++ const char *disc; ++}; ++ + static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); + static void try_spare_migration(struct state *statelist); + static void link_containers_with_subarrays(struct state *list); + static void free_statelist(struct state *statelist); ++static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); ++static int check_one_sharer(int scan); + #ifndef NO_LIBUDEV + static int check_udev_activity(void); + #endif ++static void link_containers_with_subarrays(struct state *list); ++static int make_daemon(char *pidfile); ++static void try_spare_migration(struct state *statelist); ++static void write_autorebuild_pid(void); + + int Monitor(struct mddev_dev *devlist, + char *mailaddr, char *alert_cmd, +@@ -450,7 +465,80 @@ static void write_autorebuild_pid() + } + } + +-static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) ++#define BASE_MESSAGE "%s event detected on md device %s" ++#define COMPONENT_DEVICE_MESSAGE ", component device %s" ++#define DESCRIPTION_MESSAGE ": %s" ++/* ++ * sprint_event_message() - Writes basic message about detected event to destination ptr. ++ * @dest: message destination, should be at least the size of BUFSIZ ++ * @data: event data ++ * ++ * Return: 0 on success, 1 on error ++ */ ++static int sprint_event_message(char *dest, const struct event_data *data) ++{ ++ if (!dest || !data) ++ return 1; ++ ++ if (data->disc && data->description) ++ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE DESCRIPTION_MESSAGE, ++ data->event_name, data->dev, data->disc, data->description); ++ else if (data->disc) ++ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE, ++ data->event_name, data->dev, data->disc); ++ else if (data->description) ++ snprintf(dest, BUFSIZ, BASE_MESSAGE DESCRIPTION_MESSAGE, ++ data->event_name, data->dev, data->description); ++ else ++ snprintf(dest, BUFSIZ, BASE_MESSAGE, data->event_name, data->dev); ++ ++ return 0; ++} ++ ++/* ++ * get_syslog_event_priority() - Determines event priority. ++ * @event_enum: event to be checked ++ * ++ * Return: LOG_CRIT, LOG_WARNING or LOG_INFO ++ */ ++static int get_syslog_event_priority(const enum event event_enum) ++{ ++ if (event_enum > __SYSLOG_PRIORITY_CRITICAL) ++ return LOG_CRIT; ++ if (event_enum > __SYSLOG_PRIORITY_WARNING) ++ return LOG_WARNING; ++ return LOG_INFO; ++} ++ ++/* ++ * is_email_event() - Determines whether email for event should be sent or not. ++ * @event_enum: event to be checked ++ * ++ * Return: true if email should be sent, false otherwise ++ */ ++static bool is_email_event(const enum event event_enum) ++{ ++ static const enum event email_events[] = { ++ EVENT_FAIL, ++ EVENT_FAIL_SPARE, ++ EVENT_DEGRADED_ARRAY, ++ EVENT_SPARES_MISSING, ++ EVENT_TEST_MESSAGE ++ }; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(email_events); ++i) { ++ if (event_enum == email_events[i]) ++ return true; ++ } ++ return false; ++} ++ ++/* ++ * execute_alert_cmd() - Forks and executes command provided as alert_cmd. ++ * @data: event data ++ */ ++static void execute_alert_cmd(const struct event_data *data) + { + int pid = fork(); + +@@ -462,12 +550,16 @@ static void execute_alert_cmd(const char *event_name, const char *dev, const cha + pr_err("Cannot fork to execute alert command"); + break; + case 0: +- execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); ++ execl(info.alert_cmd, info.alert_cmd, data->event_name, data->dev, data->disc, NULL); + exit(2); + } + } + +-static void send_event_email(const char *event_name, const char *dev, const char *disc) ++/* ++ * send_event_email() - Sends an email about event detected by monitor. ++ * @data: event data ++ */ ++static void send_event_email(const struct event_data *data) + { + FILE *mp, *mdstat; + char buf[BUFSIZ]; +@@ -485,15 +577,9 @@ static void send_event_email(const char *event_name, const char *dev, const char + else + fprintf(mp, "From: %s monitoring \n", Name); + fprintf(mp, "To: %s\n", info.mailaddr); +- fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); +- fprintf(mp, "This is an automatically generated mail message. \n"); +- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); +- +- if (disc && disc[0] != ' ') +- fprintf(mp, +- "It could be related to component device %s.\n\n", disc); +- if (disc && disc[0] == ' ') +- fprintf(mp, "Extra information:%s.\n\n", disc); ++ fprintf(mp, "Subject: %s event on %s:%s\n\n", data->event_name, data->dev, info.hostname); ++ fprintf(mp, "This is an automatically generated mail message.\n"); ++ fprintf(mp, "%s\n", data->message); + + mdstat = fopen("/proc/mdstat", "r"); + if (!mdstat) { +@@ -509,58 +595,60 @@ static void send_event_email(const char *event_name, const char *dev, const char + pclose(mp); + } + +-static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) ++/* ++ * log_event_to_syslog() - Logs an event into syslog. ++ * @data: event data ++ */ ++static void log_event_to_syslog(const struct event_data *data) + { + int priority; +- /* Log at a different severity depending on the event. +- * +- * These are the critical events: */ +- if (event_enum == EVENT_FAIL || +- event_enum == EVENT_DEGRADED_ARRAY || +- event_enum == EVENT_DEVICE_DISAPPEARED) +- priority = LOG_CRIT; +- /* Good to know about, but are not failures: */ +- else if (event_enum == EVENT_REBUILD || +- event_enum == EVENT_MOVE_SPARE || +- event_enum == EVENT_SPARES_MISSING) +- priority = LOG_WARNING; +- /* Everything else: */ +- else +- priority = LOG_INFO; +- +- if (disc && disc[0] != ' ') +- syslog(priority, +- "%s event detected on md device %s, component device %s", +- event_name, dev, disc); +- else if (disc) +- syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); +- else +- syslog(priority, "%s event detected on md device %s", event_name, dev); ++ ++ priority = get_syslog_event_priority(data->event_enum); ++ ++ syslog(priority, "%s\n", data->message); + } + +-static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) ++/* ++ * alert() - Alerts about the monitor event. ++ * @event_enum: event to be sent ++ * @description: event description ++ * @progress: rebuild progress ++ * @dev: md device name ++ * @disc: component device ++ * ++ * If needed function executes alert command, sends an email or logs event to syslog. ++ */ ++static void alert(const enum event event_enum, const char *description, const uint8_t progress, ++ const char *dev, const char *disc) + { +- char event_name[EVENT_NAME_MAX]; ++ struct event_data data = {.dev = dev, .disc = disc, .description = description}; ++ ++ if (!dev) ++ return; + + if (event_enum == EVENT_REBUILD) { +- snprintf(event_name, sizeof(event_name), "%s%02d", ++ snprintf(data.event_name, sizeof(data.event_name), "%s%02d", + map_num_s(events_map, EVENT_REBUILD), progress); + } else { +- snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); ++ snprintf(data.event_name, sizeof(data.event_name), "%s", map_num_s(events_map, event_enum)); + } + +- if (info.alert_cmd) +- execute_alert_cmd(event_name, dev, disc); ++ data.event_enum = event_enum; + +- if (info.mailaddr && (event_enum == EVENT_FAIL || +- event_enum == EVENT_TEST_MESSAGE || +- event_enum == EVENT_SPARES_MISSING || +- event_enum == EVENT_DEGRADED_ARRAY)) { +- send_event_email(event_name, dev, disc); ++ if (sprint_event_message(data.message, &data) != 0) { ++ pr_err("Cannot create event message.\n"); ++ return; + } ++ pr_err("%s\n", data.message); ++ ++ if (info.alert_cmd) ++ execute_alert_cmd(&data); ++ ++ if (info.mailaddr && is_email_event(event_enum)) ++ send_event_email(&data); + + if (info.dosyslog) +- log_event_to_syslog(event_enum, event_name, dev, disc); ++ log_event_to_syslog(&data); + } + + static int check_array(struct state *st, struct mdstat_ent *mdstat, +@@ -585,7 +673,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + unsigned long redundancy_only_flags = 0; + + if (info.test) +- alert(EVENT_TEST_MESSAGE, 0, dev, NULL); ++ alert(EVENT_TEST_MESSAGE, NULL, 0, dev, NULL); + + retval = 0; + +@@ -634,7 +722,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + */ + if (sra->array.level == 0 || sra->array.level == -1) { + if (!st->err && !st->from_config) +- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); ++ alert(EVENT_DEVICE_DISAPPEARED, "Wrong-Level", 0, dev, NULL); + st->err++; + goto out; + } +@@ -651,7 +739,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->percent = RESYNC_NONE; + new_array = 1; + if (!is_container) +- alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); ++ alert(EVENT_NEW_ARRAY, NULL, 0, st->devname, NULL); + } + + if (st->utime == array.utime && st->failed == sra->array.failed_disks && +@@ -664,20 +752,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + if (st->utime == 0 && /* new array */ + mse->pattern && strchr(mse->pattern, '_') /* degraded */) +- alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); ++ alert(EVENT_DEGRADED_ARRAY, NULL, 0, dev, NULL); + + if (st->utime == 0 && /* new array */ st->expected_spares > 0 && + sra->array.spare_disks < st->expected_spares) +- alert(EVENT_SPARES_MISSING, 0, dev, NULL); ++ alert(EVENT_SPARES_MISSING, NULL, 0, dev, NULL); + if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && + mse->percent >= 0) +- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); ++ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); + if (st->percent >= 0 && mse->percent >= 0 && + (mse->percent / increments) > (st->percent / increments)) { + if((mse->percent / increments) == 0) +- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); ++ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); + else +- alert(EVENT_REBUILD, mse->percent, dev, NULL); ++ alert(EVENT_REBUILD, NULL, mse->percent, dev, NULL); + } + + if (mse->percent == RESYNC_NONE && st->percent >= 0) { +@@ -690,9 +778,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + snprintf(cnt, sizeof(cnt), + " mismatches found: %d (on raid level %d)", + sra->mismatch_cnt, sra->array.level); +- alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); ++ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, cnt); + } else +- alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); ++ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, NULL); + } + st->percent = mse->percent; + +@@ -746,14 +834,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + change = newstate ^ st->devstate[i]; + if (st->utime && change && !st->err && !new_array) { + if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) +- alert(EVENT_FAIL, 0, dev, dv); ++ alert(EVENT_FAIL, NULL, 0, dev, dv); + else if ((newstate & (1 << MD_DISK_FAULTY)) && + (disc.major || disc.minor) && + st->devid[i] == makedev(disc.major, + disc.minor)) +- alert(EVENT_FAIL_SPARE, 0, dev, dv); ++ alert(EVENT_FAIL_SPARE, NULL, 0, dev, dv); + else if ((newstate&change) & (1 << MD_DISK_SYNC)) +- alert(EVENT_SPARE_ACTIVE, 0, dev, dv); ++ alert(EVENT_SPARE_ACTIVE, NULL, 0, dev, dv); + } + st->devstate[i] = newstate; + st->devid[i] = makedev(disc.major, disc.minor); +@@ -777,7 +865,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + + disappeared: + if (!st->err && !is_container) +- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); ++ alert(EVENT_DEVICE_DISAPPEARED, NULL, 0, dev, NULL); + st->err++; + goto out; + } +@@ -836,7 +924,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + st->parent_devnm[0] = 0; + *statelist = st; + if (info.test) +- alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); ++ alert(EVENT_TEST_MESSAGE, NULL, 0, st->devname, NULL); + new_found = 1; + } + return new_found; +@@ -1059,7 +1147,7 @@ static void try_spare_migration(struct state *statelist) + if (devid > 0 && + move_spare(from->devname, to->devname, + devid)) { +- alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); ++ alert(EVENT_MOVE_SPARE, NULL, 0, to->devname, from->devname); + break; + } + } +-- +2.38.1 + diff --git a/0090-Add-helpers-to-determine-whether-directories-or-file.patch b/0090-Add-helpers-to-determine-whether-directories-or-file.patch new file mode 100644 index 0000000..7d7ecdd --- /dev/null +++ b/0090-Add-helpers-to-determine-whether-directories-or-file.patch @@ -0,0 +1,83 @@ +From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:02 +0100 +Subject: [PATCH 090/120] Add helpers to determine whether directories or files + are soft links + +Signed-off-by: Mateusz Grzonka +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.h | 2 ++ + util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 47 insertions(+) + +diff --git a/mdadm.h b/mdadm.h +index 13f8b4cb..1674ce13 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1777,6 +1777,8 @@ extern void set_dlm_hooks(void); + #define MSEC_TO_NSEC(msec) ((msec) * 1000000) + #define USEC_TO_NSEC(usec) ((usec) * 1000) + extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); ++extern bool is_directory(const char *path); ++extern bool is_file(const char *path); + + #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) + #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) +diff --git a/util.c b/util.c +index 8c7f3fd5..7fc881bf 100644 +--- a/util.c ++++ b/util.c +@@ -2401,3 +2401,48 @@ void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) + } + } while (!wake_after_interrupt && errno == EINTR); + } ++ ++/* is_directory() - Checks if directory provided by path is indeed a regular directory. ++ * @path: directory path to be checked ++ * ++ * Doesn't accept symlinks. ++ * ++ * Return: true if is a directory, false if not ++ */ ++bool is_directory(const char *path) ++{ ++ struct stat st; ++ ++ if (lstat(path, &st) != 0) { ++ pr_err("%s: %s\n", strerror(errno), path); ++ return false; ++ } ++ ++ if (!S_ISDIR(st.st_mode)) ++ return false; ++ ++ return true; ++} ++ ++/* ++ * is_file() - Checks if file provided by path is indeed a regular file. ++ * @path: file path to be checked ++ * ++ * Doesn't accept symlinks. ++ * ++ * Return: true if is a file, false if not ++ */ ++bool is_file(const char *path) ++{ ++ struct stat st; ++ ++ if (lstat(path, &st) != 0) { ++ pr_err("%s: %s\n", strerror(errno), path); ++ return false; ++ } ++ ++ if (!S_ISREG(st.st_mode)) ++ return false; ++ ++ return true; ++} +-- +2.38.1 + diff --git a/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch b/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch new file mode 100644 index 0000000..0985905 --- /dev/null +++ b/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch @@ -0,0 +1,110 @@ +From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:03 +0100 +Subject: [PATCH 091/120] Mdmonitor: Refactor write_autorebuild_pid() + +Add better error handling and check for symlinks when opening MDMON_DIR. + +Signed-off-by: Mateusz Grzonka +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Monitor.c | 55 ++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 36 insertions(+), 19 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 39598ba0..14a2dfe5 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -33,6 +33,7 @@ + #endif + + #define EVENT_NAME_MAX 32 ++#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" + + struct state { + char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ +@@ -126,7 +127,7 @@ static int check_udev_activity(void); + static void link_containers_with_subarrays(struct state *list); + static int make_daemon(char *pidfile); + static void try_spare_migration(struct state *statelist); +-static void write_autorebuild_pid(void); ++static int write_autorebuild_pid(void); + + int Monitor(struct mddev_dev *devlist, + char *mailaddr, char *alert_cmd, +@@ -234,7 +235,8 @@ int Monitor(struct mddev_dev *devlist, + } + + if (share) +- write_autorebuild_pid(); ++ if (write_autorebuild_pid() != 0) ++ return 1; + + if (devlist == NULL) { + mdlist = conf_get_ident(NULL); +@@ -440,29 +442,44 @@ static int check_one_sharer(int scan) + return 0; + } + +-static void write_autorebuild_pid() ++/* ++ * write_autorebuild_pid() - Writes pid to autorebuild.pid file. ++ * ++ * Return: 0 on success, 1 on error ++ */ ++static int write_autorebuild_pid(void) + { +- char path[PATH_MAX]; +- int pid; +- FILE *fp = NULL; +- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); ++ FILE *fp; ++ int fd; + + if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) { +- pr_err("Can't create autorebuild.pid file\n"); +- } else { +- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700); ++ pr_err("%s: %s\n", strerror(errno), MDMON_DIR); ++ return 1; ++ } + +- if (fd >= 0) +- fp = fdopen(fd, "w"); ++ if (!is_directory(MDMON_DIR)) { ++ pr_err("%s is not a regular directory.\n", MDMON_DIR); ++ return 1; ++ } + +- if (!fp) +- pr_err("Can't create autorebuild.pid file\n"); +- else { +- pid = getpid(); +- fprintf(fp, "%d\n", pid); +- fclose(fp); +- } ++ fd = open(AUTOREBUILD_PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0700); ++ ++ if (fd < 0) { ++ pr_err("Error opening %s file.\n", AUTOREBUILD_PID_PATH); ++ return 1; + } ++ ++ fp = fdopen(fd, "w"); ++ ++ if (!fp) { ++ pr_err("Error opening fd for %s file.\n", AUTOREBUILD_PID_PATH); ++ return 1; ++ } ++ ++ fprintf(fp, "%d\n", getpid()); ++ ++ fclose(fp); ++ return 0; + } + + #define BASE_MESSAGE "%s event detected on md device %s" +-- +2.38.1 + diff --git a/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch b/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch new file mode 100644 index 0000000..a7de95e --- /dev/null +++ b/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch @@ -0,0 +1,139 @@ +From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:04 +0100 +Subject: [PATCH 092/120] Mdmonitor: Refactor check_one_sharer() for better + error handling + +Also check if autorebuild.pid is a symlink, which we shouldn't accept. + +Signed-off-by: Mateusz Grzonka +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Monitor.c | 89 ++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 62 insertions(+), 27 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 14a2dfe5..44918184 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -32,6 +32,7 @@ + #include + #endif + ++#define TASK_COMM_LEN 16 + #define EVENT_NAME_MAX 32 + #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" + +@@ -224,7 +225,7 @@ int Monitor(struct mddev_dev *devlist, + info.hostname[sizeof(info.hostname) - 1] = '\0'; + + if (share){ +- if (check_one_sharer(c->scan)) ++ if (check_one_sharer(c->scan) == 2) + return 1; + } + +@@ -406,39 +407,73 @@ static int make_daemon(char *pidfile) + return -1; + } + ++/* ++ * check_one_sharer() - Checks for other mdmon processes running. ++ * ++ * Return: ++ * 0 - no other processes running, ++ * 1 - warning, ++ * 2 - error, or when scan mode is enabled, and one mdmon process already exists ++ */ + static int check_one_sharer(int scan) + { + int pid; +- FILE *comm_fp; +- FILE *fp; ++ FILE *fp, *comm_fp; + char comm_path[PATH_MAX]; +- char path[PATH_MAX]; +- char comm[20]; +- +- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); +- fp = fopen(path, "r"); +- if (fp) { +- if (fscanf(fp, "%d", &pid) != 1) +- pid = -1; +- snprintf(comm_path, sizeof(comm_path), +- "/proc/%d/comm", pid); +- comm_fp = fopen(comm_path, "r"); +- if (comm_fp) { +- if (fscanf(comm_fp, "%19s", comm) && +- strncmp(basename(comm), Name, strlen(Name)) == 0) { +- if (scan) { +- pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); +- fclose(comm_fp); +- fclose(fp); +- return 1; +- } else { +- pr_err("Warning: One autorebuild process already running.\n"); +- } +- } ++ char comm[TASK_COMM_LEN]; ++ ++ if (!is_directory(MDMON_DIR)) { ++ pr_err("%s is not a regular directory.\n", MDMON_DIR); ++ 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 (fscanf(fp, "%d", &pid) != 1) { ++ pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); ++ fclose(fp); ++ return 2; ++ } ++ ++ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid); ++ ++ comm_fp = fopen(comm_path, "r"); ++ if (!comm_fp) { ++ dprintf("Warning: Cannot open %s, continuing\n", comm_path); ++ fclose(fp); ++ return 1; ++ } ++ ++ if (fscanf(comm_fp, "%15s", comm) == 0) { ++ dprintf("Warning: Cannot read comm from %s, continuing\n", comm_path); ++ fclose(comm_fp); ++ fclose(fp); ++ return 1; ++ } ++ ++ if (strncmp(basename(comm), Name, strlen(Name)) == 0) { ++ if (scan) { ++ pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); + fclose(comm_fp); ++ fclose(fp); ++ return 2; + } +- fclose(fp); ++ pr_err("Warning: One autorebuild process already running.\n"); + } ++ fclose(comm_fp); ++ fclose(fp); + return 0; + } + +-- +2.38.1 + diff --git a/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch b/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch new file mode 100644 index 0000000..b040ba7 --- /dev/null +++ b/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch @@ -0,0 +1,41 @@ +From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Sat, 4 Mar 2023 00:21:30 +0800 +Subject: [PATCH 093/120] util.c: reorder code lines in parse_layout_faulty() + +Resort the code lines in parse_layout_faulty() to make it more +comfortable, no logic change. + +Signed-off-by: Coly Li +Reviewed-by: Paul Menzel +Signed-off-by: Jes Sorensen +--- + util.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/util.c b/util.c +index 7fc881bf..b0b7aec4 100644 +--- a/util.c ++++ b/util.c +@@ -421,12 +421,15 @@ int parse_layout_10(char *layout) + + int parse_layout_faulty(char *layout) + { ++ int ln, mode; ++ char *m; ++ + if (!layout) + return -1; ++ + /* Parse the layout string for 'faulty' */ +- int ln = strcspn(layout, "0123456789"); +- char *m = xstrdup(layout); +- int mode; ++ ln = strcspn(layout, "0123456789"); ++ m = xstrdup(layout); + m[ln] = 0; + mode = map_name(faultylayout, m); + if (mode == UnSet) +-- +2.38.1 + diff --git a/0094-util.c-fix-memleak-in-parse_layout_faulty.patch b/0094-util.c-fix-memleak-in-parse_layout_faulty.patch new file mode 100644 index 0000000..b5d0d09 --- /dev/null +++ b/0094-util.c-fix-memleak-in-parse_layout_faulty.patch @@ -0,0 +1,32 @@ +From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:31 +0800 +Subject: [PATCH 094/120] util.c: fix memleak in parse_layout_faulty() + +char *m is allocated by xstrdup but not free() before return, will cause +a memory leak + +Signed-off-by: Wu Guanghao +Acked-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + util.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/util.c b/util.c +index b0b7aec4..9f1e1f7c 100644 +--- a/util.c ++++ b/util.c +@@ -432,6 +432,8 @@ int parse_layout_faulty(char *layout) + m = xstrdup(layout); + m[ln] = 0; + mode = map_name(faultylayout, m); ++ free(m); ++ + if (mode == UnSet) + return -1; + +-- +2.38.1 + diff --git a/0095-Detail.c-fix-memleak-in-Detail.patch b/0095-Detail.c-fix-memleak-in-Detail.patch new file mode 100644 index 0000000..0e9b700 --- /dev/null +++ b/0095-Detail.c-fix-memleak-in-Detail.patch @@ -0,0 +1,31 @@ +From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:32 +0800 +Subject: [PATCH 095/120] Detail.c: fix memleak in Detail() + +char *sysdev = xstrdup() but not free() in for loop, will cause memory +leak + +Signed-off-by: Wu Guanghao +Acked-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Detail.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Detail.c b/Detail.c +index ce7a8445..4ef26460 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -303,6 +303,7 @@ int Detail(char *dev, struct context *c) + if (path) + printf("MD_DEVICE_%s_DEV=%s\n", + sysdev, path); ++ free(sysdev); + } + } + goto out; +-- +2.38.1 + diff --git a/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch b/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch new file mode 100644 index 0000000..bf71aa0 --- /dev/null +++ b/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch @@ -0,0 +1,63 @@ +From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:33 +0800 +Subject: [PATCH 096/120] isuper-intel.c: fix double free in load_imsm_mpb() + +In load_imsm_mpb() there is potential double free issue on super->buf. + +The first location to free super->buf is from get_super_block() <== +load_and_parse_mpb() <== load_imsm_mpb(): + 4514 if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE, + 4515 MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { + 4516 pr_err("could not allocate migr_rec buffer\n"); + 4517 free(super->buf); + 4518 return 2; + 4519 } + +If the above error condition happens, super->buf is freed and value 2 +is returned to get_super_block() eventually. Then in the following code +block inside load_imsm_mpb(), + 5289 error: + 5290 if (!err) { + 5291 s->next = *super_list; + 5292 *super_list = s; + 5293 } else { + 5294 if (s) + 5295 free_imsm(s); + 5296 close_fd(&dfd); + 5297 } +at line 5295 when free_imsm() is called, super->buf is freed again from +the call chain free_imsm() <== __free_imsm(), in following code block, + 4651 if (super->buf) { + 4652 free(super->buf); + 4653 super->buf = NULL; + 4654 } + +This patch sets super->buf as NULL after line 4517 in load_imsm_mpb() +to avoid the potential double free(). + +(Coly Li helps to re-compose the commit log) + +Signed-off-by: Wu Guanghao +Reviewed-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-intel.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/super-intel.c b/super-intel.c +index 89fac626..4a3da847 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4515,6 +4515,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) + MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { + pr_err("could not allocate migr_rec buffer\n"); + free(super->buf); ++ super->buf = NULL; + return 2; + } + super->clean_migration_record_by_mdmon = 0; +-- +2.38.1 + diff --git a/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch b/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch new file mode 100644 index 0000000..fd60fe2 --- /dev/null +++ b/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch @@ -0,0 +1,39 @@ +From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:34 +0800 +Subject: [PATCH 097/120] super-intel.c: fix memleak in + find_disk_attached_hba() + +If disk_path = diskfd_to_devpath(), we need free(disk_path) before +return, otherwise there will be a memory leak + +Signed-off-by: Wu Guanghao +Reviewed-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-intel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 4a3da847..e155a8ae 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -713,12 +713,12 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) + + for (elem = list; elem; elem = elem->next) + if (path_attached_to_hba(disk_path, elem->path)) +- return elem; ++ break; + + if (disk_path != devname) + free(disk_path); + +- return NULL; ++ return elem; + } + + static int find_intel_hba_capability(int fd, struct intel_super *super, +-- +2.38.1 + diff --git a/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch b/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch new file mode 100644 index 0000000..d781036 --- /dev/null +++ b/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch @@ -0,0 +1,46 @@ +From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:35 +0800 +Subject: [PATCH 098/120] super-ddf.c: fix memleak in get_vd_num_of_subarray() + +sra = sysfs_read() should be free before return in +get_vd_num_of_subarray() + +Signed-off-by: Wu Guanghao +Acked-by: Mariusz Tkaczyk +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 309812df..b86c6acd 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1592,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st) + sra = sysfs_read(-1, st->devnm, GET_VERSION); + if (!sra || sra->array.major_version != -1 || + sra->array.minor_version != -2 || +- !is_subarray(sra->text_version)) ++ !is_subarray(sra->text_version)) { ++ if (sra) ++ sysfs_free(sra); + return DDF_NOTFOUND; ++ } + + sub = strchr(sra->text_version + 1, '/'); + if (sub != NULL) + vcnum = strtoul(sub + 1, &end, 10); + if (sub == NULL || *sub == '\0' || *end != '\0' || +- vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) ++ vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) { ++ sysfs_free(sra); + return DDF_NOTFOUND; ++ } + + return vcnum; + } +-- +2.38.1 + diff --git a/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch b/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch new file mode 100644 index 0000000..4fb641f --- /dev/null +++ b/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch @@ -0,0 +1,36 @@ +From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:29 -0700 +Subject: [PATCH 099/120] Create: goto abort_locked instead of return 1 in + error path + +The return 1 after the fstat_is_blkdev() check should be replaced +with an error return that goes through the error path to unlock +resources locked by this function. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Create.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Create.c b/Create.c +index 953e7372..2e8203ec 100644 +--- a/Create.c ++++ b/Create.c +@@ -939,7 +939,7 @@ int Create(struct supertype *st, char *mddev, + goto abort_locked; + } + if (!fstat_is_blkdev(fd, dv->devname, &rdev)) +- return 1; ++ goto abort_locked; + inf->disk.major = major(rdev); + inf->disk.minor = minor(rdev); + } +-- +2.38.1 + diff --git a/0100-Create-remove-safe_mode_delay-local-variable.patch b/0100-Create-remove-safe_mode_delay-local-variable.patch new file mode 100644 index 0000000..4b826a8 --- /dev/null +++ b/0100-Create-remove-safe_mode_delay-local-variable.patch @@ -0,0 +1,64 @@ +From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:30 -0700 +Subject: [PATCH 100/120] Create: remove safe_mode_delay local variable + +All .getinfo_super() call sets the info.safe_mode_delay variables +to a constant value, so no matter what the current state is +that function will always set it to the same value. + +Create() calls .getinfo_super() multiple times while creating the array. +The value is stored in a local variable for every disk in the loop +to add disks (so the last disc call takes precedence). The local +variable is then used in the call to sysfs_set_safemode(). + +This can be simplified by using info.safe_mode_delay directly. The info +variable had .getinfo_super() called on it early in the function so, by the +reasoning above, it will have the same value as the local variable which +can thus be removed. + +Doing this allows for factoring out code from Create() in a subsequent +patch. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Create.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/Create.c b/Create.c +index 2e8203ec..8ded81dc 100644 +--- a/Create.c ++++ b/Create.c +@@ -137,7 +137,6 @@ int Create(struct supertype *st, char *mddev, + int did_default = 0; + int do_default_layout = 0; + int do_default_chunk = 0; +- unsigned long safe_mode_delay = 0; + char chosen_name[1024]; + struct map_ent *map = NULL; + unsigned long long newsize; +@@ -952,7 +951,6 @@ int Create(struct supertype *st, char *mddev, + goto abort_locked; + } + st->ss->getinfo_super(st, inf, NULL); +- safe_mode_delay = inf->safe_mode_delay; + + if (have_container && c->verbose > 0) + pr_err("Using %s for device %d\n", +@@ -1065,7 +1063,7 @@ int Create(struct supertype *st, char *mddev, + "readonly"); + break; + } +- sysfs_set_safemode(&info, safe_mode_delay); ++ sysfs_set_safemode(&info, info.safe_mode_delay); + if (err) { + pr_err("failed to activate array.\n"); + ioctl(mdfd, STOP_ARRAY, NULL); +-- +2.38.1 + diff --git a/0101-Create-Factor-out-add_disks-helpers.patch b/0101-Create-Factor-out-add_disks-helpers.patch new file mode 100644 index 0000000..c4bfcc5 --- /dev/null +++ b/0101-Create-Factor-out-add_disks-helpers.patch @@ -0,0 +1,452 @@ +From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:31 -0700 +Subject: [PATCH 101/120] Create: Factor out add_disks() helpers + +The Create function is massive with a very large number of variables. +Reading and understanding the function is almost impossible. To help +with this, factor out the two pass loop that adds the disks to the array. + +This moves about 160 lines into three new helper functions and removes +a bunch of local variables from the main Create function. The main new +helper function add_disks() does the two pass loop and calls into +add_disk_to_super() and update_metadata(). Factoring out the +latter two helpers also helps to reduce a ton of indentation. + +No functional changes intended. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Create.c | 382 +++++++++++++++++++++++++++++++------------------------ + 1 file changed, 213 insertions(+), 169 deletions(-) + +diff --git a/Create.c b/Create.c +index 8ded81dc..6a044664 100644 +--- a/Create.c ++++ b/Create.c +@@ -91,6 +91,214 @@ int default_layout(struct supertype *st, int level, int verbose) + return layout; + } + ++static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, ++ struct supertype *st, struct mddev_dev *dv, ++ struct mdinfo *info, int have_container, int major_num) ++{ ++ dev_t rdev; ++ int fd; ++ ++ if (dv->disposition == 'j') { ++ info->disk.raid_disk = MD_DISK_ROLE_JOURNAL; ++ info->disk.state = (1<disk.raid_disk < s->raiddisks) { ++ info->disk.state = (1<disk.state = 0; ++ } ++ ++ if (dv->writemostly == FlagSet) { ++ if (major_num == BITMAP_MAJOR_CLUSTERED) { ++ pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); ++ return 1; ++ } else { ++ info->disk.state |= (1<failfast == FlagSet) ++ info->disk.state |= (1<ss->external && st->container_devnm[0]) ++ fd = open(dv->devname, O_RDWR); ++ else ++ fd = open(dv->devname, O_RDWR|O_EXCL); ++ ++ if (fd < 0) { ++ pr_err("failed to open %s after earlier success - aborting\n", ++ dv->devname); ++ return 1; ++ } ++ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) ++ return 1; ++ info->disk.major = major(rdev); ++ info->disk.minor = minor(rdev); ++ } ++ if (fd >= 0) ++ remove_partitions(fd); ++ if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, ++ dv->data_offset)) { ++ ioctl(mdfd, STOP_ARRAY, NULL); ++ return 1; ++ } ++ st->ss->getinfo_super(st, info, NULL); ++ ++ if (have_container && c->verbose > 0) ++ pr_err("Using %s for device %d\n", ++ map_dev(info->disk.major, info->disk.minor, 0), ++ info->disk.number); ++ ++ if (!have_container) { ++ /* getinfo_super might have lost these ... */ ++ info->disk.major = major(rdev); ++ info->disk.minor = minor(rdev); ++ } ++ ++ return 0; ++} ++ ++static int update_metadata(int mdfd, struct shape *s, struct supertype *st, ++ struct map_ent **map, struct mdinfo *info, ++ char *chosen_name) ++{ ++ struct mdinfo info_new; ++ struct map_ent *me = NULL; ++ ++ /* check to see if the uuid has changed due to these ++ * metadata changes, and if so update the member array ++ * and container uuid. Note ->write_init_super clears ++ * the subarray cursor such that ->getinfo_super once ++ * again returns container info. ++ */ ++ st->ss->getinfo_super(st, &info_new, NULL); ++ if (st->ss->external && is_container(s->level) && ++ !same_uuid(info_new.uuid, info->uuid, 0)) { ++ map_update(map, fd2devnm(mdfd), ++ info_new.text_version, ++ info_new.uuid, chosen_name); ++ me = map_by_devnm(map, st->container_devnm); ++ } ++ ++ if (st->ss->write_init_super(st)) { ++ st->ss->free_super(st); ++ return 1; ++ } ++ ++ /* ++ * Before activating the array, perform extra steps ++ * required to configure the internal write-intent ++ * bitmap. ++ */ ++ if (info_new.consistency_policy == CONSISTENCY_POLICY_BITMAP && ++ st->ss->set_bitmap && st->ss->set_bitmap(st, info)) { ++ st->ss->free_super(st); ++ return 1; ++ } ++ ++ /* update parent container uuid */ ++ if (me) { ++ char *path = xstrdup(me->path); ++ ++ st->ss->getinfo_super(st, &info_new, NULL); ++ map_update(map, st->container_devnm, info_new.text_version, ++ info_new.uuid, path); ++ free(path); ++ } ++ ++ flush_metadata_updates(st); ++ st->ss->free_super(st); ++ ++ return 0; ++} ++ ++static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, ++ struct context *c, struct supertype *st, ++ struct map_ent **map, struct mddev_dev *devlist, ++ int total_slots, int have_container, int insert_point, ++ int major_num, char *chosen_name) ++{ ++ struct mddev_dev *moved_disk = NULL; ++ int pass, raid_disk_num, dnum; ++ struct mddev_dev *dv; ++ struct mdinfo *infos; ++ int ret = 0; ++ ++ infos = xmalloc(sizeof(*infos) * total_slots); ++ enable_fds(total_slots); ++ for (pass = 1; pass <= 2; pass++) { ++ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; ++ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { ++ if (dnum >= total_slots) ++ abort(); ++ if (dnum == insert_point) { ++ raid_disk_num += 1; ++ moved_disk = dv; ++ continue; ++ } ++ if (strcasecmp(dv->devname, "missing") == 0) { ++ raid_disk_num += 1; ++ continue; ++ } ++ if (have_container) ++ moved_disk = NULL; ++ if (have_container && dnum < total_slots - 1) ++ /* repeatedly use the container */ ++ moved_disk = dv; ++ ++ switch(pass) { ++ case 1: ++ infos[dnum] = *info; ++ infos[dnum].disk.number = dnum; ++ infos[dnum].disk.raid_disk = raid_disk_num++; ++ ++ if (dv->disposition == 'j') ++ raid_disk_num--; ++ ++ ret = add_disk_to_super(mdfd, s, c, st, dv, ++ &infos[dnum], have_container, ++ major_num); ++ if (ret) ++ goto out; ++ ++ break; ++ case 2: ++ infos[dnum].errors = 0; ++ ++ ret = add_disk(mdfd, st, info, &infos[dnum]); ++ if (ret) { ++ pr_err("ADD_NEW_DISK for %s failed: %s\n", ++ dv->devname, strerror(errno)); ++ if (errno == EINVAL && ++ info->array.level == 0) { ++ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); ++ pr_err("Either upgrade, or use --layout=dangerous\n"); ++ } ++ goto out; ++ } ++ break; ++ } ++ if (!have_container && ++ dv == moved_disk && dnum != insert_point) break; ++ } ++ ++ if (pass == 1) { ++ ret = update_metadata(mdfd, s, st, map, info, ++ chosen_name); ++ if (ret) ++ goto out; ++ } ++ } ++ ++out: ++ free(infos); ++ return ret; ++} ++ + int Create(struct supertype *st, char *mddev, + char *name, int *uuid, + int subdevs, struct mddev_dev *devlist, +@@ -117,7 +325,7 @@ int Create(struct supertype *st, char *mddev, + unsigned long long minsize = 0, maxsize = 0; + char *mindisc = NULL; + char *maxdisc = NULL; +- int dnum, raid_disk_num; ++ int dnum; + struct mddev_dev *dv; + dev_t rdev; + int fail = 0, warn = 0; +@@ -126,14 +334,13 @@ int Create(struct supertype *st, char *mddev, + int missing_disks = 0; + int insert_point = subdevs * 2; /* where to insert a missing drive */ + int total_slots; +- int pass; + int rv; + int bitmap_fd; + int have_container = 0; + int container_fd = -1; + int need_mdmon = 0; + unsigned long long bitmapsize; +- struct mdinfo info, *infos; ++ struct mdinfo info; + int did_default = 0; + int do_default_layout = 0; + int do_default_chunk = 0; +@@ -869,174 +1076,11 @@ int Create(struct supertype *st, char *mddev, + } + } + +- infos = xmalloc(sizeof(*infos) * total_slots); +- enable_fds(total_slots); +- for (pass = 1; pass <= 2; pass++) { +- struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */ +- +- for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; +- dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { +- int fd; +- struct mdinfo *inf = &infos[dnum]; +- +- if (dnum >= total_slots) +- abort(); +- if (dnum == insert_point) { +- raid_disk_num += 1; +- moved_disk = dv; +- continue; +- } +- if (strcasecmp(dv->devname, "missing") == 0) { +- raid_disk_num += 1; +- continue; +- } +- if (have_container) +- moved_disk = NULL; +- if (have_container && dnum < info.array.raid_disks - 1) +- /* repeatedly use the container */ +- moved_disk = dv; +- +- switch(pass) { +- case 1: +- *inf = info; +- +- inf->disk.number = dnum; +- inf->disk.raid_disk = raid_disk_num++; +- +- if (dv->disposition == 'j') { +- inf->disk.raid_disk = MD_DISK_ROLE_JOURNAL; +- inf->disk.state = (1<disk.raid_disk < s->raiddisks) +- inf->disk.state = (1<disk.state = 0; +- +- if (dv->writemostly == FlagSet) { +- if (major_num == BITMAP_MAJOR_CLUSTERED) { +- pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); +- goto abort_locked; +- } else +- inf->disk.state |= (1<failfast == FlagSet) +- inf->disk.state |= (1<ss->external && +- st->container_devnm[0]) +- fd = open(dv->devname, O_RDWR); +- else +- fd = open(dv->devname, O_RDWR|O_EXCL); +- +- if (fd < 0) { +- pr_err("failed to open %s after earlier success - aborting\n", +- dv->devname); +- goto abort_locked; +- } +- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) +- goto abort_locked; +- inf->disk.major = major(rdev); +- inf->disk.minor = minor(rdev); +- } +- if (fd >= 0) +- remove_partitions(fd); +- if (st->ss->add_to_super(st, &inf->disk, +- fd, dv->devname, +- dv->data_offset)) { +- ioctl(mdfd, STOP_ARRAY, NULL); +- goto abort_locked; +- } +- st->ss->getinfo_super(st, inf, NULL); +- +- if (have_container && c->verbose > 0) +- pr_err("Using %s for device %d\n", +- map_dev(inf->disk.major, +- inf->disk.minor, +- 0), dnum); +- +- if (!have_container) { +- /* getinfo_super might have lost these ... */ +- inf->disk.major = major(rdev); +- inf->disk.minor = minor(rdev); +- } +- break; +- case 2: +- inf->errors = 0; +- +- rv = add_disk(mdfd, st, &info, inf); +- +- if (rv) { +- pr_err("ADD_NEW_DISK for %s failed: %s\n", +- dv->devname, strerror(errno)); +- if (errno == EINVAL && +- info.array.level == 0) { +- pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); +- pr_err("Either upgrade, or use --layout=dangerous\n"); +- } +- goto abort_locked; +- } +- break; +- } +- if (!have_container && +- dv == moved_disk && dnum != insert_point) break; +- } +- if (pass == 1) { +- struct mdinfo info_new; +- struct map_ent *me = NULL; +- +- /* check to see if the uuid has changed due to these +- * metadata changes, and if so update the member array +- * and container uuid. Note ->write_init_super clears +- * the subarray cursor such that ->getinfo_super once +- * again returns container info. +- */ +- st->ss->getinfo_super(st, &info_new, NULL); +- if (st->ss->external && !is_container(s->level) && +- !same_uuid(info_new.uuid, info.uuid, 0)) { +- map_update(&map, fd2devnm(mdfd), +- info_new.text_version, +- info_new.uuid, chosen_name); +- me = map_by_devnm(&map, st->container_devnm); +- } +- +- if (st->ss->write_init_super(st)) { +- st->ss->free_super(st); +- goto abort_locked; +- } +- /* +- * Before activating the array, perform extra steps +- * required to configure the internal write-intent +- * bitmap. +- */ +- if (info_new.consistency_policy == +- CONSISTENCY_POLICY_BITMAP && +- st->ss->set_bitmap && +- st->ss->set_bitmap(st, &info)) { +- st->ss->free_super(st); +- goto abort_locked; +- } +- +- /* update parent container uuid */ +- if (me) { +- char *path = xstrdup(me->path); +- +- st->ss->getinfo_super(st, &info_new, NULL); +- map_update(&map, st->container_devnm, +- info_new.text_version, +- info_new.uuid, path); +- free(path); +- } ++ if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots, ++ have_container, insert_point, major_num, chosen_name)) ++ goto abort_locked; + +- flush_metadata_updates(st); +- st->ss->free_super(st); +- } +- } + map_unlock(&map); +- free(infos); + + if (is_container(s->level)) { + /* No need to start. But we should signal udev to +-- +2.38.1 + diff --git a/0102-mdadm-Introduce-pr_info.patch b/0102-mdadm-Introduce-pr_info.patch new file mode 100644 index 0000000..196624f --- /dev/null +++ b/0102-mdadm-Introduce-pr_info.patch @@ -0,0 +1,72 @@ +From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:32 -0700 +Subject: [PATCH 102/120] mdadm: Introduce pr_info() + +Feedback was given to avoid informational pr_err() calls that print +to stderr, even though that's done all through out the code. + +Using printf() directly doesn't maintain the same format (an "mdadm" +prefix on every line. + +So introduce pr_info() which prints to stdout with the same format +and use it for a couple informational pr_err() calls in Create(). + +Future work can make this call used in more cases. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Acked-by: Paul Menzel +Signed-off-by: Jes Sorensen +--- + Create.c | 7 ++++--- + mdadm.h | 2 ++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/Create.c b/Create.c +index 6a044664..4acda30c 100644 +--- a/Create.c ++++ b/Create.c +@@ -984,11 +984,12 @@ int Create(struct supertype *st, char *mddev, + + mdi = sysfs_read(-1, devnm, GET_VERSION); + +- pr_err("Creating array inside %s container %s\n", ++ pr_info("Creating array inside %s container %s\n", + mdi?mdi->text_version:"managed", devnm); + sysfs_free(mdi); + } else +- pr_err("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, +@@ -1145,7 +1146,7 @@ int Create(struct supertype *st, char *mddev, + ioctl(mdfd, RESTART_ARRAY_RW, NULL); + } + if (c->verbose >= 0) +- pr_err("array %s started.\n", mddev); ++ pr_info("array %s started.\n", mddev); + if (st->ss->external && st->container_devnm[0]) { + if (need_mdmon) + start_mdmon(st->container_devnm); +diff --git a/mdadm.h b/mdadm.h +index 1674ce13..4336be4d 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1854,6 +1854,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { + #endif + #define cont_err(fmt ...) fprintf(stderr, " " fmt) + ++#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) ++ + void *xmalloc(size_t len); + void *xrealloc(void *ptr, size_t len); + void *xcalloc(size_t num, size_t size); +-- +2.38.1 + diff --git a/0103-mdadm-Add-write-zeros-option-for-Create.patch b/0103-mdadm-Add-write-zeros-option-for-Create.patch new file mode 100644 index 0000000..1e06a73 --- /dev/null +++ b/0103-mdadm-Add-write-zeros-option-for-Create.patch @@ -0,0 +1,346 @@ +From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:33 -0700 +Subject: [PATCH 103/120] mdadm: Add --write-zeros option for Create + +Add the --write-zeros option for Create which will send a write zeros +request to all the disks before assembling the array. After zeroing +the array, the disks will be in a known clean state and the initial +sync may be skipped. + +Writing zeroes is best used when there is a hardware offload method +to zero the data. But even still, zeroing can take several minutes on +a large device. Because of this, all disks are zeroed in parallel using +their own forked process and a message is printed to the user. The main +process will proceed only after all the zeroing processes have completed +successfully. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Create.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + ReadMe.c | 2 + + mdadm.c | 9 +++ + mdadm.h | 5 ++ + 4 files changed, 190 insertions(+), 2 deletions(-) + +diff --git a/Create.c b/Create.c +index 4acda30c..bbe9e13d 100644 +--- a/Create.c ++++ b/Create.c +@@ -26,6 +26,10 @@ + #include "md_u.h" + #include "md_p.h" + #include ++#include ++#include ++#include ++#include + + static int round_size_and_verify(unsigned long long *size, int chunk) + { +@@ -91,9 +95,149 @@ int default_layout(struct supertype *st, int level, int verbose) + return layout; + } + ++static pid_t write_zeroes_fork(int fd, struct shape *s, struct supertype *st, ++ struct mddev_dev *dv) ++ ++{ ++ const unsigned long long req_size = 1 << 30; ++ unsigned long long offset_bytes, size_bytes, sz; ++ sigset_t sigset; ++ int ret = 0; ++ pid_t pid; ++ ++ size_bytes = KIB_TO_BYTES(s->size); ++ ++ /* ++ * If size_bytes is zero, this is a zoned raid array where ++ * each disk is of a different size and uses its full ++ * disk. Thus zero the entire disk. ++ */ ++ if (!size_bytes && !get_dev_size(fd, dv->devname, &size_bytes)) ++ return -1; ++ ++ if (dv->data_offset != INVALID_SECTORS) ++ offset_bytes = SEC_TO_BYTES(dv->data_offset); ++ else ++ offset_bytes = SEC_TO_BYTES(st->data_offset); ++ ++ pr_info("zeroing data from %lld to %lld on: %s\n", ++ offset_bytes, size_bytes, dv->devname); ++ ++ pid = fork(); ++ if (pid < 0) { ++ pr_err("Could not fork to zero disks: %s\n", strerror(errno)); ++ return pid; ++ } else if (pid != 0) { ++ return pid; ++ } ++ ++ sigemptyset(&sigset); ++ sigaddset(&sigset, SIGINT); ++ sigprocmask(SIG_UNBLOCK, &sigset, NULL); ++ ++ while (size_bytes) { ++ /* ++ * Split requests to the kernel into 1GB chunks seeing the ++ * fallocate() call is not interruptible and blocking a ++ * ctrl-c for several minutes is not desirable. ++ * ++ * 1GB is chosen as a compromise: the user may still have ++ * to wait several seconds if they ctrl-c on devices that ++ * zero slowly, but will reduce the number of requests ++ * required and thus the overhead on devices that perform ++ * better. ++ */ ++ sz = size_bytes; ++ if (sz >= req_size) ++ sz = req_size; ++ ++ if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, ++ offset_bytes, sz)) { ++ pr_err("zeroing %s failed: %s\n", dv->devname, ++ strerror(errno)); ++ ret = 1; ++ break; ++ } ++ ++ offset_bytes += sz; ++ size_bytes -= sz; ++ } ++ ++ exit(ret); ++} ++ ++static int wait_for_zero_forks(int *zero_pids, int count) ++{ ++ int wstatus, ret = 0, i, sfd, wait_count = 0; ++ struct signalfd_siginfo fdsi; ++ bool interrupted = false; ++ sigset_t sigset; ++ ssize_t s; ++ ++ for (i = 0; i < count; i++) ++ if (zero_pids[i]) ++ wait_count++; ++ if (!wait_count) ++ return 0; ++ ++ sigemptyset(&sigset); ++ sigaddset(&sigset, SIGINT); ++ sigaddset(&sigset, SIGCHLD); ++ sigprocmask(SIG_BLOCK, &sigset, NULL); ++ ++ sfd = signalfd(-1, &sigset, 0); ++ if (sfd < 0) { ++ pr_err("Unable to create signalfd: %s\n", strerror(errno)); ++ return 1; ++ } ++ ++ while (1) { ++ s = read(sfd, &fdsi, sizeof(fdsi)); ++ if (s != sizeof(fdsi)) { ++ pr_err("Invalid signalfd read: %s\n", strerror(errno)); ++ close(sfd); ++ return 1; ++ } ++ ++ if (fdsi.ssi_signo == SIGINT) { ++ printf("\n"); ++ pr_info("Interrupting zeroing processes, please wait...\n"); ++ interrupted = true; ++ } else if (fdsi.ssi_signo == SIGCHLD) { ++ if (!--wait_count) ++ break; ++ } ++ } ++ ++ 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; ++ } ++ ++ if (ret) ++ pr_err("zeroing failed!\n"); ++ else ++ pr_info("zeroing finished\n"); ++ ++ return ret; ++} ++ + static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + struct supertype *st, struct mddev_dev *dv, +- struct mdinfo *info, int have_container, int major_num) ++ struct mdinfo *info, int have_container, int major_num, ++ int *zero_pid) + { + dev_t rdev; + int fd; +@@ -148,6 +292,14 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + } + st->ss->getinfo_super(st, info, NULL); + ++ if (fd >= 0 && s->write_zeroes) { ++ *zero_pid = write_zeroes_fork(fd, s, st, dv); ++ if (*zero_pid <= 0) { ++ ioctl(mdfd, STOP_ARRAY, NULL); ++ return 1; ++ } ++ } ++ + if (have_container && c->verbose > 0) + pr_err("Using %s for device %d\n", + map_dev(info->disk.major, info->disk.minor, 0), +@@ -224,10 +376,23 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, + { + struct mddev_dev *moved_disk = NULL; + int pass, raid_disk_num, dnum; ++ int zero_pids[total_slots]; + struct mddev_dev *dv; + struct mdinfo *infos; ++ sigset_t sigset, orig_sigset; + int ret = 0; + ++ /* ++ * Block SIGINT so the main thread will always wait for the ++ * zeroing processes when being interrupted. Otherwise the ++ * zeroing processes will finish their work in the background ++ * keeping the disk busy. ++ */ ++ sigemptyset(&sigset); ++ sigaddset(&sigset, SIGINT); ++ sigprocmask(SIG_BLOCK, &sigset, &orig_sigset); ++ memset(zero_pids, 0, sizeof(zero_pids)); ++ + infos = xmalloc(sizeof(*infos) * total_slots); + enable_fds(total_slots); + for (pass = 1; pass <= 2; pass++) { +@@ -261,7 +426,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, + + ret = add_disk_to_super(mdfd, s, c, st, dv, + &infos[dnum], have_container, +- major_num); ++ major_num, &zero_pids[dnum]); + if (ret) + goto out; + +@@ -287,6 +452,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, + } + + if (pass == 1) { ++ ret = wait_for_zero_forks(zero_pids, total_slots); ++ if (ret) ++ goto out; ++ + ret = update_metadata(mdfd, s, st, map, info, + chosen_name); + if (ret) +@@ -295,7 +464,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, + } + + out: ++ if (ret) ++ wait_for_zero_forks(zero_pids, total_slots); + free(infos); ++ sigprocmask(SIG_SETMASK, &orig_sigset, NULL); + return ret; + } + +diff --git a/ReadMe.c b/ReadMe.c +index bd8d50d2..db251ed2 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -138,6 +138,7 @@ struct option long_options[] = { + {"size", 1, 0, 'z'}, + {"auto", 1, 0, Auto}, /* also for --assemble */ + {"assume-clean",0,0, AssumeClean }, ++ {"write-zeroes",0,0, WriteZeroes }, + {"metadata", 1, 0, 'e'}, /* superblock format */ + {"bitmap", 1, 0, Bitmap}, + {"bitmap-chunk", 1, 0, BitmapChunk}, +@@ -390,6 +391,7 @@ char Help_create[] = + " --write-journal= : Specify journal device for RAID-4/5/6 array\n" + " --consistency-policy= : Specify the policy that determines how the array\n" + " -k : maintains consistency in case of unexpected shutdown.\n" ++" --write-zeroes : Write zeroes to the disks before creating. This will bypass initial sync.\n" + "\n" + ; + +diff --git a/mdadm.c b/mdadm.c +index 57e8e6fa..4685ad6b 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -590,6 +590,10 @@ int main(int argc, char *argv[]) + s.assume_clean = 1; + continue; + ++ case O(CREATE, WriteZeroes): ++ s.write_zeroes = 1; ++ continue; ++ + case O(GROW,'n'): + case O(CREATE,'n'): + case O(BUILD,'n'): /* number of raid disks */ +@@ -1251,6 +1255,11 @@ int main(int argc, char *argv[]) + } + } + ++ if (s.write_zeroes && !s.assume_clean) { ++ pr_info("Disk zeroing requested, setting --assume-clean to skip resync\n"); ++ s.assume_clean = 1; ++ } ++ + if (!mode && devs_found) { + mode = MISC; + devmode = 'Q'; +diff --git a/mdadm.h b/mdadm.h +index 4336be4d..b9127f9a 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -275,6 +275,9 @@ static inline void __put_unaligned32(__u32 val, void *p) + + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + ++#define KIB_TO_BYTES(x) ((x) << 10) ++#define SEC_TO_BYTES(x) ((x) << 9) ++ + extern const char Name[]; + + struct md_bb_entry { +@@ -435,6 +438,7 @@ extern char Version[], Usage[], Help[], OptionHelp[], + */ + enum special_options { + AssumeClean = 300, ++ WriteZeroes, + BitmapChunk, + WriteBehind, + ReAdd, +@@ -640,6 +644,7 @@ struct shape { + int bitmap_chunk; + char *bitmap_file; + int assume_clean; ++ bool write_zeroes; + int write_behind; + unsigned long long size; + unsigned long long data_offset; +-- +2.38.1 + diff --git a/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch b/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch new file mode 100644 index 0000000..6c32b5c --- /dev/null +++ b/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch @@ -0,0 +1,44 @@ +From c918cf2af993b55bca9f396c79713e54d3f8b6fb Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:34 -0700 +Subject: [PATCH 104/120] tests/00raid5-zero: Introduce test to exercise + --write-zeros. + +Attempt to create a raid5 array with --write-zeros. If it is successful +check the array to ensure it is in sync. + +If it is unsuccessful and an unsupported error is printed, skip the +test. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + tests/00raid5-zero | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + create mode 100644 tests/00raid5-zero + +diff --git a/tests/00raid5-zero b/tests/00raid5-zero +new file mode 100644 +index 00000000..7d0f05a1 +--- /dev/null ++++ b/tests/00raid5-zero +@@ -0,0 +1,12 @@ ++ ++if mdadm -CfR $md0 -l 5 -n3 $dev0 $dev1 $dev2 --write-zeroes ; then ++ check nosync ++ echo check > /sys/block/md0/md/sync_action; ++ check wait ++elif grep "zeroing [^ ]* failed: Operation not supported" \ ++ $targetdir/stderr; then ++ echo "write-zeros not supported, skipping" ++else ++ echo >&2 "ERROR: mdadm return failure without not supported message" ++ exit 1 ++fi +-- +2.38.1 + diff --git a/0105-manpage-Add-write-zeroes-option-to-manpage.patch b/0105-manpage-Add-write-zeroes-option-to-manpage.patch new file mode 100644 index 0000000..489faca --- /dev/null +++ b/0105-manpage-Add-write-zeroes-option-to-manpage.patch @@ -0,0 +1,56 @@ +From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:35 -0700 +Subject: [PATCH 105/120] manpage: Add --write-zeroes option to manpage + +Document the new --write-zeroes option in the manpage. + +Signed-off-by: Logan Gunthorpe +Acked-by: Kinga Tanska +Reviewed-by: Xiao Ni +Reviewed-by: Chaitanya Kulkarni +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 64f71ed1..6f0f6c13 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -837,6 +837,22 @@ array is resynced at creation. From Linux version 3.0, + .B \-\-assume\-clean + can be used with that command to avoid the automatic resync. + ++.TP ++.BR \-\-write-zeroes ++When creating an array, send write zeroes requests to all the block ++devices. This should zero the data area on all disks such that the ++initial sync is not necessary and, if successfull, will behave ++as if ++.B \-\-assume\-clean ++was specified. ++.IP ++This is intended for use with devices that have hardware offload for ++zeroing, but despite this zeroing can still take several minutes for ++large disks. Thus a message is printed before and after zeroing and ++each disk is zeroed in parallel with the others. ++.IP ++This is only meaningful with --create. ++ + .TP + .BR \-\-backup\-file= + This is needed when +@@ -1370,7 +1386,7 @@ and + .B layout\-alternate + options are for RAID0 arrays with non-uniform devices size that were in + use before Linux 5.4. If the array was being used with Linux 3.13 or +-earlier, then to assemble the array on a new kernel, ++earlier, then to assemble the array on a new kernel, + .B \-\-update=layout\-original + must be given. If the array was created and used with a kernel from Linux 3.14 to + Linux 5.3, then +-- +2.38.1 + diff --git a/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch b/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch new file mode 100644 index 0000000..acb55ed --- /dev/null +++ b/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch @@ -0,0 +1,53 @@ +From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Wed, 18 Jan 2023 00:32:36 -0800 +Subject: [PATCH 106/120] Define alignof using _Alignof when using C11 or newer + +WG14 N2350 made very clear that it is an UB having type definitions +within "offsetof" [1]. This patch enhances the implementation of macro +alignof_slot to use builtin "_Alignof" to avoid undefined behavior on +when using std=c11 or newer + +clang 16+ has started to flag this [2] + +Fixes build when using -std >= gnu11 and using clang16+ + +Older compilers gcc < 4.9 or clang < 8 has buggy _Alignof even though it +may support C11, exclude those compilers too + +[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm +[2] https://reviews.llvm.org/D133574 + +Upstream-Status: Pending +Signed-off-by: Khem Raj +Signed-off-by: Jes Sorensen +--- + sha1.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/sha1.c b/sha1.c +index 89b32f46..1e4ad5d9 100644 +--- a/sha1.c ++++ b/sha1.c +@@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) + if (len >= 64) + { + #if !_STRING_ARCH_unaligned +-# define alignof(type) offsetof (struct { char c; type x; }, x) ++/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 ++ . ++ clang versions < 8.0.0 have the same bug. */ ++# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ ++ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ ++ && !defined __clang__) \ ++ || (defined __clang__ && __clang_major__ < 8)) ++# define alignof(type) offsetof (struct { char c; type x; }, x) ++# else ++# define alignof(type) _Alignof(type) ++# endif + # define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0) + if (UNALIGNED_P (buffer)) + while (len > 64) +-- +2.38.1 + diff --git a/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch b/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch new file mode 100644 index 0000000..f7b06c5 --- /dev/null +++ b/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch @@ -0,0 +1,41 @@ +From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH 107/120] Use existence of /etc/initrd-release to detect + initrd. + +Since v183, systemd has used the existence of /etc/initrd-release to +detect if it is running in an initrd, rather than looking at the magic +number of the root filesystem's device. It is time for mdadm to do the +same. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + util.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/util.c b/util.c +index 9f1e1f7c..509fb43e 100644 +--- a/util.c ++++ b/util.c +@@ -2227,15 +2227,7 @@ int continue_via_systemd(char *devnm, char *service_name) + + int in_initrd(void) + { +- /* This is based on similar function in systemd. */ +- struct statfs s; +- /* statfs.f_type is signed long on s390x and MIPS, causing all +- sorts of sign extension problems with RAMFS_MAGIC being +- defined as 0x858458f6 */ +- return statfs("/", &s) >= 0 && +- ((unsigned long)s.f_type == TMPFS_MAGIC || +- ((unsigned long)s.f_type & 0xFFFFFFFFUL) == +- ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL)); ++ return access("/etc/initrd-release", F_OK) >= 0; + } + + void reopen_mddev(int mdfd) +-- +2.38.1 + diff --git a/0108-mdmon-don-t-test-both-all-and-container_name.patch b/0108-mdmon-don-t-test-both-all-and-container_name.patch new file mode 100644 index 0000000..479e5a5 --- /dev/null +++ b/0108-mdmon-don-t-test-both-all-and-container_name.patch @@ -0,0 +1,47 @@ +From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH 108/120] mdmon: don't test both 'all' and 'container_name'. + +If 'all' is not set, then container_name must be NULL, as nothing else +can set it. So simplify the test to ignore container_name. +This makes the purpose of the code more obvious. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdmon.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 60ba3182..f8fd2f0f 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -352,7 +352,6 @@ int main(int argc, char *argv[]) + } + } + +- + if (in_initrd()) { + /* + * set first char of argv[0] to @. This is used by +@@ -362,12 +361,10 @@ int main(int argc, char *argv[]) + argv[0][0] = '@'; + } + +- if (all == 0 && container_name == NULL) { +- if (argv[optind]) { +- container_name = get_md_name(argv[optind]); +- if (!container_name) +- return 1; +- } ++ if (!all && argv[optind]) { ++ container_name = get_md_name(argv[optind]); ++ if (!container_name) ++ return 1; + } + + if (container_name == NULL || argc - optind > 1) +-- +2.38.1 + diff --git a/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch b/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch new file mode 100644 index 0000000..49240d5 --- /dev/null +++ b/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch @@ -0,0 +1,33 @@ +From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH 109/120] mdmon: change systemd unit file to use --foreground + +There is no value in mdmon forking when it is running under systemd - +systemd can still track it anyway. + +So add --foreground option, and remove "Type=forking". + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/mdmon@.service | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index cb6482d9..bba9b0eb 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -20,8 +20,7 @@ Environment=IMSM_NO_PLATFORM=1 + # 'takeover'. As the '--offroot --takeover' don't hurt when + # not necessary, are are useful with root-on-md in dracut, + # have them always present. +-ExecStart=BINDIR/mdmon --offroot --takeover %I +-Type=forking ++ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I + # Don't set the PIDFile. It isn't necessary (systemd can work + # it out) and systemd will remove it when transitioning from + # initramfs to rootfs. +-- +2.38.1 + diff --git a/0110-mdmon-Remove-need-for-KillMode-none.patch b/0110-mdmon-Remove-need-for-KillMode-none.patch new file mode 100644 index 0000000..5e6cc63 --- /dev/null +++ b/0110-mdmon-Remove-need-for-KillMode-none.patch @@ -0,0 +1,55 @@ +From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH 110/120] mdmon: Remove need for KillMode=none + +mdmon needs to keep running during the switchroot out of (at boot) and +then back into (at shutdown) the initrd. It runs until a new mdmon +takes over. + +Killmode=none is used to achieve this, with the help of --offroot which +sets argv[0][0] to '@' which systemd understands. + +This is needed because mdmon is currently run in system-mdmon.slice +which conflicts with shutdown.target so without Killmode=none mdmon +would get killed early in shutdown when system.mdmon.slice is removed. + +As described in systemd.service(5), this conflict with shutdown can be +resolved by explicitly requesting system.slice, which is a natural +counterpart to DefaultDependencies=no. + +So add that, and also add IgnoreOnIsolate=true to avoid another possible +source of an early death. With these we no longer need KillMode=none +which the systemd developers have marked as "deprecated". + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/mdmon@.service | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index bba9b0eb..303ad05c 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -10,6 +10,9 @@ Description=MD Metadata Monitor on /dev/%I + DefaultDependencies=no + Before=initrd-switch-root.target + Documentation=man:mdmon(8) ++# Allow mdmon to keep running after switchroot, until a new ++# instance is started. ++IgnoreOnIsolate=true + + [Service] + # mdmon should never complain due to lack of a platform, +@@ -25,4 +28,6 @@ ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I + # it out) and systemd will remove it when transitioning from + # initramfs to rootfs. + #PIDFile=/run/mdadm/%I.pid +-KillMode=none ++# The default slice is system-mdmon.slice which Conflicts ++# with shutdown, causing mdmon to exit early. So use system.slice. ++Slice=system.slice +-- +2.38.1 + diff --git a/0111-mdmon-Improve-switchroot-interactions.patch b/0111-mdmon-Improve-switchroot-interactions.patch new file mode 100644 index 0000000..65654a0 --- /dev/null +++ b/0111-mdmon-Improve-switchroot-interactions.patch @@ -0,0 +1,166 @@ +From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH 111/120] mdmon: Improve switchroot interactions. + +We need a new mdmon@mdfoo instance to run in the root filesystem after +switch root, as /sys and /dev are removed from the initrd. + +systemd will not start a new unit with the same name running while the +old unit is still active, and we want the two mdmon processes to overlap +in time to avoid any risk of deadlock, which can happen when a write is +attempted with no mdmon running. + +So we need a different unit name in the initrd than in the root. Apart +from the name, everything else should be the same. + +This is easily achieved using a different instance name as the +mdmon@.service unit file already supports multiple instances (for +different arrays). + +So start "mdmon@mdfoo.service" from root, but +"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which +circumstance is the case by looking for /etc/initrd-release. +continue_from_systemd() is enhanced so that the "initrd-" prefix can be +requested. + +Teach mdmon that a container name like "initrd/foo" should be treated +just like "foo". Note that systemd passes the instance name +"initrd-foo" as "initrd/foo". + +We don't need a similar mechanism at shutdown because dracut runs +"mdmon --takeover --all" when appropriate. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 4 ++-- + mdadm.h | 2 +- + mdmon.c | 7 ++++++- + systemd/mdmon@.service | 2 +- + udev-md-raid-arrays.rules | 3 ++- + util.c | 7 ++++--- + 6 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/Grow.c b/Grow.c +index bb5fe45c..06001f2d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3516,7 +3516,7 @@ started: + + if (!forked) + if (continue_via_systemd(container ?: sra->sys_name, +- GROW_SERVICE)) { ++ GROW_SERVICE, NULL)) { + free(fdlist); + free(offsets); + sysfs_free(sra); +@@ -3714,7 +3714,7 @@ int reshape_container(char *container, char *devname, + ping_monitor(container); + + if (!forked && !freeze_reshape) +- if (continue_via_systemd(container, GROW_SERVICE)) ++ if (continue_via_systemd(container, GROW_SERVICE, NULL)) + return 0; + + switch (forked ? 0 : fork()) { +diff --git a/mdadm.h b/mdadm.h +index b9127f9a..1e518276 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1608,7 +1608,7 @@ extern int same_dev(char *one, char *two); + extern int compare_paths (char* path1,char* path2); + extern void enable_fds(int devices); + extern void manage_fork_fds(int close_all); +-extern int continue_via_systemd(char *devnm, char *service_name); ++extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); + + extern void ident_init(struct mddev_ident *ident); + +diff --git a/mdmon.c b/mdmon.c +index f8fd2f0f..096b4d76 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -362,7 +362,12 @@ int main(int argc, char *argv[]) + } + + if (!all && argv[optind]) { +- container_name = get_md_name(argv[optind]); ++ static const char prefix[] = "initrd/"; ++ container_name = argv[optind]; ++ if (strncmp(container_name, prefix, ++ sizeof(prefix) - 1) == 0) ++ container_name += sizeof(prefix)-1; ++ container_name = get_md_name(container_name); + if (!container_name) + return 1; + } +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index 303ad05c..23a375f6 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -6,7 +6,7 @@ + # (at your option) any later version. + + [Unit] +-Description=MD Metadata Monitor on /dev/%I ++Description=MD Metadata Monitor on %I + DefaultDependencies=no + Before=initrd-switch-root.target + Documentation=man:mdmon(8) +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index 2967ace1..4e64b249 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" + + # Tell systemd to run mdmon for our container, if we need it. + ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" +-ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" ++ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service" ++ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" + ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" + + LABEL="md_end" +diff --git a/util.c b/util.c +index 509fb43e..d70ca43b 100644 +--- a/util.c ++++ b/util.c +@@ -1916,6 +1916,7 @@ int start_mdmon(char *devnm) + int len; + pid_t pid; + int status; ++ char *prefix = in_initrd() ? "initrd-" : ""; + char pathbuf[1024]; + char *paths[4] = { + pathbuf, +@@ -1926,7 +1927,7 @@ int start_mdmon(char *devnm) + + if (check_env("MDADM_NO_MDMON")) + return 0; +- if (continue_via_systemd(devnm, MDMON_SERVICE)) ++ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix)) + return 0; + + /* That failed, try running mdmon directly */ +@@ -2197,7 +2198,7 @@ void manage_fork_fds(int close_all) + * 1- if systemd service has been started + * 0- otherwise + */ +-int continue_via_systemd(char *devnm, char *service_name) ++int continue_via_systemd(char *devnm, char *service_name, char *prefix) + { + int pid, status; + char pathbuf[1024]; +@@ -2209,7 +2210,7 @@ int continue_via_systemd(char *devnm, char *service_name) + case 0: + manage_fork_fds(1); + snprintf(pathbuf, sizeof(pathbuf), +- "%s@%s.service", service_name, devnm); ++ "%s@%s%s.service", service_name, prefix ?: "", devnm); + status = execl("/usr/bin/systemctl", "systemctl", "restart", + pathbuf, NULL); + status = execl("/bin/systemctl", "systemctl", "restart", +-- +2.38.1 + diff --git a/0112-mdopen-always-try-create_named_array.patch b/0112-mdopen-always-try-create_named_array.patch new file mode 100644 index 0000000..bfd899c --- /dev/null +++ b/0112-mdopen-always-try-create_named_array.patch @@ -0,0 +1,40 @@ +From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 14 Mar 2023 11:06:25 +1100 +Subject: [PATCH 112/120] mdopen: always try create_named_array() + +mdopen() will use create_named_array() to ask the kernel to create the +given md array, but only if it is given a number or name. +If it is NOT given a name and is required to choose one itself using +find_free_devnm() it does NOT use create_named_array(). + +On kernels with CONFIG_BLOCK_LEGACY_AUTOLOAD not set, this can result in +failure to assemble an array. This can particularly seen when the +"name" of the array begins with a host name different to the name of the +host running the command. + +So add the missing call to create_named_array(). + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=217074 +Signed-off-by: NeilBrown +Acked-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + mdopen.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/mdopen.c b/mdopen.c +index d18c9319..810f79a3 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + } + if (block_udev) + udev_block(devnm); ++ create_named_array(devnm); + } + + sprintf(devname, "/dev/%s", devnm); +-- +2.38.1 + diff --git a/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch b/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch new file mode 100644 index 0000000..d4e6a4f --- /dev/null +++ b/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch @@ -0,0 +1,172 @@ +From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 20 Mar 2023 14:43:54 +1100 +Subject: [PATCH 113/120] Improvements for IMSM_NO_PLATFORM testing. + +Factor out IMSM_NO_PLATFORM testing into a single function that caches +the result. + +Allow mdmon to explicitly set the result to "1" so that we don't need +the ENV var in the unit file + +Check if the kernel command line contains "mdadm.imsm.test=1" and in +that case assert NO_PLATFORM. This simplifies testing in a virtual +machine. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 5 +++++ + mdadm.h | 2 ++ + mdmon.c | 6 ++++++ + super-intel.c | 45 +++++++++++++++++++++++++++++++++++++++--- + systemd/mdmon@.service | 3 --- + 5 files changed, 55 insertions(+), 6 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 6f0f6c13..b7159509 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -3197,6 +3197,11 @@ 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 ++.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. ++ + .TP + .B MDADM_GROW_ALLOW_OLD + If an array is stopped while it is performing a reshape and that +diff --git a/mdadm.h b/mdadm.h +index 1e518276..0d995445 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1263,6 +1263,8 @@ extern struct superswitch super0, super1; + extern struct superswitch super_imsm, super_ddf; + extern struct superswitch mbr, gpt; + ++void imsm_set_no_platform(int v); ++ + struct metadata_update { + int len; + char *buf; +diff --git a/mdmon.c b/mdmon.c +index 096b4d76..cef5bbc8 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -318,6 +318,12 @@ int main(int argc, char *argv[]) + {NULL, 0, NULL, 0} + }; + ++ /* ++ * mdmon should never complain due to lack of a platform, ++ * that is mdadm's job if at all. ++ */ ++ imsm_set_no_platform(1); ++ + while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { + switch (opt) { + case 'a': +diff --git a/super-intel.c b/super-intel.c +index e155a8ae..a5c86cb2 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -20,6 +20,7 @@ + #define HAVE_STDINT_H 1 + #include "mdadm.h" + #include "mdmon.h" ++#include "dlink.h" + #include "sha1.h" + #include "platform-intel.h" + #include +@@ -629,6 +630,44 @@ static const char *_sys_dev_type[] = { + [SYS_DEV_VMD] = "VMD" + }; + ++static int no_platform = -1; ++ ++static int check_no_platform(void) ++{ ++ static const char search[] = "mdadm.imsm.test=1"; ++ FILE *fp; ++ ++ if (no_platform >= 0) ++ return no_platform; ++ ++ if (check_env("IMSM_NO_PLATFORM")) { ++ no_platform = 1; ++ return 1; ++ } ++ fp = fopen("/proc/cmdline", "r"); ++ if (fp) { ++ char *l = conf_line(fp); ++ char *w = l; ++ ++ do { ++ if (strcmp(w, search) == 0) ++ no_platform = 1; ++ w = dl_next(w); ++ } while (w != l); ++ free_line(l); ++ fclose(fp); ++ if (no_platform >= 0) ++ return no_platform; ++ } ++ no_platform = 0; ++ return 0; ++} ++ ++void imsm_set_no_platform(int v) ++{ ++ no_platform = v; ++} ++ + const char *get_sys_dev_type(enum sys_dev_type type) + { + if (type >= SYS_DEV_MAX) +@@ -2699,7 +2738,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle + int result=1; + + if (enumerate_only) { +- if (check_env("IMSM_NO_PLATFORM")) ++ if (check_no_platform()) + return 0; + list = find_intel_devices(); + if (!list) +@@ -4722,7 +4761,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de + devname); + return 1; + } +- if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) { ++ if (!is_fd_valid(fd) || check_no_platform()) { + super->orom = NULL; + super->hba = NULL; + return 0; +@@ -10697,7 +10736,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks, + ******************************************************************************/ + int validate_container_imsm(struct mdinfo *info) + { +- if (check_env("IMSM_NO_PLATFORM")) ++ if (check_no_platform()) + return 0; + + struct sys_dev *idev; +diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service +index 23a375f6..020cc7e1 100644 +--- a/systemd/mdmon@.service ++++ b/systemd/mdmon@.service +@@ -15,9 +15,6 @@ Documentation=man:mdmon(8) + IgnoreOnIsolate=true + + [Service] +-# mdmon should never complain due to lack of a platform, +-# that is mdadm's job if at all. +-Environment=IMSM_NO_PLATFORM=1 + # The mdmon starting in the initramfs (with dracut at least) + # cannot see sysfs after root is mounted, so we will have to + # 'takeover'. As the '--offroot --takeover' don't hurt when +-- +2.38.1 + diff --git a/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch b/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch new file mode 100644 index 0000000..39b1809 --- /dev/null +++ b/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch @@ -0,0 +1,29 @@ +From 9b6e3b43381245cb128ad98bf117a565ce5defe5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 23 Mar 2023 17:13:18 +0100 +Subject: [PATCH 114/120] Revert "Revert "mdadm/systemd: remove KillMode=none + from service file"" + +This reverts commit 28a083955c6f58f8e582734c8c82aff909a7d461. + +Resolved by commit 723d1df4946e ("mdmon: Improve switchroot +interactions.") We are ready to drop it. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 9ccadca3..64b8254a 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I + StandardInput=null + StandardOutput=null + StandardError=null +-KillMode=none +-- +2.38.1 + diff --git a/0115-Create-Fix-checking-for-container-in-update_metadata.patch b/0115-Create-Fix-checking-for-container-in-update_metadata.patch new file mode 100644 index 0000000..0868469 --- /dev/null +++ b/0115-Create-Fix-checking-for-container-in-update_metadata.patch @@ -0,0 +1,38 @@ +From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 23 Mar 2023 12:50:00 +0100 +Subject: [PATCH 115/120] Create: Fix checking for container in update_metadata + +The commit 8a4ce2c05386 ("Create: Factor out add_disks() helpers") +introduced a regression that caused timeouts and udev failing to create +links. + +Steps to reproduce the issue were as following: +$ mdadm -CR imsm -e imsm -n4 /dev/nvme[0-3]n1 +$ mdadm -CR vol -l5 -n4 /dev/nvme[0-3]n1 --assume-clean + +I found the check for container was wrong because negation was missing. + +Fixes: 8a4ce2c05386 ("Create: Factor out add_disks() helpers") +Signed-off-by: Mateusz Grzonka +Signed-off-by: Jes Sorensen +--- + Create.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Create.c b/Create.c +index bbe9e13d..0911bf92 100644 +--- a/Create.c ++++ b/Create.c +@@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st, + * again returns container info. + */ + st->ss->getinfo_super(st, &info_new, NULL); +- if (st->ss->external && is_container(s->level) && ++ if (st->ss->external && !is_container(s->level) && + !same_uuid(info_new.uuid, info->uuid, 0)) { + map_update(map, fd2devnm(mdfd), + info_new.text_version, +-- +2.38.1 + diff --git a/0116-Fix-null-pointer-for-incremental-in-mdadm.patch b/0116-Fix-null-pointer-for-incremental-in-mdadm.patch new file mode 100644 index 0000000..53bc051 --- /dev/null +++ b/0116-Fix-null-pointer-for-incremental-in-mdadm.patch @@ -0,0 +1,43 @@ +From 890212d6800646153210ac264ce73035cc7dd5cc Mon Sep 17 00:00:00 2001 +From: miaoguanqin +Date: Tue, 4 Apr 2023 19:31:24 +0800 +Subject: [PATCH 116/120] Fix null pointer for incremental in mdadm + +when we excute mdadm --assemble, udev-md-raid-assembly.rules is triggered. +Then we stop array, we found an coredump for mdadm --incremental.func +stack are as follows: + +#0 enough (level=10, raid_disks=4, layout=258, clean=1, + avail=avail@entry=0x0) at util.c:555 +#1 0x0000562170c26965 in Incremental (devlist=, + c=, st=0x5621729b6dc0) at Incremental.c:514 +#2 0x0000562170bfb6ff in main (argc=, + argv=) at mdadm.c:1762 + +func enough() use array avail,avail allocate space in func count_active, +it may not alloc space, causing a coredump.We fix this coredump. + +Signed-off-by: Guanqin Miao +Signed-off-by: lixiaokeng +Signed-off-by: Jes Sorensen +--- + Incremental.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Incremental.c b/Incremental.c +index 09b94b9f..49a71f72 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -507,6 +507,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + GET_OFFSET | GET_SIZE)); + active_disks = count_active(st, sra, mdfd, &avail, &info); + ++ if (!avail) ++ goto out_unlock; ++ + journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); + + if (info.consistency_policy == CONSISTENCY_POLICY_PPL) +-- +2.38.1 + diff --git a/0117-super1-fix-truncation-check-for-journal-device.patch b/0117-super1-fix-truncation-check-for-journal-device.patch new file mode 100644 index 0000000..bf985c8 --- /dev/null +++ b/0117-super1-fix-truncation-check-for-journal-device.patch @@ -0,0 +1,33 @@ +From 1c6f2a1dbfe17df14dd5b062fc53a60c5c387e47 Mon Sep 17 00:00:00 2001 +From: Hristo Venev +Date: Sat, 1 Apr 2023 23:01:35 +0300 +Subject: [PATCH 117/120] super1: fix truncation check for journal device + +The journal device can be smaller than the component devices. + +Fixes: 171e9743881e ("super1: report truncated device") +Signed-off-by: Hristo Venev +Signed-off-by: Jes Sorensen +--- + super1.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/super1.c b/super1.c +index f7020320..44d6ecad 100644 +--- a/super1.c ++++ b/super1.c +@@ -2359,8 +2359,9 @@ static int load_super1(struct supertype *st, int fd, char *devname) + + if (st->minor_version >= 1 && + st->ignore_hw_compat == 0 && +- (dsize < (__le64_to_cpu(super->data_offset) + +- __le64_to_cpu(super->size)) ++ ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && ++ dsize < (__le64_to_cpu(super->data_offset) + ++ __le64_to_cpu(super->size))) + || + dsize < (__le64_to_cpu(super->data_offset) + + __le64_to_cpu(super->data_size)))) { +-- +2.38.1 + diff --git a/0118-Fix-some-cases-eyesore-formatting.patch b/0118-Fix-some-cases-eyesore-formatting.patch new file mode 100644 index 0000000..4da8078 --- /dev/null +++ b/0118-Fix-some-cases-eyesore-formatting.patch @@ -0,0 +1,433 @@ +From d3bb888d885fc96fc6239fbf6c22c63143eba461 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Mon, 10 Apr 2023 11:40:42 -0400 +Subject: [PATCH 118/120] Fix some cases eyesore formatting + +Summary: No functional change .... just make it more readable. + +Signed-off-by: Jes Sorensen +--- + super1.c | 117 ++++++++++++++++++++++++++++--------------------------- + 1 file changed, 60 insertions(+), 57 deletions(-) + +diff --git a/super1.c b/super1.c +index 44d6ecad..1d20ef55 100644 +--- a/super1.c ++++ b/super1.c +@@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) + unsigned int disk_csum, csum; + unsigned long long newcsum; + int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2; +- unsigned int *isuper = (unsigned int*)sb; ++ unsigned int *isuper = (unsigned int *)sb; + + /* make sure I can count... */ + if (offsetof(struct mdp_superblock_1,data_offset) != 128 || +@@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) + disk_csum = sb->sb_csum; + sb->sb_csum = 0; + newcsum = 0; +- for (; size>=4; size -= 4 ) { ++ for (; size >= 4; size -= 4) { + newcsum += __le32_to_cpu(*isuper); + isuper++; + } +@@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk) + static void examine_super1(struct supertype *st, char *homehost) + { + struct mdp_superblock_1 *sb = st->sb; +- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); ++ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + time_t atime; + unsigned int d; + int role; +@@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost) + printf(".0\n"); + printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map)); + printf(" Array UUID : "); +- for (i=0; i<16; i++) { +- if ((i&3)==0 && i != 0) printf(":"); ++ for (i = 0; i < 16; i++) { ++ if ((i & 3) == 0 && i != 0) ++ printf(":"); + printf("%02x", sb->set_uuid[i]); + } + printf("\n"); +@@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost) + UINT64_MAX - info.space_after); + } + printf(" State : %s%s\n", +- (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", ++ (__le64_to_cpu(sb->resync_offset) + 1) ? "active":"clean", + (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); + printf(" Device UUID : "); +- for (i=0; i<16; i++) { +- if ((i&3)==0 && i != 0) ++ for (i = 0; i < 16; i++) { ++ if ((i & 3)==0 && i != 0) + printf(":"); + printf("%02x", sb->device_uuid[i]); + } +@@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost) + #if 0 + /* This turns out to just be confusing */ + printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number)); +- for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--) ++ for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--) + if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE) + break; + for (d = 0; d < i; d++) { +@@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost) + #if 0 + /* This is confusing too */ + faulty = 0; +- for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { ++ for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { + int role = __le16_to_cpu(sb->dev_roles[i]); + if (role == MD_DISK_ROLE_FAULTY) + faulty++; +@@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost) + if (inconsistent) { + printf("WARNING Array state is inconsistent - each number should appear only once\n"); + for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) +- if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY) ++ if (__le16_to_cpu(sb->dev_roles[d]) >= ++ MD_DISK_ROLE_FAULTY) + printf(" %d:-", d); + else +- printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d])); ++ printf(" %d:%d", d, ++ __le16_to_cpu(sb->dev_roles[d])); + printf("\n"); + } + } +@@ -659,7 +662,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) + printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks)); + printf("UUID="); + for (i = 0; i < 16; i++) { +- if ((i&3)==0 && i != 0) ++ if ((i & 3)==0 && i != 0) + printf(":"); + printf("%02x", sb->set_uuid[i]); + } +@@ -713,7 +716,7 @@ static void export_examine_super1(struct supertype *st) + } + printf("MD_UUID="); + for (i = 0; i < 16; i++) { +- if ((i&3) == 0 && i != 0) ++ if ((i & 3) == 0 && i != 0) + printf(":"); + printf("%02x", sb->set_uuid[i]); + } +@@ -722,7 +725,7 @@ static void export_examine_super1(struct supertype *st) + __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL); + printf("MD_DEV_UUID="); + for (i = 0; i < 16; i++) { +- if ((i&3) == 0 && i != 0) ++ if ((i & 3) == 0 && i != 0) + printf(":"); + printf("%02x", sb->device_uuid[i]); + } +@@ -812,7 +815,7 @@ static int copy_metadata1(struct supertype *st, int from, int to) + /* have the header, can calculate + * correct bitmap bytes */ + bitmap_super_t *bms; +- bms = (void*)buf; ++ bms = (void *)buf; + bytes = calc_bitmap_size(bms, 512); + if (n > bytes) + n = bytes; +@@ -867,7 +870,7 @@ err: + static void detail_super1(struct supertype *st, char *homehost, char *subarray) + { + struct mdp_superblock_1 *sb = st->sb; +- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); ++ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + int i; + int l = homehost ? strlen(homehost) : 0; + +@@ -880,7 +883,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray) + printf("\n Cluster Name : %-64s", bms->cluster_name); + printf("\n UUID : "); + for (i = 0; i < 16; i++) { +- if ((i&3) == 0 && i != 0) ++ if ((i & 3) == 0 && i != 0) + printf(":"); + printf("%02x", sb->set_uuid[i]); + } +@@ -939,7 +942,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + } + + size = __le16_to_cpu(sb->bblog_size)* 512; +- if (posix_memalign((void**)&bbl, 4096, size) != 0) { ++ if (posix_memalign((void **)&bbl, 4096, size) != 0) { + pr_err("could not allocate badblocks list\n"); + return 0; + } +@@ -987,7 +990,7 @@ static int match_home1(struct supertype *st, char *homehost) + static void uuid_from_super1(struct supertype *st, int uuid[4]) + { + struct mdp_superblock_1 *super = st->sb; +- char *cuuid = (char*)uuid; ++ char *cuuid = (char *)uuid; + int i; + for (i = 0; i < 16; i++) + cuuid[i] = super->set_uuid[i]; +@@ -996,9 +999,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) + static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + { + struct mdp_superblock_1 *sb = st->sb; +- struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE); ++ struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE); + struct misc_dev_info *misc = +- (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); ++ (void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE); + int working = 0; + unsigned int i; + unsigned int role; +@@ -1166,7 +1169,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->recovery_blocked = info->reshape_active; + + if (map) +- for (i=0; imax_dev); i++) { + role = __le16_to_cpu(sb->dev_roles[i]); +@@ -1217,7 +1220,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + */ + int rv = 0; + struct mdp_superblock_1 *sb = st->sb; +- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); ++ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + + if (update == UOPT_HOMEHOST && homehost) { + /* +@@ -1228,9 +1231,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + update = UOPT_NAME; + c = strchr(sb->set_name, ':'); + if (c) +- snprintf(info->name, sizeof(info->name), "%s", c+1); ++ snprintf(info->name, sizeof(info->name), "%s", c + 1); + else +- snprintf(info->name, sizeof(info->name), "%s", sb->set_name); ++ snprintf(info->name, sizeof(info->name), "%s", ++ sb->set_name); + } + + switch (update) { +@@ -1331,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->dev_number = __cpu_to_le32(i); + + if (i == max) +- sb->max_dev = __cpu_to_le32(max+1); ++ sb->max_dev = __cpu_to_le32(max + 1); + if (i > max) + return -2; + +@@ -1350,8 +1354,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->data_size = __cpu_to_le64( + ds - __le64_to_cpu(sb->data_offset)); + } else { +- ds -= 8*2; +- ds &= ~(unsigned long long)(4*2-1); ++ ds -= 8 * 2; ++ ds &= ~(unsigned long long)(4 * 2 - 1); + sb->super_offset = __cpu_to_le64(ds); + sb->data_size = __cpu_to_le64( + ds - __le64_to_cpu(sb->data_offset)); +@@ -1367,7 +1371,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + if (i > max) + return -2; + if (i == max) +- sb->max_dev = __cpu_to_le32(max+1); ++ sb->max_dev = __cpu_to_le32(max + 1); + sb->raid_disks = __cpu_to_le32(info->array.raid_disks); + sb->dev_roles[info->disk.number] = + __cpu_to_le16(info->disk.raid_disk); +@@ -1645,7 +1649,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, + char defname[10]; + int sbsize; + +- if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) { ++ if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) { + pr_err("could not allocate superblock\n"); + return 0; + } +@@ -1679,8 +1683,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, + name = defname; + } + if (homehost && +- strchr(name, ':')== NULL && +- strlen(homehost)+1+strlen(name) < 32) { ++ strchr(name, ':') == NULL && ++ strlen(homehost) + 1 + strlen(name) < 32) { + strcpy(sb->set_name, homehost); + strcat(sb->set_name, ":"); + strcat(sb->set_name, name); +@@ -1759,7 +1763,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + + if (dk->number >= (int)__le32_to_cpu(sb->max_dev) && + __le32_to_cpu(sb->max_dev) < MAX_DEVS) +- sb->max_dev = __cpu_to_le32(dk->number+1); ++ sb->max_dev = __cpu_to_le32(dk->number + 1); + + sb->dev_number = __cpu_to_le32(dk->number); + sb->devflags = 0; /* don't copy another disks flags */ +@@ -1840,8 +1844,8 @@ static int store_super1(struct supertype *st, int fd) + return 4; + + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { +- struct bitmap_super_s *bm = (struct bitmap_super_s*) +- (((char*)sb)+MAX_SB_SIZE); ++ struct bitmap_super_s *bm; ++ bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE); + if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { + locate_bitmap1(st, fd, 0); + if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm)) +@@ -1928,7 +1932,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) + + init_afd(&afd, fd); + +- if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) { ++ if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) { + pr_err("Could not allocate memory for the meta block.\n"); + return 1; + } +@@ -2197,7 +2201,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst, + return 1; + + if (!first) { +- if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) { ++ if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) { + pr_err("could not allocate superblock\n"); + return 1; + } +@@ -2310,7 +2314,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) + return 1; + } + +- if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) { ++ if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) { + pr_err("could not allocate superblock\n"); + return 1; + } +@@ -2349,10 +2353,10 @@ static int load_super1(struct supertype *st, int fd, char *devname) + return 2; + } + +- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); ++ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); + + misc = (struct misc_dev_info*) +- (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE); ++ (((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE); + misc->device_size = dsize; + if (st->data_offset == INVALID_SECTORS) + st->data_offset = __le64_to_cpu(super->data_offset); +@@ -2360,9 +2364,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) + if (st->minor_version >= 1 && + st->ignore_hw_compat == 0 && + ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && +- dsize < (__le64_to_cpu(super->data_offset) + +- __le64_to_cpu(super->size))) +- || ++ dsize < (__le64_to_cpu(super->data_offset) + ++ __le64_to_cpu(super->size))) || + dsize < (__le64_to_cpu(super->data_offset) + + __le64_to_cpu(super->data_size)))) { + if (devname) +@@ -2391,8 +2394,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) + return 0; + + no_bitmap: +- super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) +- & ~MD_FEATURE_BITMAP_OFFSET); ++ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & ++ ~MD_FEATURE_BITMAP_OFFSET); + return 0; + } + +@@ -2450,7 +2453,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, + if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) { + /* hot-add. allow for actual size of bitmap */ + struct bitmap_super_s *bsb; +- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); ++ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); + bmspace = calc_bitmap_size(bsb, 4096) >> 9; + } else if (md_feature_any_ppl_on(super->feature_map)) { + bmspace = __le16_to_cpu(super->ppl.size); +@@ -2519,7 +2522,7 @@ add_internal_bitmap1(struct supertype *st, + int creating = 0; + int len; + struct mdp_superblock_1 *sb = st->sb; +- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); ++ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + int uuid[4]; + + if (__le64_to_cpu(sb->data_size) == 0) +@@ -2607,10 +2610,10 @@ add_internal_bitmap1(struct supertype *st, + max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8; + + min_chunk = 4096; /* sub-page chunks don't work yet.. */ +- bits = (size*512)/min_chunk +1; ++ bits = (size * 512) / min_chunk + 1; + while (bits > max_bits) { + min_chunk *= 2; +- bits = (bits+1)/2; ++ bits = (bits + 1) / 2; + } + if (chunk == UnSet) { + /* For practical purpose, 64Meg is a good +@@ -2628,8 +2631,8 @@ add_internal_bitmap1(struct supertype *st, + /* start bitmap on a 4K boundary with enough space for + * the bitmap + */ +- bits = (size*512) / chunk + 1; +- room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096; ++ bits = (size * 512) / chunk + 1; ++ room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096; + room *= 8; /* convert 4K blocks to sectors */ + offset = -room - bbl_size; + } +@@ -2683,7 +2686,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) + + offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset); + if (node_num) { +- bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); ++ bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9; + offset += bm_sectors_per_node * node_num; + } +@@ -2696,7 +2699,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) + static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update) + { + struct mdp_superblock_1 *sb = st->sb; +- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); ++ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); + int rv = 0; + void *buf; + int towrite, n, len; +@@ -2970,16 +2973,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 + + copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); + sprintf(sb->set_name, "%d", sb0->md_minor); +- sb->ctime = __cpu_to_le32(info->array.ctime+1); ++ sb->ctime = __cpu_to_le32(info->array.ctime + 1); + sb->level = __cpu_to_le32(info->array.level); + sb->layout = __cpu_to_le32(info->array.layout); + sb->size = __cpu_to_le64(info->component_size); +- sb->chunksize = __cpu_to_le32(info->array.chunk_size/512); ++ sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512); + sb->raid_disks = __cpu_to_le32(info->array.raid_disks); + if (info->array.level > 0) + sb->data_size = sb->size; + else +- sb->data_size = st->ss->avail_size(st, st->devsize/512, 0); ++ sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0); + sb->resync_offset = MaxSector; + sb->max_dev = __cpu_to_le32(MD_SB_DISKS); + sb->dev_number = __cpu_to_le32(info->disk.number); +-- +2.38.1 + diff --git a/0119-Bump-minimum-kernel-version-to-2.6.32.patch b/0119-Bump-minimum-kernel-version-to-2.6.32.patch new file mode 100644 index 0000000..7fcbf6c --- /dev/null +++ b/0119-Bump-minimum-kernel-version-to-2.6.32.patch @@ -0,0 +1,136 @@ +From f8d2c4286a92b7acb7872271a401ad1efe336096 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Mon, 10 Apr 2023 11:45:34 -0400 +Subject: [PATCH 119/120] Bump minimum kernel version to 2.6.32 + +Summary: At this point it probably is reasonable to drop support for +anything prior to 3.10. + +Signed-off-by: Jes Sorensen +--- + Create.c | 5 ----- + Grow.c | 16 ---------------- + Manage.c | 17 ----------------- + mdadm.c | 4 ++-- + super1.c | 5 ----- + 5 files changed, 2 insertions(+), 45 deletions(-) + +diff --git a/Create.c b/Create.c +index 0911bf92..aa0472dd 100644 +--- a/Create.c ++++ b/Create.c +@@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev, + break; + case LEVEL_LINEAR: + /* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */ +- if (get_linux_version() < 2006016 && s->chunk == 0) { +- s->chunk = 64; +- if (c->verbose > 0) +- pr_err("chunk size defaults to 64K\n"); +- } + break; + case 1: + case LEVEL_FAULTY: +diff --git a/Grow.c b/Grow.c +index 06001f2d..8fa97875 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + return NULL; + } + +- if (re->after.data_disks == re->before.data_disks && +- get_linux_version() < 2006032) +- return "in-place reshape is not safe before 2.6.32 - sorry."; +- +- if (re->after.data_disks < re->before.data_disks && +- get_linux_version() < 2006030) +- return "reshape to fewer devices is not supported before 2.6.30 - sorry."; +- + re->backup_blocks = compute_backup_blocks( + info->new_chunk, info->array.chunk_size, + re->after.data_disks, re->before.data_disks); +@@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- if (s->raiddisks && s->raiddisks < array.raid_disks && +- array.level > 1 && get_linux_version() < 2006032 && +- !check_env("MDADM_FORCE_FEWER")) { +- pr_err("reducing the number of devices is not safe before Linux 2.6.32\n" +- " Please use a newer kernel\n"); +- return 1; +- } +- + if (array.level > 1 && s->size > 1 && + (unsigned long long) (array.chunk_size / 1024) > s->size) { + pr_err("component size must be larger than chunk size.\n"); +diff --git a/Manage.c b/Manage.c +index fde6aba3..f54de7c6 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -461,17 +461,6 @@ done: + goto out; + } + +- if (get_linux_version() < 2006028) { +- /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array +- * was stopped, so We'll do it here just to be sure. Drop any +- * partitions as well... +- */ +- if (fd >= 0) +- ioctl(fd, BLKRRPART, 0); +- if (mdi) +- sysfs_uevent(mdi, "change"); +- } +- + if (devnm[0] && use_udev()) { + struct map_ent *mp = map_by_devnm(&map, devnm); + remove_devices(devnm, mp ? mp->path : NULL); +@@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + * though. + */ + mdu_disk_info_t disc; +- /* re-add doesn't work for version-1 superblocks +- * before 2.6.18 :-( +- */ +- if (array->major_version == 1 && +- get_linux_version() <= 2006018) +- goto skip_re_add; + disc.number = mdi.disk.number; + if (md_get_disk_info(fd, &disc) != 0 || + disc.major != 0 || disc.minor != 0) +diff --git a/mdadm.c b/mdadm.c +index 4685ad6b..2296911d 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -107,8 +107,8 @@ int main(int argc, char *argv[]) + + srandom(time(0) ^ getpid()); + +- if (get_linux_version() < 2006015) { +- pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); ++ if (get_linux_version() < 2006032) { ++ pr_err("This version of mdadm does not support kernels older than 2.6.32\n"); + exit(1); + } + +diff --git a/super1.c b/super1.c +index 1d20ef55..938c3a68 100644 +--- a/super1.c ++++ b/super1.c +@@ -2033,11 +2033,6 @@ static int write_init_super1(struct supertype *st) + /* same array, so preserve events and + * dev_number */ + sb->events = refsb->events; +- /* bugs in 2.6.17 and earlier mean the +- * dev_number chosen in Manage must be preserved +- */ +- if (get_linux_version() >= 2006018) +- sb->dev_number = refsb->dev_number; + } + free_super1(refst); + } +-- +2.38.1 + diff --git a/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch b/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch new file mode 100644 index 0000000..cb73179 --- /dev/null +++ b/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch @@ -0,0 +1,42 @@ +From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 7 Apr 2023 08:45:28 +0800 +Subject: [PATCH 120/120] Remove the config files in mdcheck_start|continue + service + +We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files. +And mdcheck doesn't use any configs from the config file. So we can remove +the dependencies. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.service | 2 -- + systemd/mdcheck_start.service | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index f5324905..70892a1f 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) + [Service] + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" +-EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index 703a6583..fc4fc438 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) + [Service] + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" +-EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} +-- +2.38.1 + diff --git a/mdadm.spec b/mdadm.spec index e03694c..53d4357 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 4%{?dist} +Release: 5%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -13,6 +13,7 @@ Source4: mdadm.conf Source5: mdadm_event.conf Source6: raid-check.timer Source7: raid-check.service +Source8: mdcheck Patch000: 0001-Unify-error-message.patch Patch001: 0002-mdadm-Fix-double-free.patch @@ -25,84 +26,121 @@ Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch Patch008: 0009-mdadm-Update-config-manual.patch Patch009: 0010-Create-Build-use-default_layout.patch Patch010: 0011-mdadm-add-map_num_s.patch -# patch0012 is deleted because of needing KillMode=none -Patch011: 0013-mdmon-Stop-parsing-duplicate-options.patch -Patch012: 0014-Grow-block-n-on-external-volumes.patch -Patch013: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch -Patch014: 0016-Mdmonitor-Fix-segfault.patch -Patch015: 0017-Mdmonitor-Improve-logging-method.patch -Patch016: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch -Patch017: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch -Patch018: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch -Patch019: 0021-util-replace-ioctl-use-with-function.patch -Patch020: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch -Patch021: 0023-imsm-introduce-get_disk_slot_in_dev.patch -Patch022: 0024-imsm-use-same-slot-across-container.patch -Patch023: 0025-imsm-block-changing-slots-during-creation.patch -Patch024: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch -Patch025: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch -Patch026: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch -Patch027: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch -Patch028: 0030-Monitor-use-snprintf-to-fill-device-name.patch -Patch029: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch -Patch030: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch -Patch031: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch -Patch032: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch -Patch033: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch -Patch034: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch -Patch035: 0037-mdadm-Fix-optional-write-behind-parameter.patch -Patch036: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch -Patch037: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch -Patch038: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch -Patch039: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch -Patch040: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch -Patch041: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch -Patch042: 0044-tests-Add-broken-files-for-all-broken-tests.patch -Patch043: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch -Patch044: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch -Patch045: 0047-tests-add-test-for-names.patch -Patch046: 0048-mdadm-remove-symlink-option.patch -Patch047: 0049-mdadm-move-data_offset-to-struct-shape.patch -Patch048: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch -Patch049: 0051-Grow-Split-Grow_reshape-into-helper-function.patch -Patch050: 0052-Assemble-check-if-device-is-container-before-schedul.patch -Patch051: 0053-super1-report-truncated-device.patch -Patch052: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch -Patch053: 0055-Manage-Block-unsafe-member-failing.patch -Patch054: 0056-Monitor-Fix-statelist-memory-leaks.patch -Patch055: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch -Patch056: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch -Patch057: 0059-ReadMe-fix-command-line-help.patch -Patch058: 0060-mdadm-replace-container-level-checking-with-inline.patch -Patch059: 0061-Mdmonitor-Omit-non-md-devices.patch -Patch060: 0062-Mdmonitor-Split-alert-into-separate-functions.patch -Patch061: 0063-Monitor-block-if-monitor-modes-are-combined.patch -Patch062: 0064-Update-mdadm-Monitor-manual.patch -Patch063: 0065-Grow-fix-possible-memory-leak.patch -Patch064: 0066-mdadm-create-ident_init.patch -Patch065: 0067-mdadm-Add-option-validation-for-update-subarray.patch -Patch066: 0068-Fix-update-subarray-on-active-volume.patch -Patch067: 0069-Add-code-specific-update-options-to-enum.patch -Patch068: 0070-super-ddf-Remove-update_super_ddf.patch -Patch069: 0071-super0-refactor-the-code-for-enum.patch -Patch070: 0072-super1-refactor-the-code-for-enum.patch -Patch071: 0073-super-intel-refactor-the-code-for-enum.patch -Patch072: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch -Patch073: 0075-Manage-Incremental-code-refactor-string-to-enum.patch -Patch074: 0076-Change-char-to-enum-in-context-update-refactor-code.patch -Patch075: 0077-mdmon-fix-segfault.patch -Patch076: 0078-util-remove-obsolete-code-from-get_md_name.patch -Patch077: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch -Patch078: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch -Patch079: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch -Patch080: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch -Patch081: 0083-manage-move-comment-with-function-description.patch +Patch011: 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch +Patch012: 0013-mdmon-Stop-parsing-duplicate-options.patch +Patch013: 0014-Grow-block-n-on-external-volumes.patch +Patch014: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch +Patch015: 0016-Mdmonitor-Fix-segfault.patch +Patch016: 0017-Mdmonitor-Improve-logging-method.patch +Patch017: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +Patch018: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +Patch019: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +Patch020: 0021-util-replace-ioctl-use-with-function.patch +Patch021: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +Patch022: 0023-imsm-introduce-get_disk_slot_in_dev.patch +Patch023: 0024-imsm-use-same-slot-across-container.patch +Patch024: 0025-imsm-block-changing-slots-during-creation.patch +Patch025: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch +Patch026: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch +Patch027: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +Patch028: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch +Patch029: 0030-Monitor-use-snprintf-to-fill-device-name.patch +Patch030: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch +Patch031: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch +Patch032: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +Patch033: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +Patch034: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +Patch035: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch +Patch036: 0037-mdadm-Fix-optional-write-behind-parameter.patch +Patch037: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch +Patch038: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch +Patch039: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch +Patch040: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch +Patch041: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch +Patch042: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch +Patch043: 0044-tests-Add-broken-files-for-all-broken-tests.patch +Patch044: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +Patch045: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch +Patch046: 0047-tests-add-test-for-names.patch +Patch047: 0048-mdadm-remove-symlink-option.patch +Patch048: 0049-mdadm-move-data_offset-to-struct-shape.patch +Patch049: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +Patch050: 0051-Grow-Split-Grow_reshape-into-helper-function.patch +Patch051: 0052-Assemble-check-if-device-is-container-before-schedul.patch +Patch052: 0053-super1-report-truncated-device.patch +Patch053: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +Patch054: 0055-Manage-Block-unsafe-member-failing.patch +Patch055: 0056-Monitor-Fix-statelist-memory-leaks.patch +Patch056: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +Patch057: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch +Patch058: 0059-ReadMe-fix-command-line-help.patch +Patch059: 0060-mdadm-replace-container-level-checking-with-inline.patch +Patch060: 0061-Mdmonitor-Omit-non-md-devices.patch +Patch061: 0062-Mdmonitor-Split-alert-into-separate-functions.patch +Patch062: 0063-Monitor-block-if-monitor-modes-are-combined.patch +Patch063: 0064-Update-mdadm-Monitor-manual.patch +Patch064: 0065-Grow-fix-possible-memory-leak.patch +Patch065: 0066-mdadm-create-ident_init.patch +Patch066: 0067-mdadm-Add-option-validation-for-update-subarray.patch +Patch067: 0068-Fix-update-subarray-on-active-volume.patch +Patch068: 0069-Add-code-specific-update-options-to-enum.patch +Patch069: 0070-super-ddf-Remove-update_super_ddf.patch +Patch070: 0071-super0-refactor-the-code-for-enum.patch +Patch071: 0072-super1-refactor-the-code-for-enum.patch +Patch072: 0073-super-intel-refactor-the-code-for-enum.patch +Patch073: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch +Patch074: 0075-Manage-Incremental-code-refactor-string-to-enum.patch +Patch075: 0076-Change-char-to-enum-in-context-update-refactor-code.patch +Patch076: 0077-mdmon-fix-segfault.patch +Patch077: 0078-util-remove-obsolete-code-from-get_md_name.patch +Patch078: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +Patch079: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch +Patch080: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch +Patch081: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch +Patch082: 0083-manage-move-comment-with-function-description.patch +Patch083: 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch +Patch084: 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch +Patch085: 0086-Fix-NULL-dereference-in-super_by_fd.patch +Patch086: 0087-Mdmonitor-Make-alert_info-global.patch +Patch087: 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch +Patch088: 0089-Mdmonitor-Add-helper-functions.patch +Patch089: 0090-Add-helpers-to-determine-whether-directories-or-file.patch +Patch090: 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch +Patch091: 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch +Patch092: 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch +Patch093: 0094-util.c-fix-memleak-in-parse_layout_faulty.patch +Patch094: 0095-Detail.c-fix-memleak-in-Detail.patch +Patch095: 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch +Patch096: 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch +Patch097: 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch +Patch098: 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch +Patch099: 0100-Create-remove-safe_mode_delay-local-variable.patch +Patch100: 0101-Create-Factor-out-add_disks-helpers.patch +Patch101: 0102-mdadm-Introduce-pr_info.patch +Patch102: 0103-mdadm-Add-write-zeros-option-for-Create.patch +Patch103: 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch +Patch104: 0105-manpage-Add-write-zeroes-option-to-manpage.patch +Patch105: 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch +Patch106: 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch +Patch107: 0108-mdmon-don-t-test-both-all-and-container_name.patch +Patch108: 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch +Patch109: 0110-mdmon-Remove-need-for-KillMode-none.patch +Patch110: 0111-mdmon-Improve-switchroot-interactions.patch +Patch111: 0112-mdopen-always-try-create_named_array.patch +Patch112: 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch +Patch113: 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch +Patch114: 0115-Create-Fix-checking-for-container-in-update_metadata.patch +Patch115: 0116-Fix-null-pointer-for-incremental-in-mdadm.patch +Patch116: 0117-super1-fix-truncation-check-for-journal-device.patch +Patch117: 0118-Fix-some-cases-eyesore-formatting.patch +Patch118: 0119-Bump-minimum-kernel-version-to-2.6.32.patch +Patch119: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch # Fedora customization patches -Patch97: mdadm-udev.patch -Patch98: mdadm-2.5.2-static.patch +Patch197: mdadm-udev.patch +Patch198: mdadm-2.5.2-static.patch # Build without -Werror. -Patch99: disable-Werror.patch +Patch199: disable-Werror.patch BuildRequires: make BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel @@ -129,6 +167,8 @@ make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_un 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 # systemd mkdir -p %{buildroot}%{_unitdir} @@ -168,8 +208,13 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d %dir /run/%{name}/ %config(noreplace) %{_tmpfilesdir}/%{name}.conf /etc/libreport/events.d/* +/usr/share/mdadm/mdcheck %changelog +* 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 diff --git a/mdcheck b/mdcheck new file mode 100644 index 0000000..700c3e2 --- /dev/null +++ b/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 From c3138fdc957af0cb737dabc030a2f747ba4a533a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jul 2023 14:07:10 +0000 Subject: [PATCH 08/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 53d4357..edd6dfa 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 5%{?dist} +Release: 6%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -211,6 +211,9 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d /usr/share/mdadm/mdcheck %changelog +* 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 From 110a739c7d1c6e238122539e722e56d18597763d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sun, 21 Jan 2024 07:13:51 +0000 Subject: [PATCH 09/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index edd6dfa..acd22ba 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 6%{?dist} +Release: 7%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -211,6 +211,9 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d /usr/share/mdadm/mdcheck %changelog +* 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 From fc9ebc2db4a95d39b6b43de2ce156970c3eeaa93 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jan 2024 06:06:04 +0000 Subject: [PATCH 10/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index acd22ba..a3a1b43 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 7%{?dist} +Release: 8%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -211,6 +211,9 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d /usr/share/mdadm/mdcheck %changelog +* 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 From 5ec161dc73ea9803d0fc6602f58515f96816cf5f Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Wed, 8 May 2024 09:57:32 -0500 Subject: [PATCH 11/22] use more macros in %files, fixes rhbz#2279743 --- mdadm.spec | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mdadm.spec b/mdadm.spec index a3a1b43..e0c4a56 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.2 -Release: 8%{?dist} +Release: 9%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -203,14 +203,18 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d %{_sbindir}/* %{_unitdir}/* %{_mandir}/man*/md* -/usr/lib/systemd/system-shutdown/* +%{_prefix}/lib/systemd/system-shutdown/* %config(noreplace) %{_sysconfdir}/sysconfig/* -%dir /run/%{name}/ +%{_rundir}/%{name}/ %config(noreplace) %{_tmpfilesdir}/%{name}.conf -/etc/libreport/events.d/* -/usr/share/mdadm/mdcheck +%{_sysconfdir}/libreport/events.d/* +%{_datadir}/%{name}/ %changelog +* Wed May 08 2024 Jonathan Wright - 4.2-9 +- Fixes rhbz#2279743 +- Use more macros in %files definitions + * Thu Jan 25 2024 Fedora Release Engineering - 4.2-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 4220b6778bbbb150ef86a040bb65058beefd2771 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Wed, 8 May 2024 11:21:05 -0500 Subject: [PATCH 12/22] update to 4.3 rhbz#2267100 modernize spec --- 0001-Unify-error-message.patch | 47 - 0002-mdadm-Fix-double-free.patch | 33 - ...-r0-grow-size-error-message-and-upda.patch | 83 - 0004-udev-adapt-rules-to-systemd-v247.patch | 67 - ...ce-error-prone-signal-with-sigaction.patch | 252 --- ...-Respect-config-file-location-in-man.patch | 1533 ----------------- 0007-mdadm-Update-ReadMe.patch | 48 - ...fig-man-regarding-default-files-and-.patch | 203 --- 0009-mdadm-Update-config-manual.patch | 45 - 0010-Create-Build-use-default_layout.patch | 153 -- 0011-mdadm-add-map_num_s.patch | 382 ---- ...move-KillMode-none-from-service-file.patch | 69 - ...mdmon-Stop-parsing-duplicate-options.patch | 122 -- 0014-Grow-block-n-on-external-volumes.patch | 41 - ...x-possible-memory-and-resource-leaks.patch | 90 - 0016-Mdmonitor-Fix-segfault.patch | 98 -- 0017-Mdmonitor-Improve-logging-method.patch | 61 - ...LL-ptr-dereferences-and-memory-leaks.patch | 73 - ...ibility-for-get_imsm_dev-to-return-N.patch | 301 ---- ...dadm-fix-coredump-of-mdadm-monitor-r.patch | 85 - ...util-replace-ioctl-use-with-function.patch | 31 - ...tore-commit-45a87c2f31335-to-fix-clu.patch | 110 -- ...-imsm-introduce-get_disk_slot_in_dev.patch | 122 -- ...-imsm-use-same-slot-across-container.patch | 252 --- ...block-changing-slots-during-creation.patch | 122 -- ...ck-update-ppl-for-non-raid456-levels.patch | 177 -- ...m-Fix-array-size-mismatch-after-grow.patch | 30 - ...-dead-code-in-imsm_fix_size_mismatch.patch | 34 - ...ame-as-char-array-instead-of-pointer.patch | 40 - ...tor-use-snprintf-to-fill-device-name.patch | 133 -- ...uild-static-build-with-everything-an.patch | 42 - ...anup-validate_geometry_ddf_container.patch | 141 -- ...nter-dereference-in-validate_geometr.patch | 49 - ...se-after-close-bug-by-closing-after-.patch | 85 - ...gfault-when-calling-NULL-get_bad_blo.patch | 36 - ...Fix-mdadm-r-remove-option-regression.patch | 78 - ...-Fix-optional-write-behind-parameter.patch | 42 - ...d-a-test-that-validates-raid0-with-l.patch | 38 - ...ts-fix-raid0-tests-for-0.90-metadata.patch | 99 -- ...etadata-avoid-passing-chunk-size-to-.patch | 39 - ...ow-clear-the-superblock-at-every-ite.patch | 31 - ...Add-a-mode-to-repeat-specified-tests.patch | 88 - ...Mark-and-ignore-broken-test-failures.patch | 120 -- ...dd-broken-files-for-all-broken-tests.patch | 447 ----- ...place-obsolete-usleep-with-nanosleep.patch | 316 ---- ...-Run-udevadm-settle-before-setting-r.patch | 36 - 0047-tests-add-test-for-names.patch | 119 -- 0048-mdadm-remove-symlink-option.patch | 176 -- ...adm-move-data_offset-to-struct-shape.patch | 232 --- ...en-md-device-for-CREATE-and-ASSEMBLE.patch | 162 -- ...it-Grow_reshape-into-helper-function.patch | 231 --- ...f-device-is-container-before-schedul.patch | 36 - 0053-super1-report-truncated-device.patch | 112 -- ...typos-punctuation-and-grammar-in-man.patch | 616 ------- 0055-Manage-Block-unsafe-member-failing.patch | 91 - 0056-Monitor-Fix-statelist-memory-leaks.patch | 112 -- ...ort-for-Intel-Alderlake-RST-on-VMD-p.patch | 64 - ...entation-entries-to-systemd-services.patch | 111 -- 0059-ReadMe-fix-command-line-help.patch | 32 - ...container-level-checking-with-inline.patch | 257 --- 0061-Mdmonitor-Omit-non-md-devices.patch | 58 - ...-Split-alert-into-separate-functions.patch | 233 --- ...-block-if-monitor-modes-are-combined.patch | 41 - 0064-Update-mdadm-Monitor-manual.patch | 119 -- 0065-Grow-fix-possible-memory-leak.patch | 38 - 0066-mdadm-create-ident_init.patch | 148 -- ...ption-validation-for-update-subarray.patch | 287 --- ...Fix-update-subarray-on-active-volume.patch | 54 - ...code-specific-update-options-to-enum.patch | 77 - 0070-super-ddf-Remove-update_super_ddf.patch | 106 -- 0071-super0-refactor-the-code-for-enum.patch | 212 --- 0072-super1-refactor-the-code-for-enum.patch | 302 ---- ...per-intel-refactor-the-code-for-enum.patch | 106 -- ...-enum-in-update_super-and-update_sub.patch | 424 ----- ...emental-code-refactor-string-to-enum.patch | 279 --- ...enum-in-context-update-refactor-code.patch | 289 ---- 0077-mdmon-fix-segfault.patch | 86 - ...emove-obsolete-code-from-get_md_name.patch | 116 -- ...t-handle-change-event-on-raw-devices.patch | 54 - ...eck-array-state-when-drive-is-remove.patch | 33 - ...nage-do-not-verify-if-remove-is-safe.patch | 59 - ...-freesize-not-required-for-chunk-siz.patch | 52 - ...ve-comment-with-function-description.patch | 105 -- ...temd-remove-KillMode-none-from-servi.patch | 54 - ...hange-bitmap-type-from-none-to-clust.patch | 45 - ...-Fix-NULL-dereference-in-super_by_fd.patch | 76 - 0087-Mdmonitor-Make-alert_info-global.patch | 369 ---- ...vents-to-alert-using-enums-instead-o.patch | 313 ---- 0089-Mdmonitor-Add-helper-functions.patch | 406 ----- ...etermine-whether-directories-or-file.patch | 83 - ...nitor-Refactor-write_autorebuild_pid.patch | 110 -- ...or-check_one_sharer-for-better-error.patch | 139 -- ...er-code-lines-in-parse_layout_faulty.patch | 41 - ...c-fix-memleak-in-parse_layout_faulty.patch | 32 - 0095-Detail.c-fix-memleak-in-Detail.patch | 31 - ...l.c-fix-double-free-in-load_imsm_mpb.patch | 63 - ...ix-memleak-in-find_disk_attached_hba.patch | 39 - ...ix-memleak-in-get_vd_num_of_subarray.patch | 46 - ...t_locked-instead-of-return-1-in-erro.patch | 36 - ...emove-safe_mode_delay-local-variable.patch | 64 - ...-Create-Factor-out-add_disks-helpers.patch | 452 ----- 0102-mdadm-Introduce-pr_info.patch | 72 - ...dm-Add-write-zeros-option-for-Create.patch | 346 ---- ...ro-Introduce-test-to-exercise-write-.patch | 44 - ...e-Add-write-zeroes-option-to-manpage.patch | 56 - ...sing-_Alignof-when-using-C11-or-newe.patch | 53 - ...-etc-initrd-release-to-detect-initrd.patch | 41 - ...n-t-test-both-all-and-container_name.patch | 47 - ...-systemd-unit-file-to-use-foreground.patch | 33 - ...-mdmon-Remove-need-for-KillMode-none.patch | 55 - ...dmon-Improve-switchroot-interactions.patch | 166 -- ...mdopen-always-try-create_named_array.patch | 40 - ...vements-for-IMSM_NO_PLATFORM-testing.patch | 172 -- ...adm-systemd-remove-KillMode-none-fro.patch | 29 - ...ing-for-container-in-update_metadata.patch | 38 - ...ull-pointer-for-incremental-in-mdadm.patch | 43 - ...-truncation-check-for-journal-device.patch | 33 - 0118-Fix-some-cases-eyesore-formatting.patch | 433 ----- ...ump-minimum-kernel-version-to-2.6.32.patch | 136 -- ...g-files-in-mdcheck_start-continue-se.patch | 42 - disable-Werror.patch | 11 - mdadm.spec | 207 +-- sources | 2 +- 123 files changed, 52 insertions(+), 16599 deletions(-) delete mode 100644 0001-Unify-error-message.patch delete mode 100644 0002-mdadm-Fix-double-free.patch delete mode 100644 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch delete mode 100644 0004-udev-adapt-rules-to-systemd-v247.patch delete mode 100644 0005-Replace-error-prone-signal-with-sigaction.patch delete mode 100644 0006-mdadm-Respect-config-file-location-in-man.patch delete mode 100644 0007-mdadm-Update-ReadMe.patch delete mode 100644 0008-mdadm-Update-config-man-regarding-default-files-and-.patch delete mode 100644 0009-mdadm-Update-config-manual.patch delete mode 100644 0010-Create-Build-use-default_layout.patch delete mode 100644 0011-mdadm-add-map_num_s.patch delete mode 100644 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch delete mode 100644 0013-mdmon-Stop-parsing-duplicate-options.patch delete mode 100644 0014-Grow-block-n-on-external-volumes.patch delete mode 100644 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch delete mode 100644 0016-Mdmonitor-Fix-segfault.patch delete mode 100644 0017-Mdmonitor-Improve-logging-method.patch delete mode 100644 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch delete mode 100644 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch delete mode 100644 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch delete mode 100644 0021-util-replace-ioctl-use-with-function.patch delete mode 100644 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch delete mode 100644 0023-imsm-introduce-get_disk_slot_in_dev.patch delete mode 100644 0024-imsm-use-same-slot-across-container.patch delete mode 100644 0025-imsm-block-changing-slots-during-creation.patch delete mode 100644 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch delete mode 100644 0027-mdadm-Fix-array-size-mismatch-after-grow.patch delete mode 100644 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch delete mode 100644 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch delete mode 100644 0030-Monitor-use-snprintf-to-fill-device-name.patch delete mode 100644 0031-Makefile-Don-t-build-static-build-with-everything-an.patch delete mode 100644 0032-DDF-Cleanup-validate_geometry_ddf_container.patch delete mode 100644 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch delete mode 100644 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch delete mode 100644 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch delete mode 100644 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch delete mode 100644 0037-mdadm-Fix-optional-write-behind-parameter.patch delete mode 100644 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch delete mode 100644 0039-tests-fix-raid0-tests-for-0.90-metadata.patch delete mode 100644 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch delete mode 100644 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch delete mode 100644 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch delete mode 100644 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch delete mode 100644 0044-tests-Add-broken-files-for-all-broken-tests.patch delete mode 100644 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch delete mode 100644 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch delete mode 100644 0047-tests-add-test-for-names.patch delete mode 100644 0048-mdadm-remove-symlink-option.patch delete mode 100644 0049-mdadm-move-data_offset-to-struct-shape.patch delete mode 100644 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch delete mode 100644 0051-Grow-Split-Grow_reshape-into-helper-function.patch delete mode 100644 0052-Assemble-check-if-device-is-container-before-schedul.patch delete mode 100644 0053-super1-report-truncated-device.patch delete mode 100644 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch delete mode 100644 0055-Manage-Block-unsafe-member-failing.patch delete mode 100644 0056-Monitor-Fix-statelist-memory-leaks.patch delete mode 100644 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch delete mode 100644 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch delete mode 100644 0059-ReadMe-fix-command-line-help.patch delete mode 100644 0060-mdadm-replace-container-level-checking-with-inline.patch delete mode 100644 0061-Mdmonitor-Omit-non-md-devices.patch delete mode 100644 0062-Mdmonitor-Split-alert-into-separate-functions.patch delete mode 100644 0063-Monitor-block-if-monitor-modes-are-combined.patch delete mode 100644 0064-Update-mdadm-Monitor-manual.patch delete mode 100644 0065-Grow-fix-possible-memory-leak.patch delete mode 100644 0066-mdadm-create-ident_init.patch delete mode 100644 0067-mdadm-Add-option-validation-for-update-subarray.patch delete mode 100644 0068-Fix-update-subarray-on-active-volume.patch delete mode 100644 0069-Add-code-specific-update-options-to-enum.patch delete mode 100644 0070-super-ddf-Remove-update_super_ddf.patch delete mode 100644 0071-super0-refactor-the-code-for-enum.patch delete mode 100644 0072-super1-refactor-the-code-for-enum.patch delete mode 100644 0073-super-intel-refactor-the-code-for-enum.patch delete mode 100644 0074-Change-update-to-enum-in-update_super-and-update_sub.patch delete mode 100644 0075-Manage-Incremental-code-refactor-string-to-enum.patch delete mode 100644 0076-Change-char-to-enum-in-context-update-refactor-code.patch delete mode 100644 0077-mdmon-fix-segfault.patch delete mode 100644 0078-util-remove-obsolete-code-from-get_md_name.patch delete mode 100644 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch delete mode 100644 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch delete mode 100644 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch delete mode 100644 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch delete mode 100644 0083-manage-move-comment-with-function-description.patch delete mode 100644 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch delete mode 100644 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch delete mode 100644 0086-Fix-NULL-dereference-in-super_by_fd.patch delete mode 100644 0087-Mdmonitor-Make-alert_info-global.patch delete mode 100644 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch delete mode 100644 0089-Mdmonitor-Add-helper-functions.patch delete mode 100644 0090-Add-helpers-to-determine-whether-directories-or-file.patch delete mode 100644 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch delete mode 100644 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch delete mode 100644 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch delete mode 100644 0094-util.c-fix-memleak-in-parse_layout_faulty.patch delete mode 100644 0095-Detail.c-fix-memleak-in-Detail.patch delete mode 100644 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch delete mode 100644 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch delete mode 100644 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch delete mode 100644 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch delete mode 100644 0100-Create-remove-safe_mode_delay-local-variable.patch delete mode 100644 0101-Create-Factor-out-add_disks-helpers.patch delete mode 100644 0102-mdadm-Introduce-pr_info.patch delete mode 100644 0103-mdadm-Add-write-zeros-option-for-Create.patch delete mode 100644 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch delete mode 100644 0105-manpage-Add-write-zeroes-option-to-manpage.patch delete mode 100644 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch delete mode 100644 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch delete mode 100644 0108-mdmon-don-t-test-both-all-and-container_name.patch delete mode 100644 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch delete mode 100644 0110-mdmon-Remove-need-for-KillMode-none.patch delete mode 100644 0111-mdmon-Improve-switchroot-interactions.patch delete mode 100644 0112-mdopen-always-try-create_named_array.patch delete mode 100644 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch delete mode 100644 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch delete mode 100644 0115-Create-Fix-checking-for-container-in-update_metadata.patch delete mode 100644 0116-Fix-null-pointer-for-incremental-in-mdadm.patch delete mode 100644 0117-super1-fix-truncation-check-for-journal-device.patch delete mode 100644 0118-Fix-some-cases-eyesore-formatting.patch delete mode 100644 0119-Bump-minimum-kernel-version-to-2.6.32.patch delete mode 100644 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch delete mode 100644 disable-Werror.patch diff --git a/0001-Unify-error-message.patch b/0001-Unify-error-message.patch deleted file mode 100644 index 14dc69c..0000000 --- a/0001-Unify-error-message.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Tue, 15 Mar 2022 09:30:30 +0100 -Subject: [PATCH 01/83] Unify error message. - -Provide the same error message for the same error that can occur in Grow.c and super-intel.c. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - super-intel.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9c6fc95e..9a947204 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1001,8 +1001,8 @@ int remove_disks_for_takeover(struct supertype *st, - rv = 1; - sysfs_free(arrays); - if (rv) { -- pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm); -- pr_err("For this operation it MUST be single array in container\n"); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", st->devnm); - return rv; - } - } -diff --git a/super-intel.c b/super-intel.c -index d5fad102..5ffa7636 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - struct imsm_super *mpb = super->anchor; - - if (mpb->num_raid_devs > 1) { -- pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n", -- geo->dev_name); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", geo->dev_name); - change = -1; - } - } --- -2.38.1 - diff --git a/0002-mdadm-Fix-double-free.patch b/0002-mdadm-Fix-double-free.patch deleted file mode 100644 index e6b7d37..0000000 --- a/0002-mdadm-Fix-double-free.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 25 Mar 2022 12:48:59 +0100 -Subject: [PATCH 02/83] mdadm: Fix double free - -If there was a size mismatch after creation it would get fixed on grow -in imsm_fix_size_mismatch(), but due to double free "double free or corruption (fasttop)" -error occurs and grow cannot proceed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5ffa7636..6ff336ee 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - st->update_tail = &st->updates; - } else { - imsm_sync_metadata(st); -+ free(update); - } -- -- free(update); - } - ret_val = 0; - exit: --- -2.38.1 - diff --git a/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch b/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch deleted file mode 100644 index e43cdaa..0000000 --- a/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch +++ /dev/null @@ -1,83 +0,0 @@ -From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Wed, 23 Mar 2022 15:05:19 +0100 -Subject: [PATCH 03/83] Grow_reshape: Add r0 grow size error message and update - man - -Grow size on r0 is not supported for imsm and native metadata. -Add proper error message. -Update man for proper use of --size. -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 6 ++++++ - mdadm.8.in | 19 ++++++++++++------- - 2 files changed, 18 insertions(+), 7 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9a947204..aa72490b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1998,6 +1998,12 @@ int Grow_reshape(char *devname, int fd, - goto release; - } - -+ if (array.level == 0) { -+ pr_err("Component size change is not supported for RAID0\n"); -+ rv = 1; -+ goto release; -+ } -+ - if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, - devname, APPLY_METADATA_CHANGES, - c->verbose > 0)) { -diff --git a/mdadm.8.in b/mdadm.8.in -index be902dba..e2a42425 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -459,7 +459,8 @@ number of spare devices. - - .TP - .BR \-z ", " \-\-size= --Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6. -+Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10 -+and for RAID 0 on external metadata. - This must be a multiple of the chunk size, and must leave about 128Kb - of space at the end of the drive for the RAID superblock. - If this is not specified -@@ -478,10 +479,19 @@ To guard against this it can be useful to set the initial size - slightly smaller than the smaller device with the aim that it will - still be larger than any replacement. - -+This option can be used with -+.B \-\-create -+for determining initial size of an array. For external metadata, -+it can be used on a volume, but not on a container itself. -+Setting initial size of -+.B RAID 0 -+array is only valid for external metadata. -+ - This value can be set with - .B \-\-grow --for RAID level 1/4/5/6 though -+for RAID level 1/4/5/6/10 though - DDF arrays may not be able to support this. -+RAID 0 array size cannot be changed. - If the array was created with a size smaller than the currently - active drives, the extra space can be accessed using - .BR \-\-grow . -@@ -501,11 +511,6 @@ problems the array can be made bigger again with no loss with another - .B "\-\-grow \-\-size=" - command. - --This value cannot be used when creating a --.B CONTAINER --such as with DDF and IMSM metadata, though it perfectly valid when --creating an array inside a container. -- - .TP - .BR \-Z ", " \-\-array\-size= - This is only meaningful with --- -2.38.1 - diff --git a/0004-udev-adapt-rules-to-systemd-v247.patch b/0004-udev-adapt-rules-to-systemd-v247.patch deleted file mode 100644 index a755c53..0000000 --- a/0004-udev-adapt-rules-to-systemd-v247.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 14 Jan 2022 16:44:33 +0100 -Subject: [PATCH 04/83] udev: adapt rules to systemd v247 - -New events have been added in kernel 4.14 ("bind" and "unbind"). -Systemd maintainer suggests to modify "add|change" branches. -This patches implements their suggestions. There is no issue yet because -new event types are not used in md. - -Please see systemd announcement for details[1]. - -[1] https://lists.freedesktop.org/archives/systemd-devel/2020-November/045646.html - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - udev-md-raid-arrays.rules | 2 +- - udev-md-raid-assembly.rules | 5 +++-- - udev-md-raid-safe-timeouts.rules | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 13c9076e..2967ace1 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -3,7 +3,7 @@ - SUBSYSTEM!="block", GOTO="md_end" - - # handle md arrays --ACTION!="add|change", GOTO="md_end" -+ACTION=="remove", GOTO="md_end" - KERNEL!="md*", GOTO="md_end" - - # partitions have no md/{array_state,metadata_version}, but should not -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index d668cddd..39b4344b 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -30,8 +30,9 @@ LABEL="md_inc" - - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' --ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" -+ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ - ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" - ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" - -diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules -index 12bdcaa8..2e185cee 100644 ---- a/udev-md-raid-safe-timeouts.rules -+++ b/udev-md-raid-safe-timeouts.rules -@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end" - - IMPORT{program}="/sbin/mdadm --examine --export $devnode" - --ACTION=="add|change", \ -+ACTION!="remove", \ - ENV{ID_FS_TYPE}=="linux_raid_member", \ - ENV{MD_LEVEL}=="raid[1-9]*", \ - TEST=="/sys/block/$parent/device/timeout", \ --- -2.38.1 - diff --git a/0005-Replace-error-prone-signal-with-sigaction.patch b/0005-Replace-error-prone-signal-with-sigaction.patch deleted file mode 100644 index dd04b8c..0000000 --- a/0005-Replace-error-prone-signal-with-sigaction.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Mon, 21 Feb 2022 13:05:20 +0100 -Subject: [PATCH 05/83] Replace error prone signal() with sigaction() - -Up to this date signal() was used which implementation could vary [1]. -Sigaction() call is preferred. This commit introduces replacement -from signal() to sigaction() by the use of signal_s() wrapper. -Also remove redundant signal.h header includes. - -[1] https://man7.org/linux/man-pages/man2/signal.2.html - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - Monitor.c | 5 +++-- - managemon.c | 1 - - mdadm.h | 22 ++++++++++++++++++++++ - mdmon.c | 1 - - monitor.c | 1 - - probe_roms.c | 6 +++--- - raid6check.c | 25 +++++++++++++++---------- - util.c | 1 - - 9 files changed, 45 insertions(+), 21 deletions(-) - -diff --git a/Grow.c b/Grow.c -index aa72490b..18c5719b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -26,7 +26,6 @@ - #include - #include - #include --#include - #include - - #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) -@@ -3566,7 +3565,8 @@ started: - fd = -1; - mlockall(MCL_FUTURE); - -- signal(SIGTERM, catch_term); -+ if (signal_s(SIGTERM, catch_term) == SIG_ERR) -+ goto release; - - if (st->ss->external) { - /* metadata handler takes it from here */ -diff --git a/Monitor.c b/Monitor.c -index 30c031a2..c0ab5412 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -26,7 +26,6 @@ - #include "md_p.h" - #include "md_u.h" - #include --#include - #include - #include - #ifndef NO_LIBUDEV -@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) - if (mp) { - FILE *mdstat; - char hname[256]; -+ - gethostname(hname, sizeof(hname)); -- signal(SIGPIPE, SIG_IGN); -+ signal_s(SIGPIPE, SIG_IGN); -+ - if (info->mailfrom) - fprintf(mp, "From: %s\n", info->mailfrom); - else -diff --git a/managemon.c b/managemon.c -index bb7334cf..0e9bdf00 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -106,7 +106,6 @@ - #include "mdmon.h" - #include - #include --#include - - static void close_aa(struct active_array *aa) - { -diff --git a/mdadm.h b/mdadm.h -index c7268a71..26e7e5cd 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - #include - #include - #include -+#include - /* Newer glibc requires sys/sysmacros.h directly for makedev() */ - #include - #ifdef __dietlibc__ -@@ -1729,6 +1730,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) - return &ent->metadata_version[10+strlen(container)+1]; - } - -+/** -+ * signal_s() - Wrapper for sigaction() with signal()-like interface. -+ * @sig: The signal to set the signal handler to. -+ * @handler: The signal handler. -+ * -+ * Return: previous handler or SIG_ERR on failure. -+ */ -+static inline sighandler_t signal_s(int sig, sighandler_t handler) -+{ -+ struct sigaction new_act; -+ struct sigaction old_act; -+ -+ new_act.sa_handler = handler; -+ new_act.sa_flags = 0; -+ -+ if (sigaction(sig, &new_act, &old_act) == 0) -+ return old_act.sa_handler; -+ -+ return SIG_ERR; -+} -+ - #ifdef DEBUG - #define dprintf(fmt, arg...) \ - fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) -diff --git a/mdmon.c b/mdmon.c -index c71e62c6..5570574b 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -56,7 +56,6 @@ - #include - #include - #include --#include - #include - #ifdef USE_PTHREADS - #include -diff --git a/monitor.c b/monitor.c -index e0d3be67..b877e595 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -22,7 +22,6 @@ - #include "mdmon.h" - #include - #include --#include - - static char *array_states[] = { - "clear", "inactive", "suspended", "readonly", "read-auto", -diff --git a/probe_roms.c b/probe_roms.c -index 7ea04c7a..94c80c2c 100644 ---- a/probe_roms.c -+++ b/probe_roms.c -@@ -22,7 +22,6 @@ - #include "probe_roms.h" - #include "mdadm.h" - #include --#include - #include - #include - #include -@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val) - - void probe_roms_exit(void) - { -- signal(SIGBUS, SIG_DFL); -+ signal_s(SIGBUS, SIG_DFL); -+ - if (rom_fd >= 0) { - close(rom_fd); - rom_fd = -1; -@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align) - if (roms_init()) - return -1; - -- if (signal(SIGBUS, sigbus) == SIG_ERR) -+ if (signal_s(SIGBUS, sigbus) == SIG_ERR) - rc = -1; - if (rc == 0) { - fd = open("/dev/mem", O_RDONLY); -diff --git a/raid6check.c b/raid6check.c -index a8e6005b..99477761 100644 ---- a/raid6check.c -+++ b/raid6check.c -@@ -24,7 +24,6 @@ - - #include "mdadm.h" - #include --#include - #include - - #define CHECK_PAGE_BITS (12) -@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size) - } - - int lock_stripe(struct mdinfo *info, unsigned long long start, -- int chunk_size, int data_disks, sighandler_t *sig) { -+ int chunk_size, int data_disks, sighandler_t *sig) -+{ - int rv; -+ -+ sig[0] = signal_s(SIGTERM, SIG_IGN); -+ sig[1] = signal_s(SIGINT, SIG_IGN); -+ sig[2] = signal_s(SIGQUIT, SIG_IGN); -+ -+ if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR) -+ return 1; -+ - if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - return 2; - } - -- sig[0] = signal(SIGTERM, SIG_IGN); -- sig[1] = signal(SIGINT, SIG_IGN); -- sig[2] = signal(SIGQUIT, SIG_IGN); -- - rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks); - rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks); - return rv * 256; - } - --int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) { -+int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) -+{ - int rv; - rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL); - rv |= sysfs_set_num(info, NULL, "suspend_hi", 0); - rv |= sysfs_set_num(info, NULL, "suspend_lo", 0); - -- signal(SIGQUIT, sig[2]); -- signal(SIGINT, sig[1]); -- signal(SIGTERM, sig[0]); -+ signal_s(SIGQUIT, sig[2]); -+ signal_s(SIGINT, sig[1]); -+ signal_s(SIGTERM, sig[0]); - - if(munlockall() != 0) - return 3; -diff --git a/util.c b/util.c -index 3d05d074..cc94f96e 100644 ---- a/util.c -+++ b/util.c -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - #include - - --- -2.38.1 - diff --git a/0006-mdadm-Respect-config-file-location-in-man.patch b/0006-mdadm-Respect-config-file-location-in-man.patch deleted file mode 100644 index bee28ac..0000000 --- a/0006-mdadm-Respect-config-file-location-in-man.patch +++ /dev/null @@ -1,1533 +0,0 @@ -From e9dd5644843e2013a7dd1a8a5da2b9fa35837416 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:04 +0100 -Subject: [PATCH 06/83] mdadm: Respect config file location in man - -Default config file location could differ depending on OS (e.g. Debian family). -This patch takes default config file into consideration when creating mdadm.man -file as well as mdadm.conf.man. - -Rename mdadm.conf.5 to mdadm.conf.5.in. Now mdadm.conf.5 is generated automatically. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - .gitignore | 1 + - Makefile | 7 +- - mdadm.8.in | 16 +- - mdadm.conf.5 | 706 ------------------------------------------------ - mdadm.conf.5.in | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 721 insertions(+), 715 deletions(-) - delete mode 100644 mdadm.conf.5 - create mode 100644 mdadm.conf.5.in - -diff --git a/.gitignore b/.gitignore -index 217fe76d..8d791c6f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -3,6 +3,7 @@ - /*-stamp - /mdadm - /mdadm.8 -+/mdadm.conf.5 - /mdadm.udeb - /mdassemble - /mdmon -diff --git a/Makefile b/Makefile -index 2a51d813..bf126033 100644 ---- a/Makefile -+++ b/Makefile -@@ -227,7 +227,12 @@ raid6check : raid6check.o mdadm.h $(CHECK_OBJS) - - mdadm.8 : mdadm.8.in - sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \ -- -e 's,{MAP_PATH},$(MAP_PATH),g' mdadm.8.in > mdadm.8 -+ -e 's,{MAP_PATH},$(MAP_PATH),g' -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.8.in > mdadm.8 -+ -+mdadm.conf.5 : mdadm.conf.5.in -+ sed -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.conf.5.in > mdadm.conf.5 - - mdadm.man : mdadm.8 - man -l mdadm.8 > mdadm.man -diff --git a/mdadm.8.in b/mdadm.8.in -index e2a42425..8b21ffd4 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -267,13 +267,13 @@ the exact meaning of this option in different contexts. - .TP - .BR \-c ", " \-\-config= - Specify the config file or directory. Default is to use --.B /etc/mdadm.conf -+.B {CONFFILE} - and --.BR /etc/mdadm.conf.d , -+.BR {CONFFILE}.d , - or if those are missing then --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - and --.BR /etc/mdadm/mdadm.conf.d . -+.BR {CONFFILE2}.d . - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2014,9 +2014,9 @@ The config file is only used if explicitly named with - or requested with (a possibly implicit) - .BR \-\-scan . - In the later case, --.B /etc/mdadm.conf -+.B {CONFFILE} - or --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - is used. - - If -@@ -3344,7 +3344,7 @@ uses this to find arrays when - is given in Misc mode, and to monitor array reconstruction - on Monitor mode. - --.SS /etc/mdadm.conf -+.SS {CONFFILE} (or {CONFFILE2}) - - The config file lists which devices may be scanned to see if - they contain MD super block, and gives identifying information -@@ -3352,7 +3352,7 @@ they contain MD super block, and gives identifying information - .BR mdadm.conf (5) - for more details. - --.SS /etc/mdadm.conf.d -+.SS {CONFFILE}.d (or {CONFFILE2}.d) - - A directory containing configuration files which are read in lexical - order. -diff --git a/mdadm.conf.5 b/mdadm.conf.5 -deleted file mode 100644 -index 74a21c5f..00000000 ---- a/mdadm.conf.5 -+++ /dev/null -@@ -1,706 +0,0 @@ --.\" Copyright Neil Brown and others. --.\" 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. --.\" See file COPYING in distribution for details. --.TH MDADM.CONF 5 --.SH NAME --mdadm.conf \- configuration for management of Software RAID with mdadm --.SH SYNOPSIS --/etc/mdadm.conf --.SH DESCRIPTION --.PP --.I mdadm --is a tool for creating, managing, and monitoring RAID devices using the --.B md --driver in Linux. --.PP --Some common tasks, such as assembling all arrays, can be simplified --by describing the devices and arrays in this configuration file. -- --.SS SYNTAX --The file should be seen as a collection of words separated by white --space (space, tab, or newline). --Any word that beings with a hash sign (#) starts a comment and that --word together with the remainder of the line is ignored. -- --Spaces can be included in a word using quotation characters. Either --single quotes --.RB ( ' ) --or double quotes (\fB"\fP) --may be used. All the characters from one quotation character to --next identical character are protected and will not be used to --separate words to start new quoted strings. To include a single quote --it must be between double quotes. To include a double quote it must --be between single quotes. -- --Any line that starts with white space (space or tab) is treated as --though it were a continuation of the previous line. -- --Empty lines are ignored, but otherwise each (non continuation) line --must start with a keyword as listed below. The keywords are case --insensitive and can be abbreviated to 3 characters. -- --The keywords are: --.TP --.B DEVICE --A --.B device --line lists the devices (whole devices or partitions) that might contain --a component of an MD array. When looking for the components of an --array, --.I mdadm --will scan these devices (or any devices listed on the command line). -- --The --.B device --line may contain a number of different devices (separated by spaces) --and each device name can contain wild cards as defined by --.BR glob (7). -- --Also, there may be several device lines present in the file. -- --Alternatively, a --.B device --line can contain either or both of the words --.B containers --and --.BR partitions . --The word --.B containers --will cause --.I mdadm --to look for assembled CONTAINER arrays and included them as a source --for assembling further arrays. -- --The word --.I partitions --will cause --.I mdadm --to read --.I /proc/partitions --and include all devices and partitions found therein. --.I mdadm --does not use the names from --.I /proc/partitions --but only the major and minor device numbers. It scans --.I /dev --to find the name that matches the numbers. -- --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -- --For example: --.IP --DEVICE /dev/hda* /dev/hdc* --.br --DEV /dev/sd* --.br --DEVICE /dev/disk/by-path/pci* --.br --DEVICE partitions -- --.TP --.B ARRAY --The ARRAY lines identify actual arrays. The second word on the line --may be the name of the device where the array is normally --assembled, such as --.B /dev/md1 --or --.BR /dev/md/backup . --If the name does not start with a slash --.RB (' / '), --it is treated as being in --.BR /dev/md/ . --Alternately the word --.B --(complete with angle brackets) can be given in which case any array --which matches the rest of the line will never be automatically assembled. --If no device name is given, --.I mdadm --will use various heuristics to determine an appropriate name. -- --Subsequent words identify the array, or identify the array as a member --of a group. If multiple identities are given, --then a component device must match ALL identities to be considered a --match. Each identity word has a tag, and equals sign, and some value. --The tags are: --.RS 4 --.TP --.B uuid= --The value should be a 128 bit uuid in hexadecimal, with punctuation --interspersed if desired. This must match the uuid stored in the --superblock. --.TP --.B name= --The value should be a simple textual name as was given to --.I mdadm --when the array was created. This must match the name stored in the --superblock on a device for that device to be included in the array. --Not all superblock formats support names. --.TP --.B super\-minor= --The value is an integer which indicates the minor number that was --stored in the superblock when the array was created. When an array is --created as /dev/mdX, then the minor number X is stored. --.TP --.B devices= --The value is a comma separated list of device names or device name --patterns. --Only devices with names which match one entry in the list will be used --to assemble the array. Note that the devices --listed there must also be listed on a DEVICE line. --.TP --.B level= --The value is a RAID level. This is not normally used to --identify an array, but is supported so that the output of -- --.B "mdadm \-\-examine \-\-scan" -- --can be use directly in the configuration file. --.TP --.B num\-devices= --The value is the number of devices in a complete active array. As with --.B level= --this is mainly for compatibility with the output of -- --.BR "mdadm \-\-examine \-\-scan" . -- --.TP --.B spares= --The value is a number of spare devices to expect the array to have. --The sole use of this keyword and value is as follows: --.B mdadm \-\-monitor --will report an array if it is found to have fewer than this number of --spares when --.B \-\-monitor --starts or when --.B \-\-oneshot --is used. -- --.TP --.B spare\-group= --The value is a textual name for a group of arrays. All arrays with --the same --.B spare\-group --name are considered to be part of the same group. The significance of --a group of arrays is that --.I mdadm --will, when monitoring the arrays, move a spare drive from one array in --a group to another array in that group if the first array had a failed --or missing drive but no spare. -- --.TP --.B auto= --This option is rarely needed with mdadm-3.0, particularly if use with --the Linux kernel v2.6.28 or later. --It tells --.I mdadm --whether to use partitionable array or non-partitionable arrays and, --in the absence of --.IR udev , --how many partition devices to create. From 2.6.28 all md array --devices are partitionable, hence this option is not needed. -- --The value of this option can be "yes" or "md" to indicate that a --traditional, non-partitionable md array should be created, or "mdp", --"part" or "partition" to indicate that a partitionable md array (only --available in linux 2.6 and later) should be used. This later set can --also have a number appended to indicate how many partitions to create --device files for, e.g. --.BR auto=mdp5 . --The default is 4. -- --.TP --.B bitmap= --The option specifies a file in which a write-intent bitmap should be --found. When assembling the array, --.I mdadm --will provide this file to the --.B md --driver as the bitmap file. This has the same function as the --.B \-\-bitmap\-file --option to --.BR \-\-assemble . -- --.TP --.B metadata= --Specify the metadata format that the array has. This is mainly --recognised for comparability with the output of --.BR "mdadm \-Es" . -- --.TP --.B container= --Specify that this array is a member array of some container. The --value given can be either a path name in /dev, or a UUID of the --container array. -- --.TP --.B member= --Specify that this array is a member array of some container. Each --type of container has some way to enumerate member arrays, often a --simple sequence number. The value identifies which member of a --container the array is. It will usually accompany a "container=" word. --.RE -- --.TP --.B MAILADDR --The --.B mailaddr --line gives an E-mail address that alerts should be --sent to when --.I mdadm --is running in --.B \-\-monitor --mode (and was given the --.B \-\-scan --option). There should only be one --.B MAILADDR --line and it should have only one address. Any subsequent addresses --are silently ignored. -- --.TP --.B MAILFROM --The --.B mailfrom --line (which can only be abbreviated to at least 5 characters) gives an --address to appear in the "From" address for alert mails. This can be --useful if you want to explicitly set a domain, as the default from --address is "root" with no domain. All words on this line are --catenated with spaces to form the address. -- --Note that this value cannot be set via the --.I mdadm --commandline. It is only settable via the config file. -- --.TP --.B PROGRAM --The --.B program --line gives the name of a program to be run when --.B "mdadm \-\-monitor" --detects potentially interesting events on any of the arrays that it --is monitoring. This program gets run with two or three arguments, they --being the Event, the md device, and possibly the related component --device. -- --There should only be one --.B program --line and it should be give only one program. -- -- --.TP --.B CREATE --The --.B create --line gives default values to be used when creating arrays, new members --of arrays, and device entries for arrays. --These include: -- --.RS 4 --.TP --.B owner= --.TP --.B group= --These can give user/group ids or names to use instead of system --defaults (root/wheel or root/disk). --.TP --.B mode= --An octal file mode such as 0660 can be given to override the default --of 0600. --.TP --.B auto= --This corresponds to the --.B \-\-auto --flag to mdadm. Give --.BR yes , --.BR md , --.BR mdp , --.B part --\(em possibly followed by a number of partitions \(em to indicate how --missing device entries should be created. -- --.TP --.B metadata= --The name of the metadata format to use if none is explicitly given. --This can be useful to impose a system-wide default of version-1 superblocks. -- --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- --.TP --.B names=yes --Since Linux 2.6.29 it has been possible to create --.B md --devices with a name like --.B md_home --rather than just a number, like --.BR md3 . --.I mdadm --will use the numeric alternative by default as other tools that interact --with md arrays may expect only numbers. --If --.B names=yes --is given in --.I mdadm.conf --then --.I mdadm --will use a name when appropriate. --If --.B names=no --is given, then non-numeric --.I md --device names will not be used even if the default changes in a future --release of --.IR mdadm . -- --.TP --.B bbl=no --By default, --.I mdadm --will reserve space for a bad block list (bbl) on all devices --included in or added to any array that supports them. Setting --.B bbl=no --will prevent this, so newly added devices will not have a bad --block log. --.RE -- --.TP --.B HOMEHOST --The --.B homehost --line gives a default value for the --.B \-\-homehost= --option to mdadm. There should normally be only one other word on the line. --It should either be a host name, or one of the special words --.BR , --.B --and --.BR . --If --.B --is given, then the --.BR gethostname ( 2 ) --systemcall is used to get the host name. This is the default. -- --If --.B --is given, then a flag is set so that when arrays are being --auto-assembled the checking of the recorded --.I homehost --is disabled. --If --.B --is given it is also possible to give an explicit name which will be --used when creating arrays. This is the only case when there can be --more that one other word on the --.B HOMEHOST --line. If there are other words, or other --.B HOMEHOST --lines, they are silently ignored. -- --If --.B --is given, then the default of using --.BR gethostname ( 2 ) --is over-ridden and no homehost name is assumed. -- --When arrays are created, this host name will be stored in the --metadata. When arrays are assembled using auto-assembly, arrays which --do not record the correct homehost name in their metadata will be --assembled using a "foreign" name. A "foreign" name alway ends with a --digit string preceded by an underscore to differentiate it --from any possible local name. e.g. --.B /dev/md/1_1 --or --.BR /dev/md/home_0 . --.TP --.B AUTO --A list of names of metadata format can be given, each preceded by a --plus or minus sign. Also the word --.I homehost --is allowed as is --.I all --preceded by plus or minus sign. --.I all --is usually last. -- --When --.I mdadm --is auto-assembling an array, either via --.I \-\-assemble --or --.I \-\-incremental --and it finds metadata of a given type, it checks that metadata type --against those listed in this line. The first match wins, where --.I all --matches anything. --If a match is found that was preceded by a plus sign, the auto --assembly is allowed. If the match was preceded by a minus sign, the --auto assembly is disallowed. If no match is found, the auto assembly --is allowed. -- --If the metadata indicates that the array was created for --.I this --host, and the word --.I homehost --appears before any other match, then the array is treated as a valid --candidate for auto-assembly. -- --This can be used to disable all auto-assembly (so that only arrays --explicitly listed in mdadm.conf or on the command line are assembled), --or to disable assembly of certain metadata types which might be --handled by other software. It can also be used to disable assembly of --all foreign arrays - normally such arrays are assembled but given a --non-deterministic name in --.BR /dev/md/ . -- --The known metadata types are --.BR 0.90 , --.BR 1.x , --.BR ddf , --.BR imsm . -- --.B AUTO --should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -- --.TP --.B POLICY --This is used to specify what automatic behavior is allowed on devices --newly appearing in the system and provides a way of marking spares that can --be moved to other arrays as well as the migration domains. --.I Domain --can be defined through --.I policy --line by specifying a domain name for a number of paths from --.BR /dev/disk/by-path/ . --A device may belong to several domains. The domain of an array is a union --of domains of all devices in that array. A spare can be automatically --moved from one array to another if the set of the destination array's --.I domains --contains all the --.I domains --of the new disk or if both arrays have the same --.IR spare-group . -- --To update hot plug configuration it is necessary to execute --.B mdadm \-\-udev\-rules --command after changing the config file -- --Keywords used in the --.I POLICY --line and supported values are: -- --.RS 4 --.TP --.B domain= --any arbitrary string --.TP --.B metadata= --0.9 1.x ddf or imsm --.TP --.B path= --file glob matching anything from --.B /dev/disk/by-path --.TP --.B type= --either --.B disk --or --.BR part . --.TP --.B action= --include, re-add, spare, spare-same-slot, or force-spare --.TP --.B auto= --yes, no, or homehost. -- --.P --The --.I action --item determines the automatic behavior allowed for devices matching the --.I path --and --.I type --in the same line. If a device matches several lines with different --.I actions --then the most permissive will apply. The ordering of policy lines --is irrelevant to the end result. --.TP --.B include --allows adding a disk to an array if metadata on that disk matches that array --.TP --.B re\-add --will include the device in the array if it appears to be a current member --or a member that was recently removed and the array has a --write-intent-bitmap to allow the --.B re\-add --functionality. --.TP --.B spare --as above and additionally: if the device is bare it can --become a spare if there is any array that it is a candidate for based --on domains and metadata. --.TP --.B spare\-same\-slot --as above and additionally if given slot was used by an array that went --degraded recently and the device plugged in has no metadata then it will --be automatically added to that array (or it's container) --.TP --.B force\-spare --as above and the disk will become a spare in remaining cases --.RE -- --.TP --.B PART-POLICY --This is similar to --.B POLICY --and accepts the same keyword assignments. It allows a consistent set --of policies to applied to each of the partitions of a device. -- --A --.B PART-POLICY --line should set --.I type=disk --and identify the path to one or more disk devices. Each partition on --these disks will be treated according to the --.I action= --setting from this line. If a --.I domain --is set in the line, then the domain associated with each patition will --be based on the domain, but with --.RB \(dq -part N\(dq --appended, when N is the partition number for the partition that was --found. -- --.TP --.B SYSFS --The --.B SYSFS --line lists custom values of MD device's sysfs attributes which will be --stored in sysfs after the array is assembled. Multiple lines are allowed and each --line has to contain the uuid or the name of the device to which it relates. --.RS 4 --.TP --.B uuid= --hexadecimal identifier of MD device. This has to match the uuid stored in the --superblock. --.TP --.B name= --name of the MD device as was given to --.I mdadm --when the array was created. It will be ignored if --.B uuid --is not empty. --.RE -- --.TP --.B MONITORDELAY --The --.B monitordelay --line gives a delay in seconds --.I mdadm --shall wait before pooling md arrays --when --.I mdadm --is running in --.B \-\-monitor --mode. --.B \-d/\-\-delay --command line argument takes precedence over the config file -- --.SH EXAMPLE --DEVICE /dev/sd[bcdjkl]1 --.br --DEVICE /dev/hda1 /dev/hdb1 -- --# /dev/md0 is known by its UUID. --.br --ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 --.br --# /dev/md1 contains all devices with a minor number of --.br --# 1 in the superblock. --.br --ARRAY /dev/md1 superminor=1 --.br --# /dev/md2 is made from precisely these two devices --.br --ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -- --# /dev/md4 and /dev/md5 are a spare-group and spares --.br --# can be moved between them --.br --ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df --.br -- spare\-group=group1 --.br --ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 --.br -- spare\-group=group1 --.br --# /dev/md/home is created if need to be a partitionable md array --.br --# any spare device number is allocated. --.br --ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b --.br -- auto=part --.br --# The name of this array contains a space. --.br --ARRAY /dev/md9 name='Data Storage' --.sp --POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* --.br -- action=spare --.br --POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* --.br -- action=include --.br --# One domain comprising of devices attached to specified paths is defined. --.br --# Bare device matching first path will be made an imsm spare on hot plug. --.br --# If more than one array is created on devices belonging to domain1 and --.br --# one of them becomes degraded, then any imsm spare matching any path for --.br --# given domain name can be migrated. --.br --MAILADDR root@mydomain.tld --.br --PROGRAM /usr/sbin/handle\-mdadm\-events --.br --CREATE group=system mode=0640 auto=part\-8 --.br --HOMEHOST --.br --AUTO +1.x homehost \-all --.br --SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 --.br --SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 --sync_speed_max=1000000 --.br --MONITORDELAY 60 -- --.SH SEE ALSO --.BR mdadm (8), --.BR md (4). -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -new file mode 100644 -index 00000000..83edd008 ---- /dev/null -+++ b/mdadm.conf.5.in -@@ -0,0 +1,706 @@ -+.\" Copyright Neil Brown and others. -+.\" 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. -+.\" See file COPYING in distribution for details. -+.TH MDADM.CONF 5 -+.SH NAME -+mdadm.conf \- configuration for management of Software RAID with mdadm -+.SH SYNOPSIS -+{CONFFILE} -+.SH DESCRIPTION -+.PP -+.I mdadm -+is a tool for creating, managing, and monitoring RAID devices using the -+.B md -+driver in Linux. -+.PP -+Some common tasks, such as assembling all arrays, can be simplified -+by describing the devices and arrays in this configuration file. -+ -+.SS SYNTAX -+The file should be seen as a collection of words separated by white -+space (space, tab, or newline). -+Any word that beings with a hash sign (#) starts a comment and that -+word together with the remainder of the line is ignored. -+ -+Spaces can be included in a word using quotation characters. Either -+single quotes -+.RB ( ' ) -+or double quotes (\fB"\fP) -+may be used. All the characters from one quotation character to -+next identical character are protected and will not be used to -+separate words to start new quoted strings. To include a single quote -+it must be between double quotes. To include a double quote it must -+be between single quotes. -+ -+Any line that starts with white space (space or tab) is treated as -+though it were a continuation of the previous line. -+ -+Empty lines are ignored, but otherwise each (non continuation) line -+must start with a keyword as listed below. The keywords are case -+insensitive and can be abbreviated to 3 characters. -+ -+The keywords are: -+.TP -+.B DEVICE -+A -+.B device -+line lists the devices (whole devices or partitions) that might contain -+a component of an MD array. When looking for the components of an -+array, -+.I mdadm -+will scan these devices (or any devices listed on the command line). -+ -+The -+.B device -+line may contain a number of different devices (separated by spaces) -+and each device name can contain wild cards as defined by -+.BR glob (7). -+ -+Also, there may be several device lines present in the file. -+ -+Alternatively, a -+.B device -+line can contain either or both of the words -+.B containers -+and -+.BR partitions . -+The word -+.B containers -+will cause -+.I mdadm -+to look for assembled CONTAINER arrays and included them as a source -+for assembling further arrays. -+ -+The word -+.I partitions -+will cause -+.I mdadm -+to read -+.I /proc/partitions -+and include all devices and partitions found therein. -+.I mdadm -+does not use the names from -+.I /proc/partitions -+but only the major and minor device numbers. It scans -+.I /dev -+to find the name that matches the numbers. -+ -+If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+ -+For example: -+.IP -+DEVICE /dev/hda* /dev/hdc* -+.br -+DEV /dev/sd* -+.br -+DEVICE /dev/disk/by-path/pci* -+.br -+DEVICE partitions -+ -+.TP -+.B ARRAY -+The ARRAY lines identify actual arrays. The second word on the line -+may be the name of the device where the array is normally -+assembled, such as -+.B /dev/md1 -+or -+.BR /dev/md/backup . -+If the name does not start with a slash -+.RB (' / '), -+it is treated as being in -+.BR /dev/md/ . -+Alternately the word -+.B -+(complete with angle brackets) can be given in which case any array -+which matches the rest of the line will never be automatically assembled. -+If no device name is given, -+.I mdadm -+will use various heuristics to determine an appropriate name. -+ -+Subsequent words identify the array, or identify the array as a member -+of a group. If multiple identities are given, -+then a component device must match ALL identities to be considered a -+match. Each identity word has a tag, and equals sign, and some value. -+The tags are: -+.RS 4 -+.TP -+.B uuid= -+The value should be a 128 bit uuid in hexadecimal, with punctuation -+interspersed if desired. This must match the uuid stored in the -+superblock. -+.TP -+.B name= -+The value should be a simple textual name as was given to -+.I mdadm -+when the array was created. This must match the name stored in the -+superblock on a device for that device to be included in the array. -+Not all superblock formats support names. -+.TP -+.B super\-minor= -+The value is an integer which indicates the minor number that was -+stored in the superblock when the array was created. When an array is -+created as /dev/mdX, then the minor number X is stored. -+.TP -+.B devices= -+The value is a comma separated list of device names or device name -+patterns. -+Only devices with names which match one entry in the list will be used -+to assemble the array. Note that the devices -+listed there must also be listed on a DEVICE line. -+.TP -+.B level= -+The value is a RAID level. This is not normally used to -+identify an array, but is supported so that the output of -+ -+.B "mdadm \-\-examine \-\-scan" -+ -+can be use directly in the configuration file. -+.TP -+.B num\-devices= -+The value is the number of devices in a complete active array. As with -+.B level= -+this is mainly for compatibility with the output of -+ -+.BR "mdadm \-\-examine \-\-scan" . -+ -+.TP -+.B spares= -+The value is a number of spare devices to expect the array to have. -+The sole use of this keyword and value is as follows: -+.B mdadm \-\-monitor -+will report an array if it is found to have fewer than this number of -+spares when -+.B \-\-monitor -+starts or when -+.B \-\-oneshot -+is used. -+ -+.TP -+.B spare\-group= -+The value is a textual name for a group of arrays. All arrays with -+the same -+.B spare\-group -+name are considered to be part of the same group. The significance of -+a group of arrays is that -+.I mdadm -+will, when monitoring the arrays, move a spare drive from one array in -+a group to another array in that group if the first array had a failed -+or missing drive but no spare. -+ -+.TP -+.B auto= -+This option is rarely needed with mdadm-3.0, particularly if use with -+the Linux kernel v2.6.28 or later. -+It tells -+.I mdadm -+whether to use partitionable array or non-partitionable arrays and, -+in the absence of -+.IR udev , -+how many partition devices to create. From 2.6.28 all md array -+devices are partitionable, hence this option is not needed. -+ -+The value of this option can be "yes" or "md" to indicate that a -+traditional, non-partitionable md array should be created, or "mdp", -+"part" or "partition" to indicate that a partitionable md array (only -+available in linux 2.6 and later) should be used. This later set can -+also have a number appended to indicate how many partitions to create -+device files for, e.g. -+.BR auto=mdp5 . -+The default is 4. -+ -+.TP -+.B bitmap= -+The option specifies a file in which a write-intent bitmap should be -+found. When assembling the array, -+.I mdadm -+will provide this file to the -+.B md -+driver as the bitmap file. This has the same function as the -+.B \-\-bitmap\-file -+option to -+.BR \-\-assemble . -+ -+.TP -+.B metadata= -+Specify the metadata format that the array has. This is mainly -+recognised for comparability with the output of -+.BR "mdadm \-Es" . -+ -+.TP -+.B container= -+Specify that this array is a member array of some container. The -+value given can be either a path name in /dev, or a UUID of the -+container array. -+ -+.TP -+.B member= -+Specify that this array is a member array of some container. Each -+type of container has some way to enumerate member arrays, often a -+simple sequence number. The value identifies which member of a -+container the array is. It will usually accompany a "container=" word. -+.RE -+ -+.TP -+.B MAILADDR -+The -+.B mailaddr -+line gives an E-mail address that alerts should be -+sent to when -+.I mdadm -+is running in -+.B \-\-monitor -+mode (and was given the -+.B \-\-scan -+option). There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. -+ -+.TP -+.B MAILFROM -+The -+.B mailfrom -+line (which can only be abbreviated to at least 5 characters) gives an -+address to appear in the "From" address for alert mails. This can be -+useful if you want to explicitly set a domain, as the default from -+address is "root" with no domain. All words on this line are -+catenated with spaces to form the address. -+ -+Note that this value cannot be set via the -+.I mdadm -+commandline. It is only settable via the config file. -+ -+.TP -+.B PROGRAM -+The -+.B program -+line gives the name of a program to be run when -+.B "mdadm \-\-monitor" -+detects potentially interesting events on any of the arrays that it -+is monitoring. This program gets run with two or three arguments, they -+being the Event, the md device, and possibly the related component -+device. -+ -+There should only be one -+.B program -+line and it should be give only one program. -+ -+ -+.TP -+.B CREATE -+The -+.B create -+line gives default values to be used when creating arrays, new members -+of arrays, and device entries for arrays. -+These include: -+ -+.RS 4 -+.TP -+.B owner= -+.TP -+.B group= -+These can give user/group ids or names to use instead of system -+defaults (root/wheel or root/disk). -+.TP -+.B mode= -+An octal file mode such as 0660 can be given to override the default -+of 0600. -+.TP -+.B auto= -+This corresponds to the -+.B \-\-auto -+flag to mdadm. Give -+.BR yes , -+.BR md , -+.BR mdp , -+.B part -+\(em possibly followed by a number of partitions \(em to indicate how -+missing device entries should be created. -+ -+.TP -+.B metadata= -+The name of the metadata format to use if none is explicitly given. -+This can be useful to impose a system-wide default of version-1 superblocks. -+ -+.TP -+.B symlinks=no -+Normally when creating devices in -+.B /dev/md/ -+.I mdadm -+will create a matching symlink from -+.B /dev/ -+with a name starting -+.B md -+or -+.BR md_ . -+Give -+.B symlinks=no -+to suppress this symlink creation. -+ -+.TP -+.B names=yes -+Since Linux 2.6.29 it has been possible to create -+.B md -+devices with a name like -+.B md_home -+rather than just a number, like -+.BR md3 . -+.I mdadm -+will use the numeric alternative by default as other tools that interact -+with md arrays may expect only numbers. -+If -+.B names=yes -+is given in -+.I mdadm.conf -+then -+.I mdadm -+will use a name when appropriate. -+If -+.B names=no -+is given, then non-numeric -+.I md -+device names will not be used even if the default changes in a future -+release of -+.IR mdadm . -+ -+.TP -+.B bbl=no -+By default, -+.I mdadm -+will reserve space for a bad block list (bbl) on all devices -+included in or added to any array that supports them. Setting -+.B bbl=no -+will prevent this, so newly added devices will not have a bad -+block log. -+.RE -+ -+.TP -+.B HOMEHOST -+The -+.B homehost -+line gives a default value for the -+.B \-\-homehost= -+option to mdadm. There should normally be only one other word on the line. -+It should either be a host name, or one of the special words -+.BR , -+.B -+and -+.BR . -+If -+.B -+is given, then the -+.BR gethostname ( 2 ) -+systemcall is used to get the host name. This is the default. -+ -+If -+.B -+is given, then a flag is set so that when arrays are being -+auto-assembled the checking of the recorded -+.I homehost -+is disabled. -+If -+.B -+is given it is also possible to give an explicit name which will be -+used when creating arrays. This is the only case when there can be -+more that one other word on the -+.B HOMEHOST -+line. If there are other words, or other -+.B HOMEHOST -+lines, they are silently ignored. -+ -+If -+.B -+is given, then the default of using -+.BR gethostname ( 2 ) -+is over-ridden and no homehost name is assumed. -+ -+When arrays are created, this host name will be stored in the -+metadata. When arrays are assembled using auto-assembly, arrays which -+do not record the correct homehost name in their metadata will be -+assembled using a "foreign" name. A "foreign" name alway ends with a -+digit string preceded by an underscore to differentiate it -+from any possible local name. e.g. -+.B /dev/md/1_1 -+or -+.BR /dev/md/home_0 . -+.TP -+.B AUTO -+A list of names of metadata format can be given, each preceded by a -+plus or minus sign. Also the word -+.I homehost -+is allowed as is -+.I all -+preceded by plus or minus sign. -+.I all -+is usually last. -+ -+When -+.I mdadm -+is auto-assembling an array, either via -+.I \-\-assemble -+or -+.I \-\-incremental -+and it finds metadata of a given type, it checks that metadata type -+against those listed in this line. The first match wins, where -+.I all -+matches anything. -+If a match is found that was preceded by a plus sign, the auto -+assembly is allowed. If the match was preceded by a minus sign, the -+auto assembly is disallowed. If no match is found, the auto assembly -+is allowed. -+ -+If the metadata indicates that the array was created for -+.I this -+host, and the word -+.I homehost -+appears before any other match, then the array is treated as a valid -+candidate for auto-assembly. -+ -+This can be used to disable all auto-assembly (so that only arrays -+explicitly listed in mdadm.conf or on the command line are assembled), -+or to disable assembly of certain metadata types which might be -+handled by other software. It can also be used to disable assembly of -+all foreign arrays - normally such arrays are assembled but given a -+non-deterministic name in -+.BR /dev/md/ . -+ -+The known metadata types are -+.BR 0.90 , -+.BR 1.x , -+.BR ddf , -+.BR imsm . -+ -+.B AUTO -+should be given at most once. Subsequent lines are silently ignored. -+Thus an earlier config file in a config directory will over-ride -+the setting in a later config file. -+ -+.TP -+.B POLICY -+This is used to specify what automatic behavior is allowed on devices -+newly appearing in the system and provides a way of marking spares that can -+be moved to other arrays as well as the migration domains. -+.I Domain -+can be defined through -+.I policy -+line by specifying a domain name for a number of paths from -+.BR /dev/disk/by-path/ . -+A device may belong to several domains. The domain of an array is a union -+of domains of all devices in that array. A spare can be automatically -+moved from one array to another if the set of the destination array's -+.I domains -+contains all the -+.I domains -+of the new disk or if both arrays have the same -+.IR spare-group . -+ -+To update hot plug configuration it is necessary to execute -+.B mdadm \-\-udev\-rules -+command after changing the config file -+ -+Keywords used in the -+.I POLICY -+line and supported values are: -+ -+.RS 4 -+.TP -+.B domain= -+any arbitrary string -+.TP -+.B metadata= -+0.9 1.x ddf or imsm -+.TP -+.B path= -+file glob matching anything from -+.B /dev/disk/by-path -+.TP -+.B type= -+either -+.B disk -+or -+.BR part . -+.TP -+.B action= -+include, re-add, spare, spare-same-slot, or force-spare -+.TP -+.B auto= -+yes, no, or homehost. -+ -+.P -+The -+.I action -+item determines the automatic behavior allowed for devices matching the -+.I path -+and -+.I type -+in the same line. If a device matches several lines with different -+.I actions -+then the most permissive will apply. The ordering of policy lines -+is irrelevant to the end result. -+.TP -+.B include -+allows adding a disk to an array if metadata on that disk matches that array -+.TP -+.B re\-add -+will include the device in the array if it appears to be a current member -+or a member that was recently removed and the array has a -+write-intent-bitmap to allow the -+.B re\-add -+functionality. -+.TP -+.B spare -+as above and additionally: if the device is bare it can -+become a spare if there is any array that it is a candidate for based -+on domains and metadata. -+.TP -+.B spare\-same\-slot -+as above and additionally if given slot was used by an array that went -+degraded recently and the device plugged in has no metadata then it will -+be automatically added to that array (or it's container) -+.TP -+.B force\-spare -+as above and the disk will become a spare in remaining cases -+.RE -+ -+.TP -+.B PART-POLICY -+This is similar to -+.B POLICY -+and accepts the same keyword assignments. It allows a consistent set -+of policies to applied to each of the partitions of a device. -+ -+A -+.B PART-POLICY -+line should set -+.I type=disk -+and identify the path to one or more disk devices. Each partition on -+these disks will be treated according to the -+.I action= -+setting from this line. If a -+.I domain -+is set in the line, then the domain associated with each patition will -+be based on the domain, but with -+.RB \(dq -part N\(dq -+appended, when N is the partition number for the partition that was -+found. -+ -+.TP -+.B SYSFS -+The -+.B SYSFS -+line lists custom values of MD device's sysfs attributes which will be -+stored in sysfs after the array is assembled. Multiple lines are allowed and each -+line has to contain the uuid or the name of the device to which it relates. -+.RS 4 -+.TP -+.B uuid= -+hexadecimal identifier of MD device. This has to match the uuid stored in the -+superblock. -+.TP -+.B name= -+name of the MD device as was given to -+.I mdadm -+when the array was created. It will be ignored if -+.B uuid -+is not empty. -+.RE -+ -+.TP -+.B MONITORDELAY -+The -+.B monitordelay -+line gives a delay in seconds -+.I mdadm -+shall wait before pooling md arrays -+when -+.I mdadm -+is running in -+.B \-\-monitor -+mode. -+.B \-d/\-\-delay -+command line argument takes precedence over the config file -+ -+.SH EXAMPLE -+DEVICE /dev/sd[bcdjkl]1 -+.br -+DEVICE /dev/hda1 /dev/hdb1 -+ -+# /dev/md0 is known by its UUID. -+.br -+ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 -+.br -+# /dev/md1 contains all devices with a minor number of -+.br -+# 1 in the superblock. -+.br -+ARRAY /dev/md1 superminor=1 -+.br -+# /dev/md2 is made from precisely these two devices -+.br -+ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -+ -+# /dev/md4 and /dev/md5 are a spare-group and spares -+.br -+# can be moved between them -+.br -+ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df -+.br -+ spare\-group=group1 -+.br -+ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 -+.br -+ spare\-group=group1 -+.br -+# /dev/md/home is created if need to be a partitionable md array -+.br -+# any spare device number is allocated. -+.br -+ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b -+.br -+ auto=part -+.br -+# The name of this array contains a space. -+.br -+ARRAY /dev/md9 name='Data Storage' -+.sp -+POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* -+.br -+ action=spare -+.br -+POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* -+.br -+ action=include -+.br -+# One domain comprising of devices attached to specified paths is defined. -+.br -+# Bare device matching first path will be made an imsm spare on hot plug. -+.br -+# If more than one array is created on devices belonging to domain1 and -+.br -+# one of them becomes degraded, then any imsm spare matching any path for -+.br -+# given domain name can be migrated. -+.br -+MAILADDR root@mydomain.tld -+.br -+PROGRAM /usr/sbin/handle\-mdadm\-events -+.br -+CREATE group=system mode=0640 auto=part\-8 -+.br -+HOMEHOST -+.br -+AUTO +1.x homehost \-all -+.br -+SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 -+.br -+SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 -+sync_speed_max=1000000 -+.br -+MONITORDELAY 60 -+ -+.SH SEE ALSO -+.BR mdadm (8), -+.BR md (4). --- -2.38.1 - diff --git a/0007-mdadm-Update-ReadMe.patch b/0007-mdadm-Update-ReadMe.patch deleted file mode 100644 index a143a22..0000000 --- a/0007-mdadm-Update-ReadMe.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:05 +0100 -Subject: [PATCH 07/83] mdadm: Update ReadMe - -Instead of hardcoded config file path give reference to config manual. - -Add missing monitordelay and homecluster parameters. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 81399765..8f873c48 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -613,7 +613,6 @@ char Help_incr[] = - ; - - char Help_config[] = --"The /etc/mdadm.conf config file:\n\n" - " The config file contains, apart from blank lines and comment lines that\n" - " start with a hash(#), array lines, device lines, and various\n" - " configuration lines.\n" -@@ -636,10 +635,12 @@ char Help_config[] = - " than a device must match all of them to be considered.\n" - "\n" - " Other configuration lines include:\n" --" mailaddr, mailfrom, program used for --monitor mode\n" --" create, auto used when creating device names in /dev\n" --" homehost, policy, part-policy used to guide policy in various\n" --" situations\n" -+" mailaddr, mailfrom, program, monitordelay used for --monitor mode\n" -+" create, auto used when creating device names in /dev\n" -+" homehost, homecluster, policy, part-policy used to guide policy in various\n" -+" situations\n" -+"\n" -+"For more details see mdadm.conf(5).\n" - "\n" - ; - --- -2.38.1 - diff --git a/0008-mdadm-Update-config-man-regarding-default-files-and-.patch b/0008-mdadm-Update-config-man-regarding-default-files-and-.patch deleted file mode 100644 index 0109e9a..0000000 --- a/0008-mdadm-Update-config-man-regarding-default-files-and-.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:06 +0100 -Subject: [PATCH 08/83] mdadm: Update config man regarding default files and - multi-keyword behavior - -Simplify default and alternative config file and directory location references -from mdadm(8) as references to mdadm.conf(5). Add FILE section in config man -and explain order and conditions in which default and alternative config files -and directories are used. - -Update config man behavior regarding parsing order when multiple keywords/config -files are involved. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 30 +++++++++-------------- - mdadm.conf.5.in | 65 ++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 71 insertions(+), 24 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 8b21ffd4..0be02e4a 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. Default is to use --.B {CONFFILE} --and --.BR {CONFFILE}.d , --or if those are missing then --.B {CONFFILE2} --and --.BR {CONFFILE2}.d . -+Specify the config file or directory. If not specified, default config file -+and default conf.d directory will be used. See -+.BR mdadm.conf (5) -+for more details. -+ - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2013,11 +2010,9 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, --.B {CONFFILE} --or --.B {CONFFILE2} --is used. -+In the later case, default config file is used. See -+.BR mdadm.conf (5) -+for more details. - - If - .B \-\-scan -@@ -3346,16 +3341,15 @@ on Monitor mode. - - .SS {CONFFILE} (or {CONFFILE2}) - --The config file lists which devices may be scanned to see if --they contain MD super block, and gives identifying information --(e.g. UUID) about known MD arrays. See -+Default config file. See - .BR mdadm.conf (5) - for more details. - - .SS {CONFFILE}.d (or {CONFFILE2}.d) - --A directory containing configuration files which are read in lexical --order. -+Default directory containing configuration files. See -+.BR mdadm.conf (5) -+for more details. - - .SS {MAP_PATH} - When -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index 83edd008..dd331a6a 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -88,7 +88,8 @@ but only the major and minor device numbers. It scans - .I /dev - to find the name that matches the numbers. - --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+If no DEVICE line is present in any config file, -+then "DEVICE partitions containers" is assumed. - - For example: - .IP -@@ -272,6 +273,10 @@ catenated with spaces to form the address. - Note that this value cannot be set via the - .I mdadm - commandline. It is only settable via the config file. -+There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. - - .TP - .B PROGRAM -@@ -286,7 +291,8 @@ device. - - There should only be one - .B program --line and it should be give only one program. -+line and it should be given only one program. Any subsequent programs -+are silently ignored. - - - .TP -@@ -295,7 +301,14 @@ The - .B create - line gives default values to be used when creating arrays, new members - of arrays, and device entries for arrays. --These include: -+ -+There should only be one -+.B create -+line. Any subsequent lines will override the previous settings. -+ -+Keywords used in the -+.I CREATE -+line and supported values are: - - .RS 4 - .TP -@@ -475,8 +488,8 @@ The known metadata types are - - .B AUTO - should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -+Thus a later config file in a config directory will not overwrite -+the setting in an earlier config file. - - .TP - .B POLICY -@@ -594,6 +607,7 @@ The - line lists custom values of MD device's sysfs attributes which will be - stored in sysfs after the array is assembled. Multiple lines are allowed and each - line has to contain the uuid or the name of the device to which it relates. -+Lines are applied in reverse order. - .RS 4 - .TP - .B uuid= -@@ -621,7 +635,46 @@ is running in - .B \-\-monitor - mode. - .B \-d/\-\-delay --command line argument takes precedence over the config file -+command line argument takes precedence over the config file. -+ -+If multiple -+.B MINITORDELAY -+lines are provided, only first non-zero value is considered. -+ -+.SH FILES -+ -+.SS {CONFFILE} -+ -+The default config file location, used when -+.I mdadm -+is running without --config option. -+ -+.SS {CONFFILE}.d -+ -+The default directory with config files. Used when -+.I mdadm -+is running without --config option, after successful reading of the -+.B {CONFFILE} -+default config file. Files in that directory -+are read in lexical order. -+ -+ -+.SS {CONFFILE2} -+ -+Alternative config file that is read, when -+.I mdadm -+is running without --config option and the -+.B {CONFFILE} -+default config file was not opened successfully. -+ -+.SS {CONFFILE2}.d -+ -+The alternative directory with config files. Used when -+.I mdadm -+is runninng without --config option, after reading the -+.B {CONFFILE2} -+alternative config file whether it was successful or not. Files in -+that directory are read in lexical order. - - .SH EXAMPLE - DEVICE /dev/sd[bcdjkl]1 --- -2.38.1 - diff --git a/0009-mdadm-Update-config-manual.patch b/0009-mdadm-Update-config-manual.patch deleted file mode 100644 index 08599d5..0000000 --- a/0009-mdadm-Update-config-manual.patch +++ /dev/null @@ -1,45 +0,0 @@ -From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:07 +0100 -Subject: [PATCH 09/83] mdadm: Update config manual - -Add missing HOMECLUSTER keyword description. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.conf.5.in | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index dd331a6a..cd4e6a9d 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -439,6 +439,23 @@ from any possible local name. e.g. - .B /dev/md/1_1 - or - .BR /dev/md/home_0 . -+ -+.TP -+.B HOMECLUSTER -+The -+.B homcluster -+line gives a default value for the -+.B \-\-homecluster= -+option to mdadm. It specifies the cluster name for the md device. -+The md device can be assembled only on the cluster which matches -+the name specified. If -+.B homcluster -+is not provided, mdadm tries to detect the cluster name automatically. -+ -+There should only be one -+.B homecluster -+line. Any subsequent lines will be silently ignored. -+ - .TP - .B AUTO - A list of names of metadata format can be given, each preceded by a --- -2.38.1 - diff --git a/0010-Create-Build-use-default_layout.patch b/0010-Create-Build-use-default_layout.patch deleted file mode 100644 index 7f9791b..0000000 --- a/0010-Create-Build-use-default_layout.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:32 +0100 -Subject: [PATCH 10/83] Create, Build: use default_layout() - -This code is duplicated for Build mode so make default_layout() extern -and use it. Simplify the function structure. - -It introduced change for Build mode, now for raid0 RAID0_ORIG_LAYOUT -will be returned same as for Create. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Build.c | 23 +------------------ - Create.c | 67 ++++++++++++++++++++++++++++++++++---------------------- - mdadm.h | 1 + - 3 files changed, 43 insertions(+), 48 deletions(-) - -diff --git a/Build.c b/Build.c -index 962c2e37..8d6f6f58 100644 ---- a/Build.c -+++ b/Build.c -@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - - if (s->layout == UnSet) -- switch(s->level) { -- default: /* no layout */ -- s->layout = 0; -- break; -- case 10: -- s->layout = 0x102; /* near=2, far=1 */ -- if (c->verbose > 0) -- pr_err("layout defaults to n1\n"); -- break; -- case 5: -- case 6: -- s->layout = map_name(r5layout, "default"); -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, s->layout)); -- break; -- case LEVEL_FAULTY: -- s->layout = map_name(faultylayout, "default"); -- -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout)); -- break; -- } -+ s->layout = default_layout(NULL, s->level, c->verbose); - - /* We need to create the device. It can have no name. */ - map_lock(&map); -diff --git a/Create.c b/Create.c -index 0ff1922d..9ea19de0 100644 ---- a/Create.c -+++ b/Create.c -@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk) - return 0; - } - --static int default_layout(struct supertype *st, int level, int verbose) -+/** -+ * default_layout() - Get default layout for level. -+ * @st: metadata requested, could be NULL. -+ * @level: raid level requested. -+ * @verbose: verbose level. -+ * -+ * Try to ask metadata handler first, otherwise use global defaults. -+ * -+ * Return: Layout or &UnSet, return value meaning depends of level used. -+ */ -+int default_layout(struct supertype *st, int level, int verbose) - { - int layout = UnSet; -+ mapping_t *layout_map = NULL; -+ char *layout_name = NULL; - - if (st && st->ss->default_geometry) - st->ss->default_geometry(st, &level, &layout, NULL); - -- if (layout == UnSet) -- switch(level) { -- default: /* no layout */ -- layout = 0; -- break; -- case 0: -- layout = RAID0_ORIG_LAYOUT; -- break; -- case 10: -- layout = 0x102; /* near=2, far=1 */ -- if (verbose > 0) -- pr_err("layout defaults to n2\n"); -- break; -- case 5: -- case 6: -- layout = map_name(r5layout, "default"); -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, layout)); -- break; -- case LEVEL_FAULTY: -- layout = map_name(faultylayout, "default"); -+ if (layout != UnSet) -+ return layout; - -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, layout)); -- break; -- } -+ switch (level) { -+ default: /* no layout */ -+ layout = 0; -+ break; -+ case 0: -+ layout = RAID0_ORIG_LAYOUT; -+ break; -+ case 10: -+ layout = 0x102; /* near=2, far=1 */ -+ layout_name = "n2"; -+ break; -+ case 5: -+ case 6: -+ layout_map = r5layout; -+ break; -+ case LEVEL_FAULTY: -+ layout_map = faultylayout; -+ break; -+ } -+ -+ if (layout_map) { -+ layout = map_name(layout_map, "default"); -+ layout_name = map_num(layout_map, layout); -+ } -+ if (layout_name && verbose > 0) -+ pr_err("layout defaults to %s\n", layout_name); - - return layout; - } -diff --git a/mdadm.h b/mdadm.h -index 26e7e5cd..cd72e711 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1512,6 +1512,7 @@ extern int get_linux_version(void); - extern int mdadm_version(char *version); - extern unsigned long long parse_size(char *size); - extern int parse_uuid(char *str, int uuid[4]); -+int default_layout(struct supertype *st, int level, int verbose); - extern int is_near_layout_10(int layout); - extern int parse_layout_10(char *layout); - extern int parse_layout_faulty(char *layout); --- -2.38.1 - diff --git a/0011-mdadm-add-map_num_s.patch b/0011-mdadm-add-map_num_s.patch deleted file mode 100644 index ee2c755..0000000 --- a/0011-mdadm-add-map_num_s.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:33 +0100 -Subject: [PATCH 11/83] mdadm: add map_num_s() - -map_num() returns NULL if key is not defined. This patch adds -alternative, non NULL version for cases where NULL is not expected. - -There are many printf() calls where map_num() is called on variable -without NULL verification. It works, even if NULL is passed because -gcc is able to ignore NULL argument quietly but the behavior is -undefined. For safety reasons such usages will use map_num_s() now. -It is a potential point of regression. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Assemble.c | 6 ++---- - Create.c | 2 +- - Detail.c | 4 ++-- - Grow.c | 16 ++++++++-------- - Query.c | 4 ++-- - maps.c | 24 ++++++++++++++++++++++++ - mdadm.c | 20 ++++++++++---------- - mdadm.h | 2 +- - super-ddf.c | 6 +++--- - super-intel.c | 2 +- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 9 +++++---- - 13 files changed, 61 insertions(+), 38 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 704b8293..9eac9ce0 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c, - struct assembly_array_info *arr) - { - int raid_disks = arr->preexist_cnt + arr->new_cnt; -- char *status_msg = map_num(assemble_statuses, status); -+ char *status_msg = map_num_s(assemble_statuses, status); - - if (c->export && result) - *result |= status; -@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c, - fprintf(stderr, " (%d new)", arr->new_cnt); - if (arr->exp_cnt) - fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt); -- if (status_msg) -- fprintf(stderr, " %s", status_msg); -- fprintf(stderr, ".\n"); -+ fprintf(stderr, " %s.\n", status_msg); - } - - static int name_matches(char *found, char *required, char *homehost, int require_homehost) -diff --git a/Create.c b/Create.c -index 9ea19de0..c84c1ac8 100644 ---- a/Create.c -+++ b/Create.c -@@ -83,7 +83,7 @@ int default_layout(struct supertype *st, int level, int verbose) - - if (layout_map) { - layout = map_name(layout_map, "default"); -- layout_name = map_num(layout_map, layout); -+ layout_name = map_num_s(layout_map, layout); - } - if (layout_name && verbose > 0) - pr_err("layout defaults to %s\n", layout_name); -diff --git a/Detail.c b/Detail.c -index 95d4cc70..ce7a8445 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c) - if (array.state & (1 << MD_SB_CLEAN)) { - if ((array.level == 0) || - (array.level == LEVEL_LINEAR)) -- arrayst = map_num(sysfs_array_states, -- sra->array_state); -+ arrayst = map_num_s(sysfs_array_states, -+ sra->array_state); - else - arrayst = "clean"; - } else { -diff --git a/Grow.c b/Grow.c -index 18c5719b..8a242b0f 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -547,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && - s->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Operation not supported for consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 1; - } - -@@ -578,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - - if (sra->consistency_policy == (unsigned)s->consistency_policy) { - pr_err("Consistency policy is already %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC && - sra->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Current consistency policy is %s, cannot change to %s\n", -- map_num(consistency_policies, sra->consistency_policy), -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, sra->consistency_policy), -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } -@@ -704,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - ret = sysfs_set_str(sra, NULL, "consistency_policy", -- map_num(consistency_policies, -- s->consistency_policy)); -+ map_num_s(consistency_policies, -+ s->consistency_policy)); - if (ret) - pr_err("Failed to change array consistency policy\n"); - -@@ -2241,7 +2241,7 @@ size_change_error: - info.new_layout = UnSet; - if (info.array.level == 6 && info.new_level == UnSet) { - char l[40], *h; -- strcpy(l, map_num(r6layout, info.array.layout)); -+ strcpy(l, map_num_s(r6layout, info.array.layout)); - h = strrchr(l, '-'); - if (h && strcmp(h, "-6") == 0) { - *h = 0; -@@ -2266,7 +2266,7 @@ size_change_error: - info.new_layout = info.array.layout; - else if (info.array.level == 5 && info.new_level == 6) { - char l[40]; -- strcpy(l, map_num(r5layout, info.array.layout)); -+ strcpy(l, map_num_s(r5layout, info.array.layout)); - strcat(l, "-6"); - info.new_layout = map_name(r6layout, l); - } else { -diff --git a/Query.c b/Query.c -index 23fbf8aa..adcd231e 100644 ---- a/Query.c -+++ b/Query.c -@@ -93,7 +93,7 @@ int Query(char *dev) - else { - printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n", - dev, human_size_brief(larray_size,IEC), -- map_num(pers, level), raid_disks, -+ map_num_s(pers, level), raid_disks, - spare_disks, spare_disks == 1 ? "" : "s"); - } - st = guess_super(fd); -@@ -131,7 +131,7 @@ int Query(char *dev) - dev, - info.disk.number, info.array.raid_disks, - activity, -- map_num(pers, info.array.level), -+ map_num_s(pers, info.array.level), - mddev); - if (st->ss == &super0) - put_md_name(mddev); -diff --git a/maps.c b/maps.c -index a4fd2797..20fcf719 100644 ---- a/maps.c -+++ b/maps.c -@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = { - { NULL, ARRAY_UNKNOWN_STATE } - }; - -+/** -+ * map_num_s() - Safer alternative of map_num() function. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Shall be used only if key existence is quaranted. -+ * -+ * Return: Pointer to name of the element. -+ */ -+char *map_num_s(mapping_t *map, int num) -+{ -+ char *ret = map_num(map, num); -+ -+ assert(ret); -+ return ret; -+} -+ -+/** -+ * map_num() - get element name by key. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Return: Pointer to name of the element or NULL. -+ */ - char *map_num(mapping_t *map, int num) - { - while (map->name) { -diff --git a/mdadm.c b/mdadm.c -index 26299b2e..be40686c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -280,8 +280,8 @@ int main(int argc, char *argv[]) - else - fprintf(stderr, "-%c", opt); - fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n", -- map_num(modes, newmode), -- map_num(modes, mode)); -+ map_num_s(modes, newmode), -+ map_num_s(modes, mode)); - exit(2); - } else if (!mode && newmode) { - mode = newmode; -@@ -544,7 +544,7 @@ int main(int argc, char *argv[]) - switch(s.level) { - default: - pr_err("layout not meaningful for %s arrays.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - case UnSet: - pr_err("raid level must be given before layout.\n"); -@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[]) - if (option_index > 0) - pr_err(":option --%s not valid in %s mode\n", - long_options[option_index].name, -- map_num(modes, mode)); -+ map_num_s(modes, mode)); - else - pr_err("option -%c not valid in %s mode\n", -- opt, map_num(modes, mode)); -+ opt, map_num_s(modes, mode)); - exit(2); - - } -@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[]) - if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--write-journal is not supported with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[]) - s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - if (s.level <= 0) { - pr_err("--consistency-policy not meaningful with level %s.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL && - !s.journaldisks) { - pr_err("--write-journal is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL && - s.level != 5) { -@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[]) - (!s.bitmap_file || - strcmp(s.bitmap_file, "none") == 0)) { - pr_err("--bitmap is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.bitmap_file && - strcmp(s.bitmap_file, "none") != 0 && - s.consistency_policy != CONSISTENCY_POLICY_BITMAP && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--bitmap is not compatible with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -diff --git a/mdadm.h b/mdadm.h -index cd72e711..09915a00 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -770,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, - #endif - - #define SYSLOG_FACILITY LOG_DAEMON -- -+extern char *map_num_s(mapping_t *map, int num); - extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], -diff --git a/super-ddf.c b/super-ddf.c -index 3f304cdc..8cda23a7 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb) - printf("\n"); - printf(" unit[%d] : %d\n", i, be16_to_cpu(ve->unit)); - printf(" state[%d] : %s, %s%s\n", i, -- map_num(ddf_state, ve->state & 7), -+ map_num_s(ddf_state, ve->state & 7), - (ve->state & DDF_state_morphing) ? "Morphing, ": "", - (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent"); - printf(" init state[%d] : %s\n", i, -- map_num(ddf_init_state, ve->init_state&DDF_initstate_mask)); -+ map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask)); - printf(" access[%d] : %s\n", i, -- map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); -+ map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); - printf(" Name[%d] : %.16s\n", i, ve->name); - examine_vd(i, sb, ve->guid); - } -diff --git a/super-intel.c b/super-intel.c -index 6ff336ee..ba3bd41f 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, - free(dev); - free(dv); - pr_err("imsm does not support consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 0; - } - -diff --git a/super0.c b/super0.c -index b79b97a9..61c9ec1d 100644 ---- a/super0.c -+++ b/super0.c -@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st) - { - mdp_super_t *sb = st->sb; - -- printf("MD_LEVEL=%s\n", map_num(pers, sb->level)); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level)); - printf("MD_DEVICES=%d\n", sb->raid_disks); - if (sb->minor_version >= 90) - printf("MD_UUID=%08x:%08x:%08x:%08x\n", -diff --git a/super1.c b/super1.c -index a12a5bc8..e3e2f954 100644 ---- a/super1.c -+++ b/super1.c -@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st) - int len = 32; - int layout; - -- printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level))); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level))); - printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks)); - for (i = 0; i < 32; i++) - if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { -diff --git a/sysfs.c b/sysfs.c -index 2995713d..0d98a65f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) - if (info->array.level < 0) - return 0; /* FIXME */ - rv |= sysfs_set_str(info, NULL, "level", -- map_num(pers, info->array.level)); -+ map_num_s(pers, info->array.level)); - if (info->reshape_active && info->delta_disks != UnSet) - raid_disks -= info->delta_disks; - rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks); -@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers) - } - - if (info->consistency_policy == CONSISTENCY_POLICY_PPL) { -- if (sysfs_set_str(info, NULL, "consistency_policy", -- map_num(consistency_policies, -- info->consistency_policy))) { -+ char *policy = map_num_s(consistency_policies, -+ info->consistency_policy); -+ -+ if (sysfs_set_str(info, NULL, "consistency_policy", policy)) { - pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n"); - info->consistency_policy = CONSISTENCY_POLICY_RESYNC; - } --- -2.38.1 - diff --git a/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch b/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch deleted file mode 100644 index ae67325..0000000 --- a/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Tue, 15 Feb 2022 21:34:15 +0800 -Subject: [PATCH 012/120] mdadm/systemd: remove KillMode=none from service file - -For mdadm's systemd configuration, current systemd KillMode is "none" in -following service files, -- mdadm-grow-continue@.service -- mdmon@.service - -This "none" mode is strongly againsted by systemd developers (see man 5 -systemd.kill for "KillMode=" section), and is considering to remove in -future systemd version. - -As systemd developer explained in disuccsion, the systemd kill process -is, -1. send the signal specified by KillSignal= to the list of processes (if - any), TERM is the default -2. wait until either the target of process(es) exit or a timeout expires -3. if the timeout expires send the signal specified by FinalKillSignal=, - KILL is the default - -For "control-group", all remaining processes will receive the SIGTERM -signal (by default) and if there are still processes after a period f -time, they will get the SIGKILL signal. - -For "mixed", only the main process will receive the SIGTERM signal, and -if there are still processes after a period of time, all remaining -processes (including the main one) will receive the SIGKILL signal. - -From the above comment, currently KillMode=control-group is a proper -kill mode. Since control-gropu is the default kill mode, the fix can be -simply removing KillMode=none line from the service file, then the -default mode will take effect. - -Signed-off-by: Coly Li -Cc: Benjamin Brunner -Cc: Franck Bui -Cc: Jes Sorensen -Cc: Mariusz Tkaczyk -Cc: Neil Brown -Cc: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - systemd/mdmon@.service | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 5c667d2a..9fdc8ec7 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 85a3a7c5..77533958 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -25,4 +25,3 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none --- -2.38.1 - diff --git a/0013-mdmon-Stop-parsing-duplicate-options.patch b/0013-mdmon-Stop-parsing-duplicate-options.patch deleted file mode 100644 index 77324cf..0000000 --- a/0013-mdmon-Stop-parsing-duplicate-options.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 13 May 2022 09:19:42 +0200 -Subject: [PATCH 13/83] mdmon: Stop parsing duplicate options - -Introduce new function is_duplicate_opt() to check if given option -was already used and prevent setting it again along with an error -message. - -Move parsing above in_initrd() check to be able to detect --offroot -option duplicates. - -Now help option is executed after parsing to prevent executing commands -like: 'mdmon --help --ndlksnlksajndfjksndafasj'. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 44 +++++++++++++++++++++++++++++++++++--------- - 1 file changed, 35 insertions(+), 9 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 5570574b..c057da63 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -288,6 +288,15 @@ void usage(void) - exit(2); - } - -+static bool is_duplicate_opt(const int opt, const int set_val, const char *long_name) -+{ -+ if (opt == set_val) { -+ pr_err("--%s option duplicated!\n", long_name); -+ return true; -+ } -+ return false; -+} -+ - static int mdmon(char *devnm, int must_fork, int takeover); - - int main(int argc, char *argv[]) -@@ -299,6 +308,7 @@ int main(int argc, char *argv[]) - int all = 0; - int takeover = 0; - int dofork = 1; -+ bool help = false; - static struct option options[] = { - {"all", 0, NULL, 'a'}, - {"takeover", 0, NULL, 't'}, -@@ -308,37 +318,50 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -- if (in_initrd()) { -- /* -- * set first char of argv[0] to @. This is used by -- * systemd to signal that the task was launched from -- * initrd/initramfs and should be preserved during shutdown -- */ -- argv[0][0] = '@'; -- } -- - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -+ if (is_duplicate_opt(all, 1, "all")) -+ exit(1); - container_name = argv[optind-1]; - all = 1; - break; - case 't': -+ if (is_duplicate_opt(takeover, 1, "takeover")) -+ exit(1); - takeover = 1; - break; - case 'F': -+ if (is_duplicate_opt(dofork, 0, "foreground")) -+ exit(1); - dofork = 0; - break; - case OffRootOpt: -+ if (is_duplicate_opt(argv[0][0], '@', "offroot")) -+ exit(1); - argv[0][0] = '@'; - break; - case 'h': -+ if (is_duplicate_opt(help, true, "help")) -+ exit(1); -+ help = true; -+ break; - default: - usage(); - break; - } - } - -+ -+ if (in_initrd()) { -+ /* -+ * set first char of argv[0] to @. This is used by -+ * systemd to signal that the task was launched from -+ * initrd/initramfs and should be preserved during shutdown -+ */ -+ argv[0][0] = '@'; -+ } -+ - if (all == 0 && container_name == NULL) { - if (argv[optind]) - container_name = argv[optind]; -@@ -353,6 +376,9 @@ int main(int argc, char *argv[]) - if (strcmp(container_name, "/proc/mdstat") == 0) - all = 1; - -+ if (help) -+ usage(); -+ - if (all) { - struct mdstat_ent *mdstat, *e; - int container_len = strlen(container_name); --- -2.38.1 - diff --git a/0014-Grow-block-n-on-external-volumes.patch b/0014-Grow-block-n-on-external-volumes.patch deleted file mode 100644 index 4e6a874..0000000 --- a/0014-Grow-block-n-on-external-volumes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 19 May 2022 09:16:08 +0200 -Subject: [PATCH 14/83] Grow: block -n on external volumes. - -Performing --raid-devices on external metadata volume should be blocked -as it causes unwanted behaviour. - -Eg. Performing -mdadm -G /dev/md/volume -l10 -n4 -on r0_d2 inside 4 disk container, returns -mdadm: Need 2 spares to avoid degraded array, only have 0. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/Grow.c b/Grow.c -index 8a242b0f..f6efbc48 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1892,6 +1892,14 @@ int Grow_reshape(char *devname, int fd, - - if (retval) { - pr_err("Cannot read superblock for %s\n", devname); -+ close(cfd); -+ free(subarray); -+ return 1; -+ } -+ -+ if (s->raiddisks && subarray) { -+ pr_err("--raid-devices operation can be performed on a container only\n"); -+ close(cfd); - free(subarray); - return 1; - } --- -2.38.1 - diff --git a/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch b/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch deleted file mode 100644 index 51a9e0f..0000000 --- a/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch +++ /dev/null @@ -1,90 +0,0 @@ -From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:11:25 +0200 -Subject: [PATCH 15/83] Incremental: Fix possible memory and resource leaks - -map allocated through map_by_uuid() is not freed if mdfd is invalid. -In addition mdfd is not closed, and mdinfo list is not freed too. - -Signed-off-by: Mateusz Grzonka -Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc -Signed-off-by: Jes Sorensen ---- - Incremental.c | 32 +++++++++++++++++++++++--------- - 1 file changed, 23 insertions(+), 9 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index a57fc323..4d0cd9d6 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1499,7 +1499,7 @@ static int Incremental_container(struct supertype *st, char *devname, - return 0; - } - for (ra = list ; ra ; ra = ra->next) { -- int mdfd; -+ int mdfd = -1; - char chosen_name[1024]; - struct map_ent *mp; - struct mddev_ident *match = NULL; -@@ -1514,6 +1514,12 @@ static int Incremental_container(struct supertype *st, char *devname, - - if (mp) { - mdfd = open_dev(mp->devnm); -+ if (!is_fd_valid(mdfd)) { -+ pr_err("failed to open %s: %s.\n", -+ mp->devnm, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - if (mp->path) - strcpy(chosen_name, mp->path); - else -@@ -1573,21 +1579,25 @@ static int Incremental_container(struct supertype *st, char *devname, - c->autof, - trustworthy, - chosen_name, 0); -+ -+ if (!is_fd_valid(mdfd)) { -+ pr_err("create_mddev failed with chosen name %s: %s.\n", -+ chosen_name, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - } -- if (only && (!mp || strcmp(mp->devnm, only) != 0)) -- continue; - -- if (mdfd < 0) { -- pr_err("failed to open %s: %s.\n", -- chosen_name, strerror(errno)); -- return 2; -+ if (only && (!mp || strcmp(mp->devnm, only) != 0)) { -+ close_fd(&mdfd); -+ continue; - } - - assemble_container_content(st, mdfd, ra, c, - chosen_name, &result); - map_free(map); - map = NULL; -- close(mdfd); -+ close_fd(&mdfd); - } - if (c->export && result) { - char sep = '='; -@@ -1610,7 +1620,11 @@ static int Incremental_container(struct supertype *st, char *devname, - } - printf("\n"); - } -- return 0; -+ -+release: -+ map_free(map); -+ sysfs_free(list); -+ return rv; - } - - static void run_udisks(char *arg1, char *arg2) --- -2.38.1 - diff --git a/0016-Mdmonitor-Fix-segfault.patch b/0016-Mdmonitor-Fix-segfault.patch deleted file mode 100644 index 61c64ab..0000000 --- a/0016-Mdmonitor-Fix-segfault.patch +++ /dev/null @@ -1,98 +0,0 @@ -From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:12 +0200 -Subject: [PATCH 16/83] Mdmonitor: Fix segfault - -Mdadm with "--monitor" parameter requires md device -as an argument to be monitored. If given argument is -not a md device, error shall be returned. Previously -it was not checked and invalid argument caused -segmentation fault. This commit adds checking -that devices passed to mdmonitor are md devices. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 10 +++++++++- - mdadm.h | 1 + - mdopen.c | 17 +++++++++++++++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index c0ab5412..4e5802b5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -182,6 +182,7 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ - st = xcalloc(1, sizeof *st); - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); -@@ -190,6 +191,8 @@ int Monitor(struct mddev_dev *devlist, - strcpy(strcpy(st->devname, "/dev/md/"), - mdlist->devname); - } -+ if (!is_mddev(mdlist->devname)) -+ return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -203,7 +206,12 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_dev *dv; - - for (dv = devlist; dv; dv = dv->next) { -- struct state *st = xcalloc(1, sizeof *st); -+ struct state *st; -+ -+ if (!is_mddev(dv->devname)) -+ return 1; -+ -+ st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); - st->devname = xstrdup(dv->devname); - st->next = statelist; -diff --git a/mdadm.h b/mdadm.h -index 09915a00..d53df169 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1636,6 +1636,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy, - #define FOREIGN 2 - #define METADATA 3 - extern int open_mddev(char *dev, int report_errors); -+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); -diff --git a/mdopen.c b/mdopen.c -index 245be537..d18c9319 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -475,6 +475,23 @@ int open_mddev(char *dev, int report_errors) - return mdfd; - } - -+/** -+ * is_mddev() - check that file name passed is an md device. -+ * @dev: file name that has to be checked. -+ * Return: 1 if file passed is an md device, 0 if not. -+ */ -+int is_mddev(char *dev) -+{ -+ int fd = open_mddev(dev, 1); -+ -+ if (fd >= 0) { -+ close(fd); -+ return 1; -+ } -+ -+ return 0; -+} -+ - char *find_free_devnm(int use_partitions) - { - static char devnm[32]; --- -2.38.1 - diff --git a/0017-Mdmonitor-Improve-logging-method.patch b/0017-Mdmonitor-Improve-logging-method.patch deleted file mode 100644 index 3c7eed2..0000000 --- a/0017-Mdmonitor-Improve-logging-method.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:13 +0200 -Subject: [PATCH 17/83] Mdmonitor: Improve logging method - -Change logging, and as a result, mdmonitor in verbose -mode will report its configuration. - -Signed-off-by: Kinga Tanska -Signed-off-by: Oleksandr Shchirskyi -Signed-off-by: Jes Sorensen ---- - Monitor.c | 25 ++++++++++++++----------- - 1 file changed, 14 insertions(+), 11 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 4e5802b5..6ca1ebe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -136,24 +136,27 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -- if (!mailaddr) { -+ if (!mailaddr) - mailaddr = conf_get_mailaddr(); -- if (mailaddr && ! c->scan) -- pr_err("Monitor using email address \"%s\" from config file\n", -- mailaddr); -- } -- mailfrom = conf_get_mailfrom(); - -- if (!alert_cmd) { -+ if (!alert_cmd) - alert_cmd = conf_get_program(); -- if (alert_cmd && !c->scan) -- pr_err("Monitor using program \"%s\" from config file\n", -- alert_cmd); -- } -+ -+ mailfrom = conf_get_mailfrom(); -+ - if (c->scan && !mailaddr && !alert_cmd && !dosyslog) { - pr_err("No mail address or alert command - not monitoring.\n"); - return 1; - } -+ -+ if (c->verbose) { -+ pr_err("Monitor is started with delay %ds\n", c->delay); -+ if (mailaddr) -+ pr_err("Monitor using email address %s\n", mailaddr); -+ if (alert_cmd) -+ pr_err("Monitor using program %s\n", alert_cmd); -+ } -+ - info.alert_cmd = alert_cmd; - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; --- -2.38.1 - diff --git a/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch deleted file mode 100644 index 24db49f..0000000 --- a/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 11:59:34 +0200 -Subject: [PATCH 18/83] Fix possible NULL ptr dereferences and memory leaks - -In Assemble there was a NULL check for sra variable, -which effectively didn't stop the execution in every case. -That might have resulted in a NULL pointer dereference. - -Also in super-ddf, mu variable was set to NULL for some condition, -and then immidiately dereferenced. -Additionally some memory wasn't freed as well. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 ++++++- - super-ddf.c | 9 +++++++-- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 9eac9ce0..4b213560 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1982,7 +1982,12 @@ int assemble_container_content(struct supertype *st, int mdfd, - } - - sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); -- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { -+ if (sra == NULL) { -+ pr_err("Failed to read sysfs parameters\n"); -+ return 1; -+ } -+ -+ if (strcmp(sra->text_version, content->text_version) != 0) { - if (content->array.major_version == -1 && - content->array.minor_version == -2 && - c->readonly && -diff --git a/super-ddf.c b/super-ddf.c -index 8cda23a7..abbc8b09 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -5125,13 +5125,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - */ - vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk, - &n_bvd, &vcl); -- if (vc == NULL) -+ if (vc == NULL) { -+ free(rv); - return NULL; -+ } - - mu = xmalloc(sizeof(*mu)); - if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) { - free(mu); -- mu = NULL; -+ free(rv); -+ return NULL; - } - - mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count; -@@ -5161,6 +5164,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - pr_err("BUG: can't find disk %d (%d/%d)\n", - di->disk.raid_disk, - di->disk.major, di->disk.minor); -+ free(mu); -+ free(rv); - return NULL; - } - vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum; --- -2.38.1 - diff --git a/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch b/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch deleted file mode 100644 index 12dd070..0000000 --- a/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:00:09 +0200 -Subject: [PATCH 19/83] imsm: Remove possibility for get_imsm_dev to return - NULL - -Returning NULL from get_imsm_dev or __get_imsm_dev will cause segfault. -Guarantee that it never happens. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - super-intel.c | 153 +++++++++++++++++++++++++------------------------- - 1 file changed, 78 insertions(+), 75 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index ba3bd41f..3788feb9 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -851,6 +851,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update) - return inf; - } - -+/** -+ * __get_imsm_dev() - Get device with index from imsm_super. -+ * @mpb: &imsm_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - { - int offset; -@@ -858,30 +873,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - void *_mpb = mpb; - - if (index >= mpb->num_raid_devs) -- return NULL; -+ goto error; - - /* devices start after all disks */ - offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb; - -- for (i = 0; i <= index; i++) -+ for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0)) - if (i == index) - return _mpb + offset; -- else -- offset += sizeof_imsm_dev(_mpb + offset, 0); -- -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in imsm_super\n", index); -+ abort(); - } - -+/** -+ * get_imsm_dev() - Get device with index from intel_super. -+ * @super: &intel_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index) - { - struct intel_dev *dv; - - if (index >= super->anchor->num_raid_devs) -- return NULL; -+ goto error; -+ - for (dv = super->devlist; dv; dv = dv->next) - if (dv->index == index) - return dv->dev; -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in intel_super\n", index); -+ abort(); - } - - static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr -@@ -4364,8 +4396,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 && -- dev_iter->vol.migr_state == 1 && -+ if (dev_iter->vol.migr_state == 1 && - dev_iter->vol.migr_type == MIGR_GEN_MIGR) { - /* This device is migrating */ - map0 = get_imsm_map(dev_iter, MAP_0); -@@ -4514,8 +4545,6 @@ static void clear_hi(struct intel_super *super) - } - for (i = 0; i < mpb->num_raid_devs; ++i) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- if (!dev) -- return; - for (n = 0; n < 2; ++n) { - struct imsm_map *map = get_imsm_map(dev, n); - if (!map) -@@ -5836,7 +5865,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_dev *_dev = __get_imsm_dev(mpb, 0); - - _disk = __get_imsm_disk(mpb, dl->index); -- if (!_dev || !_disk) { -+ if (!_disk) { - pr_err("BUG mpb setup error\n"); - return 1; - } -@@ -6171,10 +6200,10 @@ static int write_super_imsm(struct supertype *st, int doclose) - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = __get_imsm_dev(mpb, i); - struct imsm_dev *dev2 = get_imsm_dev(super, i); -- if (dev && dev2) { -- imsm_copy_dev(dev, dev2); -- mpb_size += sizeof_imsm_dev(dev, 0); -- } -+ -+ imsm_copy_dev(dev, dev2); -+ mpb_size += sizeof_imsm_dev(dev, 0); -+ - if (is_gen_migration(dev2)) - clear_migration_record = 0; - } -@@ -9033,29 +9062,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed) - __u8 state; - - dev2 = get_imsm_dev(cont->sb, dev_idx); -- if (dev2) { -- state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -- if (state == IMSM_T_STATE_FAILED) { -- map = get_imsm_map(dev2, MAP_0); -- if (!map) -- return 1; -- for (slot = 0; slot < map->num_members; slot++) { -- /* -- * Check if failed disks are deleted from intel -- * disk list or are marked to be deleted -- */ -- idx = get_imsm_disk_idx(dev2, slot, MAP_X); -- idisk = get_imsm_dl_disk(cont->sb, idx); -- /* -- * Do not rebuild the array if failed disks -- * from failed sub-array are not removed from -- * container. -- */ -- if (idisk && -- is_failed(&idisk->disk) && -- (idisk->action != DISK_REMOVE)) -- return 0; -- } -+ -+ state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -+ if (state == IMSM_T_STATE_FAILED) { -+ map = get_imsm_map(dev2, MAP_0); -+ for (slot = 0; slot < map->num_members; slot++) { -+ /* -+ * Check if failed disks are deleted from intel -+ * disk list or are marked to be deleted -+ */ -+ idx = get_imsm_disk_idx(dev2, slot, MAP_X); -+ idisk = get_imsm_dl_disk(cont->sb, idx); -+ /* -+ * Do not rebuild the array if failed disks -+ * from failed sub-array are not removed from -+ * container. -+ */ -+ if (idisk && -+ is_failed(&idisk->disk) && -+ (idisk->action != DISK_REMOVE)) -+ return 0; - } - } - return 1; -@@ -10089,7 +10115,6 @@ static void imsm_process_update(struct supertype *st, - int victim = u->dev_idx; - struct active_array *a; - struct intel_dev **dp; -- struct imsm_dev *dev; - - /* sanity check that we are not affecting the uuid of - * active arrays, or deleting an active array -@@ -10105,8 +10130,7 @@ static void imsm_process_update(struct supertype *st, - * is active in the container, so checking - * mpb->num_raid_devs is just extra paranoia - */ -- dev = get_imsm_dev(super, victim); -- if (a || !dev || mpb->num_raid_devs == 1) { -+ if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) { - dprintf("failed to delete subarray-%d\n", victim); - break; - } -@@ -10140,7 +10164,7 @@ static void imsm_process_update(struct supertype *st, - if (a->info.container_member == target) - break; - dev = get_imsm_dev(super, u->dev_idx); -- if (a || !dev || !check_name(super, name, 1)) { -+ if (a || !check_name(super, name, 1)) { - dprintf("failed to rename subarray-%d\n", target); - break; - } -@@ -10169,10 +10193,6 @@ static void imsm_process_update(struct supertype *st, - struct imsm_update_rwh_policy *u = (void *)update->buf; - int target = u->dev_idx; - struct imsm_dev *dev = get_imsm_dev(super, target); -- if (!dev) { -- dprintf("could not find subarray-%d\n", target); -- break; -- } - - if (dev->rwh_policy != u->new_policy) { - dev->rwh_policy = u->new_policy; -@@ -11397,8 +11417,10 @@ static int imsm_create_metadata_update_for_migration( - { - struct intel_super *super = st->sb; - int update_memory_size; -+ int current_chunk_size; - struct imsm_update_reshape_migration *u; -- struct imsm_dev *dev; -+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); - int previous_level = -1; - - dprintf("(enter) New Level = %i\n", geo->level); -@@ -11415,23 +11437,15 @@ static int imsm_create_metadata_update_for_migration( - u->new_disks[0] = -1; - u->new_chunksize = -1; - -- dev = get_imsm_dev(super, u->subdev); -- if (dev) { -- struct imsm_map *map; -+ current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2; - -- map = get_imsm_map(dev, MAP_0); -- if (map) { -- int current_chunk_size = -- __le16_to_cpu(map->blocks_per_strip) / 2; -- -- if (geo->chunksize != current_chunk_size) { -- u->new_chunksize = geo->chunksize / 1024; -- dprintf("imsm: chunk size change from %i to %i\n", -- current_chunk_size, u->new_chunksize); -- } -- previous_level = map->raid_level; -- } -+ if (geo->chunksize != current_chunk_size) { -+ u->new_chunksize = geo->chunksize / 1024; -+ dprintf("imsm: chunk size change from %i to %i\n", -+ current_chunk_size, u->new_chunksize); - } -+ previous_level = map->raid_level; -+ - if (geo->level == 5 && previous_level == 0) { - struct mdinfo *spares = NULL; - -@@ -12519,9 +12533,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st) - unsigned long long offset; - struct dl *d; - -- if (!dev) -- return -1; -- - if (dev->rwh_policy != RWH_BITMAP) - return 0; - -@@ -12567,16 +12578,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp, - return -1; - - dev = get_imsm_dev(super, vol_idx); -- -- if (!dev) { -- dprintf("cannot find the device for volume index %d\n", -- vol_idx); -- return -1; -- } - dev->rwh_policy = RWH_BITMAP; -- - *chunkp = calculate_bitmap_chunksize(st, dev); -- - return 0; - } - --- -2.38.1 - diff --git a/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch b/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch deleted file mode 100644 index f51c730..0000000 --- a/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001 -From: Nigel Croxon -Date: Mon, 18 Apr 2022 13:44:23 -0400 -Subject: [PATCH 20/83] Revert "mdadm: fix coredump of mdadm --monitor -r" - -This reverts commit 546047688e1c64638f462147c755b58119cabdc8. - -The change from commit mdadm: fix coredump of mdadm ---monitor -r broke the printing of the return message when -passing -r to mdadm --manage, the removal of a device from -an array. - -If the current code reverts this commit, both issues are -still fixed. - -The original problem reported that the fix tried to address -was: The --monitor -r option requires a parameter, -otherwise a null pointer will be manipulated when -converting to integer data, and a core dump will appear. - -The original problem was really fixed with: -60815698c0a Refactor parse_num and use it to parse optarg. -Which added a check for NULL in 'optarg' before moving it -to the 'increments' variable. - -New issue: When trying to remove a device using the short -argument -r, instead of the long argument --remove, the -output is empty. The problem started when commit -546047688e1c was added. - -Steps to Reproduce: -1. create/assemble /dev/md0 device -2. mdadm --manage /dev/md0 -r /dev/vdxx - -Actual results: -Nothing, empty output, nothing happens, the device is still -connected to the array. - -The output should have stated "mdadm: hot remove failed -for /dev/vdxx: Device or resource busy", if the device was -still active. Or it should remove the device and print -a message: - -mdadm: set /dev/vdd faulty in /dev/md0 -mdadm: hot removed /dev/vdd from /dev/md0 - -The following commit should be reverted as it breaks -mdadm --manage -r. - -commit 546047688e1c64638f462147c755b58119cabdc8 -Author: Wu Guanghao -Date: Mon Aug 16 15:24:51 2021 +0800 -mdadm: fix coredump of mdadm --monitor -r - --Nigel - -Signed-off-by: Nigel Croxon -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 8f873c48..bec1be9a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -81,11 +81,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - * found, it is started. - */ - --char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k"; -+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; - - struct option long_options[] = { - {"manage", 0, 0, ManageOpt}, --- -2.38.1 - diff --git a/0021-util-replace-ioctl-use-with-function.patch b/0021-util-replace-ioctl-use-with-function.patch deleted file mode 100644 index 56ee5e8..0000000 --- a/0021-util-replace-ioctl-use-with-function.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 21 Jun 2022 00:10:39 +0800 -Subject: [PATCH 21/83] util: replace ioctl use with function - -Replace using of ioctl calling to get md array info with -special function prepared to it. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util.c b/util.c -index cc94f96e..38f0420e 100644 ---- a/util.c -+++ b/util.c -@@ -267,7 +267,7 @@ int md_array_active(int fd) - * GET_ARRAY_INFO doesn't provide access to the proper state - * information, so fallback to a basic check for raid_disks != 0 - */ -- ret = ioctl(fd, GET_ARRAY_INFO, &array); -+ ret = md_get_array_info(fd, &array); - } - - return !ret; --- -2.38.1 - diff --git a/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch b/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch deleted file mode 100644 index 88bba83..0000000 --- a/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Tue, 21 Jun 2022 00:10:40 +0800 -Subject: [PATCH 22/83] mdadm/super1: restore commit 45a87c2f31335 to fix - clustered slot issue - -Commit 9d67f6496c71 ("mdadm:check the nodes when operate clustered -array") modified assignment logic for st->nodes in write_bitmap1(), -which introduced bitmap slot issue: - -load_super1 didn't set up supertype.nodes, which made spare disk only -have one slot info. Then it triggered kernel md_bitmap_load_sb to get -wrong bitmap slot data. - -For fixing this issue, there are two methods: - -1> revert the related code of commit 9d67f6496c71. and restore the code - from former commit 45a87c2f31335 ("super1: add more checks for - NodeNumUpdate option"). - st->nodes value would be 0 & 1 under current code logic. i.e. - When adding a spare disk, there is no place to init st->nodes, and - the value is ZERO. - -2> keep 9d67f6496c71, add additional ->nodes handling in load_super1(), - let load_super1 to set st->nodes when bitmap is BITMAP_MAJOR_CLUSTERED. - Under current mdadm code logic, load_super1 will be called many - times, any new code in load_super1 will cost mdadm running more time. - And more reason is I prefer as much as possible to limit clustered - code spreading in every corner. - -So I used method <1> to fix this issue. - -How to trigger: - -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdc -mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb -mdadm -a /dev/md0 /dev/sdc -mdadm /dev/md0 --fail /dev/sda -mdadm /dev/md0 --remove /dev/sda -mdadm -Ss -mdadm -A /dev/md0 /dev/sdb /dev/sdc - -the output of current "mdadm -X /dev/sdc": -(there should be (by default) 4 slot info for correct output) -``` - Filename : /dev/sdc - Magic : 6d746962 - Version : 5 - UUID : a74642f8:a6b1fba8:58e1f8db:cfe7b082 - Events : 29 - Events Cleared : 0 - State : OK - Chunksize : 64 MB - Daemon : 5s flush period - Write Mode : Normal - Sync Size : 306176 (299.00 MiB 313.52 MB) - Bitmap : 5 bits (chunks), 5 dirty (100.0%) -``` - -And mdadm later operations will trigger kernel output error message: -(triggered by "mdadm -A /dev/md0 /dev/sdb /dev/sdc") -``` -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 1 -kernel: md-cluster: Could not gather bitmaps from slot 1 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2 -kernel: md-cluster: Could not gather bitmaps from slot 2 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 3 -kernel: md-cluster: Could not gather bitmaps from slot 3 -kernel: md-cluster: failed to gather all resyn infos -kernel: md0: detected capacity change from 0 to 612352 -``` - -Acked-by: Coly Li -Signed-off-by: Heming Zhao -Signed-off-by: Jes Sorensen ---- - super1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/super1.c b/super1.c -index e3e2f954..3a0c69fd 100644 ---- a/super1.c -+++ b/super1.c -@@ -2674,7 +2674,17 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update - } - - if (bms->version == BITMAP_MAJOR_CLUSTERED) { -- if (__cpu_to_le32(st->nodes) < bms->nodes) { -+ if (st->nodes == 1) { -+ /* the parameter for nodes is not valid */ -+ pr_err("Warning: cluster-md at least needs two nodes\n"); -+ return -EINVAL; -+ } else if (st->nodes == 0) { -+ /* -+ * parameter "--nodes" is not specified, (eg, add a disk to -+ * clustered raid) -+ */ -+ break; -+ } else if (__cpu_to_le32(st->nodes) < bms->nodes) { - /* - * Since the nodes num is not increased, no - * need to check the space enough or not, --- -2.38.1 - diff --git a/0023-imsm-introduce-get_disk_slot_in_dev.patch b/0023-imsm-introduce-get_disk_slot_in_dev.patch deleted file mode 100644 index ca1d015..0000000 --- a/0023-imsm-introduce-get_disk_slot_in_dev.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:41 +0800 -Subject: [PATCH 23/83] imsm: introduce get_disk_slot_in_dev() - -The routine was added to remove unnecessary get_imsm_dev() and -get_imsm_map() calls, used only to determine disk slot. - -Additionally, enum for IMSM return statues was added for further usage. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 47 ++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 36 insertions(+), 11 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 3788feb9..cd1f1e3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -366,6 +366,18 @@ struct migr_record { - }; - ASSERT_SIZE(migr_record, 128) - -+/** -+ * enum imsm_status - internal IMSM return values representation. -+ * @STATUS_OK: function succeeded. -+ * @STATUS_ERROR: General error ocurred (not specified). -+ * -+ * Typedefed to imsm_status_t. -+ */ -+typedef enum imsm_status { -+ IMSM_STATUS_ERROR = -1, -+ IMSM_STATUS_OK = 0, -+} imsm_status_t; -+ - struct md_list { - /* usage marker: - * 1: load metadata -@@ -1183,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord) - map->disk_ord_tbl[slot] = __cpu_to_le32(ord); - } - --static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) -+static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) - { - int slot; - __u32 ord; -@@ -1194,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) - return slot; - } - -- return -1; -+ return IMSM_STATUS_ERROR; - } - - static int get_imsm_raid_level(struct imsm_map *map) -@@ -1209,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map) - return map->raid_level; - } - -+/** -+ * get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev. -+ * @super: &intel_super pointer, not NULL. -+ * @dev_idx: imsm device index. -+ * @idx: disk index. -+ * -+ * Return: Slot on success, IMSM_STATUS_ERROR otherwise. -+ */ -+static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx, -+ const unsigned int idx) -+{ -+ struct imsm_dev *dev = get_imsm_dev(super, dev_idx); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); -+ -+ return get_imsm_disk_slot(map, idx); -+} -+ - static int cmp_extent(const void *av, const void *bv) - { - const struct extent *a = av; -@@ -1225,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super) - int memberships = 0; - int i; - -- for (i = 0; i < super->anchor->num_raid_devs; i++) { -- struct imsm_dev *dev = get_imsm_dev(super, i); -- struct imsm_map *map = get_imsm_map(dev, MAP_0); -- -- if (get_imsm_disk_slot(map, dl->index) >= 0) -+ for (i = 0; i < super->anchor->num_raid_devs; i++) -+ if (get_disk_slot_in_dev(super, i, dl->index) >= 0) - memberships++; -- } - - return memberships; - } -@@ -1941,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super) - - /* first map under migration */ - map = get_imsm_map(dev, MAP_0); -+ - if (map) - slot = get_imsm_disk_slot(map, super->disks->index); - if (map == NULL || slot > 1 || slot < 0) { -@@ -9655,10 +9681,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u, - /* count arrays using the victim in the metadata */ - found = 0; - for (a = active_array; a ; a = a->next) { -- dev = get_imsm_dev(super, a->info.container_member); -- map = get_imsm_map(dev, MAP_0); -+ int dev_idx = a->info.container_member; - -- if (get_imsm_disk_slot(map, victim) >= 0) -+ if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0) - found++; - } - --- -2.38.1 - diff --git a/0024-imsm-use-same-slot-across-container.patch b/0024-imsm-use-same-slot-across-container.patch deleted file mode 100644 index dc23b3c..0000000 --- a/0024-imsm-use-same-slot-across-container.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:42 +0800 -Subject: [PATCH 24/83] imsm: use same slot across container - -Autolayout relies on drives order on super->disks list, but -it is not quaranted by readdir() in sysfs_read(). As a result -drive could be put in different slot in second volume. - -Make it consistent by reffering to first volume, if exists. - -Use enum imsm_status to unify error handling. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 169 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 108 insertions(+), 61 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index cd1f1e3d..deef7c87 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7522,11 +7522,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 1; - } - --static int imsm_get_free_size(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * imsm_get_free_size() - get the biggest, common free space from members. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. -+ * -+ * @freesize is set to meaningful value, this can be @size, or calculated -+ * max free size. -+ * super->create_offset value is modified and set appropriately in -+ * merge_extends() for further creation. -+ */ -+static imsm_status_t imsm_get_free_size(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, -+ const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - struct dl *dl; - int i; -@@ -7570,12 +7586,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - /* chunk is in K */ - minsize = chunk * 2; - -- if (cnt < raiddisks || -- (super->orom && used && used != raiddisks) || -- maxsize < minsize || -- maxsize == 0) { -+ if (cnt < raiddisks || (super->orom && used && used != raiddisks) || -+ maxsize < minsize || maxsize == 0) { - pr_err("not enough devices with space to create array.\n"); -- return 0; /* No enough free spaces large enough */ -+ return IMSM_STATUS_ERROR; - } - - if (size == 0) { -@@ -7588,37 +7602,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - } - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- - *freesize = size; - - dprintf("imsm: imsm_get_free_size() returns : %llu\n", size); - -- return 1; -+ return IMSM_STATUS_OK; - } - --static int reserve_space(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * autolayout_imsm() - automatically layout a new volume. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * We are being asked to automatically layout a new volume based on the current -+ * contents of the container. If the parameters can be satisfied autolayout_imsm -+ * will record the disks, start offset, and will return size of the volume to -+ * be created. See imsm_get_free_size() for details. -+ * add_to_super() and getinfo_super() detect when autolayout is in progress. -+ * If first volume exists, slots are set consistently to it. -+ * -+ * Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise. -+ * -+ * Disks are marked for creation via dl->raiddisk. -+ */ -+static imsm_status_t autolayout_imsm(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; -- struct dl *dl; -- int cnt; -- int rv = 0; -+ int curr_slot = 0; -+ struct dl *disk; -+ int vol_cnt = super->anchor->num_raid_devs; -+ imsm_status_t rv; - -- rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize); -- if (rv) { -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- rv = 1; -+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); -+ if (rv != IMSM_STATUS_OK) -+ return IMSM_STATUS_ERROR; -+ -+ for (disk = super->disks; disk; disk = disk->next) { -+ if (!disk->e) -+ continue; -+ -+ if (curr_slot == raiddisks) -+ break; -+ -+ if (vol_cnt == 0) { -+ disk->raiddisk = curr_slot; -+ } else { -+ int _slot = get_disk_slot_in_dev(super, 0, disk->index); -+ -+ if (_slot == -1) { -+ pr_err("Disk %s is not used in first volume, aborting\n", -+ disk->devname); -+ return IMSM_STATUS_ERROR; -+ } -+ disk->raiddisk = _slot; -+ } -+ curr_slot++; - } - -- return rv; -+ return IMSM_STATUS_OK; - } - - static int validate_geometry_imsm(struct supertype *st, int level, int layout, -@@ -7654,35 +7700,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - } - - if (!dev) { -- if (st->sb) { -- struct intel_super *super = st->sb; -- if (!validate_geometry_imsm_orom(st->sb, level, layout, -- raiddisks, chunk, size, -- verbose)) -+ struct intel_super *super = st->sb; -+ -+ /* -+ * Autolayout mode, st->sb and freesize must be set. -+ */ -+ if (!super || !freesize) { -+ pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -+ return 1; -+ } -+ -+ if (!validate_geometry_imsm_orom(st->sb, level, layout, -+ raiddisks, chunk, size, -+ verbose)) -+ return 0; -+ -+ if (super->orom) { -+ imsm_status_t rv; -+ 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; -- /* we are being asked to automatically layout a -- * new volume based on the current contents of -- * the container. If the the parameters can be -- * satisfied reserve_space will record the disks, -- * start offset, and size of the volume to be -- * created. add_to_super and getinfo_super -- * detect when autolayout is in progress. -- */ -- /* assuming that freesize is always given when array is -- created */ -- if (super->orom && freesize) { -- int count; -- 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; -- } - } -- if (freesize) -- return reserve_space(st, raiddisks, size, -- *chunk, freesize); -+ -+ rv = autolayout_imsm(super, raiddisks, size, *chunk, -+ freesize); -+ if (rv != IMSM_STATUS_OK) -+ return 0; - } - return 1; - } -@@ -11538,7 +11584,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - unsigned long long current_size; - unsigned long long free_size; - unsigned long long max_size; -- int rv; -+ imsm_status_t rv; - - getinfo_super_imsm_volume(st, &info, NULL); - if (geo->level != info.array.level && geo->level >= 0 && -@@ -11657,9 +11703,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - } - /* check the maximum available size - */ -- rv = imsm_get_free_size(st, dev->vol.map->num_members, -- 0, chunk, &free_size); -- if (rv == 0) -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, -+ 0, chunk, &free_size); -+ -+ if (rv != IMSM_STATUS_OK) - /* Cannot find maximum available space - */ - max_size = 0; --- -2.38.1 - diff --git a/0025-imsm-block-changing-slots-during-creation.patch b/0025-imsm-block-changing-slots-during-creation.patch deleted file mode 100644 index 4c3b918..0000000 --- a/0025-imsm-block-changing-slots-during-creation.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:43 +0800 -Subject: [PATCH 25/83] imsm: block changing slots during creation - -If user specifies drives for array creation, then slot order across -volumes is not preserved. -Ideally, it should be checked in validate_geometry() but it is not -possible in current implementation (order is determined later). -Add verification in add_to_super_imsm_volume() and throw error if -mismatch is detected. -IMSM allows to use only same members within container. -This is not hardware dependency but metadata limitation. -Therefore, 09-imsm-overlap test is removed. Testing it is pointless. -After this patch, creation in this scenario is blocked. Offset -verification is covered in other tests. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 33 ++++++++++++++++++++++----------- - tests/09imsm-overlap | 28 ---------------------------- - 2 files changed, 22 insertions(+), 39 deletions(-) - delete mode 100644 tests/09imsm-overlap - -diff --git a/super-intel.c b/super-intel.c -index deef7c87..8ffe485c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_map *map; - struct dl *dl, *df; - int slot; -+ int autolayout = 0; -+ -+ if (!is_fd_valid(fd)) -+ autolayout = 1; - - dev = get_imsm_dev(super, super->current_vol); - map = get_imsm_map(dev, MAP_0); -@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - return 1; - } - -- if (!is_fd_valid(fd)) { -- /* we're doing autolayout so grab the pre-marked (in -- * validate_geometry) raid_disk -- */ -- for (dl = super->disks; dl; dl = dl->next) -+ for (dl = super->disks; dl ; dl = dl->next) { -+ if (autolayout) { - if (dl->raiddisk == dk->raid_disk) - break; -- } else { -- for (dl = super->disks; dl ; dl = dl->next) -- if (dl->major == dk->major && -- dl->minor == dk->minor) -- break; -+ } else if (dl->major == dk->major && dl->minor == dk->minor) -+ break; - } - - if (!dl) { -- pr_err("%s is not a member of the same container\n", devname); -+ if (!autolayout) -+ pr_err("%s is not a member of the same container.\n", -+ devname); - return 1; - } - -+ if (!autolayout && super->current_vol > 0) { -+ int _slot = get_disk_slot_in_dev(super, 0, dl->index); -+ -+ if (_slot != dk->raid_disk) { -+ pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n", -+ dl->devname, _slot, dk->raid_disk); -+ pr_err("Raid members are in different order than for the first volume, aborting.\n"); -+ return 1; -+ } -+ } -+ - if (mpb->num_disks == 0) - if (!get_dev_sector_size(dl->fd, dl->devname, - &super->sector_size)) -diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap -deleted file mode 100644 -index ff5d2093..00000000 ---- a/tests/09imsm-overlap -+++ /dev/null -@@ -1,28 +0,0 @@ -- --. tests/env-imsm-template -- --# create raid arrays with varying degress of overlap --mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5 --imsm_check container 6 -- --size=1024 --level=1 --num_disks=2 --mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size --mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size --mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size --mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size --mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size -- --udevadm settle -- --offset=0 --imsm_check member $member0 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member1 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member2 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member3 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member4 $num_disks $level $size 1024 $offset --- -2.38.1 - diff --git a/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch b/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch deleted file mode 100644 index d593669..0000000 --- a/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Wed, 15 Jun 2022 14:28:39 +0200 -Subject: [PATCH 26/83] mdadm: block update=ppl for non raid456 levels - -Option ppl should be used only for raid levels 4, 5 and 6. Cancel update -for other levels. - -Applied globally for imsm and ddf format. - -Additionally introduce is_level456() helper function. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 11 +++++------ - Grow.c | 2 +- - Manage.c | 14 ++++++++++++-- - mdadm.h | 11 +++++++++++ - super0.c | 2 +- - super1.c | 3 +-- - 6 files changed, 31 insertions(+), 12 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 4b213560..6df6bfbc 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content, - * devices in RAID4 or last devices in RAID4/5/6. - */ - delta = devices[j].i.delta_disks; -- if (devices[j].i.array.level >= 4 && -- devices[j].i.array.level <= 6 && -+ if (is_level456(devices[j].i.array.level) && - i/2 >= content->array.raid_disks - delta) - /* OK */; - else if (devices[j].i.array.level == 4 && -@@ -1226,8 +1225,7 @@ static int start_array(int mdfd, - fprintf(stderr, ".\n"); - } - if (content->reshape_active && -- content->array.level >= 4 && -- content->array.level <= 6) { -+ is_level456(content->array.level)) { - /* might need to increase the size - * of the stripe cache - default is 256 - */ -@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd, - int start_reshape; - char *avail; - int err; -- int is_raid456, is_clean, all_disks; -+ int is_clean, all_disks; -+ bool is_raid456; - - if (sysfs_init(content, mdfd, NULL)) { - pr_err("Unable to initialize sysfs\n"); -@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd, - content->array.state |= 1; - } - -- is_raid456 = (content->array.level >= 4 && content->array.level <= 6); -+ is_raid456 = is_level456(content->array.level); - is_clean = content->array.state & 1; - - if (enough(content->array.level, content->array.raid_disks, -diff --git a/Grow.c b/Grow.c -index f6efbc48..8c520d42 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) - } - - md_get_array_info(fd, &array); -- if (level == 0 && (array.level >= 4 && array.level <= 6)) { -+ if (level == 0 && is_level456(array.level)) { - /* To convert to RAID0 we need to fail and - * remove any non-data devices. */ - int found = 0; -diff --git a/Manage.c b/Manage.c -index f789e0c1..e5e6abe4 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * - unfreeze reshape - * - wait on 'sync_completed' for that point to be reached. - */ -- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) && -+ if (mdi && is_level456(mdi->array.level) && - sysfs_attribute_available(mdi, NULL, "sync_action") && - sysfs_attribute_available(mdi, NULL, "reshape_direction") && - sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 && -@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; -+ struct mdinfo *info = NULL; - - memset(st, 0, sizeof(*st)); - -@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -+ info = st->ss->container_content(st, subarray); -+ -+ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); -+ goto free_super; -+ } -+ - rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { -@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -- free_super: -+free_super: -+ if (info) -+ free(info); - st->ss->free_super(st); - close(fd); - -diff --git a/mdadm.h b/mdadm.h -index d53df169..974415b9 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -796,6 +796,17 @@ static inline int is_fd_valid(int fd) - return (fd > -1); - } - -+/** -+ * is_level456() - check whether given level is between inclusive 4 and 6. -+ * @level: level to check. -+ * -+ * Return: true if condition is met, false otherwise -+ */ -+static inline bool is_level456(int level) -+{ -+ return (level >= 4 && level <= 6); -+} -+ - /** - * close_fd() - verify, close and unset file descriptor. - * @fd: pointer to file descriptor. -diff --git a/super0.c b/super0.c -index 61c9ec1d..37f595ed 100644 ---- a/super0.c -+++ b/super0.c -@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int parity = sb->level == 6 ? 2 : 1; - rv = 0; - -- if (sb->level >= 4 && sb->level <= 6 && -+ if (is_level456(sb->level) && - sb->reshape_position % ( - sb->new_chunk/512 * - (sb->raid_disks - sb->delta_disks - parity))) { -diff --git a/super1.c b/super1.c -index 3a0c69fd..71af860c 100644 ---- a/super1.c -+++ b/super1.c -@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * So we reject a revert-reshape unless the - * alignment is good. - */ -- if (__le32_to_cpu(sb->level) >= 4 && -- __le32_to_cpu(sb->level) <= 6) { -+ if (is_level456(__le32_to_cpu(sb->level))) { - reshape_sectors = - __le64_to_cpu(sb->reshape_position); - reshape_chunk = __le32_to_cpu(sb->new_chunk); --- -2.38.1 - diff --git a/0027-mdadm-Fix-array-size-mismatch-after-grow.patch b/0027-mdadm-Fix-array-size-mismatch-after-grow.patch deleted file mode 100644 index 02bdf9c..0000000 --- a/0027-mdadm-Fix-array-size-mismatch-after-grow.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:47 +0200 -Subject: [PATCH 27/83] mdadm: Fix array size mismatch after grow - -imsm_fix_size_mismatch() is invoked to fix the problem, but it couldn't -proceed due to migration check. This patch allows for intended behavior. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/super-intel.c b/super-intel.c -index 8ffe485c..76b947f5 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11854,7 +11854,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - unsigned long long d_size = imsm_dev_size(dev); - int u_size; - -- if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR) -+ if (calc_size == d_size) - continue; - - /* There is a difference, confirm that imsm_dev_size is --- -2.38.1 - diff --git a/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch b/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch deleted file mode 100644 index 08688dd..0000000 --- a/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:48 +0200 -Subject: [PATCH 28/83] mdadm: Remove dead code in imsm_fix_size_mismatch - -imsm_create_metadata_update_for_size_change() that returns u_size value -could return 0 in the past. As its behavior changed, and returned value -is always the size of imsm_update_size_change structure, check for -u_size is no longer needed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 76b947f5..4ddfcf94 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11869,10 +11869,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - geo.size = d_size; - u_size = imsm_create_metadata_update_for_size_change(st, &geo, - &update); -- if (u_size < 1) { -- dprintf("imsm: Cannot prepare size change update\n"); -- goto exit; -- } - imsm_update_metadata_locally(st, update, u_size); - if (st->update_tail) { - append_metadata_update(st, update, u_size); --- -2.38.1 - diff --git a/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch b/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch deleted file mode 100644 index f337ff0..0000000 --- a/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch +++ /dev/null @@ -1,40 +0,0 @@ -From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:10 +0200 -Subject: [PATCH 29/83] Monitor: use devname as char array instead of pointer - -Device name wasn't filled properly due to incorrect use of strcpy. -Strcpy was used twice. Firstly to fill devname with "/dev/md/" -and then to add chosen name. First strcpy result was overwritten by -second one (as a result instead of "/dev/md/" -was assigned). This commit changes this implementation to use snprintf -and devname with fixed size. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 6ca1ebe5..a5b11ae2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -190,9 +190,11 @@ int Monitor(struct mddev_dev *devlist, - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); - else { -- st->devname = xmalloc(8+strlen(mdlist->devname)+1); -- strcpy(strcpy(st->devname, "/dev/md/"), -- mdlist->devname); -+ /* length of "/dev/md/" + device name + terminating byte */ -+ size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -+ -+ st->devname = xcalloc(_len, sizeof(char)); -+ snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); - } - if (!is_mddev(mdlist->devname)) - return 1; --- -2.38.1 - diff --git a/0030-Monitor-use-snprintf-to-fill-device-name.patch b/0030-Monitor-use-snprintf-to-fill-device-name.patch deleted file mode 100644 index 7d3b4bc..0000000 --- a/0030-Monitor-use-snprintf-to-fill-device-name.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:11 +0200 -Subject: [PATCH 30/83] Monitor: use snprintf to fill device name - -Safe string functions are propagated in Monitor.c. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 37 ++++++++++++++----------------------- - 1 file changed, 14 insertions(+), 23 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index a5b11ae2..93f36ac0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,8 +33,8 @@ - #endif - - struct state { -- char *devname; -- char devnm[32]; /* to sync with mdstat info */ -+ char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -+ char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ - unsigned int utime; - int err; - char *spare_group; -@@ -45,9 +45,9 @@ struct state { - int devstate[MAX_DISKS]; - dev_t devid[MAX_DISKS]; - int percent; -- char parent_devnm[32]; /* For subarray, devnm of parent. -- * For others, "" -- */ -+ char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. -+ * For others, "" -+ */ - struct supertype *metadata; - struct state *subarray;/* for a container it is a link to first subarray - * for a subarray it is a link to next subarray -@@ -187,15 +187,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - - st = xcalloc(1, sizeof *st); -- if (mdlist->devname[0] == '/') -- st->devname = xstrdup(mdlist->devname); -- else { -- /* length of "/dev/md/" + device name + terminating byte */ -- size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -- -- st->devname = xcalloc(_len, sizeof(char)); -- snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); -- } -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -+ "/dev/md/%s", basename(mdlist->devname)); - if (!is_mddev(mdlist->devname)) - return 1; - st->next = statelist; -@@ -218,7 +211,7 @@ int Monitor(struct mddev_dev *devlist, - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -- st->devname = xstrdup(dv->devname); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -301,7 +294,6 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->devname); - free(st->spare_group); - free(st); - } else -@@ -554,7 +546,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - goto disappeared; - - if (st->devnm[0] == 0) -- strcpy(st->devnm, fd2devnm(fd)); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", fd2devnm(fd)); - - for (mse2 = mdstat; mse2; mse2 = mse2->next) - if (strcmp(mse2->devnm, st->devnm) == 0) { -@@ -684,7 +676,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - strncmp(mse->metadata_version, "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, 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; -@@ -772,14 +764,13 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - continue; - } - -- st->devname = xstrdup(name); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); - if ((fd = open(st->devname, O_RDONLY)) < 0 || - md_get_array_info(fd, &array) < 0) { - /* no such array */ - if (fd >= 0) - close(fd); - put_md_name(st->devname); -- free(st->devname); - if (st->metadata) { - st->metadata->ss->free_super(st->metadata); - free(st->metadata); -@@ -791,7 +782,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - st->next = *statelist; - st->err = 1; - st->from_auto = 1; -- strcpy(st->devnm, mse->devnm); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm); - st->percent = RESYNC_UNKNOWN; - st->expected_spares = -1; - if (mse->metadata_version && -@@ -799,8 +790,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, -- mse->metadata_version+10); -+ snprintf(st->parent_devnm, MD_NAME_MAX, -+ "%s", mse->metadata_version + 10); - sl = strchr(st->parent_devnm, '/'); - *sl = 0; - } else --- -2.38.1 - diff --git a/0031-Makefile-Don-t-build-static-build-with-everything-an.patch b/0031-Makefile-Don-t-build-static-build-with-everything-an.patch deleted file mode 100644 index de5e49e..0000000 --- a/0031-Makefile-Don-t-build-static-build-with-everything-an.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:06 -0600 -Subject: [PATCH 31/83] Makefile: Don't build static build with everything and - everything-test - -Running the test suite requires building everything, but it seems to be -difficult to build the static version of mdadm now seeing there -is no readily available static udev library. - -The test suite doesn't need the static binary so just don't build it -with the everything or everything-test targets. - -Leave the mdadm.static and install-static targets in place in case -someone still has a use case for the static binary. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index bf126033..ec1f99ed 100644 ---- a/Makefile -+++ b/Makefile -@@ -182,9 +182,9 @@ check_rundir: - echo "***** or set CHECK_RUN_DIR=0"; exit 1; \ - fi - --everything: all mdadm.static swap_super test_stripe raid6check \ -+everything: all swap_super test_stripe raid6check \ - mdadm.Os mdadm.O2 man --everything-test: all mdadm.static swap_super test_stripe \ -+everything-test: all swap_super test_stripe \ - mdadm.Os mdadm.O2 man - # mdadm.uclibc doesn't work on x86-64 - # mdadm.tcc doesn't work.. --- -2.38.1 - diff --git a/0032-DDF-Cleanup-validate_geometry_ddf_container.patch b/0032-DDF-Cleanup-validate_geometry_ddf_container.patch deleted file mode 100644 index ec2954d..0000000 --- a/0032-DDF-Cleanup-validate_geometry_ddf_container.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:07 -0600 -Subject: [PATCH 32/83] DDF: Cleanup validate_geometry_ddf_container() - -Move the function up so that the function declaration is not necessary -and remove the unused arguments to the function. - -No functional changes are intended but will help with a bug fix in the -next patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 88 ++++++++++++++++++++++++----------------------------- - 1 file changed, 39 insertions(+), 49 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index abbc8b09..9d867f69 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -503,13 +503,6 @@ struct ddf_super { - static int load_super_ddf_all(struct supertype *st, int fd, - void **sbp, char *devname); - static int get_svd_state(const struct ddf_super *, const struct vcl *); --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose); - - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, -@@ -3322,6 +3315,42 @@ static int reserve_space(struct supertype *st, int raiddisks, - return 1; - } - -+static int -+validate_geometry_ddf_container(struct supertype *st, -+ int level, int raiddisks, -+ unsigned long long data_offset, -+ char *dev, unsigned long long *freesize, -+ int verbose) -+{ -+ int fd; -+ unsigned long long ldsize; -+ -+ if (level != LEVEL_CONTAINER) -+ return 0; -+ if (!dev) -+ return 1; -+ -+ fd = dev_open(dev, O_RDONLY|O_EXCL); -+ if (fd < 0) { -+ if (verbose) -+ pr_err("ddf: Cannot open %s: %s\n", -+ dev, strerror(errno)); -+ return 0; -+ } -+ if (!get_dev_size(fd, dev, &ldsize)) { -+ close(fd); -+ return 0; -+ } -+ close(fd); -+ if (freesize) { -+ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -+ if (*freesize == 0) -+ return 0; -+ } -+ -+ return 1; -+} -+ - static int validate_geometry_ddf(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, -@@ -3347,11 +3376,9 @@ static int validate_geometry_ddf(struct supertype *st, - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { - /* Must be a fresh device to add to a container */ -- return validate_geometry_ddf_container(st, level, layout, -- raiddisks, *chunk, -- size, data_offset, dev, -- freesize, -- verbose); -+ return validate_geometry_ddf_container(st, level, raiddisks, -+ data_offset, dev, -+ freesize, verbose); - } - - if (!dev) { -@@ -3449,43 +3476,6 @@ static int validate_geometry_ddf(struct supertype *st, - return 1; - } - --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose) --{ -- int fd; -- unsigned long long ldsize; -- -- if (level != LEVEL_CONTAINER) -- return 0; -- if (!dev) -- return 1; -- -- fd = dev_open(dev, O_RDONLY|O_EXCL); -- if (fd < 0) { -- if (verbose) -- pr_err("ddf: Cannot open %s: %s\n", -- dev, strerror(errno)); -- return 0; -- } -- if (!get_dev_size(fd, dev, &ldsize)) { -- close(fd); -- return 0; -- } -- close(fd); -- if (freesize) { -- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -- if (*freesize == 0) -- return 0; -- } -- -- return 1; --} -- - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, --- -2.38.1 - diff --git a/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch b/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch deleted file mode 100644 index 3a53577..0000000 --- a/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:08 -0600 -Subject: [PATCH 33/83] DDF: Fix NULL pointer dereference in - validate_geometry_ddf() - -A relatively recent patch added a call to validate_geometry() in -Manage_add() that has level=LEVEL_CONTAINER and chunk=NULL. - -This causes some ddf tests to segfault which aborts the test suite. - -To fix this, avoid dereferencing chunk when the level is -LEVEL_CONTAINER or LEVEL_NONE. - -Fixes: 1f5d54a06df0 ("Manage: Call validate_geometry when adding drive to external container") -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d867f69..949e7d15 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3369,9 +3369,6 @@ static int validate_geometry_ddf(struct supertype *st, - * If given BVDs, we make an SVD, changing all the GUIDs in the process. - */ - -- if (*chunk == UnSet) -- *chunk = DEFAULT_CHUNK; -- - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { -@@ -3381,6 +3378,9 @@ static int validate_geometry_ddf(struct supertype *st, - freesize, verbose); - } - -+ if (*chunk == UnSet) -+ *chunk = DEFAULT_CHUNK; -+ - if (!dev) { - mdu_array_info_t array = { - .level = level, --- -2.38.1 - diff --git a/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch b/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch deleted file mode 100644 index 2695f67..0000000 --- a/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:09 -0600 -Subject: [PATCH 34/83] mdadm/Grow: Fix use after close bug by closing after - fork - -The test 07reshape-grow fails most of the time. But it succeeds around -1 in 5 times. When it does succeed, it causes the tests to die because -mdadm has segfaulted. - -The segfault was caused by mdadm attempting to repoen a file -descriptor that was already closed. The backtrace of the segfault -was: - - #0 __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:101 - #1 0x000056146e31d44b in devnm2devid (devnm=0x0) at util.c:956 - #2 0x000056146e31dab4 in open_dev_flags (devnm=0x0, flags=0) - at util.c:1072 - #3 0x000056146e31db22 in open_dev (devnm=0x0) at util.c:1079 - #4 0x000056146e3202e8 in reopen_mddev (mdfd=4) at util.c:2244 - #5 0x000056146e329f36 in start_array (mdfd=4, - mddev=0x7ffc55342450 "/dev/md0", content=0x7ffc55342860, - st=0x56146fc78660, ident=0x7ffc55342f70, best=0x56146fc6f5d0, - bestcnt=10, chosen_drive=0, devices=0x56146fc706b0, okcnt=5, - sparecnt=0, rebuilding_cnt=0, journalcnt=0, c=0x7ffc55342e90, - clean=1, avail=0x56146fc78720 "\001\001\001\001\001", - start_partial_ok=0, err_ok=0, was_forced=0) - at Assemble.c:1206 - #6 0x000056146e32c36e in Assemble (st=0x56146fc78660, - mddev=0x7ffc55342450 "/dev/md0", ident=0x7ffc55342f70, - devlist=0x56146fc6e2d0, c=0x7ffc55342e90) - at Assemble.c:1914 - #7 0x000056146e312ac9 in main (argc=11, argv=0x7ffc55343238) - at mdadm.c:1510 - -The file descriptor was closed early in Grow_continue(). The noted commit -moved the close() call to close the fd above the fork which caused the -parent process to return with a closed fd. - -This meant reshape_array() and Grow_continue() would return in the parent -with the fd forked. The fd would eventually be passed to reopen_mddev() -which returned an unhandled NULL from fd2devnm() which would then be -dereferenced in devnm2devid. - -Fix this by moving the close() call below the fork. This appears to -fix the 07revert-grow test. While we're at it, switch to using -close_fd() to invalidate the file descriptor. - -Fixes: 77b72fa82813 ("mdadm/Grow: prevent md's fd from being occupied during delayed time") -Cc: Alex Wu -Cc: BingJing Chang -Cc: Danny Shih -Cc: ChangSyun Peng -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8c520d42..97f22c75 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3514,7 +3514,6 @@ started: - return 0; - } - -- close(fd); - /* Now we just need to kick off the reshape and watch, while - * handling backups of the data... - * This is all done by a forked background process. -@@ -3535,6 +3534,9 @@ started: - break; - } - -+ /* Close unused file descriptor in the forked process */ -+ close_fd(&fd); -+ - /* If another array on the same devices is busy, the - * reshape will wait for them. This would mean that - * the first section that we suspend will stay suspended --- -2.38.1 - diff --git a/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch b/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch deleted file mode 100644 index ed09288..0000000 --- a/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:10 -0600 -Subject: [PATCH 35/83] monitor: Avoid segfault when calling NULL - get_bad_blocks - -Not all struct superswitch implement a get_bad_blocks() function, -yet mdmon seems to call it without checking for NULL and thus -occasionally segfaults in the test 10ddf-geometry. - -Fix this by checking for NULL before calling it. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - monitor.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/monitor.c b/monitor.c -index b877e595..820a93d0 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -311,6 +311,9 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi) - struct md_bb *bb; - int i; - -+ if (!ss->get_bad_blocks) -+ return -1; -+ - /* - * Get a list of bad blocks for an array, then read list of - * acknowledged bad blocks from kernel and compare it against metadata --- -2.38.1 - diff --git a/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch b/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch deleted file mode 100644 index f091c64..0000000 --- a/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:11 -0600 -Subject: [PATCH 36/83] mdadm: Fix mdadm -r remove option regression - -The commit noted below globally adds a parameter to the -r option but missed -the fact that -r is used for another purpose: --remove. - -After that commit, a command such as: - - mdadm /dev/md0 -r /dev/loop0 - -will do nothing seeing the device parameter will be consumed as a -argument to the -r option; thus, there will only be one device -seen one the command line, devs_found will only be 1 and nothing will -happen. - -This caused the 01r5integ and 01raid6integ tests to hang indefinitely -as mdadm did not remove the failed device. With the device not removed, -it would not be readded. Then the loop waiting for the array status to -change would loop forever. - -This commit was recently reverted, but the legitimate fix for the -monitor operations was still not fixed. So add specific monitor -short ops to re-fix the --monitor -r option. - -Fixes: 546047688e1c ("mdadm: fix coredump of mdadm --monitor -r") -Fixes: 190dc029b141 ("Revert "mdadm: fix coredump of mdadm --monitor -r"") -Cc: Wu Guanghao -Cc: Mariusz Tkaczyk -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 + - mdadm.c | 1 + - mdadm.h | 1 + - 3 files changed, 3 insertions(+) - -diff --git a/ReadMe.c b/ReadMe.c -index bec1be9a..7518a32a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -82,6 +82,7 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - */ - - char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+char short_monitor_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k:"; - char short_bitmap_options[]= - "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -diff --git a/mdadm.c b/mdadm.c -index be40686c..d0c5e6de 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -227,6 +227,7 @@ int main(int argc, char *argv[]) - shortopt = short_bitmap_auto_options; - break; - case 'F': newmode = MONITOR; -+ shortopt = short_monitor_options; - break; - case 'G': newmode = GROW; - shortopt = short_bitmap_options; -diff --git a/mdadm.h b/mdadm.h -index 974415b9..163f4a49 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -419,6 +419,7 @@ enum mode { - }; - - extern char short_options[]; -+extern char short_monitor_options[]; - extern char short_bitmap_options[]; - extern char short_bitmap_auto_options[]; - extern struct option long_options[]; --- -2.38.1 - diff --git a/0037-mdadm-Fix-optional-write-behind-parameter.patch b/0037-mdadm-Fix-optional-write-behind-parameter.patch deleted file mode 100644 index 60cafdb..0000000 --- a/0037-mdadm-Fix-optional-write-behind-parameter.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:12 -0600 -Subject: [PATCH 37/83] mdadm: Fix optional --write-behind parameter - -The commit noted below changed the behaviour of --write-behind to -require an argument. This broke the 06wrmostly test with the error: - - mdadm: Invalid value for maximum outstanding write-behind writes: (null). - Must be between 0 and 16383. - -To fix this, check if optarg is NULL before parising it, as the origial -code did. - -Fixes: 60815698c0ac ("Refactor parse_num and use it to parse optarg.") -Cc: Mateusz Grzonka -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdadm.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/mdadm.c b/mdadm.c -index d0c5e6de..56722ed9 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1201,8 +1201,9 @@ int main(int argc, char *argv[]) - case O(BUILD, WriteBehind): - case O(CREATE, WriteBehind): - s.write_behind = DEFAULT_MAX_WRITE_BEHIND; -- if (parse_num(&s.write_behind, optarg) != 0 || -- s.write_behind < 0 || s.write_behind > 16383) { -+ if (optarg && -+ (parse_num(&s.write_behind, optarg) != 0 || -+ s.write_behind < 0 || s.write_behind > 16383)) { - pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", - optarg); - exit(2); --- -2.38.1 - diff --git a/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch b/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch deleted file mode 100644 index 7794e18..0000000 --- a/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7539254342bc591717b0051734cc6c09c1b88640 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:13 -0600 -Subject: [PATCH 38/83] tests/00raid0: add a test that validates raid0 with - layout fails for 0.9 - -329dfc28debb disallows the creation of raid0 with layouts for 0.9 -metadata. This test confirms the new behavior. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index 8bc18985..e6b21cc4 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -6,11 +6,9 @@ check raid0 - testdev $md0 3 $mdsize2_l 512 - mdadm -S $md0 - --# now with version-0.90 superblock -+# verify raid0 with layouts fail for 0.90 - mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 --check raid0 --testdev $md0 4 $mdsize0 512 --mdadm -S $md0 -+check opposite_result - - # now with no superblock - mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --- -2.38.1 - diff --git a/0039-tests-fix-raid0-tests-for-0.90-metadata.patch b/0039-tests-fix-raid0-tests-for-0.90-metadata.patch deleted file mode 100644 index d897fb1..0000000 --- a/0039-tests-fix-raid0-tests-for-0.90-metadata.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 14c2161edb77d7294199e8aa7daa9f9d1d0ad5d7 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:14 -0600 -Subject: [PATCH 39/83] tests: fix raid0 tests for 0.90 metadata - -Some of the test cases fail because raid0 creation fails with the error, -"0.90 metadata does not support layouts for RAID0" added by commit, -329dfc28debb. Fix some of the test cases by switching from raid0 to -linear level for 0.9 metadata where possible. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 4 ++-- - tests/00readonly | 4 ++++ - tests/03r0assem | 6 +++--- - tests/04r0update | 4 ++-- - tests/04update-metadata | 2 +- - 5 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index e6b21cc4..9b8896cb 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -20,8 +20,8 @@ mdadm -S $md0 - # now same again with different chunk size - for chunk in 4 32 256 - do -- mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 -- check raid0 -+ mdadm -CR $md0 -e0.90 -l linear --chunk $chunk -n3 $dev0 $dev1 $dev2 -+ check linear - testdev $md0 3 $mdsize0 $chunk - mdadm -S $md0 - -diff --git a/tests/00readonly b/tests/00readonly -index 28b0fa13..39202487 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -4,6 +4,10 @@ for metadata in 0.9 1.0 1.1 1.2 - do - for level in linear raid0 raid1 raid4 raid5 raid6 raid10 - do -+ if [[ $metadata == "0.9" && $level == "raid0" ]]; -+ then -+ continue -+ fi - mdadm -CR $md0 -l $level -n 4 --metadata=$metadata \ - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync -diff --git a/tests/03r0assem b/tests/03r0assem -index 6744e322..44df0645 100644 ---- a/tests/03r0assem -+++ b/tests/03r0assem -@@ -68,9 +68,9 @@ mdadm -S $md2 - ### Now for version 0... - - mdadm --zero-superblock $dev0 $dev1 $dev2 --mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 --check raid0 --tst="testdev $md2 3 $mdsize0 512" -+mdadm -CR $md2 -llinear --metadata=0.90 -n3 $dev0 $dev1 $dev2 -+check linear -+tst="testdev $md2 3 $mdsize0 1" - $tst - - uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` -diff --git a/tests/04r0update b/tests/04r0update -index 73ee3b9f..b95efb06 100644 ---- a/tests/04r0update -+++ b/tests/04r0update -@@ -1,7 +1,7 @@ - - # create a raid0, re-assemble with a different super-minor --mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 --testdev $md0 3 $mdsize0 512 -+mdadm -CR -e 0.90 $md0 -llinear -n3 $dev0 $dev1 $dev2 -+testdev $md0 3 $mdsize0 1 - minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` - mdadm -S /dev/md0 - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 232fc1ff..08c14af7 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -8,7 +8,7 @@ set -xe - - dlist="$dev0 $dev1 $dev2 $dev3" - --for ls in raid0/4 linear/4 raid1/1 raid5/3 raid6/2 -+for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} - mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist --- -2.38.1 - diff --git a/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch b/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch deleted file mode 100644 index 12b291b..0000000 --- a/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From de045db607b1ac4b70fc2a8878463e029c2ab1dc Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:15 -0600 -Subject: [PATCH 40/83] tests/04update-metadata: avoid passing chunk size to - raid1 - -'04update-metadata' test fails with error, "specifying chunk size is -forbidden for this level" added by commit, 5b30a34aa4b5e. Hence, -correcting the test to ignore passing chunk size to raid1. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -[logang@deltatee.com: fix if/then style and dropped unrelated hunk] -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/04update-metadata | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 08c14af7..2b72a303 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -11,7 +11,11 @@ dlist="$dev0 $dev1 $dev2 $dev3" - for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} -- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist -+ 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 --- -2.38.1 - diff --git a/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch b/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch deleted file mode 100644 index e6b9bba..0000000 --- a/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a2c832465fc75202e244327b2081231dfa974617 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:16 -0600 -Subject: [PATCH 41/83] tests/02lineargrow: clear the superblock at every - iteration - -This fixes 02lineargrow test as prior metadata causes --add operation -to misbehave. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/02lineargrow | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/tests/02lineargrow b/tests/02lineargrow -index e05c219d..595bf9f2 100644 ---- a/tests/02lineargrow -+++ b/tests/02lineargrow -@@ -20,4 +20,6 @@ do - testdev $md0 3 $sz 1 - - mdadm -S $md0 -+ mdadm --zero /dev/loop2 -+ mdadm --zero /dev/loop3 - done --- -2.38.1 - diff --git a/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch b/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch deleted file mode 100644 index 63f72dc..0000000 --- a/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch +++ /dev/null @@ -1,88 +0,0 @@ -From a7bfcc716e235664dfb3b6c5a9590273e611ac72 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:17 -0600 -Subject: [PATCH 42/83] mdadm/test: Add a mode to repeat specified tests - -Many tests fail infrequently or rarely. To help find these, add -an option to run the tests multiple times by specifying --loop=N. - -If --loop=0 is specified, the test will be looped forever. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 36 ++++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 12 deletions(-) - -diff --git a/test b/test -index 711a3c7a..da6db5e0 100755 ---- a/test -+++ b/test -@@ -10,6 +10,7 @@ devlist= - - savelogs=0 - exitonerror=1 -+loop=1 - prefix='[0-9][0-9]' - - # use loop devices by default if doesn't specify --dev -@@ -117,6 +118,7 @@ do_help() { - --logdir=directory Directory to save all logfiles in - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests -+ --loop=N Run tests N times (0 to run forever) - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -211,6 +213,9 @@ parse_args() { - --keep-going | --no-error ) - exitonerror=0 - ;; -+ --loop=* ) -+ loop="${i##*=}" -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -263,19 +268,26 @@ main() { - echo "Testing on linux-$(uname -r) kernel" - [ "$savelogs" == "1" ] && - echo "Saving logs to $logdir" -- if [ "x$TESTLIST" != "x" ] -- then -- for script in ${TESTLIST[@]} -- do -- do_test $testdir/$script -- done -- else -- for script in $testdir/$prefix $testdir/$prefix*[^~] -- do -- do_test $script -- done -- fi - -+ while true; do -+ if [ "x$TESTLIST" != "x" ] -+ then -+ for script in ${TESTLIST[@]} -+ do -+ do_test $testdir/$script -+ done -+ else -+ for script in $testdir/$prefix $testdir/$prefix*[^~] -+ do -+ do_test $script -+ done -+ fi -+ -+ let loop=$loop-1 -+ if [ "$loop" == "0" ]; then -+ break -+ fi -+ done - exit 0 - } - --- -2.38.1 - diff --git a/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch b/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch deleted file mode 100644 index 52fd3e9..0000000 --- a/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 28520bf114b3b0515a48ff44fff4ecbe9ed6dfad Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:18 -0600 -Subject: [PATCH 43/83] mdadm/test: Mark and ignore broken test failures - -Add functionality to continue if a test marked as broken fails. - -To mark a test as broken, a file with the same name but with the suffix -'.broken' should exist. The first line in the file will be printed with -a KNOWN BROKEN message; the rest of the file can describe the how the -test is broken. - -Also adds --skip-broken and --skip-always-broken to skip all the tests -that have a .broken file or to skip all tests whose .broken file's first -line contains the keyword always. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 37 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/test b/test -index da6db5e0..61d9ee83 100755 ---- a/test -+++ b/test -@@ -10,6 +10,8 @@ devlist= - - savelogs=0 - exitonerror=1 -+ctrl_c_error=0 -+skipbroken=0 - loop=1 - prefix='[0-9][0-9]' - -@@ -36,6 +38,7 @@ die() { - - ctrl_c() { - exitonerror=1 -+ ctrl_c_error=1 - } - - # mdadm always adds --quiet, and we want to see any unexpected messages -@@ -80,8 +83,21 @@ mdadm() { - do_test() { - _script=$1 - _basename=`basename $_script` -+ _broken=0 -+ - if [ -f "$_script" ] - then -+ if [ -f "${_script}.broken" ]; then -+ _broken=1 -+ _broken_msg=$(head -n1 "${_script}.broken" | tr -d '\n') -+ if [ "$skipbroken" == "all" ]; then -+ return -+ elif [ "$skipbroken" == "always" ] && -+ [[ "$_broken_msg" == *always* ]]; then -+ return -+ fi -+ fi -+ - rm -f $targetdir/stderr - # this might have been reset: restore the default. - echo 2000 > /proc/sys/dev/raid/speed_limit_max -@@ -98,10 +114,15 @@ do_test() { - else - save_log fail - _fail=1 -+ if [ "$_broken" == "1" ]; then -+ echo " (KNOWN BROKEN TEST: $_broken_msg)" -+ fi - fi - [ "$savelogs" == "1" ] && - mv -f $targetdir/log $logdir/$_basename.log -- [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1 -+ [ "$ctrl_c_error" == "1" ] && exit 1 -+ [ "$_fail" == "1" -a "$exitonerror" == "1" \ -+ -a "$_broken" == "0" ] && exit 1 - fi - } - -@@ -119,6 +140,8 @@ do_help() { - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests - --loop=N Run tests N times (0 to run forever) -+ --skip-broken Skip tests that are known to be broken -+ --skip-always-broken Skip tests that are known to always fail - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -216,6 +239,12 @@ parse_args() { - --loop=* ) - loop="${i##*=}" - ;; -+ --skip-broken ) -+ skipbroken=all -+ ;; -+ --skip-always-broken ) -+ skipbroken=always -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -279,7 +308,11 @@ main() { - else - for script in $testdir/$prefix $testdir/$prefix*[^~] - do -- do_test $script -+ case $script in -+ *.broken) ;; -+ *) -+ do_test $script -+ esac - done - fi - --- -2.38.1 - diff --git a/0044-tests-Add-broken-files-for-all-broken-tests.patch b/0044-tests-Add-broken-files-for-all-broken-tests.patch deleted file mode 100644 index 2484e1b..0000000 --- a/0044-tests-Add-broken-files-for-all-broken-tests.patch +++ /dev/null @@ -1,447 +0,0 @@ -From daa86d6634761796ada1f535c13e47fdd3cc95eb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:19 -0600 -Subject: [PATCH 44/83] tests: Add broken files for all broken tests - -Each broken file contains the rough frequency of brokeness as well -as a brief explanation of what happens when it breaks. Estimates -of failure rates are not statistically significant and can vary -run to run. - -This is really just a view from my window. Tests were done on a -small VM with the default loop devices, not real hardware. We've -seen different kernel configurations can cause bugs to appear as well -(ie. different block schedulers). It may also be that different race -conditions will be seen on machines with different performance -characteristics. - -These annotations were done with the kernel currently in md/md-next: - - facef3b96c5b ("md: Notify sysfs sync_completed in md_reap_sync_thread()") - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/01r5integ.broken | 7 ++++ - tests/01raid6integ.broken | 7 ++++ - tests/04r5swap.broken | 7 ++++ - tests/07autoassemble.broken | 8 ++++ - tests/07autodetect.broken | 5 +++ - tests/07changelevelintr.broken | 9 +++++ - tests/07changelevels.broken | 9 +++++ - tests/07reshape5intr.broken | 45 ++++++++++++++++++++++ - tests/07revert-grow.broken | 31 +++++++++++++++ - tests/07revert-shrink.broken | 9 +++++ - tests/07testreshape5.broken | 12 ++++++ - tests/09imsm-assemble.broken | 6 +++ - tests/09imsm-create-fail-rebuild.broken | 5 +++ - tests/09imsm-overlap.broken | 7 ++++ - tests/10ddf-assemble-missing.broken | 6 +++ - tests/10ddf-fail-create-race.broken | 7 ++++ - tests/10ddf-fail-two-spares.broken | 5 +++ - tests/10ddf-incremental-wrong-order.broken | 9 +++++ - tests/14imsm-r1_2d-grow-r1_3d.broken | 5 +++ - tests/14imsm-r1_2d-takeover-r0_2d.broken | 6 +++ - tests/18imsm-r10_4d-takeover-r0_2d.broken | 5 +++ - tests/18imsm-r1_2d-takeover-r0_1d.broken | 6 +++ - tests/19raid6auto-repair.broken | 5 +++ - tests/19raid6repair.broken | 5 +++ - 24 files changed, 226 insertions(+) - create mode 100644 tests/01r5integ.broken - create mode 100644 tests/01raid6integ.broken - create mode 100644 tests/04r5swap.broken - create mode 100644 tests/07autoassemble.broken - create mode 100644 tests/07autodetect.broken - create mode 100644 tests/07changelevelintr.broken - create mode 100644 tests/07changelevels.broken - create mode 100644 tests/07reshape5intr.broken - create mode 100644 tests/07revert-grow.broken - create mode 100644 tests/07revert-shrink.broken - create mode 100644 tests/07testreshape5.broken - create mode 100644 tests/09imsm-assemble.broken - create mode 100644 tests/09imsm-create-fail-rebuild.broken - create mode 100644 tests/09imsm-overlap.broken - create mode 100644 tests/10ddf-assemble-missing.broken - create mode 100644 tests/10ddf-fail-create-race.broken - create mode 100644 tests/10ddf-fail-two-spares.broken - create mode 100644 tests/10ddf-incremental-wrong-order.broken - create mode 100644 tests/14imsm-r1_2d-grow-r1_3d.broken - create mode 100644 tests/14imsm-r1_2d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r10_4d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r1_2d-takeover-r0_1d.broken - create mode 100644 tests/19raid6auto-repair.broken - create mode 100644 tests/19raid6repair.broken - -diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken -new file mode 100644 -index 00000000..20737637 ---- /dev/null -+++ b/tests/01r5integ.broken -@@ -0,0 +1,7 @@ -+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 -diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken -new file mode 100644 -index 00000000..1df735f0 ---- /dev/null -+++ b/tests/01raid6integ.broken -@@ -0,0 +1,7 @@ -+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 -diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken -new file mode 100644 -index 00000000..e38987db ---- /dev/null -+++ b/tests/04r5swap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 has no superblock - assembly aborted -+ -+ ERROR: no recovery happening -diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken -new file mode 100644 -index 00000000..8be09407 ---- /dev/null -+++ b/tests/07autoassemble.broken -@@ -0,0 +1,8 @@ -+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 -diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken -new file mode 100644 -index 00000000..294954a1 ---- /dev/null -+++ b/tests/07autodetect.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ ERROR: no resync happening -diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken -new file mode 100644 -index 00000000..284b4906 ---- /dev/null -+++ b/tests/07changelevelintr.broken -@@ -0,0 +1,9 @@ -+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 -diff --git a/tests/07changelevels.broken b/tests/07changelevels.broken -new file mode 100644 -index 00000000..9b930d93 ---- /dev/null -+++ b/tests/07changelevels.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop1 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop2 is smaller than given size. 18976K < 19968K + metadata -+ -+ ERROR: /dev/md0 isn't a block device. -diff --git a/tests/07reshape5intr.broken b/tests/07reshape5intr.broken -new file mode 100644 -index 00000000..efe52a66 ---- /dev/null -+++ b/tests/07reshape5intr.broken -@@ -0,0 +1,45 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex -+held") -+ -+The new error is simply: -+ -+ ERROR: no reshape happening -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails infrequently -+ -+Fails roughly 1 in 4 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: cannot re-read metadata from /dev/loop6 - aborting -+ -+ ERROR: no reshape happening -+ -+Also have seen a random deadlock: -+ -+ INFO: task mdadm:109702 blocked for more than 30 seconds. -+ Not tainted 5.18.0-rc3-eid-vmlocalyes-dbg-00095-g3c2b5427979d #2040 -+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. -+ task:mdadm state:D stack: 0 pid:109702 ppid: 1 flags:0x00004000 -+ Call Trace: -+ -+ __schedule+0x67e/0x13b0 -+ schedule+0x82/0x110 -+ mddev_suspend+0x2e1/0x330 -+ suspend_lo_store+0xbd/0x140 -+ md_attr_store+0xcb/0x130 -+ sysfs_kf_write+0x89/0xb0 -+ kernfs_fop_write_iter+0x202/0x2c0 -+ new_sync_write+0x222/0x330 -+ vfs_write+0x3bc/0x4d0 -+ ksys_write+0xd9/0x180 -+ __x64_sys_write+0x43/0x50 -+ do_syscall_64+0x3b/0x90 -+ entry_SYSCALL_64_after_hwframe+0x44/0xae -diff --git a/tests/07revert-grow.broken b/tests/07revert-grow.broken -new file mode 100644 -index 00000000..9b6db86f ---- /dev/null -+++ b/tests/07revert-grow.broken -@@ -0,0 +1,31 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex held") -+ -+The errors are: -+ -+ mdadm: No active reshape to revert on /dev/loop0 -+ ERROR: active raid5 not found -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails rarely -+ -+Fails about 1 in every 30 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: backup file /tmp/md-backup inaccessible: No such file or directory -+ mdadm: failed to add /dev/loop1 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop2 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop3 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop0 to /dev/md/0: Invalid argument -+ mdadm: /dev/md/0 assembled from 1 drive - need all 5 to start it -+ (use --run to insist). -+ -+ grep: /sys/block/md*/md/sync_action: No such file or directory -+ -+ ERROR: active raid5 not found -diff --git a/tests/07revert-shrink.broken b/tests/07revert-shrink.broken -new file mode 100644 -index 00000000..c33c39ec ---- /dev/null -+++ b/tests/07revert-shrink.broken -@@ -0,0 +1,9 @@ -+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 53760 -+ -+ ERROR: active raid5 not found -diff --git a/tests/07testreshape5.broken b/tests/07testreshape5.broken -new file mode 100644 -index 00000000..a8ce03e4 ---- /dev/null -+++ b/tests/07testreshape5.broken -@@ -0,0 +1,12 @@ -+always fails -+ -+Test seems to run 'test_stripe' at $dir directory, but $dir is never -+set. If $dir is adjusted to $PWD, the test still fails with: -+ -+ mdadm: /dev/loop2 is not suitable for this array. -+ mdadm: create aborted -+ ++ return 1 -+ ++ cmp -s -n 8192 /dev/md0 /tmp/RandFile -+ ++ echo cmp failed -+ cmp failed -+ ++ exit 2 -diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken -new file mode 100644 -index 00000000..a6d4d5cf ---- /dev/null -+++ b/tests/09imsm-assemble.broken -@@ -0,0 +1,6 @@ -+fails infrequently -+ -+Fails roughly 1 in 10 runs with errors: -+ -+ mdadm: /dev/loop2 is still in use, cannot remove. -+ /dev/loop2 removal from /dev/md/container should have succeeded -diff --git a/tests/09imsm-create-fail-rebuild.broken b/tests/09imsm-create-fail-rebuild.broken -new file mode 100644 -index 00000000..40c4b294 ---- /dev/null -+++ b/tests/09imsm-create-fail-rebuild.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ **Error**: Array size mismatch - expected 3072, actual 16384 -diff --git a/tests/09imsm-overlap.broken b/tests/09imsm-overlap.broken -new file mode 100644 -index 00000000..e7ccab76 ---- /dev/null -+++ b/tests/09imsm-overlap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ /dev/md/vol3 failed check -diff --git a/tests/10ddf-assemble-missing.broken b/tests/10ddf-assemble-missing.broken -new file mode 100644 -index 00000000..bfd8d103 ---- /dev/null -+++ b/tests/10ddf-assemble-missing.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with errors: -+ -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -diff --git a/tests/10ddf-fail-create-race.broken b/tests/10ddf-fail-create-race.broken -new file mode 100644 -index 00000000..6c0df023 ---- /dev/null -+++ b/tests/10ddf-fail-create-race.broken -@@ -0,0 +1,7 @@ -+usually fails -+ -+Fails about 9 out of 10 times with many errors: -+ -+ mdadm: cannot open MISSING: No such file or directory -+ ERROR: non-degraded array found -+ ERROR: disk 0 not marked as failed in meta data -diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken -new file mode 100644 -index 00000000..eeea56d9 ---- /dev/null -+++ b/tests/10ddf-fail-two-spares.broken -@@ -0,0 +1,5 @@ -+fails infrequently -+ -+Fails roughly 1 in 3 with error: -+ -+ ERROR: /dev/md/vol1 should be optimal in meta data -diff --git a/tests/10ddf-incremental-wrong-order.broken b/tests/10ddf-incremental-wrong-order.broken -new file mode 100644 -index 00000000..a5af3bab ---- /dev/null -+++ b/tests/10ddf-incremental-wrong-order.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ ERROR: sha1sum of /dev/md/vol0 has changed -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop8 -+ ERROR: unexpected number of online disks on /dev/loop8 -+ ERROR: sha1sum of /dev/md/vol0 has changed -diff --git a/tests/14imsm-r1_2d-grow-r1_3d.broken b/tests/14imsm-r1_2d-grow-r1_3d.broken -new file mode 100644 -index 00000000..4ef1d406 ---- /dev/null -+++ b/tests/14imsm-r1_2d-grow-r1_3d.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ mdadm/tests/func.sh: line 325: dvsize/chunk: division by 0 (error token is "chunk") -diff --git a/tests/14imsm-r1_2d-takeover-r0_2d.broken b/tests/14imsm-r1_2d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..89cd4e57 ---- /dev/null -+++ b/tests/14imsm-r1_2d-takeover-r0_2d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/18imsm-r10_4d-takeover-r0_2d.broken b/tests/18imsm-r10_4d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..a27399f5 ---- /dev/null -+++ b/tests/18imsm-r10_4d-takeover-r0_2d.broken -@@ -0,0 +1,5 @@ -+fails rarely -+ -+Fails about 1 run in 100 with message: -+ -+ ERROR: size is wrong for /dev/md/vol0: 2 * 5120 (chunk=128) = 20480, not 0 -diff --git a/tests/18imsm-r1_2d-takeover-r0_1d.broken b/tests/18imsm-r1_2d-takeover-r0_1d.broken -new file mode 100644 -index 00000000..aa1982e6 ---- /dev/null -+++ b/tests/18imsm-r1_2d-takeover-r0_1d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/19raid6auto-repair.broken b/tests/19raid6auto-repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6auto-repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" -diff --git a/tests/19raid6repair.broken b/tests/19raid6repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" --- -2.38.1 - diff --git a/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch b/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch deleted file mode 100644 index 74bf834..0000000 --- a/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +++ /dev/null @@ -1,316 +0,0 @@ -From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:36:02 +0200 -Subject: [PATCH 45/83] mdadm: Replace obsolete usleep with nanosleep - -According to POSIX.1-2001, usleep is considered obsolete. -Replace it with a wrapper that uses nanosleep, as recommended in man. -Add handy macros for conversions between msec, usec and nsec. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 2 +- - Grow.c | 4 ++-- - Manage.c | 10 +++++----- - managemon.c | 8 ++++---- - mdadm.h | 4 ++++ - mdmon.c | 4 ++-- - super-intel.c | 6 +++--- - util.c | 42 +++++++++++++++++++++++++++++++++--------- - 8 files changed, 54 insertions(+), 26 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 6df6bfbc..be2160b4 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1947,7 +1947,7 @@ out: - break; - close(mdfd); - } -- usleep(usecs); -+ sleep_for(0, USEC_TO_NSEC(usecs), true); - usecs <<= 1; - } - } -diff --git a/Grow.c b/Grow.c -index 97f22c75..5780635a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -954,7 +954,7 @@ int start_reshape(struct mdinfo *sra, int already_running, - err = sysfs_set_str(sra, NULL, "sync_action", - "reshape"); - if (err) -- sleep(1); -+ sleep_for(1, 0, true); - } while (err && errno == EBUSY && cnt-- > 0); - } - return err; -@@ -5058,7 +5058,7 @@ int Grow_continue_command(char *devname, int fd, - } - st->ss->getinfo_super(st, content, NULL); - if (!content->reshape_active) -- sleep(3); -+ sleep_for(3, 0, true); - else - break; - } while (cnt-- > 0); -diff --git a/Manage.c b/Manage.c -index e5e6abe4..a142f8bd 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -244,7 +244,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - "array_state", - "inactive")) < 0 && - errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count--; - } - if (err) { -@@ -328,7 +328,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) { - /* must be in the critical section - wait a bit */ - delay -= 1; -- usleep(100000); -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } - - if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0) -@@ -405,7 +405,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * quite started yet. Wait a bit and - * check 'sync_action' to see. - */ -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf)); - if (strncmp(buf, "reshape", 7) != 0) - break; -@@ -447,7 +447,7 @@ done: - count = 25; err = 0; - while (count && fd >= 0 && - (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count --; - } - if (fd >= 0 && err) { -@@ -1105,7 +1105,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, - ret = sysfs_unique_holder(devnm, rdev); - if (ret < 2) - break; -- usleep(100 * 1000); /* 100ms */ -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } while (--count > 0); - - if (ret == 0) { -diff --git a/managemon.c b/managemon.c -index 0e9bdf00..a7bfa8f6 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -207,7 +207,7 @@ static void replace_array(struct supertype *container, - remove_old(); - while (pending_discard) { - while (discard_this == NULL) -- sleep(1); -+ sleep_for(1, 0, true); - remove_old(); - } - pending_discard = old; -@@ -568,7 +568,7 @@ static void manage_member(struct mdstat_ent *mdstat, - updates = NULL; - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - replace_array(container, a, newa); - if (sysfs_set_str(&a->info, NULL, -@@ -822,7 +822,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - if (msg->len <= 0) - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - - if (msg->len == 0) { /* ping_monitor */ -@@ -836,7 +836,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - wakeup_monitor(); - - while (monitor_loop_cnt - cnt < 0) -- usleep(10 * 1000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - } else if (msg->len == -1) { /* ping_manager */ - struct mdstat_ent *mdstat = mdstat_read(1, 0); - -diff --git a/mdadm.h b/mdadm.h -index 163f4a49..add9c0b6 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1720,6 +1720,10 @@ extern int cluster_get_dlmlock(void); - extern int cluster_release_dlmlock(void); - extern void set_dlm_hooks(void); - -+#define MSEC_TO_NSEC(msec) ((msec) * 1000000) -+#define USEC_TO_NSEC(usec) ((usec) * 1000) -+extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+ - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) - #define ROUND_UP_PTR(ptr, base) ((typeof(ptr)) \ -diff --git a/mdmon.c b/mdmon.c -index c057da63..e9d035eb 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -99,7 +99,7 @@ static int clone_monitor(struct supertype *container) - if (rc) - return rc; - while (mon_tid == -1) -- usleep(10); -+ sleep_for(0, USEC_TO_NSEC(10), true); - pthread_attr_destroy(&attr); - - mgr_tid = syscall(SYS_gettid); -@@ -209,7 +209,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) - rv = kill(pid, SIGUSR1); - if (rv < 0) - break; -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - } - } - -diff --git a/super-intel.c b/super-intel.c -index 4ddfcf94..4d82af3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5275,7 +5275,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d - /* retry the load if we might have raced against mdmon */ - if (err == 3 && devnm && mdmon_running(devnm)) - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - err = load_and_parse_mpb(dfd, s, NULL, keep_fd); - if (err != 3) - break; -@@ -5377,7 +5377,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) - - if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) { - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - rv = load_and_parse_mpb(fd, super, devname, 0); - if (rv != 3) - break; -@@ -12084,7 +12084,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) - close(fd); - return 1; - } -- usleep(30000); -+ sleep_for(0, MSEC_TO_NSEC(30), true); - } else - break; - } while (retry--); -diff --git a/util.c b/util.c -index 38f0420e..ca48d976 100644 ---- a/util.c -+++ b/util.c -@@ -166,7 +166,7 @@ retry: - pr_err("error %d when get PW mode on lock %s\n", errno, str); - /* let's try several times if EAGAIN happened */ - if (dlm_lock_res->lksb.sb_status == EAGAIN && retry_count < 10) { -- sleep(10); -+ sleep_for(10, 0, true); - retry_count++; - goto retry; - } -@@ -1085,7 +1085,7 @@ int open_dev_excl(char *devnm) - int i; - int flags = O_RDWR; - dev_t devid = devnm2devid(devnm); -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - sprintf(buf, "%d:%d", major(devid), minor(devid)); - for (i = 0; i < 25; i++) { -@@ -1098,8 +1098,8 @@ int open_dev_excl(char *devnm) - } - if (errno != EBUSY) - return fd; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - return -1; -@@ -1123,7 +1123,7 @@ void wait_for(char *dev, int fd) - { - int i; - struct stat stb_want; -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - if (fstat(fd, &stb_want) != 0 || - (stb_want.st_mode & S_IFMT) != S_IFBLK) -@@ -1135,8 +1135,8 @@ void wait_for(char *dev, int fd) - (stb.st_mode & S_IFMT) == S_IFBLK && - (stb.st_rdev == stb_want.st_rdev)) - return; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - if (i == 25) -@@ -1821,7 +1821,7 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force) - while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - - return ret; - } -@@ -1834,7 +1834,7 @@ int sys_hot_remove_disk(int statefd, int force) - while ((ret = write(statefd, "remove", 6)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - return ret == 6 ? 0 : -1; - } - -@@ -2375,3 +2375,27 @@ out: - close(fd_zero); - return ret; - } -+ -+/** -+ * sleep_for() - Sleeps for specified time. -+ * @sec: Seconds to sleep for. -+ * @nsec: Nanoseconds to sleep for, has to be less than one second. -+ * @wake_after_interrupt: If set, wake up if interrupted. -+ * -+ * Function immediately returns if error different than EINTR occurs. -+ */ -+void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) -+{ -+ struct timespec delay = {.tv_sec = sec, .tv_nsec = nsec}; -+ -+ assert(nsec < MSEC_TO_NSEC(1000)); -+ -+ do { -+ errno = 0; -+ nanosleep(&delay, &delay); -+ if (errno != 0 && errno != EINTR) { -+ pr_err("Error sleeping for %us %ldns: %s\n", sec, nsec, strerror(errno)); -+ return; -+ } -+ } while (!wake_after_interrupt && errno == EINTR); -+} --- -2.38.1 - diff --git a/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch b/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch deleted file mode 100644 index 5872416..0000000 --- a/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 39b381252c32275079344d30de18b76fda4bba26 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:45 -0600 -Subject: [PATCH 46/83] tests/00readonly: Run udevadm settle before setting ro - -In some recent kernel versions, 00readonly fails with: - - mdadm: failed to set readonly for /dev/md0: Device or resource busy - ERROR: array is not read-only! - -This was traced down to a race condition with udev holding a reference -to the block device at the same time as trying to set it read only. - -To fix this, call udevadm settle before setting the array read only. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00readonly | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/00readonly b/tests/00readonly -index 39202487..afe243b3 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -12,6 +12,7 @@ do - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync - check $level -+ udevadm settle - mdadm -ro $md0 - check readonly - state=$(cat /sys/block/md0/md/array_state) --- -2.38.1 - diff --git a/0047-tests-add-test-for-names.patch b/0047-tests-add-test-for-names.patch deleted file mode 100644 index 03aee00..0000000 --- a/0047-tests-add-test-for-names.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b7671c82010ffc04dfaecff2dd19ef8b2283e2b6 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:21 +0200 -Subject: [PATCH 47/83] tests: add test for names - -Current behavior is not documented and tested. This test is a base for -future improvements. It is enough to test it only with native metadata, -because it is generic code. Generated properties are passed to metadata -handler. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00createnames | 93 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 93 insertions(+) - create mode 100644 tests/00createnames - -diff --git a/tests/00createnames b/tests/00createnames -new file mode 100644 -index 00000000..64b81b92 ---- /dev/null -+++ b/tests/00createnames -@@ -0,0 +1,93 @@ -+set -x -e -+ -+# Test how and --name= are handled for create mode. -+# We need to check three properties, generated from those parameters: -+# - devnode name -+# - link in /dev/md/ (MD_DEVNAME property from --detail --export) -+# - name in metadata (MD_NAME property from --examine --export) -+ -+function _verify() { -+ local DEVNODE_NAME="$1" -+ local WANTED_LINK="$2" -+ local WANTED_NAME="$3" -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -+ exit 1 -+ fi -+ -+ if [[ "$WANTED_LINK" != "empty" ]]; then -+ local EXPECTED="MD_DEVNAME=$WANTED_LINK" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+ fi -+ -+ -+ local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get metadata from $dev0." -+ exit 1 -+ fi -+ -+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+} -+ -+function _create() { -+ local DEVNAME=$1 -+ local NAME=$2 -+ -+ if [[ -z "$NAME" ]]; then -+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -+ else -+ mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force -+ fi -+ -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot create device." -+ exit 1 -+ fi -+} -+ -+# The most trivial case. -+_create "/dev/md/name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+_create "name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# Use 'mdX' as name. -+_create "/dev/md/md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+_create "md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+# is used to create MD_DEVNAME but, name is used to create MD_NAME. -+_create "/dev/md/devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+_create "devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. -+_create "/dev/md0" -+_verify "/dev/md0" "empty" "0" -+mdadm -S "/dev/md0" -+ -+# Devnode points to /dev/ directory and name is set. -+_create "/dev/md0" "name" -+_verify "/dev/md0" "empty" "name" -+mdadm -S "/dev/md0" --- -2.38.1 - diff --git a/0048-mdadm-remove-symlink-option.patch b/0048-mdadm-remove-symlink-option.patch deleted file mode 100644 index 1956e2b..0000000 --- a/0048-mdadm-remove-symlink-option.patch +++ /dev/null @@ -1,176 +0,0 @@ -From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:22 +0200 -Subject: [PATCH 48/83] mdadm: remove symlink option - -The option is not used. Remove it from code. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 - - config.c | 7 +------ - mdadm.8.in | 9 --------- - mdadm.c | 20 -------------------- - mdadm.conf.5.in | 15 --------------- - mdadm.h | 2 -- - 6 files changed, 1 insertion(+), 53 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7518a32a..7f94847e 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -147,7 +147,6 @@ struct option long_options[] = { - {"nofailfast",0, 0, NoFailFast}, - {"re-add", 0, 0, ReAdd}, - {"homehost", 1, 0, HomeHost}, -- {"symlinks", 1, 0, Symlinks}, - {"data-offset",1, 0, DataOffset}, - {"nodes",1, 0, Nodes}, /* also for --assemble */ - {"home-cluster",1, 0, ClusterName}, -diff --git a/config.c b/config.c -index 9c725457..dc1620c1 100644 ---- a/config.c -+++ b/config.c -@@ -194,7 +194,6 @@ struct mddev_dev *load_containers(void) - - struct createinfo createinfo = { - .autof = 2, /* by default, create devices with standard names */ -- .symlinks = 1, - .names = 0, /* By default, stick with numbered md devices. */ - .bblist = 1, /* Use a bad block list by default */ - #ifdef DEBIAN -@@ -310,11 +309,7 @@ static void createline(char *line) - if (!createinfo.supertype) - pr_err("metadata format %s unknown, ignoring\n", - w+9); -- } else if (strncasecmp(w, "symlinks=yes", 12) == 0) -- createinfo.symlinks = 1; -- else if (strncasecmp(w, "symlinks=no", 11) == 0) -- createinfo.symlinks = 0; -- else if (strncasecmp(w, "names=yes", 12) == 0) -+ } else if (strncasecmp(w, "names=yes", 12) == 0) - createinfo.names = 1; - else if (strncasecmp(w, "names=no", 11) == 0) - createinfo.names = 0; -diff --git a/mdadm.8.in b/mdadm.8.in -index 0be02e4a..f2736226 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -1048,11 +1048,6 @@ simultaneously. If not specified, this defaults to 4. - Specify journal device for the RAID-4/5/6 array. The journal device - should be a SSD with reasonable lifetime. - --.TP --.BR \-\-symlinks --Auto creation of symlinks in /dev to /dev/md, option --symlinks must --be 'no' or 'yes' and work with --create and --build. -- - .TP - .BR \-k ", " \-\-consistency\-policy= - Specify how the array maintains consistency in case of unexpected shutdown. -@@ -1405,10 +1400,6 @@ Reshape can be continued later using the - .B \-\-continue - option for the grow command. - --.TP --.BR \-\-symlinks --See this option under Create and Build options. -- - .SH For Manage mode: - - .TP -diff --git a/mdadm.c b/mdadm.c -index 56722ed9..180f7a9c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -59,7 +59,6 @@ int main(int argc, char *argv[]) - struct mddev_dev *dv; - mdu_array_info_t array; - int devs_found = 0; -- char *symlinks = NULL; - int grow_continue = 0; - /* autof indicates whether and how to create device node. - * bottom 3 bits are style. Rest (when shifted) are number of parts -@@ -663,13 +662,6 @@ int main(int argc, char *argv[]) - case O(ASSEMBLE,Auto): /* auto-creation of device node */ - c.autof = parse_auto(optarg, "--auto flag", 0); - continue; -- -- case O(CREATE,Symlinks): -- case O(BUILD,Symlinks): -- case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */ -- symlinks = optarg; -- continue; -- - case O(BUILD,'f'): /* force honouring '-n 1' */ - case O(BUILD,Force): /* force honouring '-n 1' */ - case O(GROW,'f'): /* ditto */ -@@ -1325,18 +1317,6 @@ int main(int argc, char *argv[]) - exit(2); - } - -- if (symlinks) { -- struct createinfo *ci = conf_get_create_info(); -- -- if (strcasecmp(symlinks, "yes") == 0) -- ci->symlinks = 1; -- else if (strcasecmp(symlinks, "no") == 0) -- ci->symlinks = 0; -- else { -- pr_err("option --symlinks must be 'no' or 'yes'\n"); -- exit(2); -- } -- } - /* Ok, got the option parsing out of the way - * hopefully it's mostly right but there might be some stuff - * missing -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index cd4e6a9d..bc2295c2 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -338,21 +338,6 @@ missing device entries should be created. - The name of the metadata format to use if none is explicitly given. - This can be useful to impose a system-wide default of version-1 superblocks. - --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- - .TP - .B names=yes - Since Linux 2.6.29 it has been possible to create -diff --git a/mdadm.h b/mdadm.h -index add9c0b6..93e72786 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -394,7 +394,6 @@ struct createinfo { - int gid; - int autof; - int mode; -- int symlinks; - int names; - int bblist; - struct supertype *supertype; -@@ -442,7 +441,6 @@ enum special_options { - BackupFile, - HomeHost, - AutoHomeHost, -- Symlinks, - AutoDetect, - Waitclean, - DetailPlatform, --- -2.38.1 - diff --git a/0049-mdadm-move-data_offset-to-struct-shape.patch b/0049-mdadm-move-data_offset-to-struct-shape.patch deleted file mode 100644 index 5dca508..0000000 --- a/0049-mdadm-move-data_offset-to-struct-shape.patch +++ /dev/null @@ -1,232 +0,0 @@ -From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:23 +0200 -Subject: [PATCH 49/83] mdadm: move data_offset to struct shape - -Data offset is a shape property so move it there to remove additional -parameter from some functions. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Create.c | 16 ++++++++-------- - Grow.c | 7 +++---- - mdadm.c | 20 +++++++++----------- - mdadm.h | 5 ++--- - 4 files changed, 22 insertions(+), 26 deletions(-) - -diff --git a/Create.c b/Create.c -index c84c1ac8..e06ec2ae 100644 ---- a/Create.c -+++ b/Create.c -@@ -95,7 +95,7 @@ int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, unsigned long long data_offset) -+ struct context *c) - { - /* - * Create a new raid array. -@@ -288,7 +288,7 @@ int Create(struct supertype *st, char *mddev, - newsize = s->size * 2; - if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, - &s->chunk, s->size*2, -- data_offset, NULL, -+ s->data_offset, NULL, - &newsize, s->consistency_policy, - c->verbose >= 0)) - return 1; -@@ -323,10 +323,10 @@ int Create(struct supertype *st, char *mddev, - info.array.working_disks = 0; - dnum = 0; - for (dv = devlist; dv; dv = dv->next) -- if (data_offset == VARIABLE_OFFSET) -+ if (s->data_offset == VARIABLE_OFFSET) - dv->data_offset = INVALID_SECTORS; - else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) { - char *dname = dv->devname; -@@ -342,7 +342,7 @@ int Create(struct supertype *st, char *mddev, - missing_disks ++; - continue; - } -- if (data_offset == VARIABLE_OFFSET) { -+ if (s->data_offset == VARIABLE_OFFSET) { - doff = strchr(dname, ':'); - if (doff) { - *doff++ = 0; -@@ -350,7 +350,7 @@ int Create(struct supertype *st, char *mddev, - } else - dv->data_offset = INVALID_SECTORS; - } else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - dfd = open(dname, O_RDONLY); - if (dfd < 0) { -@@ -535,7 +535,7 @@ int Create(struct supertype *st, char *mddev, - if (!st->ss->validate_geometry(st, s->level, s->layout, - s->raiddisks, - &s->chunk, minsize*2, -- data_offset, -+ s->data_offset, - NULL, NULL, - s->consistency_policy, 0)) { - pr_err("devices too large for RAID level %d\n", s->level); -@@ -754,7 +754,7 @@ int Create(struct supertype *st, char *mddev, - } - } - if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid, -- data_offset)) -+ s->data_offset)) - goto abort_locked; - - total_slots = info.array.nr_disks; -diff --git a/Grow.c b/Grow.c -index 5780635a..868bdc3a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1775,7 +1775,6 @@ static int reshape_container(char *container, char *devname, - - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s) - { - /* Make some changes in the shape of an array. -@@ -1821,7 +1820,7 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (data_offset != INVALID_SECTORS && array.level != 10 && -+ if (s->data_offset != INVALID_SECTORS && array.level != 10 && - (array.level < 4 || array.level > 6)) { - pr_err("--grow --data-offset not yet supported\n"); - return 1; -@@ -2179,7 +2178,7 @@ size_change_error: - if ((s->level == UnSet || s->level == array.level) && - (s->layout_str == NULL) && - (s->chunk == 0 || s->chunk == array.chunk_size) && -- data_offset == INVALID_SECTORS && -+ s->data_offset == INVALID_SECTORS && - (s->raiddisks == 0 || s->raiddisks == array.raid_disks)) { - /* Nothing more to do */ - if (!changed && c->verbose >= 0) -@@ -2379,7 +2378,7 @@ size_change_error: - } - sync_metadata(st); - rv = reshape_array(container, fd, devname, st, &info, c->force, -- devlist, data_offset, c->backup_file, -+ devlist, s->data_offset, c->backup_file, - c->verbose, 0, 0, 0); - frozen = 0; - } -diff --git a/mdadm.c b/mdadm.c -index 180f7a9c..845e4466 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -49,7 +49,6 @@ int main(int argc, char *argv[]) - int i; - - unsigned long long array_size = 0; -- unsigned long long data_offset = INVALID_SECTORS; - struct mddev_ident ident; - char *configfile = NULL; - int devmode = 0; -@@ -79,6 +78,7 @@ int main(int argc, char *argv[]) - .layout = UnSet, - .bitmap_chunk = UnSet, - .consistency_policy = CONSISTENCY_POLICY_UNKNOWN, -+ .data_offset = INVALID_SECTORS, - }; - - char sys_hostname[256]; -@@ -479,15 +479,15 @@ int main(int argc, char *argv[]) - - case O(CREATE,DataOffset): - case O(GROW,DataOffset): -- if (data_offset != INVALID_SECTORS) { -+ if (s.data_offset != INVALID_SECTORS) { - pr_err("data-offset may only be specified one. Second value is %s.\n", optarg); - exit(2); - } - if (mode == CREATE && strcmp(optarg, "variable") == 0) -- data_offset = VARIABLE_OFFSET; -+ s.data_offset = VARIABLE_OFFSET; - else -- data_offset = parse_size(optarg); -- if (data_offset == INVALID_SECTORS) { -+ s.data_offset = parse_size(optarg); -+ if (s.data_offset == INVALID_SECTORS) { - pr_err("invalid data-offset: %s\n", - optarg); - exit(2); -@@ -1416,7 +1416,7 @@ int main(int argc, char *argv[]) - exit(1); - } - -- if (c.backup_file && data_offset != INVALID_SECTORS) { -+ if (c.backup_file && s.data_offset != INVALID_SECTORS) { - pr_err("--backup-file and --data-offset are incompatible\n"); - exit(2); - } -@@ -1587,8 +1587,7 @@ int main(int argc, char *argv[]) - - rv = Create(ss, devlist->devname, - ident.name, ident.uuid_set ? ident.uuid : NULL, -- devs_found-1, devlist->next, -- &s, &c, data_offset); -+ devs_found - 1, devlist->next, &s, &c); - break; - case MISC: - if (devmode == 'E') { -@@ -1706,10 +1705,9 @@ int main(int argc, char *argv[]) - c.verbose); - else if (s.size > 0 || s.raiddisks || s.layout_str || - s.chunk != 0 || s.level != UnSet || -- data_offset != INVALID_SECTORS) { -+ s.data_offset != INVALID_SECTORS) { - rv = Grow_reshape(devlist->devname, mdfd, -- devlist->next, -- data_offset, &c, &s); -+ devlist->next, &c, &s); - } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); - } else if (array_size == 0) -diff --git a/mdadm.h b/mdadm.h -index 93e72786..adb7cdaa 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -595,6 +595,7 @@ struct shape { - int assume_clean; - int write_behind; - unsigned long long size; -+ unsigned long long data_offset; - int consistency_policy; - }; - -@@ -1431,7 +1432,6 @@ extern int Grow_addbitmap(char *devname, int fd, - struct context *c, struct shape *s); - extern int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s); - extern int Grow_restart(struct supertype *st, struct mdinfo *info, - int *fdlist, int cnt, char *backup_file, int verbose); -@@ -1462,8 +1462,7 @@ extern int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, -- unsigned long long data_offset); -+ struct context *c); - - extern int Detail(char *dev, struct context *c); - extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); --- -2.38.1 - diff --git a/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch deleted file mode 100644 index c319da2..0000000 --- a/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:46 -0600 -Subject: [PATCH 50/83] mdadm: Don't open md device for CREATE and ASSEMBLE - -The mdadm command tries to open the md device for most modes, first -thing, no matter what. When running to create or assemble an array, -in most cases, the md device will not exist, the open call will fail -and everything will proceed correctly. - -However, when running tests, a create or assembly command may be run -shortly after stopping an array and the old md device file may still -be around. Then, if create_on_open is set in the kernel, a new md -device will be created when mdadm does its initial open. - -When mdadm gets around to creating the new device with the new_array -parameter it issues this error: - - mdadm: Fail to create md0 when using - /sys/module/md_mod/parameters/new_array, fallback to creation via node - -This is because an mddev was already created by the kernel with the -earlier open() call and thus the new one being created will fail with -EEXIST. The mdadm command will still successfully be created due to -falling back to the node creation method. However, the error message -itself will fail any test that's running it. - -This issue is a race condition that is very rare, but a recent change -in the kernel caused this to happen more frequently: about 1 in 50 -times. - -To fix this, don't bother trying to open the md device for CREATE, -ASSEMBLE and BUILD commands, as the file descriptor will never be used -anyway even if it is successfully openned. The mdfd has not been used -for these commands since: - - 7f91af49ad09 ("Delay creation of array devices for assemble/build/create") - -The checks that were done on the open device can be changed to being -done with stat. - -Side note: it would be nice to disable create_on_open as well to help -solve this, but it seems the work for this was never finished. By default, -mdadm will create using the old node interface when a name is specified -unless the user specifically puts names=yes in a config file, which -doesn't seem to be common or desirable to require this.. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - lib.c | 12 ++++++++++++ - mdadm.c | 40 ++++++++++++++++++++-------------------- - mdadm.h | 1 + - 3 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/lib.c b/lib.c -index 7e3e3d47..e395b28d 100644 ---- a/lib.c -+++ b/lib.c -@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st) - return devid2devnm(st->st_rdev); - } - -+bool stat_is_md_dev(struct stat *st) -+{ -+ if ((S_IFMT & st->st_mode) != S_IFBLK) -+ return false; -+ if (major(st->st_rdev) == MD_MAJOR) -+ return true; -+ if (major(st->st_rdev) == (unsigned)get_mdp_major()) -+ return true; -+ -+ return false; -+} -+ - char *fd2devnm(int fd) - { - struct stat stb; -diff --git a/mdadm.c b/mdadm.c -index 845e4466..972adb52 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1329,6 +1329,9 @@ int main(int argc, char *argv[]) - - if (mode == MANAGE || mode == BUILD || mode == CREATE || - mode == GROW || (mode == ASSEMBLE && ! c.scan)) { -+ struct stat stb; -+ int ret; -+ - if (devs_found < 1) { - pr_err("an md device must be given in this mode\n"); - exit(2); -@@ -1341,6 +1344,12 @@ int main(int argc, char *argv[]) - mdfd = open_mddev(devlist->devname, 1); - if (mdfd < 0) - exit(1); -+ -+ ret = fstat(mdfd, &stb); -+ if (ret) { -+ pr_err("fstat failed on %s.\n", devlist->devname); -+ exit(1); -+ } - } else { - char *bname = basename(devlist->devname); - -@@ -1348,30 +1357,21 @@ int main(int argc, char *argv[]) - pr_err("Name %s is too long.\n", devlist->devname); - exit(1); - } -- /* non-existent device is OK */ -- mdfd = open_mddev(devlist->devname, 0); -- } -- if (mdfd == -2) { -- pr_err("device %s exists but is not an md array.\n", devlist->devname); -- exit(1); -- } -- if ((int)ident.super_minor == -2) { -- struct stat stb; -- if (mdfd < 0) { -+ -+ ret = stat(devlist->devname, &stb); -+ if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -- devlist->devname); -+ devlist->devname); -+ exit(1); -+ } -+ -+ if (!ret && !stat_is_md_dev(&stb)) { -+ pr_err("device %s exists but is not an md array.\n", devlist->devname); - exit(1); - } -- fstat(mdfd, &stb); -- ident.super_minor = minor(stb.st_rdev); -- } -- if (mdfd >= 0 && mode != MANAGE && mode != GROW) { -- /* We don't really want this open yet, we just might -- * have wanted to check some things -- */ -- close(mdfd); -- mdfd = -1; - } -+ if (ident.super_minor == -2) -+ ident.super_minor = minor(stb.st_rdev); - } - - if (s.raiddisks) { -diff --git a/mdadm.h b/mdadm.h -index adb7cdaa..8208b81e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1672,6 +1672,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - extern char *stat2kname(struct stat *st); - extern char *fd2kname(int fd); - extern char *stat2devnm(struct stat *st); -+bool stat_is_md_dev(struct stat *st); - extern char *fd2devnm(int fd); - extern void udev_block(char *devnm); - extern void udev_unblock(void); --- -2.38.1 - diff --git a/0051-Grow-Split-Grow_reshape-into-helper-function.patch b/0051-Grow-Split-Grow_reshape-into-helper-function.patch deleted file mode 100644 index 8fe5894..0000000 --- a/0051-Grow-Split-Grow_reshape-into-helper-function.patch +++ /dev/null @@ -1,231 +0,0 @@ -From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 28 Jul 2022 20:20:53 +0800 -Subject: [PATCH 51/83] Grow: Split Grow_reshape into helper function - -Grow_reshape should be split into helper functions given its size. -- Add helper function for preparing reshape on external metadata. -- Close cfd file descriptor. - -Signed-off-by: Mateusz Kusiak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 125 ++++++++++++++++++++++++++++++-------------------------- - mdadm.h | 1 + - util.c | 14 +++++++ - 3 files changed, 81 insertions(+), 59 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 868bdc3a..0f07a894 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname, - char *backup_file, int verbose, - int forked, int restart, int freeze_reshape); - -+/** -+ * prepare_external_reshape() - prepares update on external metadata if supported. -+ * @devname: Device name. -+ * @subarray: Subarray. -+ * @st: Supertype. -+ * @container: Container. -+ * @cfd: Container file descriptor. -+ * -+ * Function checks that the requested reshape is supported on external metadata, -+ * and performs an initial check that the container holds the pre-requisite -+ * spare devices (mdmon owns final validation). -+ * -+ * Return: 0 on success, else 1 -+ */ -+static int prepare_external_reshape(char *devname, char *subarray, -+ struct supertype *st, char *container, -+ const int cfd) -+{ -+ struct mdinfo *cc = NULL; -+ struct mdinfo *content = NULL; -+ -+ if (st->ss->load_container(st, cfd, NULL)) { -+ pr_err("Cannot read superblock for %s\n", devname); -+ return 1; -+ } -+ -+ if (!st->ss->container_content) -+ return 1; -+ -+ cc = st->ss->container_content(st, subarray); -+ for (content = cc; content ; content = content->next) { -+ /* -+ * check if reshape is allowed based on metadata -+ * indications stored in content.array.status -+ */ -+ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) || -+ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) { -+ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -+ devname, container); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) { -+ pr_err("Operation not supported when ppl consistency policy is enabled\n"); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) { -+ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n"); -+ goto error; -+ } -+ } -+ sysfs_free(cc); -+ if (mdmon_running(container)) -+ st->update_tail = &st->updates; -+ return 0; -+error: -+ sysfs_free(cc); -+ return 1; -+} -+ - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, - struct context *c, struct shape *s) -@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd, - struct supertype *st; - char *subarray = NULL; - -- int frozen; -+ int frozen = 0; - int changed = 0; - char *container = NULL; - int cfd = -1; -@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd, - int added_disks; - - struct mdinfo info; -- struct mdinfo *sra; -+ struct mdinfo *sra = NULL; - - if (md_get_array_info(fd, &array) < 0) { - pr_err("%s is not an active md array - aborting\n", -@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd, - } - } - -- /* in the external case we need to check that the requested reshape is -- * supported, and perform an initial check that the container holds the -- * pre-requisite spare devices (mdmon owns final validation) -- */ - if (st->ss->external) { -- int retval; -- - if (subarray) { - container = st->container_devnm; - cfd = open_dev_excl(st->container_devnm); -@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- retval = st->ss->load_container(st, cfd, NULL); -- -- if (retval) { -- pr_err("Cannot read superblock for %s\n", devname); -- close(cfd); -+ rv = prepare_external_reshape(devname, subarray, st, -+ container, cfd); -+ if (rv > 0) { - free(subarray); -- return 1; -+ close(cfd); -+ goto release; - } - - if (s->raiddisks && subarray) { -@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd, - free(subarray); - return 1; - } -- -- /* check if operation is supported for metadata handler */ -- if (st->ss->container_content) { -- struct mdinfo *cc = NULL; -- struct mdinfo *content = NULL; -- -- cc = st->ss->container_content(st, subarray); -- for (content = cc; content ; content = content->next) { -- int allow_reshape = 1; -- -- /* check if reshape is allowed based on metadata -- * indications stored in content.array.status -- */ -- if (content->array.state & -- (1 << MD_SB_BLOCK_VOLUME)) -- allow_reshape = 0; -- if (content->array.state & -- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE)) -- allow_reshape = 0; -- if (!allow_reshape) { -- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -- devname, container); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_PPL) { -- pr_err("Operation not supported when ppl consistency policy is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_BITMAP) { -- pr_err("Operation not supported when write-intent bitmap is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- } -- sysfs_free(cc); -- } -- if (mdmon_running(container)) -- st->update_tail = &st->updates; - } - - added_disks = 0; -diff --git a/mdadm.h b/mdadm.h -index 8208b81e..941a5f38 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev); - extern bool is_dev_alive(char *path); - extern int get_mdp_major(void); - extern int get_maj_min(char *dev, int *major, int *minor); -+extern bool is_bit_set(int *val, unsigned char index); - extern int dev_open(char *dev, int flags); - extern int open_dev(char *devnm); - extern void reopen_mddev(int mdfd); -diff --git a/util.c b/util.c -index ca48d976..26ffdcea 100644 ---- a/util.c -+++ b/util.c -@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor) - *e == 0); - } - -+/** -+ * is_bit_set() - get bit value by index. -+ * @val: value. -+ * @index: index of the bit (LSB numbering). -+ * -+ * Return: bit value. -+ */ -+bool is_bit_set(int *val, unsigned char index) -+{ -+ if ((*val) & (1 << index)) -+ return true; -+ return false; -+} -+ - int dev_open(char *dev, int flags) - { - /* like 'open', but if 'dev' matches %d:%d, create a temp --- -2.38.1 - diff --git a/0052-Assemble-check-if-device-is-container-before-schedul.patch b/0052-Assemble-check-if-device-is-container-before-schedul.patch deleted file mode 100644 index 52d08b8..0000000 --- a/0052-Assemble-check-if-device-is-container-before-schedul.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 19 Aug 2022 02:55:46 +0200 -Subject: [PATCH 52/83] Assemble: check if device is container before - scheduling force-clean update - -Up to now using assemble with force flag making each array as clean. -Force-clean should not be done for the container. This commit add -check if device is different than container before cleaning. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Assemble.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index be2160b4..1dd82a8c 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1809,10 +1809,9 @@ try_again: - } - #endif - } -- if (c->force && !clean && -+ if (c->force && !clean && content->array.level != LEVEL_CONTAINER && - !enough(content->array.level, content->array.raid_disks, -- content->array.layout, clean, -- avail)) { -+ content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", - devices[chosen_drive].devname, c->verbose, - 0, NULL); --- -2.38.1 - diff --git a/0053-super1-report-truncated-device.patch b/0053-super1-report-truncated-device.patch deleted file mode 100644 index 35cbd4b..0000000 --- a/0053-super1-report-truncated-device.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Fri, 26 Aug 2022 08:55:56 +1000 -Subject: [PATCH 53/83] super1: report truncated device - -When the metadata is at the start of the device, it is possible that it -describes a device large than the one it is actually stored on. When -this happens, report it loudly in --examine. - -.... - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE -.... - -Also report in --assemble so that the failure which the kernel will -report will be explained. - -mdadm: Device /dev/sdb is not large enough for data described in superblock -mdadm: no RAID superblock on /dev/sdb -mdadm: /dev/sdb has no superblock - assembly aborted - -Scenario can be demonstrated as follows: - -mdadm: Note: this array has metadata at the start and - may not be suitable as a boot device. If you plan to - store '/boot' on this device please ensure that - your boot-loader understands md/v1.x metadata, or use - --metadata=0.90 -mdadm: Defaulting to version 1.2 metadata -mdadm: array /dev/md/test started. -mdadm: stopped /dev/md/test - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - super1.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - -diff --git a/super1.c b/super1.c -index 71af860c..58345e68 100644 ---- a/super1.c -+++ b/super1.c -@@ -406,12 +406,18 @@ static void examine_super1(struct supertype *st, char *homehost) - - st->ss->getinfo_super(st, &info, NULL); - if (info.space_after != 1 && -- !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) -- printf(" Unused Space : before=%llu sectors, after=%llu sectors\n", -- info.space_before, info.space_after); -- -- printf(" State : %s\n", -- (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); -+ !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { -+ printf(" Unused Space : before=%llu sectors, ", -+ info.space_before); -+ if (info.space_after < INT64_MAX) -+ printf("after=%llu sectors\n", info.space_after); -+ else -+ printf("after=-%llu sectors DEVICE TOO SMALL\n", -+ UINT64_MAX - info.space_after); -+ } -+ printf(" State : %s%s\n", -+ (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); - for (i=0; i<16; i++) { - if ((i&3)==0 && i != 0) -@@ -2206,6 +2212,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - tst.ss = &super1; - for (tst.minor_version = 0; tst.minor_version <= 2; - tst.minor_version++) { -+ tst.ignore_hw_compat = st->ignore_hw_compat; - switch(load_super1(&tst, fd, devname)) { - case 0: super = tst.sb; - if (bestvers == -1 || -@@ -2312,7 +2319,6 @@ static int load_super1(struct supertype *st, int fd, char *devname) - free(super); - return 2; - } -- st->sb = super; - - bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); - -@@ -2322,6 +2328,21 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); - -+ if (st->minor_version >= 1 && -+ st->ignore_hw_compat == 0 && -+ (dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size)) -+ || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->data_size)))) { -+ if (devname) -+ pr_err("Device %s is not large enough for data described in superblock\n", -+ devname); -+ free(super); -+ return 2; -+ } -+ st->sb = super; -+ - /* Now check on the bitmap superblock */ - if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) - return 0; --- -2.38.1 - diff --git a/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch b/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch deleted file mode 100644 index c37276f..0000000 --- a/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:52:12 +0200 -Subject: [PATCH 54/83] mdadm: Correct typos, punctuation and grammar in man - -Signed-off-by: Mateusz Grzonka -Reviewed-by: Wol -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 178 ++++++++++++++++++++++++++--------------------------- - 1 file changed, 88 insertions(+), 90 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index f2736226..70c79d1e 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -158,7 +158,7 @@ adding new spares and removing faulty devices. - .B Misc - This is an 'everything else' mode that supports operations on active - arrays, operations on component devices such as erasing old superblocks, and --information gathering operations. -+information-gathering operations. - .\"This mode allows operations on independent devices such as examine MD - .\"superblocks, erasing old superblocks and stopping active arrays. - -@@ -231,12 +231,12 @@ mode to be assumed. - - .TP - .BR \-h ", " \-\-help --Display general help message or, after one of the above options, a -+Display a general help message or, after one of the above options, a - mode-specific help message. - - .TP - .B \-\-help\-options --Display more detailed help about command line parsing and some commonly -+Display more detailed help about command-line parsing and some commonly - used options. - - .TP -@@ -266,7 +266,7 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. If not specified, default config file -+Specify the config file or directory. If not specified, the default config file - and default conf.d directory will be used. See - .BR mdadm.conf (5) - for more details. -@@ -379,7 +379,7 @@ When creating an array, the - .B homehost - will be recorded in the metadata. For version-1 superblocks, it will - be prefixed to the array name. For version-0.90 superblocks, part of --the SHA1 hash of the hostname will be stored in the later half of the -+the SHA1 hash of the hostname will be stored in the latter half of the - UUID. - - When reporting information about an array, any array which is tagged -@@ -388,7 +388,7 @@ for the given homehost will be reported as such. - When using Auto-Assemble, only arrays tagged for the given homehost - will be allowed to use 'local' names (i.e. not ending in '_' followed - by a digit string). See below under --.BR "Auto Assembly" . -+.BR "Auto-Assembly" . - - The special name "\fBany\fP" can be used as a wild card. If an array - is created with -@@ -403,7 +403,7 @@ When - .I mdadm - needs to print the name for a device it normally finds the name in - .B /dev --which refers to the device and is shortest. When a path component is -+which refers to the device and is the shortest. When a path component is - given with - .B \-\-prefer - .I mdadm -@@ -478,9 +478,9 @@ still be larger than any replacement. - - This option can be used with - .B \-\-create --for determining initial size of an array. For external metadata, -+for determining the initial size of an array. For external metadata, - it can be used on a volume, but not on a container itself. --Setting initial size of -+Setting the initial size of - .B RAID 0 - array is only valid for external metadata. - -@@ -545,20 +545,20 @@ Clustered arrays do not support this parameter yet. - - .TP - .BR \-c ", " \-\-chunk= --Specify chunk size of kilobytes. The default when creating an -+Specify chunk size in kilobytes. The default when creating an - array is 512KB. To ensure compatibility with earlier versions, the - default when building an array with no persistent metadata is 64KB. - This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10. - - RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power --of 2. In any case it must be a multiple of 4KB. -+of 2, with minimal chunk size being 4KB. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, - Megabytes, Gigabytes or Terabytes respectively. - - .TP - .BR \-\-rounding= --Specify rounding factor for a Linear array. The size of each -+Specify the rounding factor for a Linear array. The size of each - component will be rounded down to a multiple of this size. - This is a synonym for - .B \-\-chunk -@@ -655,7 +655,8 @@ option to set subsequent failure modes. - and "flush" will clear any persistent faults. - - The layout options for RAID10 are one of 'n', 'o' or 'f' followed --by a small number. The default is 'n2'. The supported options are: -+by a small number signifying the number of copies of each datablock. -+The default is 'n2'. The supported options are: - - .I 'n' - signals 'near' copies. Multiple copies of one data block are at -@@ -673,7 +674,7 @@ signals 'far' copies - (multiple copies have very different offsets). - See md(4) for more detail about 'near', 'offset', and 'far'. - --The number is the number of copies of each datablock. 2 is normal, 3 -+As for the number of copies of each data block, 2 is normal, 3 - can be useful. This number can be at most equal to the number of - devices in the array. It does not need to divide evenly into that - number (e.g. it is perfectly legal to have an 'n2' layout for an array -@@ -684,7 +685,7 @@ A bug introduced in Linux 3.14 means that RAID0 arrays - started using a different layout. This could lead to - data corruption. Since Linux 5.4 (and various stable releases that received - backports), the kernel will not accept such an array unless --a layout is explictly set. It can be set to -+a layout is explicitly set. It can be set to - .RB ' original ' - or - .RB ' alternate '. -@@ -760,13 +761,13 @@ or by selecting a different consistency policy with - - .TP - .BR \-\-bitmap\-chunk= --Set the chunksize of the bitmap. Each bit corresponds to that many -+Set the chunk size of the bitmap. Each bit corresponds to that many - Kilobytes of storage. --When using a file based bitmap, the default is to use the smallest --size that is at-least 4 and requires no more than 2^21 chunks. -+When using a file-based bitmap, the default is to use the smallest -+size that is at least 4 and requires no more than 2^21 chunks. - When using an - .B internal --bitmap, the chunksize defaults to 64Meg, or larger if necessary to -+bitmap, the chunk size defaults to 64Meg, or larger if necessary to - fit the bitmap into the available space. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, -@@ -840,7 +841,7 @@ can be used with that command to avoid the automatic resync. - .BR \-\-backup\-file= - This is needed when - .B \-\-grow --is used to increase the number of raid-devices in a RAID5 or RAID6 if -+is used to increase the number of raid devices in a RAID5 or RAID6 if - there are no spare devices available, or to shrink, change RAID level - or layout. See the GROW MODE section below on RAID\-DEVICES CHANGES. - The file must be stored on a separate device, not on the RAID array -@@ -879,7 +880,7 @@ When creating an array, - .B \-\-data\-offset - can be specified as - .BR variable . --In the case each member device is expected to have a offset appended -+In the case each member device is expected to have an offset appended - to the name, separated by a colon. This makes it possible to recreate - exactly an array which has varying data offsets (as can happen when - different versions of -@@ -943,7 +944,7 @@ Insist that - .I mdadm - accept the geometry and layout specified without question. Normally - .I mdadm --will not allow creation of an array with only one device, and will try -+will not allow the creation of an array with only one device, and will try - to create a RAID5 array with one missing drive (as this makes the - initial resync work faster). With - .BR \-\-force , -@@ -1004,7 +1005,7 @@ number added, e.g. - If the md device name is in a 'standard' format as described in DEVICE - NAMES, then it will be created, if necessary, with the appropriate - device number based on that name. If the device name is not in one of these --formats, then a unused device number will be allocated. The device -+formats, then an unused device number will be allocated. The device - number will be considered unused if there is no active array for that - number, and there is no entry in /dev for that number and with a - non-standard name. Names that are not in 'standard' format are only -@@ -1032,25 +1033,25 @@ then - .B \-\-add - can be used to add some extra devices to be included in the array. - In most cases this is not needed as the extra devices can be added as --spares first, and then the number of raid-disks can be changed. --However for RAID0, it is not possible to add spares. So to increase -+spares first, and then the number of raid disks can be changed. -+However, for RAID0 it is not possible to add spares. So to increase - the number of devices in a RAID0, it is necessary to set the new - number of devices, and to add the new devices, in the same command. - - .TP - .BR \-\-nodes --Only works when the array is for clustered environment. It specifies -+Only works when the array is created for a clustered environment. It specifies - the maximum number of nodes in the cluster that will use this device - simultaneously. If not specified, this defaults to 4. - - .TP - .BR \-\-write-journal - Specify journal device for the RAID-4/5/6 array. The journal device --should be a SSD with reasonable lifetime. -+should be an SSD with a reasonable lifetime. - - .TP - .BR \-k ", " \-\-consistency\-policy= --Specify how the array maintains consistency in case of unexpected shutdown. -+Specify how the array maintains consistency in the case of an unexpected shutdown. - Only relevant for RAID levels with redundancy. - Currently supported options are: - .RS -@@ -1058,7 +1059,7 @@ Currently supported options are: - .TP - .B resync - Full resync is performed and all redundancy is regenerated when the array is --started after unclean shutdown. -+started after an unclean shutdown. - - .TP - .B bitmap -@@ -1067,8 +1068,8 @@ Resync assisted by a write-intent bitmap. Implicitly selected when using - - .TP - .B journal --For RAID levels 4/5/6, journal device is used to log transactions and replay --after unclean shutdown. Implicitly selected when using -+For RAID levels 4/5/6, the journal device is used to log transactions and replay -+after an unclean shutdown. Implicitly selected when using - .BR \-\-write\-journal . - - .TP -@@ -1237,7 +1238,7 @@ This can be useful if - reports a different "Preferred Minor" to - .BR \-\-detail . - In some cases this update will be performed automatically --by the kernel driver. In particular the update happens automatically -+by the kernel driver. In particular, the update happens automatically - at the first write to an array with redundancy (RAID level 1 or - greater) on a 2.6 (or later) kernel. - -@@ -1277,7 +1278,7 @@ For version-1 superblocks, this involves updating the name. - The - .B home\-cluster - option will change the cluster name as recorded in the superblock and --bitmap. This option only works for clustered environment. -+bitmap. This option only works for a clustered environment. - - The - .B resync -@@ -1390,10 +1391,10 @@ This option should be used with great caution. - - .TP - .BR \-\-freeze\-reshape --Option is intended to be used in start-up scripts during initrd boot phase. --When array under reshape is assembled during initrd phase, this option --stops reshape after reshape critical section is being restored. This happens --before file system pivot operation and avoids loss of file system context. -+This option is intended to be used in start-up scripts during the initrd boot phase. -+When the array under reshape is assembled during the initrd phase, this option -+stops the reshape after the reshape-critical section has been restored. This happens -+before the file system pivot operation and avoids loss of filesystem context. - Losing file system context would cause reshape to be broken. - - Reshape can be continued later using the -@@ -1437,9 +1438,9 @@ re\-add a device that was previously removed from an array. - If the metadata on the device reports that it is a member of the - array, and the slot that it used is still vacant, then the device will - be added back to the array in the same position. This will normally --cause the data for that device to be recovered. However based on the -+cause the data for that device to be recovered. However, based on the - event count on the device, the recovery may only require sections that --are flagged a write-intent bitmap to be recovered or may not require -+are flagged by a write-intent bitmap to be recovered or may not require - any recovery at all. - - When used on an array that has no metadata (i.e. it was built with -@@ -1447,13 +1448,12 @@ When used on an array that has no metadata (i.e. it was built with - it will be assumed that bitmap-based recovery is enough to make the - device fully consistent with the array. - --When used with v1.x metadata, - .B \-\-re\-add --can be accompanied by -+can also be accompanied by - .BR \-\-update=devicesize , - .BR \-\-update=bbl ", or" - .BR \-\-update=no\-bbl . --See the description of these option when used in Assemble mode for an -+See descriptions of these options when used in Assemble mode for an - explanation of their use. - - If the device name given is -@@ -1480,7 +1480,7 @@ Add a device as a spare. This is similar to - except that it does not attempt - .B \-\-re\-add - first. The device will be added as a spare even if it looks like it --could be an recent member of the array. -+could be a recent member of the array. - - .TP - .BR \-r ", " \-\-remove -@@ -1497,12 +1497,12 @@ and names like - .B set-A - can be given to - .BR \-\-remove . --The first causes all failed device to be removed. The second causes -+The first causes all failed devices to be removed. The second causes - any device which is no longer connected to the system (i.e an 'open' - returns - .BR ENXIO ) - to be removed. --The third will remove a set as describe below under -+The third will remove a set as described below under - .BR \-\-fail . - - .TP -@@ -1519,7 +1519,7 @@ For RAID10 arrays where the number of copies evenly divides the number - of devices, the devices can be conceptually divided into sets where - each set contains a single complete copy of the data on the array. - Sometimes a RAID10 array will be configured so that these sets are on --separate controllers. In this case all the devices in one set can be -+separate controllers. In this case, all the devices in one set can be - failed by giving a name like - .B set\-A - or -@@ -1549,9 +1549,9 @@ This can follow a list of - .B \-\-replace - devices. The devices listed after - .B \-\-with --will be preferentially used to replace the devices listed after -+will preferentially be used to replace the devices listed after - .BR \-\-replace . --These device must already be spare devices in the array. -+These devices must already be spare devices in the array. - - .TP - .BR \-\-write\-mostly -@@ -1574,8 +1574,8 @@ the device is found or :missing in case the device is not found. - - .TP - .BR \-\-add-journal --Add journal to an existing array, or recreate journal for RAID-4/5/6 array --that lost a journal device. To avoid interrupting on-going write opertions, -+Add a journal to an existing array, or recreate journal for a RAID-4/5/6 array -+that lost a journal device. To avoid interrupting ongoing write operations, - .B \-\-add-journal - only works for array in Read-Only state. - -@@ -1631,9 +1631,9 @@ Print details of one or more md devices. - .TP - .BR \-\-detail\-platform - Print details of the platform's RAID capabilities (firmware / hardware --topology) for a given metadata format. If used without argument, mdadm -+topology) for a given metadata format. If used without an argument, mdadm - will scan all controllers looking for their capabilities. Otherwise, mdadm --will only look at the controller specified by the argument in form of an -+will only look at the controller specified by the argument in the form of an - absolute filepath or a link, e.g. - .IR /sys/devices/pci0000:00/0000:00:1f.2 . - -@@ -1742,8 +1742,8 @@ the block where the superblock would be is overwritten even if it - doesn't appear to be valid. - - .B Note: --Be careful to call \-\-zero\-superblock with clustered raid, make sure --array isn't used or assembled in other cluster node before execute it. -+Be careful when calling \-\-zero\-superblock with clustered raid. Make sure -+the array isn't used or assembled in another cluster node before executing it. - - .TP - .B \-\-kill\-subarray= -@@ -1790,7 +1790,7 @@ For each md device given, or each device in /proc/mdstat if - is given, arrange for the array to be marked clean as soon as possible. - .I mdadm - will return with success if the array uses external metadata and we --successfully waited. For native arrays this returns immediately as the -+successfully waited. For native arrays, this returns immediately as the - kernel handles dirty-clean transitions at shutdown. No action is taken - if safe-mode handling is disabled. - -@@ -1830,7 +1830,7 @@ uses to help track which arrays are currently being assembled. - - .TP - .BR \-\-run ", " \-R --Run any array assembled as soon as a minimal number of devices are -+Run any array assembled as soon as a minimal number of devices is - available, rather than waiting until all expected devices are present. - - .TP -@@ -1860,7 +1860,7 @@ Only used with \-\-fail. The 'path' given will be recorded so that if - a new device appears at the same location it can be automatically - added to the same array. This allows the failed device to be - automatically replaced by a new device without metadata if it appears --at specified path. This option is normally only set by a -+at specified path. This option is normally only set by an - .I udev - script. - -@@ -1961,7 +1961,7 @@ Usage: - .PP - This usage assembles one or more RAID arrays from pre-existing components. - For each array, mdadm needs to know the md device, the identity of the --array, and a number of component-devices. These can be found in a number of ways. -+array, and the number of component devices. These can be found in a number of ways. - - In the first usage example (without the - .BR \-\-scan ) -@@ -2001,7 +2001,7 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, default config file is used. See -+In the latter case, the default config file is used. See - .BR mdadm.conf (5) - for more details. - -@@ -2039,14 +2039,14 @@ detects that udev is not configured, it will create the devices in - .B /dev - itself. - --In Linux kernels prior to version 2.6.28 there were two distinctly --different types of md devices that could be created: one that could be -+In Linux kernels prior to version 2.6.28 there were two distinct -+types of md devices that could be created: one that could be - partitioned using standard partitioning tools and one that could not. --Since 2.6.28 that distinction is no longer relevant as both type of -+Since 2.6.28 that distinction is no longer relevant as both types of - devices can be partitioned. - .I mdadm - will normally create the type that originally could not be partitioned --as it has a well defined major number (9). -+as it has a well-defined major number (9). - - Prior to 2.6.28, it is important that mdadm chooses the correct type - of array device to use. This can be controlled with the -@@ -2066,7 +2066,7 @@ can also be given in the configuration file as a word starting - .B auto= - on the ARRAY line for the relevant array. - --.SS Auto Assembly -+.SS Auto-Assembly - When - .B \-\-assemble - is used with -@@ -2122,11 +2122,11 @@ See - .IR mdadm.conf (5) - for further details. - --Note: Auto assembly cannot be used for assembling and activating some -+Note: Auto-assembly cannot be used for assembling and activating some - arrays which are undergoing reshape. In particular as the - .B backup\-file --cannot be given, any reshape which requires a backup-file to continue --cannot be started by auto assembly. An array which is growing to more -+cannot be given, any reshape which requires a backup file to continue -+cannot be started by auto-assembly. An array which is growing to more - devices and has passed the critical section can be assembled using - auto-assembly. - -@@ -2233,7 +2233,7 @@ When creating a partition based array, using - .I mdadm - with version-1.x metadata, the partition type should be set to - .B 0xDA --(non fs-data). This type selection allows for greater precision since -+(non fs-data). This type of selection allows for greater precision since - using any other [RAID auto-detect (0xFD) or a GNU/Linux partition (0x83)], - might create problems in the event of array recovery through a live cdrom. - -@@ -2249,7 +2249,7 @@ when creating a v0.90 array will silently override any - setting. - .\"If the - .\".B \-\-size --.\"option is given, it is not necessary to list any component-devices in this command. -+.\"option is given, it is not necessary to list any component devices in this command. - .\"They can be added later, before a - .\".B \-\-run. - .\"If no -@@ -2263,7 +2263,7 @@ requested with the - .B \-\-bitmap - option or a different consistency policy is selected with the - .B \-\-consistency\-policy --option. In any case space for a bitmap will be reserved so that one -+option. In any case, space for a bitmap will be reserved so that one - can be added later with - .BR "\-\-grow \-\-bitmap=internal" . - -@@ -2313,7 +2313,7 @@ will firstly mark - as faulty in - .B /dev/md0 - and will then remove it from the array and finally add it back --in as a spare. However only one md array can be affected by a single -+in as a spare. However, only one md array can be affected by a single - command. - - When a device is added to an active array, mdadm checks to see if it -@@ -2458,14 +2458,14 @@ config file to be examined. - If the device contains RAID metadata, a file will be created in the - .I directory - and the metadata will be written to it. The file will be the same --size as the device and have the metadata written in the file at the --same locate that it exists in the device. However the file will be "sparse" so -+size as the device and will have the metadata written at the -+same location as it exists in the device. However, the file will be "sparse" so - that only those blocks containing metadata will be allocated. The - total space used will be small. - --The file name used in the -+The filename used in the - .I directory --will be the base name of the device. Further if any links appear in -+will be the base name of the device. Further, if any links appear in - .I /dev/disk/by-id - which point to the device, then hard links to the file will be created - in -@@ -2567,7 +2567,7 @@ and if the destination array has a failed drive but no spares. - - If any devices are listed on the command line, - .I mdadm --will only monitor those devices. Otherwise all arrays listed in the -+will only monitor those devices, otherwise, all arrays listed in the - configuration file will be monitored. Further, if - .B \-\-scan - is given, then any other md devices that appear in -@@ -2624,10 +2624,10 @@ check, repair). (syslog priority: Warning) - .BI Rebuild NN - Where - .I NN --is a two-digit number (ie. 05, 48). This indicates that rebuild --has passed that many percent of the total. The events are generated --with fixed increment since 0. Increment size may be specified with --a commandline option (default is 20). (syslog priority: Warning) -+is a two-digit number (eg. 05, 48). This indicates that the rebuild -+has reached that percentage of the total. The events are generated -+at a fixed increment from 0. The increment size may be specified with -+a command-line option (the default is 20). (syslog priority: Warning) - - .TP - .B RebuildFinished -@@ -2735,8 +2735,8 @@ When - detects that an array in a spare group has fewer active - devices than necessary for the complete array, and has no spare - devices, it will look for another array in the same spare group that --has a full complement of working drive and a spare. It will then --attempt to remove the spare from the second drive and add it to the -+has a full complement of working drives and a spare. It will then -+attempt to remove the spare from the second array and add it to the - first. - If the removal succeeds but the adding fails, then it is added back to - the original array. -@@ -2750,10 +2750,8 @@ and then follow similar steps as above if a matching spare is found. - .SH GROW MODE - The GROW mode is used for changing the size or shape of an active - array. --For this to work, the kernel must support the necessary change. --Various types of growth are being added during 2.6 development. - --Currently the supported changes include -+During the kernel 2.6 era the following changes were added: - .IP \(bu 4 - change the "size" attribute for RAID1, RAID4, RAID5 and RAID6. - .IP \(bu 4 -@@ -2796,8 +2794,8 @@ use more than half of a spare device for backup space. - - .SS SIZE CHANGES - Normally when an array is built the "size" is taken from the smallest --of the drives. If all the small drives in an arrays are, one at a --time, removed and replaced with larger drives, then you could have an -+of the drives. If all the small drives in an arrays are, over time, -+removed and replaced with larger drives, then you could have an - array of large drives with only a small amount used. In this - situation, changing the "size" with "GROW" mode will allow the extra - space to start being used. If the size is increased in this way, a -@@ -2812,7 +2810,7 @@ after growing, or to reduce its size - .B prior - to shrinking the array. - --Also the size of an array cannot be changed while it has an active -+Also, the size of an array cannot be changed while it has an active - bitmap. If an array has a bitmap, it must be removed before the size - can be changed. Once the change is complete a new bitmap can be created. - -@@ -2892,7 +2890,7 @@ long time. A - is required. If the array is not simultaneously being grown or - shrunk, so that the array size will remain the same - for example, - reshaping a 3-drive RAID5 into a 4-drive RAID6 - the backup file will --be used not just for a "cricital section" but throughout the reshape -+be used not just for a "critical section" but throughout the reshape - operation, as described below under LAYOUT CHANGES. - - .SS CHUNK-SIZE AND LAYOUT CHANGES -@@ -2910,7 +2908,7 @@ slowly. - If the reshape is interrupted for any reason, this backup file must be - made available to - .B "mdadm --assemble" --so the array can be reassembled. Consequently the file cannot be -+so the array can be reassembled. Consequently, the file cannot be - stored on the device being reshaped. - - --- -2.38.1 - diff --git a/0055-Manage-Block-unsafe-member-failing.patch b/0055-Manage-Block-unsafe-member-failing.patch deleted file mode 100644 index 290c56f..0000000 --- a/0055-Manage-Block-unsafe-member-failing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 18 Aug 2022 11:47:21 +0200 -Subject: [PATCH 55/83] Manage: Block unsafe member failing - -Kernel may or may not block mdadm from removing member device if it -will cause arrays failed state. It depends on raid personality -implementation in kernel. -Add verification on requested removal path (#mdadm --set-faulty -command). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 52 insertions(+), 1 deletion(-) - -diff --git a/Manage.c b/Manage.c -index a142f8bd..b1d0e630 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1285,6 +1285,50 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, - return -1; - } - -+/** -+ * is_remove_safe() - Check if remove is safe. -+ * @array: Array info. -+ * @fd: Array file descriptor. -+ * @devname: Name of device to remove. -+ * @verbose: Verbose. -+ * -+ * The function determines if array will be operational -+ * after removing &devname. -+ * -+ * Return: True if array will be operational, false otherwise. -+ */ -+bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose) -+{ -+ dev_t devid = devnm2devid(devname + 5); -+ struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE); -+ -+ if (!mdi) { -+ if (verbose) -+ pr_err("Failed to read sysfs attributes for %s\n", devname); -+ return false; -+ } -+ -+ char *avail = xcalloc(array->raid_disks, sizeof(char)); -+ -+ for (mdi = mdi->devs; mdi; mdi = mdi->next) { -+ if (mdi->disk.raid_disk < 0) -+ continue; -+ if (!(mdi->disk.state & (1 << MD_DISK_SYNC))) -+ continue; -+ if (makedev(mdi->disk.major, mdi->disk.minor) == devid) -+ continue; -+ avail[mdi->disk.raid_disk] = 1; -+ } -+ sysfs_free(mdi); -+ -+ bool is_enough = enough(array->level, array->raid_disks, -+ array->layout, (array->state & 1), -+ avail); -+ -+ free(avail); -+ return is_enough; -+} -+ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - char *update, int force) -@@ -1598,7 +1642,14 @@ int Manage_subdevs(char *devname, int fd, - break; - - case 'f': /* set faulty */ -- /* FIXME check current member */ -+ 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); -+ goto abort; -+ } -+ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/0056-Monitor-Fix-statelist-memory-leaks.patch b/0056-Monitor-Fix-statelist-memory-leaks.patch deleted file mode 100644 index ad36a25..0000000 --- a/0056-Monitor-Fix-statelist-memory-leaks.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001 -From: Pawel Baldysiak -Date: Thu, 1 Sep 2022 11:20:31 +0200 -Subject: [PATCH 56/83] Monitor: Fix statelist memory leaks - -Free statelist in error path in Monitor initialization. - -Signed-off-by: Pawel Baldysiak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 40 +++++++++++++++++++++++++++++++--------- - 1 file changed, 31 insertions(+), 9 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 93f36ac0..b4e954c6 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - int test, struct alert_info *info); - static void try_spare_migration(struct state *statelist, struct alert_info *info); - static void link_containers_with_subarrays(struct state *list); -+static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -@@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist, - */ - - struct state *statelist = NULL; -- struct state *st2; - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -@@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ if (!is_mddev(mdlist->devname)) { -+ free_statelist(statelist); -+ return 1; -+ } - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), - "/dev/md/%s", basename(mdlist->devname)); -- if (!is_mddev(mdlist->devname)) -- return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) -+ if (!is_mddev(dv->devname)) { -+ free_statelist(statelist); - return 1; -+ } - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -@@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->spare_group); -+ if (st->spare_group) -+ free(st->spare_group); -+ - free(st); - } else - stp = &st->next; - } - } -- for (st2 = statelist; st2; st2 = statelist) { -- statelist = st2->next; -- free(st2); -- } -+ -+ free_statelist(statelist); - - if (pidfile) - unlink(pidfile); -@@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list) - } - } - -+/** -+ * free_statelist() - Frees statelist. -+ * @statelist: statelist to free -+ */ -+static void free_statelist(struct state *statelist) -+{ -+ struct state *tmp = NULL; -+ -+ while (statelist) { -+ if (statelist->spare_group) -+ free(statelist->spare_group); -+ -+ tmp = statelist; -+ statelist = statelist->next; -+ free(tmp); -+ } -+} -+ - #ifndef NO_LIBUDEV - /* function: check_udev_activity - * Description: Function waits for udev to finish --- -2.38.1 - diff --git a/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch b/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch deleted file mode 100644 index 79a3262..0000000 --- a/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ea7a02a3294aae223e1329aed5da7f4aa3ac05c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= -Date: Wed, 31 Aug 2022 19:57:29 +0200 -Subject: [PATCH 57/83] mdadm: added support for Intel Alderlake RST on VMD - platform -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Alderlake RST on VMD uses RstVmdV UEFI variable name, so detect it. - -Signed-off-by: Oldřich Jedlička -Reviewed-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index 5a8729e7..757f0b1b 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -512,7 +512,8 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) - #define AHCI_PROP "RstSataV" - #define AHCI_SSATA_PROP "RstsSatV" - #define AHCI_TSATA_PROP "RsttSatV" --#define VMD_PROP "RstUefiV" -+#define VROC_VMD_PROP "RstUefiV" -+#define RST_VMD_PROP "RstVmdV" - - #define VENDOR_GUID \ - EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) -@@ -605,6 +606,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - struct orom_entry *ret; - static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP, - AHCI_TSATA_PROP}; -+ static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP}; - unsigned long i; - - if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) -@@ -636,10 +638,16 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - - break; - case SYS_DEV_VMD: -- if (!read_efi_variable(&orom, sizeof(orom), VMD_PROP, -- VENDOR_GUID)) -- break; -- return NULL; -+ for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { -+ if (!read_efi_variable(&orom, sizeof(orom), -+ vmd_efivars[i], VENDOR_GUID)) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(vmd_efivars)) -+ return NULL; -+ -+ break; - default: - return NULL; - } --- -2.38.1 - diff --git a/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch b/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch deleted file mode 100644 index 6e1a179..0000000 --- a/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch +++ /dev/null @@ -1,111 +0,0 @@ -From ea109700563d93704ebdc540c7770d874369f667 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:33 +0200 -Subject: [PATCH 58/83] mdadm: Add Documentation entries to systemd services - -Add documentation section. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdadm-last-resort@.service | 1 + - systemd/mdcheck_continue.service | 3 ++- - systemd/mdcheck_start.service | 1 + - systemd/mdmon@.service | 1 + - systemd/mdmonitor-oneshot.service | 1 + - systemd/mdmonitor.service | 1 + - 7 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9fdc8ec7..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -8,6 +8,7 @@ - [Unit] - Description=Manage MD Reshape on /dev/%I - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - ExecStart=BINDIR/mdadm --grow --continue /dev/%I -diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service -index efeb3f63..e9381125 100644 ---- a/systemd/mdadm-last-resort@.service -+++ b/systemd/mdadm-last-resort@.service -@@ -2,6 +2,7 @@ - Description=Activate md array %I even though degraded - DefaultDependencies=no - ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index 854317f1..f5324905 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -7,7 +7,8 @@ - - [Unit] - Description=MD array scrubbing - continuation --ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* -+ConditionPathExistsGlob=/var/lib/mdcheck/MD_UUID_* -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 3bb3d130..703a6583 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array scrubbing - Wants=mdcheck_continue.timer -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 77533958..97a1acd9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -9,6 +9,7 @@ - Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target -+Documentation=man:mdmon(8) - - [Service] - # mdmon should never complain due to lack of a platform, -diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service -index 373955a2..ba86b44e 100644 ---- a/systemd/mdmonitor-oneshot.service -+++ b/systemd/mdmonitor-oneshot.service -@@ -7,6 +7,7 @@ - - [Unit] - Description=Reminder for degraded MD arrays -+Documentation=man:mdadm(8) - - [Service] - Environment=MDADM_MONITOR_ARGS=--scan -diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service -index 46f7b880..9c364785 100644 ---- a/systemd/mdmonitor.service -+++ b/systemd/mdmonitor.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array monitor - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - Environment= MDADM_MONITOR_ARGS=--scan --- -2.38.1 - diff --git a/0059-ReadMe-fix-command-line-help.patch b/0059-ReadMe-fix-command-line-help.patch deleted file mode 100644 index 837a339..0000000 --- a/0059-ReadMe-fix-command-line-help.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f7cbd810b639eb946ba1b3bddb1faefb9696de42 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:34 +0200 -Subject: [PATCH 59/83] ReadMe: fix command-line help - -Make command-line help consistent with manual page. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7f94847e..50a5e36d 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -477,7 +477,7 @@ char Help_assemble[] = - ; - - char Help_manage[] = --"Usage: mdadm arraydevice options component devices...\n" -+"Usage: mdadm [mode] arraydevice [options] \n" - "\n" - "This usage is for managing the component devices within an array.\n" - "The --manage option is not needed and is assumed if the first argument\n" --- -2.38.1 - diff --git a/0060-mdadm-replace-container-level-checking-with-inline.patch b/0060-mdadm-replace-container-level-checking-with-inline.patch deleted file mode 100644 index 7b2b6b2..0000000 --- a/0060-mdadm-replace-container-level-checking-with-inline.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 6f2af6a48c541f207cb727a31fb86de2cd04fc21 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 2 Sep 2022 08:49:23 +0200 -Subject: [PATCH 60/83] mdadm: replace container level checking with inline - -To unify all containers checks in code, is_container() function is -added and propagated. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 +++---- - Create.c | 6 +++--- - Grow.c | 6 +++--- - Incremental.c | 4 ++-- - mdadm.h | 14 ++++++++++++++ - super-ddf.c | 6 +++--- - super-intel.c | 4 ++-- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 2 +- - 10 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 1dd82a8c..8b0af0c9 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1120,7 +1120,7 @@ static int start_array(int mdfd, - i/2, mddev); - } - -- if (content->array.level == LEVEL_CONTAINER) { -+ if (is_container(content->array.level)) { - sysfs_rules_apply(mddev, content); - if (c->verbose >= 0) { - pr_err("Container %s has been assembled with %d drive%s", -@@ -1549,8 +1549,7 @@ try_again: - */ - trustworthy = LOCAL; - -- if (name[0] == 0 && -- content->array.level == LEVEL_CONTAINER) { -+ if (!name[0] && is_container(content->array.level)) { - name = content->text_version; - trustworthy = METADATA; - } -@@ -1809,7 +1808,7 @@ try_again: - } - #endif - } -- if (c->force && !clean && content->array.level != LEVEL_CONTAINER && -+ if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", -diff --git a/Create.c b/Create.c -index e06ec2ae..953e7372 100644 ---- a/Create.c -+++ b/Create.c -@@ -487,7 +487,7 @@ int Create(struct supertype *st, char *mddev, - st->minor_version >= 1) - /* metadata at front */ - warn |= check_partitions(fd, dname, 0, 0); -- else if (s->level == 1 || s->level == LEVEL_CONTAINER || -+ else if (s->level == 1 || is_container(s->level) || - (s->level == 0 && s->raiddisks == 1)) - /* partitions could be meaningful */ - warn |= check_partitions(fd, dname, freesize*2, s->size*2); -@@ -997,7 +997,7 @@ int Create(struct supertype *st, char *mddev, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && s->level != LEVEL_CONTAINER && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info.uuid, 0)) { - map_update(&map, fd2devnm(mdfd), - info_new.text_version, -@@ -1040,7 +1040,7 @@ int Create(struct supertype *st, char *mddev, - map_unlock(&map); - free(infos); - -- if (s->level == LEVEL_CONTAINER) { -+ if (is_container(s->level)) { - /* No need to start. But we should signal udev to - * create links */ - sysfs_uevent(&info, "change"); -diff --git a/Grow.c b/Grow.c -index 0f07a894..e362403a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2175,7 +2175,7 @@ size_change_error: - devname, s->size); - } - changed = 1; -- } else if (array.level != LEVEL_CONTAINER) { -+ } else if (!is_container(array.level)) { - s->size = get_component_size(fd)/2; - if (s->size == 0) - s->size = array.size; -@@ -2231,7 +2231,7 @@ size_change_error: - info.component_size = s->size*2; - info.new_level = s->level; - info.new_chunk = s->chunk * 1024; -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - info.delta_disks = UnSet; - info.array.raid_disks = s->raiddisks; - } else if (s->raiddisks) -@@ -2344,7 +2344,7 @@ size_change_error: - printf("layout for %s set to %d\n", - devname, array.layout); - } -- } else if (array.level == LEVEL_CONTAINER) { -+ } else if (is_container(array.level)) { - /* This change is to be applied to every array in the - * container. This is only needed when the metadata imposes - * restraints of the various arrays in the container. -diff --git a/Incremental.c b/Incremental.c -index 4d0cd9d6..5a5f4c4c 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -244,7 +244,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - c->autof = ci->autof; - - name_to_use = info.name; -- if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) { -+ if (name_to_use[0] == 0 && is_container(info.array.level)) { - name_to_use = info.text_version; - trustworthy = METADATA; - } -@@ -472,7 +472,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - - /* 7/ Is there enough devices to possibly start the array? */ - /* 7a/ if not, finish with success. */ -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - char devnm[32]; - /* Try to assemble within the container */ - sysfs_uevent(sra, "change"); -diff --git a/mdadm.h b/mdadm.h -index 941a5f38..3673494e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1924,3 +1924,17 @@ enum r0layout { - * This is true for native and DDF, IMSM allows 16. - */ - #define MD_NAME_MAX 32 -+ -+/** -+ * is_container() - check if @level is &LEVEL_CONTAINER -+ * @level: level value -+ * -+ * return: -+ * 1 if level is equal to &LEVEL_CONTAINER, 0 otherwise. -+ */ -+static inline int is_container(const int level) -+{ -+ if (level == LEVEL_CONTAINER) -+ return 1; -+ return 0; -+} -diff --git a/super-ddf.c b/super-ddf.c -index 949e7d15..9d1e3b94 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3325,7 +3325,7 @@ validate_geometry_ddf_container(struct supertype *st, - int fd; - unsigned long long ldsize; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -3371,7 +3371,7 @@ static int validate_geometry_ddf(struct supertype *st, - - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - /* Must be a fresh device to add to a container */ - return validate_geometry_ddf_container(st, level, raiddisks, - data_offset, dev, -@@ -3488,7 +3488,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, - struct dl *dl; - unsigned long long maxsize; - /* ddf/bvd supports lots of things, but not containers */ -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("DDF cannot create a container within an container\n"); - return 0; -diff --git a/super-intel.c b/super-intel.c -index 4d82af3d..b0565610 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6727,7 +6727,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, - struct intel_super *super = NULL; - int rv = 0; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -7692,7 +7692,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - * if given unused devices create a container - * if given given devices in a container create a member volume - */ -- if (level == LEVEL_CONTAINER) -+ if (is_container(level)) - /* Must be a fresh device to add to a container */ - return validate_geometry_imsm_container(st, level, raiddisks, - data_offset, dev, -diff --git a/super0.c b/super0.c -index 37f595ed..93876e2e 100644 ---- a/super0.c -+++ b/super0.c -@@ -1273,7 +1273,7 @@ static int validate_geometry0(struct supertype *st, int level, - if (get_linux_version() < 3001000) - tbmax = 2; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("0.90 metadata does not support containers\n"); - return 0; -diff --git a/super1.c b/super1.c -index 58345e68..0b505a7e 100644 ---- a/super1.c -+++ b/super1.c -@@ -2830,7 +2830,7 @@ static int validate_geometry1(struct supertype *st, int level, - unsigned long long overhead; - int fd; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("1.x metadata does not support containers\n"); - return 0; -diff --git a/sysfs.c b/sysfs.c -index 0d98a65f..ca1d888f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -763,7 +763,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) - - rv = sysfs_set_num(sra, sd, "offset", sd->data_offset); - rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2); -- if (sra->array.level != LEVEL_CONTAINER) { -+ if (!is_container(sra->array.level)) { - if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) { - rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector); - rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size); --- -2.38.1 - diff --git a/0061-Mdmonitor-Omit-non-md-devices.patch b/0061-Mdmonitor-Omit-non-md-devices.patch deleted file mode 100644 index 062ecdf..0000000 --- a/0061-Mdmonitor-Omit-non-md-devices.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8b668d4aa3305af5963162b7499b128bd71f8f29 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Thu, 22 Sep 2022 08:29:50 +0200 -Subject: [PATCH 61/83] Mdmonitor: Omit non-md devices - -Fix segfault commit [1] introduced check whether given device is -mddevice, but it happend to terminate Mdmonitor if at least one of given -devices didn't fulfill that condition. In result Mdmonitor service was -no longer started on boot (with --scan option) when config contained some -non-existent array entry. - -This commit introduces ommiting non-md devices so scan option can still -be used when config is wrong and allow Mdmonitor service to run on boot. - -Giving a list of devices to monitor containing non-existing or -non-md devices will result in monitoring only confirmed mddevices. - -[1] https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=e702f392959d1c2ad2089e595b52235ed97b4e18 - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index b4e954c6..7d7dc4d2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -185,10 +185,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -- if (!is_mddev(mdlist->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(mdlist->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -@@ -208,10 +206,8 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(dv->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); --- -2.38.1 - diff --git a/0062-Mdmonitor-Split-alert-into-separate-functions.patch b/0062-Mdmonitor-Split-alert-into-separate-functions.patch deleted file mode 100644 index c7562e7..0000000 --- a/0062-Mdmonitor-Split-alert-into-separate-functions.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 3698867194f27fdd7824b8bdd172d619a2c087cc Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 7 Sep 2022 14:56:49 +0200 -Subject: [PATCH 62/83] Mdmonitor: Split alert() into separate functions - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 186 ++++++++++++++++++++++++++++-------------------------- - 1 file changed, 95 insertions(+), 91 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 7d7dc4d2..0036e8cd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -66,7 +66,7 @@ struct alert_info { - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(char *event, char *dev, char *disc, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); - static int check_array(struct state *st, struct mdstat_ent *mdstat, - int test, struct alert_info *info, - int increments, char *prefer); -@@ -407,111 +407,115 @@ static void write_autorebuild_pid() - } - } - --static void alert(char *event, char *dev, char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ int pid = fork(); -+ -+ switch (pid) { -+ default: -+ waitpid(pid, NULL, 0); -+ break; -+ case -1: -+ pr_err("Cannot fork to execute alert command"); -+ break; -+ case 0: -+ execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ exit(2); -+ } -+} -+ -+static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ FILE *mp, *mdstat; -+ char hname[256]; -+ char buf[BUFSIZ]; -+ int n; -+ -+ mp = popen(Sendmail, "w"); -+ if (!mp) { -+ pr_err("Cannot open pipe stream for sendmail.\n"); -+ return; -+ } -+ -+ gethostname(hname, sizeof(hname)); -+ signal(SIGPIPE, SIG_IGN); -+ if (info->mailfrom) -+ fprintf(mp, "From: %s\n", info->mailfrom); -+ else -+ fprintf(mp, "From: %s monitoring \n", Name); -+ fprintf(mp, "To: %s\n", info->mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "This is an automatically generated mail message. \n"); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ -+ if (disc && disc[0] != ' ') -+ fprintf(mp, -+ "It could be related to component device %s.\n\n", disc); -+ if (disc && disc[0] == ' ') -+ fprintf(mp, "Extra information:%s.\n\n", disc); -+ -+ mdstat = fopen("/proc/mdstat", "r"); -+ if (!mdstat) { -+ pr_err("Cannot open /proc/mdstat\n"); -+ pclose(mp); -+ return; -+ } -+ -+ fprintf(mp, "The /proc/mdstat file currently contains the following:\n\n"); -+ while ((n = fread(buf, 1, sizeof(buf), mdstat)) > 0) -+ n = fwrite(buf, 1, n, mp); -+ fclose(mdstat); -+ pclose(mp); -+} -+ -+static void log_event_to_syslog(const char *event, const char *dev, const char *disc) - { - int priority; -+ /* Log at a different severity depending on the event. -+ * -+ * These are the critical events: */ -+ if (strncmp(event, "Fail", 4) == 0 || -+ strncmp(event, "Degrade", 7) == 0 || -+ strncmp(event, "DeviceDisappeared", 17) == 0) -+ priority = LOG_CRIT; -+ /* Good to know about, but are not failures: */ -+ else if (strncmp(event, "Rebuild", 7) == 0 || -+ strncmp(event, "MoveSpare", 9) == 0 || -+ strncmp(event, "Spares", 6) != 0) -+ priority = LOG_WARNING; -+ /* Everything else: */ -+ else -+ priority = LOG_INFO; - -+ if (disc && disc[0] != ' ') -+ syslog(priority, -+ "%s event detected on md device %s, component device %s", event, dev, disc); -+ else if (disc) -+ syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ else -+ syslog(priority, "%s event detected on md device %s", event, dev); -+} -+ -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ - if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) { -- int pid = fork(); -- switch(pid) { -- default: -- waitpid(pid, NULL, 0); -- break; -- case -1: -- break; -- case 0: -- execl(info->alert_cmd, info->alert_cmd, -- event, dev, disc, NULL); -- exit(2); -- } -- } -+ if (info->alert_cmd) -+ execute_alert_cmd(event, dev, disc, info); -+ - if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- FILE *mp = popen(Sendmail, "w"); -- if (mp) { -- FILE *mdstat; -- char hname[256]; -- -- gethostname(hname, sizeof(hname)); -- signal_s(SIGPIPE, SIG_IGN); -- -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -- else -- fprintf(mp, "From: %s monitoring \n", -- Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", -- event, dev, hname); -- -- fprintf(mp, -- "This is an automatically generated mail message from %s\n", Name); -- fprintf(mp, "running on %s\n\n", hname); -- -- fprintf(mp, -- "A %s event had been detected on md device %s.\n\n", event, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -- -- fprintf(mp, "Faithfully yours, etc.\n"); -- -- mdstat = fopen("/proc/mdstat", "r"); -- if (mdstat) { -- char buf[8192]; -- int n; -- fprintf(mp, -- "\nP.S. The /proc/mdstat file currently contains the following:\n\n"); -- while ((n = fread(buf, 1, sizeof(buf), -- mdstat)) > 0) -- n = fwrite(buf, 1, n, mp); -- fclose(mdstat); -- } -- pclose(mp); -- } -+ send_event_email(event, dev, disc, info); - } - -- /* log the event to syslog maybe */ -- if (info->dosyslog) { -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -- else if (disc) -- syslog(priority, -- "%s event detected on md device %s: %s", -- event, dev, disc); -- else -- syslog(priority, -- "%s event detected on md device %s", -- event, dev); -- } -+ if (info->dosyslog) -+ log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, --- -2.38.1 - diff --git a/0063-Monitor-block-if-monitor-modes-are-combined.patch b/0063-Monitor-block-if-monitor-modes-are-combined.patch deleted file mode 100644 index d993d9d..0000000 --- a/0063-Monitor-block-if-monitor-modes-are-combined.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f40ac0e7e6043361ad12e9db97c07e56c3977cf6 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:57 +0100 -Subject: [PATCH 63/83] Monitor: block if monitor modes are combined. - -Block monitoring start if --scan mode and MD devices list are combined. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Monitor.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index 0036e8cd..188cb8be 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -123,7 +123,7 @@ int Monitor(struct mddev_dev *devlist, - * and if we can get_disk_info and find a name - * Then we hot-remove and hot-add to the other array - * -- * If devlist is NULL, then we can monitor everything because --scan -+ * If devlist is NULL, then we can monitor everything if --scan - * was given. We get an initial list from config file and add anything - * that appears in /proc/mdstat - */ -@@ -136,6 +136,11 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -+ if (devlist && c->scan) { -+ pr_err("Devices list and --scan option cannot be combined - not monitoring.\n"); -+ return 1; -+ } -+ - if (!mailaddr) - mailaddr = conf_get_mailaddr(); - --- -2.38.1 - diff --git a/0064-Update-mdadm-Monitor-manual.patch b/0064-Update-mdadm-Monitor-manual.patch deleted file mode 100644 index 15f52e1..0000000 --- a/0064-Update-mdadm-Monitor-manual.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 725e37cd14866906ba28c970394b9f7a4cd97413 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:58 +0100 -Subject: [PATCH 64/83] Update mdadm Monitor manual. - -- describe monitor work modes, -- clarify the turning off condition, -- describe the mdmonitor.service as a prefered management way. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 71 ++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 50 insertions(+), 21 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 70c79d1e..64f71ed1 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -2548,13 +2548,33 @@ Usage: - .I options... devices... - - .PP --This usage causes -+Monitor option can work in two modes: -+.IP \(bu 4 -+system wide mode, follow all md devices based on -+.B /proc/mdstat, -+.IP \(bu 4 -+follow only specified MD devices in command line. -+.PP -+ -+.B \-\-scan - -+indicates system wide mode. Option causes the -+.I monitor -+to track all md devices that appear in -+.B /proc/mdstat. -+If it is not set, then at least one -+.B device -+must be specified. -+ -+Monitor usage causes - .I mdadm - to periodically poll a number of md arrays and to report on any events - noticed. --.I mdadm --will never exit once it decides that there are arrays to be checked, --so it should normally be run in the background. -+ -+In both modes, -+.I monitor -+will work as long as there is an active array with redundancy and it is defined to follow (for -+.B \-\-scan -+every array is followed). - - As well as reporting events, - .I mdadm -@@ -2565,15 +2585,6 @@ or - .B domain - and if the destination array has a failed drive but no spares. - --If any devices are listed on the command line, --.I mdadm --will only monitor those devices, otherwise, all arrays listed in the --configuration file will be monitored. Further, if --.B \-\-scan --is given, then any other md devices that appear in --.B /proc/mdstat --will also be monitored. -- - The result of monitoring the arrays is the generation of events. - These events are passed to a separate program (if specified) and may - be mailed to a given E-mail address. -@@ -2586,16 +2597,34 @@ device if relevant (such as a component device that has failed). - - If - .B \-\-scan --is given, then a program or an E-mail address must be specified on the --command line or in the config file. If neither are available, then -+is given, then a -+.B program -+or an -+.B e-mail -+address must be specified on the -+command line or in the config file. If neither are available, then - .I mdadm - will not monitor anything. --Without --.B \-\-scan, --.I mdadm --will continue monitoring as long as something was found to monitor. If --no program or email is given, then each event is reported to --.BR stdout . -+For devices given directly in command line, without -+.B program -+or -+.B email -+specified, each event is reported to -+.BR stdout. -+ -+Note: For systems where -+.If mdadm monitor -+is configured via systemd, -+.B mdmonitor(mdmonitor.service) -+should be configured. The service is designed to be primary solution for array monitoring, -+it is configured to work in system wide mode. -+It is automatically started and stopped according to current state and types of MD arrays in system. -+The service may require additional configuration, like -+.B e-mail -+or -+.B delay. -+That should be done in -+.B mdadm.conf. - - The different events are: - --- -2.38.1 - diff --git a/0065-Grow-fix-possible-memory-leak.patch b/0065-Grow-fix-possible-memory-leak.patch deleted file mode 100644 index 07d9fb6..0000000 --- a/0065-Grow-fix-possible-memory-leak.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 434b3b9bb96a76dc12f693b64cf23b581781e20b Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Tue, 20 Dec 2022 12:07:51 +0100 -Subject: [PATCH 65/83] Grow: fix possible memory leak. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Grow.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index e362403a..b73ec2ae 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -432,6 +432,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); -+ free(mdi); - return 1; - } - fd2 = dev_open(dv, O_RDWR); -@@ -453,8 +454,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - pr_err("failed to load super-block.\n"); - } - close(fd2); -- if (rv) -+ if (rv) { -+ free(mdi); - return 1; -+ } - } - if (offset_setable) { - st->ss->getinfo_super(st, mdi, NULL); --- -2.38.1 - diff --git a/0066-mdadm-create-ident_init.patch b/0066-mdadm-create-ident_init.patch deleted file mode 100644 index 32d374b..0000000 --- a/0066-mdadm-create-ident_init.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 7fcbfd7c620e2dcd3b539d18e93cb503ee3a8a62 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Wed, 21 Dec 2022 12:50:17 +0100 -Subject: [PATCH 66/83] mdadm: create ident_init() - -Add a wrapper for repeated initializations in mdadm.c and config.c. -Move includes up. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 45 +++++++++++++++++++++++++++++---------------- - mdadm.c | 16 ++-------------- - mdadm.h | 7 +++++-- - 3 files changed, 36 insertions(+), 32 deletions(-) - -diff --git a/config.c b/config.c -index dc1620c1..eeedd0c6 100644 ---- a/config.c -+++ b/config.c -@@ -119,6 +119,34 @@ int match_keyword(char *word) - return -1; - } - -+/** -+ * ident_init() - Set defaults. -+ * @ident: ident pointer, not NULL. -+ */ -+inline void ident_init(struct mddev_ident *ident) -+{ -+ assert(ident); -+ -+ ident->assembled = false; -+ ident->autof = 0; -+ ident->bitmap_fd = -1; -+ ident->bitmap_file = NULL; -+ ident->container = NULL; -+ ident->devices = NULL; -+ ident->devname = NULL; -+ ident->level = UnSet; -+ ident->member = NULL; -+ ident->name[0] = 0; -+ ident->next = NULL; -+ ident->raid_disks = UnSet; -+ ident->spare_group = NULL; -+ ident->spare_disks = 0; -+ ident->st = NULL; -+ ident->super_minor = UnSet; -+ ident->uuid[0] = 0; -+ ident->uuid_set = 0; -+} -+ - struct conf_dev { - struct conf_dev *next; - char *name; -@@ -363,22 +391,7 @@ void arrayline(char *line) - struct mddev_ident mis; - struct mddev_ident *mi; - -- mis.uuid_set = 0; -- mis.super_minor = UnSet; -- mis.level = UnSet; -- mis.raid_disks = UnSet; -- mis.spare_disks = 0; -- mis.devices = NULL; -- mis.devname = NULL; -- mis.spare_group = NULL; -- mis.autof = 0; -- mis.next = NULL; -- mis.st = NULL; -- mis.bitmap_fd = -1; -- mis.bitmap_file = NULL; -- mis.name[0] = 0; -- mis.container = NULL; -- mis.member = NULL; -+ ident_init(&mis); - - for (w = dl_next(line); w != line; w = dl_next(w)) { - if (w[0] == '/' || strchr(w, '=') == NULL) { -diff --git a/mdadm.c b/mdadm.c -index 972adb52..74fdec31 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,25 +107,13 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- ident.uuid_set = 0; -- ident.level = UnSet; -- ident.raid_disks = UnSet; -- ident.super_minor = UnSet; -- ident.devices = 0; -- ident.spare_group = NULL; -- ident.autof = 0; -- ident.st = NULL; -- ident.bitmap_fd = -1; -- ident.bitmap_file = NULL; -- ident.name[0] = 0; -- ident.container = NULL; -- ident.member = NULL; -- - if (get_linux_version() < 2006015) { - pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); - exit(1); - } - -+ ident_init(&ident); -+ - while ((option_index = -1), - (opt = getopt_long(argc, argv, shortopt, long_options, - &option_index)) != -1) { -diff --git a/mdadm.h b/mdadm.h -index 3673494e..23ffe977 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - # endif - #endif - -+#include - #include - #include -+#include - #include - #include - #include -@@ -1552,6 +1554,8 @@ extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name); - -+extern void ident_init(struct mddev_ident *ident); -+ - extern int parse_auto(char *str, char *msg, int config); - extern struct mddev_ident *conf_get_ident(char *dev); - extern struct mddev_dev *conf_get_devs(void); -@@ -1779,8 +1783,7 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler) - #define dprintf_cont(fmt, arg...) \ - ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) - #endif --#include --#include -+ - static inline int xasprintf(char **strp, const char *fmt, ...) { - va_list ap; - int ret; --- -2.38.1 - diff --git a/0067-mdadm-Add-option-validation-for-update-subarray.patch b/0067-mdadm-Add-option-validation-for-update-subarray.patch deleted file mode 100644 index faa7113..0000000 --- a/0067-mdadm-Add-option-validation-for-update-subarray.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 2568ce89ea5c26225e8984733adc2ea7559d853a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:15 +0100 -Subject: [PATCH 67/83] mdadm: Add option validation for --update-subarray - -Subset of options available for "--update" is not same as for "--update-subarray". -Define maps and enum for update options and use them instead of direct comparisons. -Add proper error message. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 31 +++++++++++++++++ - maps.c | 31 +++++++++++++++++ - mdadm.c | 104 +++++++++++++++++-------------------------------------- - mdadm.h | 32 ++++++++++++++++- - 4 files changed, 124 insertions(+), 74 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 50a5e36d..bd8d50d2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -655,3 +655,34 @@ char *mode_help[mode_count] = { - [GROW] = Help_grow, - [INCREMENTAL] = Help_incr, - }; -+ -+/** -+ * fprint_update_options() - Print valid update options depending on the mode. -+ * @outf: File (output stream) -+ * @update_mode: Used to distinguish update and update_subarray -+ */ -+void fprint_update_options(FILE *outf, enum update_opt update_mode) -+{ -+ int counter = UOPT_NAME, breakpoint = UOPT_HELP; -+ mapping_t *map = update_options; -+ -+ if (!outf) -+ return; -+ if (update_mode == UOPT_SUBARRAY_ONLY) { -+ breakpoint = UOPT_SUBARRAY_ONLY; -+ fprintf(outf, "Valid --update options for update-subarray are:\n\t"); -+ } else -+ fprintf(outf, "Valid --update options are:\n\t"); -+ while (map->num) { -+ if (map->num >= breakpoint) -+ break; -+ fprintf(outf, "'%s', ", map->name); -+ if (counter % 5 == 0) -+ fprintf(outf, "\n\t"); -+ counter++; -+ map++; -+ } -+ if ((counter - 1) % 5) -+ fprintf(outf, "\n"); -+ fprintf(outf, "\r"); -+} -diff --git a/maps.c b/maps.c -index 20fcf719..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -165,6 +165,37 @@ mapping_t sysfs_array_states[] = { - { "broken", ARRAY_BROKEN }, - { NULL, ARRAY_UNKNOWN_STATE } - }; -+/** -+ * mapping_t update_options - stores supported update options. -+ */ -+mapping_t update_options[] = { -+ { "name", UOPT_NAME }, -+ { "ppl", UOPT_PPL }, -+ { "no-ppl", UOPT_NO_PPL }, -+ { "bitmap", UOPT_BITMAP }, -+ { "no-bitmap", UOPT_NO_BITMAP }, -+ { "sparc2.2", UOPT_SPARC22 }, -+ { "super-minor", UOPT_SUPER_MINOR }, -+ { "summaries", UOPT_SUMMARIES }, -+ { "resync", UOPT_RESYNC }, -+ { "uuid", UOPT_UUID }, -+ { "homehost", UOPT_HOMEHOST }, -+ { "home-cluster", UOPT_HOME_CLUSTER }, -+ { "nodes", UOPT_NODES }, -+ { "devicesize", UOPT_DEVICESIZE }, -+ { "bbl", UOPT_BBL }, -+ { "no-bbl", UOPT_NO_BBL }, -+ { "force-no-bbl", UOPT_FORCE_NO_BBL }, -+ { "metadata", UOPT_METADATA }, -+ { "revert-reshape", UOPT_REVERT_RESHAPE }, -+ { "layout-original", UOPT_LAYOUT_ORIGINAL }, -+ { "layout-alternate", UOPT_LAYOUT_ALTERNATE }, -+ { "layout-unspecified", UOPT_LAYOUT_UNSPECIFIED }, -+ { "byteorder", UOPT_BYTEORDER }, -+ { "help", UOPT_HELP }, -+ { "?", UOPT_HELP }, -+ { NULL, UOPT_UNDEFINED} -+}; - - /** - * map_num_s() - Safer alternative of map_num() function. -diff --git a/mdadm.c b/mdadm.c -index 74fdec31..f5f505fe 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -100,7 +100,7 @@ int main(int argc, char *argv[]) - char *dump_directory = NULL; - - int print_help = 0; -- FILE *outf; -+ FILE *outf = NULL; - - int mdfd = -1; - int locked = 0; -@@ -723,7 +723,11 @@ int main(int argc, char *argv[]) - continue; - - case O(ASSEMBLE,'U'): /* update the superblock */ -- case O(MISC,'U'): -+ case O(MISC,'U'): { -+ enum update_opt updateopt = map_name(update_options, c.update); -+ enum update_opt print_mode = UOPT_HELP; -+ const char *error_addon = "update option"; -+ - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", - c.update, optarg); -@@ -733,83 +737,37 @@ int main(int argc, char *argv[]) - pr_err("Only subarrays can be updated in misc mode\n"); - exit(2); - } -+ - c.update = optarg; -- if (strcmp(c.update, "sparc2.2") == 0) -- continue; -- if (strcmp(c.update, "super-minor") == 0) -- continue; -- if (strcmp(c.update, "summaries") == 0) -- continue; -- if (strcmp(c.update, "resync") == 0) -- continue; -- if (strcmp(c.update, "uuid") == 0) -- continue; -- if (strcmp(c.update, "name") == 0) -- continue; -- if (strcmp(c.update, "homehost") == 0) -- continue; -- if (strcmp(c.update, "home-cluster") == 0) -- continue; -- if (strcmp(c.update, "nodes") == 0) -- continue; -- if (strcmp(c.update, "devicesize") == 0) -- continue; -- if (strcmp(c.update, "bitmap") == 0) -- continue; -- if (strcmp(c.update, "no-bitmap") == 0) -- continue; -- if (strcmp(c.update, "bbl") == 0) -- continue; -- if (strcmp(c.update, "no-bbl") == 0) -- continue; -- if (strcmp(c.update, "force-no-bbl") == 0) -- continue; -- if (strcmp(c.update, "ppl") == 0) -- continue; -- if (strcmp(c.update, "no-ppl") == 0) -- continue; -- if (strcmp(c.update, "metadata") == 0) -- continue; -- if (strcmp(c.update, "revert-reshape") == 0) -- continue; -- if (strcmp(c.update, "layout-original") == 0 || -- strcmp(c.update, "layout-alternate") == 0 || -- strcmp(c.update, "layout-unspecified") == 0) -- continue; -- if (strcmp(c.update, "byteorder") == 0) { -+ -+ if (devmode == UpdateSubarray) { -+ print_mode = UOPT_SUBARRAY_ONLY; -+ error_addon = "update-subarray option"; -+ -+ if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -+ updateopt = UOPT_UNDEFINED; -+ } -+ -+ switch (updateopt) { -+ case UOPT_UNDEFINED: -+ pr_err("'--update=%s' is invalid %s. ", -+ c.update, error_addon); -+ outf = stderr; -+ case UOPT_HELP: -+ if (!outf) -+ outf = stdout; -+ fprint_update_options(outf, print_mode); -+ exit(outf == stdout ? 0 : 2); -+ case UOPT_BYTEORDER: - if (ss) { - pr_err("must not set metadata type with --update=byteorder.\n"); - exit(2); - } -- for(i = 0; !ss && superlist[i]; i++) -- ss = superlist[i]->match_metadata_desc( -- "0.swap"); -- if (!ss) { -- pr_err("INTERNAL ERROR cannot find 0.swap\n"); -- exit(2); -- } -- -- continue; -+ default: -+ break; - } -- if (strcmp(c.update,"?") == 0 || -- strcmp(c.update, "help") == 0) { -- outf = stdout; -- fprintf(outf, "%s: ", Name); -- } else { -- outf = stderr; -- fprintf(outf, -- "%s: '--update=%s' is invalid. ", -- Name, c.update); -- } -- fprintf(outf, "Valid --update options are:\n" -- " 'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n" -- " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n" -- " 'bitmap', 'no-bitmap', 'metadata', 'revert-reshape'\n" -- " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n" -- " 'layout-original', 'layout-alternate', 'layout-unspecified'\n" -- ); -- exit(outf == stdout ? 0 : 2); -- -+ continue; -+ } - case O(MANAGE,'U'): - /* update=devicesize is allowed with --re-add */ - if (devmode != 'A') { -diff --git a/mdadm.h b/mdadm.h -index 23ffe977..51f1db2d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -497,6 +497,36 @@ enum special_options { - ConsistencyPolicy, - }; - -+enum update_opt { -+ UOPT_NAME = 1, -+ UOPT_PPL, -+ UOPT_NO_PPL, -+ UOPT_BITMAP, -+ UOPT_NO_BITMAP, -+ UOPT_SUBARRAY_ONLY, -+ UOPT_SPARC22, -+ UOPT_SUPER_MINOR, -+ UOPT_SUMMARIES, -+ UOPT_RESYNC, -+ UOPT_UUID, -+ UOPT_HOMEHOST, -+ UOPT_HOME_CLUSTER, -+ UOPT_NODES, -+ UOPT_DEVICESIZE, -+ UOPT_BBL, -+ UOPT_NO_BBL, -+ UOPT_FORCE_NO_BBL, -+ UOPT_METADATA, -+ UOPT_REVERT_RESHAPE, -+ UOPT_LAYOUT_ORIGINAL, -+ UOPT_LAYOUT_ALTERNATE, -+ UOPT_LAYOUT_UNSPECIFIED, -+ UOPT_BYTEORDER, -+ UOPT_HELP, -+ UOPT_UNDEFINED -+}; -+extern void fprint_update_options(FILE *outf, enum update_opt update_mode); -+ - enum prefix_standard { - JEDEC, - IEC -@@ -777,7 +807,7 @@ extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], - pers[], modes[], faultylayout[]; --extern mapping_t consistency_policies[], sysfs_array_states[]; -+extern mapping_t consistency_policies[], sysfs_array_states[], update_options[]; - - extern char *map_dev_preferred(int major, int minor, int create, - char *prefer); --- -2.38.1 - diff --git a/0068-Fix-update-subarray-on-active-volume.patch b/0068-Fix-update-subarray-on-active-volume.patch deleted file mode 100644 index 7c1c4bc..0000000 --- a/0068-Fix-update-subarray-on-active-volume.patch +++ /dev/null @@ -1,54 +0,0 @@ -From db10eab68e652f141169b7240e057d110d626c3d Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:16 +0100 -Subject: [PATCH 68/83] Fix --update-subarray on active volume - -Options: bitmap, ppl and name should not be updated when array is active. -Those features are mutually exclusive and share the same data area in IMSM (danger of overwriting by kernel). -Remove check for active subarrays from super-intel. -Since ddf is not supported, apply it globally for all options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 7 +++++++ - super-intel.c | 5 ----- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/Manage.c b/Manage.c -index b1d0e630..5a9ea316 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1745,6 +1745,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -+ if (is_subarray_active(subarray, st->devnm)) { -+ if (verbose >= 0) -+ pr_err("Subarray %s in %s is active, cannot update %s\n", -+ subarray, dev, update); -+ goto free_super; -+ } -+ - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -diff --git a/super-intel.c b/super-intel.c -index b0565610..5f93f3d3 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7914,11 +7914,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - char *ep; - int vol; - -- if (is_subarray_active(subarray, st->devnm)) { -- pr_err("Unable to update name of active subarray\n"); -- return 2; -- } -- - if (!check_name(super, name, 0)) - return 2; - --- -2.38.1 - diff --git a/0069-Add-code-specific-update-options-to-enum.patch b/0069-Add-code-specific-update-options-to-enum.patch deleted file mode 100644 index 57386f5..0000000 --- a/0069-Add-code-specific-update-options-to-enum.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2257de106cbf17a7f1df33a10cfd2be0d5a064cb Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:17 +0100 -Subject: [PATCH 69/83] Add code specific update options to enum. - -Some of update options aren't taken from user input, but are hard-coded -as strings. -Include those options in enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - maps.c | 21 +++++++++++++++++++++ - mdadm.h | 15 +++++++++++++++ - 2 files changed, 36 insertions(+) - -diff --git a/maps.c b/maps.c -index b586679a..c59036f1 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,6 +194,27 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -+ /* -+ * Those enries are temporary and will be removed in this patchset. -+ * -+ * Before update_super:update can be changed to enum, -+ * all update_super sub-functions must be adapted first. -+ * Update options will be passed as string (as it is for now), -+ * and then mapped, so all options must be handled temporarily. -+ * -+ * Those options code specific and should not be accessible for user. -+ */ -+ { "force-one", UOPT_SPEC_FORCE_ONE }, -+ { "force-array", UOPT_SPEC_FORCE_ARRAY }, -+ { "assemble", UOPT_SPEC_ASSEMBLE }, -+ { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -+ { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -+ { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -+ { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -+ { "readwrite", UOPT_SPEC_READWRITE }, -+ { "failfast", UOPT_SPEC_FAILFAST }, -+ { "nofailfast", UOPT_SPEC_NOFAILFAST }, -+ { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 51f1db2d..31db25f5 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -523,6 +523,21 @@ enum update_opt { - UOPT_LAYOUT_UNSPECIFIED, - UOPT_BYTEORDER, - UOPT_HELP, -+ UOPT_USER_ONLY, -+ /* -+ * Code specific options, cannot be set by the user -+ */ -+ UOPT_SPEC_FORCE_ONE, -+ UOPT_SPEC_FORCE_ARRAY, -+ UOPT_SPEC_ASSEMBLE, -+ UOPT_SPEC_LINEAR_GROW_NEW, -+ UOPT_SPEC_LINEAR_GROW_UPDATE, -+ UOPT_SPEC__RESHAPE_PROGRESS, -+ UOPT_SPEC_WRITEMOSTLY, -+ UOPT_SPEC_READWRITE, -+ 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.38.1 - diff --git a/0070-super-ddf-Remove-update_super_ddf.patch b/0070-super-ddf-Remove-update_super_ddf.patch deleted file mode 100644 index 7a6d213..0000000 --- a/0070-super-ddf-Remove-update_super_ddf.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 35aa44c549290e22f285896684c704acb53b7717 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:18 +0100 -Subject: [PATCH 70/83] super-ddf: Remove update_super_ddf. - -This is not supported by ddf. -It hides errors by returning success status for some updates. -Remove update_super_dff(). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 70 ----------------------------------------------------- - 1 file changed, 70 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d1e3b94..309812df 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -2139,75 +2139,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha - } - } - --static int update_super_ddf(struct supertype *st, struct mdinfo *info, -- char *update, -- char *devname, int verbose, -- int uuid_set, char *homehost) --{ -- /* For 'assemble' and 'force' we need to return non-zero if any -- * change was made. For others, the return value is ignored. -- * Update options are: -- * force-one : This device looks a bit old but needs to be included, -- * update age info appropriately. -- * assemble: clear any 'faulty' flag to allow this device to -- * be assembled. -- * force-array: Array is degraded but being forced, mark it clean -- * if that will be needed to assemble it. -- * -- * newdev: not used ???? -- * grow: Array has gained a new device - this is currently for -- * linear only -- * resync: mark as dirty so a resync will happen. -- * uuid: Change the uuid of the array to match what is given -- * homehost: update the recorded homehost -- * name: update the name - preserving the homehost -- * _reshape_progress: record new reshape_progress position. -- * -- * Following are not relevant for this version: -- * sparc2.2 : update from old dodgey metadata -- * super-minor: change the preferred_minor number -- * summaries: update redundant counters. -- */ -- int rv = 0; --// struct ddf_super *ddf = st->sb; --// struct vd_config *vd = find_vdcr(ddf, info->container_member); --// struct virtual_entry *ve = find_ve(ddf); -- -- /* we don't need to handle "force-*" or "assemble" as -- * there is no need to 'trick' the kernel. When the metadata is -- * first updated to activate the array, all the implied modifications -- * will just happen. -- */ -- -- if (strcmp(update, "grow") == 0) { -- /* FIXME */ -- } else if (strcmp(update, "resync") == 0) { --// info->resync_checkpoint = 0; -- } else if (strcmp(update, "homehost") == 0) { -- /* homehost is stored in controller->vendor_data, -- * or it is when we are the vendor -- */ --// if (info->vendor_is_local) --// strcpy(ddf->controller.vendor_data, homehost); -- rv = -1; -- } else if (strcmp(update, "name") == 0) { -- /* name is stored in virtual_entry->name */ --// memset(ve->name, ' ', 16); --// strncpy(ve->name, info->name, 16); -- rv = -1; -- } else if (strcmp(update, "_reshape_progress") == 0) { -- /* We don't support reshape yet */ -- } else if (strcmp(update, "assemble") == 0 ) { -- /* Do nothing, just succeed */ -- rv = 0; -- } else -- rv = -1; -- --// update_all_csum(ddf); -- -- return rv; --} -- - static void make_header_guid(char *guid) - { - be32 stamp; -@@ -5211,7 +5142,6 @@ struct superswitch super_ddf = { - .match_home = match_home_ddf, - .uuid_from_super= uuid_from_super_ddf, - .getinfo_super = getinfo_super_ddf, -- .update_super = update_super_ddf, - - .avail_size = avail_size_ddf, - --- -2.38.1 - diff --git a/0071-super0-refactor-the-code-for-enum.patch b/0071-super0-refactor-the-code-for-enum.patch deleted file mode 100644 index f01c534..0000000 --- a/0071-super0-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0a9e39383d3bf63e1f5cf10f64200083a1af8091 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:19 +0100 -Subject: [PATCH 71/83] super0: refactor the code for enum - -It prepares update_super0 for change context->update to enum. -Change if else statements to switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super0.c | 102 ++++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 63 insertions(+), 39 deletions(-) - -diff --git a/super0.c b/super0.c -index 93876e2e..d9f5bff4 100644 ---- a/super0.c -+++ b/super0.c -@@ -502,19 +502,39 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update = "uuid"; -+ update_enum = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- if (strcmp(update, "sparc2.2")==0 ) { -+ switch (update_enum) { -+ case UOPT_UUID: -+ if (!uuid_set && homehost) { -+ char buf[20]; -+ memcpy(info->uuid+2, -+ sha1_buffer(homehost, strlen(homehost), buf), -+ 8); -+ } -+ sb->set_uuid0 = info->uuid[0]; -+ sb->set_uuid1 = info->uuid[1]; -+ sb->set_uuid2 = info->uuid[2]; -+ sb->set_uuid3 = info->uuid[3]; -+ if (sb->state & (1<uuid, uuid, 16); -+ } -+ break; -+ case UOPT_SPARC22: { - /* 2.2 sparc put the events in the wrong place - * So we copy the tail of the superblock - * up 4 bytes before continuing -@@ -527,12 +547,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (verbose >= 0) - pr_err("adjusting superblock of %s for 2.2/sparc compatibility.\n", - devname); -- } else if (strcmp(update, "super-minor") ==0) { -+ break; -+ } -+ case UOPT_SUPER_MINOR: - sb->md_minor = info->array.md_minor; - if (verbose > 0) - pr_err("updating superblock of %s with minor number %d\n", - devname, info->array.md_minor); -- } else if (strcmp(update, "summaries") == 0) { -+ break; -+ case UOPT_SUMMARIES: { - unsigned int i; - /* set nr_disks, active_disks, working_disks, - * failed_disks, spare_disks based on disks[] -@@ -559,7 +582,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->spare_disks++; - } else if (i >= sb->raid_disks && sb->disks[i].number == 0) - sb->disks[i].state = 0; -- } else if (strcmp(update, "force-one")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: { - /* Not enough devices for a working array, so - * bring this one up-to-date. - */ -@@ -569,7 +594,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (sb->events_hi != ehi || - sb->events_lo != elo) - rv = 1; -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ARRAY: - /* degraded array and 'force' requested, so - * maybe need to mark it 'clean' - */ -@@ -579,7 +606,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->state |= (1 << MD_SB_CLEAN); - rv = 1; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int wonly = sb->disks[d].state & (1<disks[d].state & (1<reshape_position = info->reshape_progress; - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: - memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); - sb->disks[info->disk.number].number = info->disk.number; - sb->disks[info->disk.number].major = info->disk.major; -@@ -617,7 +647,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; - sb->this_disk = sb->disks[info->disk.number]; -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: - sb->raid_disks = info->array.raid_disks; - sb->nr_disks = info->array.nr_disks; - sb->active_disks = info->array.active_disks; -@@ -628,29 +659,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].minor = info->disk.minor; - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -+ break; -+ case UOPT_RESYNC: -+ /* -+ * make sure resync happens -+ */ - sb->state &= ~(1<recovery_cp = 0; -- } else if (strcmp(update, "uuid") == 0) { -- if (!uuid_set && homehost) { -- char buf[20]; -- char *hash = sha1_buffer(homehost, -- strlen(homehost), -- buf); -- memcpy(info->uuid+2, hash, 8); -- } -- sb->set_uuid0 = info->uuid[0]; -- sb->set_uuid1 = info->uuid[1]; -- sb->set_uuid2 = info->uuid[2]; -- sb->set_uuid3 = info->uuid[3]; -- if (sb->state & (1<uuid, uuid, 16); -- } -- } else if (strcmp(update, "metadata") == 0) { -+ break; -+ case UOPT_METADATA: - /* Create some v1.0 metadata to match ours but make the - * ctime bigger. Also update info->array.*_version. - * We need to arrange that store_super writes out -@@ -670,7 +687,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - uuid_from_super0(st, info->uuid); - st->other = super1_make_v0(st, info, st->sb); - } -- } else if (strcmp(update, "revert-reshape") == 0) { -+ break; -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (sb->minor_version <= 90) - pr_err("No active reshape to revert on %s\n", -@@ -702,16 +720,22 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->new_chunk = sb->chunk_size; - sb->chunk_size = tmp; - } -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->state &= ~(1<reshape_position = info->reshape_progress; -- else if (strcmp(update, "writemostly")==0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->state |= (1<state &= ~(1<sb_csum = calc_sb0_csum(sb); - return rv; --- -2.38.1 - diff --git a/0072-super1-refactor-the-code-for-enum.patch b/0072-super1-refactor-the-code-for-enum.patch deleted file mode 100644 index bd164b8..0000000 --- a/0072-super1-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 7e8daba8b7937716dce8ea28298a4e2e72cb829e Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:20 +0100 -Subject: [PATCH 72/83] super1: refactor the code for enum - -It prepares update_super1 for change context->update to enum. -Change if else statements into switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super1.c | 152 +++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 91 insertions(+), 61 deletions(-) - -diff --git a/super1.c b/super1.c -index 0b505a7e..b0a97016 100644 ---- a/super1.c -+++ b/super1.c -@@ -1218,30 +1218,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* Note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update = "name"; -+ update_enum = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- strncpy(info->name, c+1, 31 - (c-sb->set_name)); -+ snprintf(info->name, sizeof(info->name), "%s", c+1); - else -- strncpy(info->name, sb->set_name, 32); -- info->name[32] = 0; -+ snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- if (strcmp(update, "force-one")==0) { -+ switch (update_enum) { -+ case UOPT_NAME: { -+ int namelen; -+ -+ if (!info->name[0]) -+ snprintf(info->name, sizeof(info->name), "%d", info->array.md_minor); -+ memset(sb->set_name, 0, sizeof(sb->set_name)); -+ -+ namelen = strnlen(homehost, MD_NAME_MAX) + 1 + strnlen(info->name, MD_NAME_MAX); -+ if (homehost && -+ strchr(info->name, ':') == NULL && -+ namelen < MD_NAME_MAX) { -+ strcpy(sb->set_name, homehost); -+ strcat(sb->set_name, ":"); -+ strcat(sb->set_name, info->name); -+ } else { -+ namelen = min((int)strnlen(info->name, MD_NAME_MAX), -+ (int)sizeof(sb->set_name) - 1); -+ memcpy(sb->set_name, info->name, namelen); -+ memset(&sb->set_name[namelen], '\0', -+ sizeof(sb->set_name) - namelen); -+ } -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: - /* Not enough devices for a working array, - * so bring this one up-to-date - */ - if (sb->events != __cpu_to_le64(info->events)) - rv = 1; - sb->events = __cpu_to_le64(info->events); -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ case UOPT_SPEC_FORCE_ARRAY: - /* Degraded array and 'force' requests to - * maybe need to mark it 'clean'. - */ -@@ -1254,7 +1279,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - rv = 1; - sb->resync_offset = MaxSector; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int want; - if (info->disk.state & (1<reshape_progress); - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: { - int i; - int fd; - int max = __le32_to_cpu(sb->max_dev); -@@ -1330,7 +1358,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - ds - __le64_to_cpu(sb->data_offset)); - } - } -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: { - int max = __le32_to_cpu(sb->max_dev); - int i = info->disk.number; - if (max > MAX_DEVS || i > MAX_DEVS) -@@ -1342,19 +1372,20 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -- sb->resync_offset = 0ULL; -- } else if (strcmp(update, "uuid") == 0) { -+ break; -+ } -+ case UOPT_UUID: - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - - if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) - memcpy(bms->uuid, sb->set_uuid, 16); -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); - if (bms->version == BITMAP_MAJOR_CLUSTERED && !IsBitmapDirty(devname)) - sb->resync_offset = MaxSector; -- } else if (strcmp(update, "bbl") == 0) { -+ break; -+ case UOPT_BBL: { - /* only possible if there is room after the bitmap, or if - * there is no bitmap - */ -@@ -1383,14 +1414,12 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - bb_offset = bitmap_offset + bm_sectors; - while (bb_offset < (long)sb_offset + 8 + 32*2 && - bb_offset + 8+8 <= (long)data_offset) -- /* too close to bitmap, and room to grow */ - bb_offset += 8; - if (bb_offset + 8 <= (long)data_offset) { - sb->bblog_size = __cpu_to_le16(8); - sb->bblog_offset = __cpu_to_le32(bb_offset); - } - } else { -- /* 1.0 - Put bbl just before super block */ - if (bm_sectors && bitmap_offset < 0) - space = -bitmap_offset - bm_sectors; - else -@@ -1401,7 +1430,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_offset = __cpu_to_le32((unsigned)-8); - } - } -- } else if (strcmp(update, "no-bbl") == 0) { -+ break; -+ } -+ case UOPT_NO_BBL: - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) - pr_err("Cannot remove active bbl from %s\n",devname); - else { -@@ -1409,12 +1440,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_shift = 0; - sb->bblog_offset = 0; - } -- } else if (strcmp(update, "force-no-bbl") == 0) { -+ break; -+ case UOPT_FORCE_NO_BBL: - sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_BAD_BLOCKS); - sb->bblog_size = 0; - sb->bblog_shift = 0; - sb->bblog_offset = 0; -- } else if (strcmp(update, "ppl") == 0) { -+ break; -+ case UOPT_PPL: { - unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); - unsigned long long data_offset = __le64_to_cpu(sb->data_offset); - unsigned long long data_size = __le64_to_cpu(sb->data_size); -@@ -1464,37 +1497,26 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->ppl.offset = __cpu_to_le16(offset); - sb->ppl.size = __cpu_to_le16(space); - sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); -- } else if (strcmp(update, "no-ppl") == 0) { -+ break; -+ } -+ case UOPT_NO_PPL: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | - MD_FEATURE_MUTLIPLE_PPLS); -- } else if (strcmp(update, "name") == 0) { -- if (info->name[0] == 0) -- sprintf(info->name, "%d", info->array.md_minor); -- memset(sb->set_name, 0, sizeof(sb->set_name)); -- if (homehost && -- strchr(info->name, ':') == NULL && -- strlen(homehost)+1+strlen(info->name) < 32) { -- strcpy(sb->set_name, homehost); -- strcat(sb->set_name, ":"); -- strcat(sb->set_name, info->name); -- } else { -- int namelen; -- -- namelen = min((int)strlen(info->name), -- (int)sizeof(sb->set_name) - 1); -- memcpy(sb->set_name, info->name, namelen); -- memset(&sb->set_name[namelen], '\0', -- sizeof(sb->set_name) - namelen); -- } -- } else if (strcmp(update, "devicesize") == 0 && -- __le64_to_cpu(sb->super_offset) < -- __le64_to_cpu(sb->data_offset)) { -- /* set data_size to device size less data_offset */ -+ break; -+ case UOPT_DEVICESIZE: -+ if (__le64_to_cpu(sb->super_offset) >= -+ __le64_to_cpu(sb->data_offset)) -+ break; -+ /* -+ * set data_size to device size less data_offset -+ */ - struct misc_dev_info *misc = (struct misc_dev_info*) - (st->sb + MAX_SB_SIZE + BM_SUPER_SIZE); - sb->data_size = __cpu_to_le64( - misc->device_size - __le64_to_cpu(sb->data_offset)); -- } else if (strncmp(update, "revert-reshape", 14) == 0) { -+ break; -+ case UOPT_SPEC_REVERT_RESHAPE_NOBACKUP: -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (!(sb->feature_map & - __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) -@@ -1512,7 +1534,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (strcmp(update, "revert-reshape-nobackup") == 0 && -+ if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1575,32 +1597,40 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - } - done:; - } -- } else if (strcmp(update, "_reshape_progress") == 0) -+ break; -+ case UOPT_SPEC__RESHAPE_PROGRESS: - sb->reshape_position = __cpu_to_le64(info->reshape_progress); -- else if (strcmp(update, "writemostly") == 0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->devflags |= WriteMostly1; -- else if (strcmp(update, "readwrite") == 0) -+ break; -+ case UOPT_SPEC_READWRITE: - sb->devflags &= ~WriteMostly1; -- else if (strcmp(update, "failfast") == 0) -+ break; -+ case UOPT_SPEC_FAILFAST: - sb->devflags |= FailFast1; -- else if (strcmp(update, "nofailfast") == 0) -+ break; -+ case UOPT_SPEC_NOFAILFAST: - sb->devflags &= ~FailFast1; -- else if (strcmp(update, "layout-original") == 0 || -- strcmp(update, "layout-alternate") == 0 || -- strcmp(update, "layout-unspecified") == 0) { -+ break; -+ case UOPT_LAYOUT_ORIGINAL: -+ case UOPT_LAYOUT_ALTERNATE: -+ case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname?:"", update); -+ devname ?: "", map_num(update_options, update_enum)); - rv = -1; -- } else if (strcmp(update, "layout-unspecified") == 0) { -+ } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); -+ sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } -- } else -+ break; -+ default: - rv = -1; -+ } - - sb->sb_csum = calc_sb_1_csum(sb); - --- -2.38.1 - diff --git a/0073-super-intel-refactor-the-code-for-enum.patch b/0073-super-intel-refactor-the-code-for-enum.patch deleted file mode 100644 index 6756297..0000000 --- a/0073-super-intel-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 4345e135c4c7dd04bb15bad140dfc4747f677738 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:21 +0100 -Subject: [PATCH 73/83] super-intel: refactor the code for enum - -It prepares super-intel for change context->update to enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 37 +++++++++++++++++++++++++------------ - 1 file changed, 25 insertions(+), 12 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5f93f3d3..85fb7f17 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3930,7 +3930,8 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- if (strcmp(update, "uuid") == 0) { -+ switch (map_name(update_options, update)) { -+ case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really - * allow an explicit uuid to be given. And it is hard to reliably -@@ -3954,10 +3955,14 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - } - if (rv == 0) - mpb->orig_family_num = info->uuid[0]; -- } else if (strcmp(update, "assemble") == 0) -+ break; -+ case UOPT_SPEC_ASSEMBLE: - rv = 0; -- else -+ break; -+ default: - rv = -1; -+ break; -+ } - - /* successful update? recompute checksum */ - if (rv == 0) -@@ -7889,17 +7894,25 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) - return 0; - } - --static int get_rwh_policy_from_update(char *update) -+/** -+ * get_rwh_policy_from_update() - Get the rwh policy for update option. -+ * @update: Update option. -+ */ -+static int get_rwh_policy_from_update(enum update_opt update) - { -- if (strcmp(update, "ppl") == 0) -+ switch (update) { -+ case UOPT_PPL: - return RWH_MULTIPLE_DISTRIBUTED; -- else if (strcmp(update, "no-ppl") == 0) -+ case UOPT_NO_PPL: - return RWH_MULTIPLE_OFF; -- else if (strcmp(update, "bitmap") == 0) -+ case UOPT_BITMAP: - return RWH_BITMAP; -- else if (strcmp(update, "no-bitmap") == 0) -+ case UOPT_NO_BITMAP: - return RWH_OFF; -- return -1; -+ default: -+ break; -+ } -+ return UOPT_UNDEFINED; - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -@@ -7909,7 +7922,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (strcmp(update, "name") == 0) { -+ if (map_name(update_options, update) == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7943,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(update) != -1) { -+ } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7951,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(update); -+ new_policy = get_rwh_policy_from_update(map_name(update_options, update)); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); --- -2.38.1 - diff --git a/0074-Change-update-to-enum-in-update_super-and-update_sub.patch b/0074-Change-update-to-enum-in-update_super-and-update_sub.patch deleted file mode 100644 index c9e186e..0000000 --- a/0074-Change-update-to-enum-in-update_super-and-update_sub.patch +++ /dev/null @@ -1,424 +0,0 @@ -From 03312b5240438ffc3b63114bdc87e911222f01e5 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:22 +0100 -Subject: [PATCH 74/83] Change update to enum in update_super and - update_subarray - -Use already existing enum, change update_super and update_subarray -update to enum globally. -Refactor function references also. -Remove code specific options from update_options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 14 +++++++++----- - Examine.c | 2 +- - Grow.c | 9 +++++---- - Manage.c | 14 ++++++++------ - maps.c | 21 --------------------- - mdadm.h | 12 +++++++++--- - super-intel.c | 16 ++++++++-------- - super0.c | 9 ++++----- - super1.c | 17 ++++++++--------- - 9 files changed, 52 insertions(+), 62 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 8b0af0c9..dba910cd 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -695,12 +695,16 @@ static int load_devices(struct devs *devices, char *devmap, - } else if (strcmp(c->update, "revert-reshape") == 0 && - c->invalid_backup) - err = tst->ss->update_super(tst, content, -- "revert-reshape-nobackup", -+ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- err = tst->ss->update_super(tst, content, c->update, -+ /* -+ * Mapping is temporary, will be removed in this patchset -+ */ -+ err = tst->ss->update_super(tst, content, -+ map_name(update_options, c->update), - devname, c->verbose, - ident->uuid_set, - c->homehost); -@@ -960,7 +964,7 @@ static int force_array(struct mdinfo *content, - continue; - } - content->events = devices[most_recent].i.events; -- tst->ss->update_super(tst, content, "force-one", -+ tst->ss->update_super(tst, content, UOPT_SPEC_FORCE_ONE, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - -@@ -1788,7 +1792,7 @@ try_again: - if (!(devices[j].i.array.state & 1)) - clean = 0; - -- if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, -+ if (st->ss->update_super(st, &devices[j].i, UOPT_SPEC_ASSEMBLE, NULL, - c->verbose, 0, NULL)) { - if (c->force) { - if (c->verbose >= 0) -@@ -1811,7 +1815,7 @@ try_again: - if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { -- change += st->ss->update_super(st, content, "force-array", -+ change += st->ss->update_super(st, content, UOPT_SPEC_FORCE_ARRAY, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - was_forced = 1; -diff --git a/Examine.c b/Examine.c -index 9574a3cc..c9605a60 100644 ---- a/Examine.c -+++ b/Examine.c -@@ -117,7 +117,7 @@ int Examine(struct mddev_dev *devlist, - } - - if (c->SparcAdjust) -- st->ss->update_super(st, NULL, "sparc2.2", -+ st->ss->update_super(st, NULL, UOPT_SPARC22, - devlist->devname, 0, 0, NULL); - /* Ok, its good enough to try, though the checksum could be wrong */ - -diff --git a/Grow.c b/Grow.c -index b73ec2ae..82d5d2ea 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -196,7 +196,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.disk.minor = minor(rdev); - info.disk.raid_disk = d; - info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); -- if (st->ss->update_super(st, &info, "linear-grow-new", newdev, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_NEW, newdev, - 0, 0, NULL) != 0) { - pr_err("Preparing new metadata failed on %s\n", newdev); - close(nfd); -@@ -254,7 +254,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.array.active_disks = nd+1; - info.array.working_disks = nd+1; - -- if (st->ss->update_super(st, &info, "linear-grow-update", dv, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_UPDATE, dv, - 0, 0, NULL) != 0) { - pr_err("Updating metadata failed on %s\n", dv); - close(fd2); -@@ -668,7 +668,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - goto free_info; - } - -- ret = st->ss->update_super(st, sra, "ppl", -+ ret = st->ss->update_super(st, sra, UOPT_PPL, - devname, - c->verbose, 0, NULL); - if (ret) { -@@ -4950,7 +4950,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, - continue; - st->ss->getinfo_super(st, &dinfo, NULL); - dinfo.reshape_progress = info->reshape_progress; -- st->ss->update_super(st, &dinfo, "_reshape_progress", -+ st->ss->update_super(st, &dinfo, -+ UOPT_SPEC__RESHAPE_PROGRESS, - NULL,0, 0, NULL); - st->ss->store_super(st, fdlist[j]); - st->ss->free_super(st); -diff --git a/Manage.c b/Manage.c -index 5a9ea316..87b8aa0c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -605,6 +605,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -+ enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -666,23 +667,23 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - - if (dv->writemostly == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "writemostly", -+ dev_st, NULL, UOPT_SPEC_WRITEMOSTLY, - devname, verbose, 0, NULL); - if (dv->writemostly == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "readwrite", -+ dev_st, NULL, UOPT_SPEC_READWRITE, - devname, verbose, 0, NULL); - if (dv->failfast == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "failfast", -+ dev_st, NULL, UOPT_SPEC_FAILFAST, - devname, verbose, 0, NULL); - if (dv->failfast == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "nofailfast", -+ dev_st, NULL, UOPT_SPEC_NOFAILFAST, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update, -+ dev_st, NULL, update_enum, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -1731,6 +1732,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -+ enum update_opt update_enum = map_name(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1762,7 +1764,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update, ident); -+ rv = st->ss->update_subarray(st, subarray, update_enum, ident); - - if (rv) { - if (verbose >= 0) -diff --git a/maps.c b/maps.c -index c59036f1..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,27 +194,6 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -- /* -- * Those enries are temporary and will be removed in this patchset. -- * -- * Before update_super:update can be changed to enum, -- * all update_super sub-functions must be adapted first. -- * Update options will be passed as string (as it is for now), -- * and then mapped, so all options must be handled temporarily. -- * -- * Those options code specific and should not be accessible for user. -- */ -- { "force-one", UOPT_SPEC_FORCE_ONE }, -- { "force-array", UOPT_SPEC_FORCE_ARRAY }, -- { "assemble", UOPT_SPEC_ASSEMBLE }, -- { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -- { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -- { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -- { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -- { "readwrite", UOPT_SPEC_READWRITE }, -- { "failfast", UOPT_SPEC_FAILFAST }, -- { "nofailfast", UOPT_SPEC_NOFAILFAST }, -- { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 31db25f5..5dc94390 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1011,7 +1011,7 @@ extern struct superswitch { - * it will resume going in the opposite direction. - */ - int (*update_super)(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost); - -@@ -1137,9 +1137,15 @@ extern struct superswitch { - /* Permit subarray's to be deleted from inactive containers */ - int (*kill_subarray)(struct supertype *st, - char *subarray_id); /* optional */ -- /* Permit subarray's to be modified */ -+ /** -+ * update_subarray() - Permit subarray to be modified. -+ * @st: Supertype. -+ * @subarray: Subarray name. -+ * @update: Update option. -+ * @ident: Optional identifiers. -+ */ - int (*update_subarray)(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident); /* optional */ -+ enum update_opt update, struct mddev_ident *ident); - /* Check if reshape is supported for this external format. - * st is obtained from super_by_fd() where st->subarray[0] is - * initialized to indicate if reshape is being performed at the -diff --git a/super-intel.c b/super-intel.c -index 85fb7f17..1f5f6eda 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3893,8 +3893,8 @@ struct mdinfo *getinfo_super_disks_imsm(struct supertype *st) - } - - static int update_super_imsm(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -- int uuid_set, char *homehost) -+ enum update_opt update, char *devname, -+ int verbose, int uuid_set, char *homehost) - { - /* For 'assemble' and 'force' we need to return non-zero if any - * change was made. For others, the return value is ignored. -@@ -3930,7 +3930,7 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- switch (map_name(update_options, update)) { -+ switch (update) { - case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really -@@ -6538,7 +6538,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, - if (mdmon_running(st->container_devnm)) - st->update_tail = &st->updates; - -- if (st->ss->update_subarray(st, subarray, "ppl", NULL)) { -+ if (st->ss->update_subarray(st, subarray, UOPT_PPL, NULL)) { - pr_err("Failed to update subarray %s\n", - subarray); - } else { -@@ -7916,13 +7916,13 @@ static int get_rwh_policy_from_update(enum update_opt update) - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident) -+ enum update_opt update, struct mddev_ident *ident) - { - /* update the subarray currently referenced by ->current_vol */ - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (map_name(update_options, update) == UOPT_NAME) { -+ if (update == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7956,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { -+ } else if (get_rwh_policy_from_update(update) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7964,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(map_name(update_options, update)); -+ new_policy = get_rwh_policy_from_update(update); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); -diff --git a/super0.c b/super0.c -index d9f5bff4..a7c5f813 100644 ---- a/super0.c -+++ b/super0.c -@@ -491,7 +491,7 @@ static struct mdinfo *container_content0(struct supertype *st, char *subarray) - } - - static int update_super0(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost) - { -@@ -502,20 +502,19 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update_enum = UOPT_UUID; -+ update = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_UUID: - if (!uuid_set && homehost) { - char buf[20]; -diff --git a/super1.c b/super1.c -index b0a97016..f7020320 100644 ---- a/super1.c -+++ b/super1.c -@@ -1208,7 +1208,7 @@ static struct mdinfo *container_content1(struct supertype *st, char *subarray) - } - - static int update_super1(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -+ enum update_opt update, char *devname, int verbose, - int uuid_set, char *homehost) - { - /* NOTE: for 'assemble' and 'force' we need to return non-zero -@@ -1218,15 +1218,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update_enum = UOPT_NAME; -+ update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) - snprintf(info->name, sizeof(info->name), "%s", c+1); -@@ -1234,7 +1233,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_NAME: { - int namelen; - -@@ -1534,7 +1533,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && -+ if (update == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1618,14 +1617,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname ?: "", map_num(update_options, update_enum)); -+ devname ?: "", map_num(update_options, update)); - rv = -1; -- } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { -+ } else if (update == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); -+ sb->layout = __cpu_to_le32(update == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } - break; - default: --- -2.38.1 - diff --git a/0075-Manage-Incremental-code-refactor-string-to-enum.patch b/0075-Manage-Incremental-code-refactor-string-to-enum.patch deleted file mode 100644 index d4b20ff..0000000 --- a/0075-Manage-Incremental-code-refactor-string-to-enum.patch +++ /dev/null @@ -1,279 +0,0 @@ -From f2e8393bd7223c419aaa33c45feeb5c75440b986 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:23 +0100 -Subject: [PATCH 75/83] Manage&Incremental: code refactor, string to enum - -Prepare Manage and Incremental for later changing context->update to enum. -Change update from string to enum in multiple functions and pass enum -where already possible. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++---- - Incremental.c | 8 ++++---- - Manage.c | 35 +++++++++++++++++------------------ - mdadm.c | 23 ++++++++++++++++++----- - mdadm.h | 4 ++-- - 5 files changed, 45 insertions(+), 33 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 82d5d2ea..8f5cf07d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -605,12 +605,12 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - if (subarray) { -- char *update; -+ enum update_opt update; - - if (s->consistency_policy == CONSISTENCY_POLICY_PPL) -- update = "ppl"; -+ update = UOPT_PPL; - else -- update = "no-ppl"; -+ update = UOPT_NO_PPL; - - sprintf(container_dev, "/dev/%s", st->container_devnm); - -@@ -3243,7 +3243,7 @@ static int reshape_array(char *container, int fd, char *devname, - * level and frozen, we can safely add them. - */ - if (devlist) { -- if (Manage_subdevs(devname, fd, devlist, verbose, 0, NULL, 0)) -+ if (Manage_subdevs(devname, fd, devlist, verbose, 0, UOPT_UNDEFINED, 0)) - goto release; - } - -diff --git a/Incremental.c b/Incremental.c -index 5a5f4c4c..ff3548c0 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1025,7 +1025,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, - close(dfd); - *dfdp = -1; - rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - close(mdfd); - } - if (verbose > 0) { -@@ -1666,7 +1666,7 @@ static void remove_from_member_array(struct mdstat_ent *memb, - - if (subfd >= 0) { - rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, -- 0, NULL, 0); -+ 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - if (sysfs_init(&mmdi, -1, memb->devnm)) - pr_err("unable to initialize sysfs for: %s\n", -@@ -1758,7 +1758,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - free_mdstat(mdstat); - } else { - rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - /* Failed due to EBUSY, try to stop the array. - * Give udisks a chance to unmount it first. -@@ -1770,7 +1770,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - devlist.disposition = 'r'; - rv = Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - end: - close(mdfd); - free_mdstat(ent); -diff --git a/Manage.c b/Manage.c -index 87b8aa0c..594e3d2c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -598,14 +598,12 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) - - int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *dev_st, struct supertype *tst, -- unsigned long rdev, -- char *update, char *devname, int verbose, -- mdu_array_info_t *array) -+ unsigned long rdev, enum update_opt update, -+ char *devname, int verbose, mdu_array_info_t *array) - { - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -- enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -683,7 +681,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update_enum, -+ dev_st, NULL, update, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -715,8 +713,8 @@ skip_re_add: - 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, -- char *update, unsigned long rdev, unsigned long long array_size, -- int raid_slot) -+ enum update_opt update, unsigned long rdev, -+ unsigned long long array_size, int raid_slot) - { - unsigned long long ldsize; - struct supertype *dev_st; -@@ -1332,7 +1330,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force) -+ enum update_opt update, int force) - { - /* Do something to each dev. - * devmode can be -@@ -1727,12 +1725,13 @@ int autodetect(void) - return rv; - } - --int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int verbose) -+int Update_subarray(char *dev, char *subarray, enum update_opt update, -+ struct mddev_ident *ident, int verbose) - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -- enum update_opt update_enum = map_name(update_options, update); -+ char *update_verb = map_num(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1750,7 +1749,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (is_subarray_active(subarray, st->devnm)) { - if (verbose >= 0) - pr_err("Subarray %s in %s is active, cannot update %s\n", -- subarray, dev, update); -+ subarray, dev, update_verb); - goto free_super; - } - -@@ -1759,23 +1758,23 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - - info = st->ss->container_content(st, subarray); - -- if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ if (update == UOPT_PPL && !is_level456(info->array.level)) { - pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update_enum, ident); -+ rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { - if (verbose >= 0) - pr_err("Failed to update %s of subarray-%s in %s\n", -- update, subarray, dev); -+ update_verb, subarray, dev); - } else if (st->update_tail) - flush_metadata_updates(st); - else - st->ss->sync_metadata(st); - -- if (rv == 0 && strcmp(update, "name") == 0 && verbose >= 0) -+ if (rv == 0 && update == UOPT_NAME && verbose >= 0) - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -@@ -1816,10 +1815,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - sprintf(devname, "%d:%d", major(devid), minor(devid)); - - devlist.disposition = 'r'; -- if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { -+ if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, UOPT_UNDEFINED, 0) == 0) { - devlist.disposition = 'a'; - if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, -- NULL, 0) == 0) { -+ UOPT_UNDEFINED, 0) == 0) { - /* make sure manager is aware of changes */ - ping_manager(to_devname); - ping_manager(from_devname); -@@ -1829,7 +1828,7 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - } - else - Manage_subdevs(from_devname, fd2, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - } - close(fd1); - close(fd2); -diff --git a/mdadm.c b/mdadm.c -index f5f505fe..d06e2820 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1402,10 +1402,22 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found>1) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- c.update, c.force); -+ if (!rv && devs_found > 1) { -+ /* -+ * This is temporary and will be removed in next patches -+ * Null c.update will cause segfault -+ */ -+ if (c.update) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ map_name(update_options, c.update), -+ c.force); -+ else -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ UOPT_UNDEFINED, -+ c.force); -+ } - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1931,7 +1943,8 @@ static int misc_list(struct mddev_dev *devlist, - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- c->update, ident, c->verbose); -+ map_name(update_options, c->update), -+ ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 5dc94390..924f4b63 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1478,7 +1478,7 @@ extern int Manage_stop(char *devname, int fd, int quiet, - int will_retry); - extern int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force); -+ enum update_opt update, int force); - extern int autodetect(void); - extern int Grow_Add_device(char *devname, int fd, char *newdev); - extern int Grow_addbitmap(char *devname, int fd, -@@ -1532,7 +1532,7 @@ extern int Monitor(struct mddev_dev *devlist, - - extern int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl); - extern int Kill_subarray(char *dev, char *subarray, int verbose); --extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet); -+extern int Update_subarray(char *dev, char *subarray, enum update_opt update, struct mddev_ident *ident, int quiet); - extern int Wait(char *dev); - extern int WaitClean(char *dev, int verbose); - extern int SetAction(char *dev, char *action); --- -2.38.1 - diff --git a/0076-Change-char-to-enum-in-context-update-refactor-code.patch b/0076-Change-char-to-enum-in-context-update-refactor-code.patch deleted file mode 100644 index a18f8d1..0000000 --- a/0076-Change-char-to-enum-in-context-update-refactor-code.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 3a87fa67112dc2c2c3664aeecd0b49cb4b6ceaa9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:24 +0100 -Subject: [PATCH 76/83] Change char* to enum in context->update & refactor code - -Storing update option in string is bad for frequent comparisons and -error prone. -Replace char array with enum so already existing enum is passed around -instead of string. -Adapt code to changes. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 40 +++++++++++++++++----------------------- - mdadm.c | 52 +++++++++++++++++++--------------------------------- - mdadm.h | 2 +- - 3 files changed, 37 insertions(+), 57 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index dba910cd..49804941 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -135,17 +135,17 @@ static int ident_matches(struct mddev_ident *ident, - struct mdinfo *content, - struct supertype *tst, - char *homehost, int require_homehost, -- char *update, char *devname) -+ enum update_opt update, char *devname) - { - -- if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) && -+ if (ident->uuid_set && update != UOPT_UUID && - same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 && - memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) { - if (devname) - pr_err("%s has wrong uuid.\n", devname); - return 0; - } -- if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && -+ if (ident->name[0] && update != UOPT_NAME && - name_matches(content->name, ident->name, homehost, require_homehost)==0) { - if (devname) - pr_err("%s has wrong name.\n", devname); -@@ -648,11 +648,10 @@ static int load_devices(struct devs *devices, char *devmap, - int err; - fstat(mdfd, &stb2); - -- if (strcmp(c->update, "uuid") == 0 && !ident->uuid_set) -+ if (c->update == UOPT_UUID && !ident->uuid_set) - random_uuid((__u8 *)ident->uuid); - -- if (strcmp(c->update, "ppl") == 0 && -- ident->bitmap_fd >= 0) { -+ if (c->update == UOPT_PPL && ident->bitmap_fd >= 0) { - pr_err("PPL is not compatible with bitmap\n"); - close(mdfd); - free(devices); -@@ -684,34 +683,30 @@ static int load_devices(struct devs *devices, char *devmap, - strcpy(content->name, ident->name); - content->array.md_minor = minor(stb2.st_rdev); - -- if (strcmp(c->update, "byteorder") == 0) -+ if (c->update == UOPT_BYTEORDER) - err = 0; -- else if (strcmp(c->update, "home-cluster") == 0) { -+ else if (c->update == UOPT_HOME_CLUSTER) { - tst->cluster_name = c->homecluster; - err = tst->ss->write_bitmap(tst, dfd, NameUpdate); -- } else if (strcmp(c->update, "nodes") == 0) { -+ } else if (c->update == UOPT_NODES) { - tst->nodes = c->nodes; - err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate); -- } else if (strcmp(c->update, "revert-reshape") == 0 && -- c->invalid_backup) -+ } else if (c->update == UOPT_REVERT_RESHAPE && c->invalid_backup) - err = tst->ss->update_super(tst, content, - UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- /* -- * Mapping is temporary, will be removed in this patchset -- */ - err = tst->ss->update_super(tst, content, -- map_name(update_options, c->update), -+ c->update, - devname, c->verbose, - ident->uuid_set, - c->homehost); - if (err < 0) { - if (err == -1) - pr_err("--update=%s not understood for %s metadata\n", -- c->update, tst->ss->name); -+ map_num(update_options, c->update), tst->ss->name); - tst->ss->free_super(tst); - free(tst); - close(mdfd); -@@ -721,7 +716,7 @@ static int load_devices(struct devs *devices, char *devmap, - *stp = st; - return -1; - } -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - !ident->uuid_set) { - ident->uuid_set = 1; - memcpy(ident->uuid, content->uuid, 16); -@@ -730,7 +725,7 @@ static int load_devices(struct devs *devices, char *devmap, - pr_err("Could not re-write superblock on %s.\n", - devname); - -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - ident->bitmap_fd >= 0 && !bitmap_done) { - if (bitmap_update_uuid(ident->bitmap_fd, - content->uuid, -@@ -1188,8 +1183,7 @@ static int start_array(int mdfd, - pr_err("%s: Need a backup file to complete reshape of this array.\n", - mddev); - pr_err("Please provided one with \"--backup-file=...\"\n"); -- if (c->update && -- strcmp(c->update, "revert-reshape") == 0) -+ if (c->update == UOPT_REVERT_RESHAPE) - pr_err("(Don't specify --update=revert-reshape again, that part succeeded.)\n"); - return 1; - } -@@ -1487,7 +1481,7 @@ try_again: - */ - if (map_lock(&map)) - pr_err("failed to get exclusive lock on mapfile - continue anyway...\n"); -- if (c->update && strcmp(c->update,"uuid") == 0) -+ if (c->update == UOPT_UUID) - mp = NULL; - else - mp = map_by_uuid(&map, content->uuid); -@@ -1634,7 +1628,7 @@ try_again: - goto out; - } - -- if (c->update && strcmp(c->update, "byteorder")==0) -+ if (c->update == UOPT_BYTEORDER) - st->minor_version = 90; - - st->ss->getinfo_super(st, content, NULL); -@@ -1902,7 +1896,7 @@ try_again: - /* First, fill in the map, so that udev can find our name - * as soon as we become active. - */ -- if (c->update && strcmp(c->update, "metadata")==0) { -+ if (c->update == UOPT_METADATA) { - content->array.major_version = 1; - content->array.minor_version = 0; - strcpy(content->text_version, "1.0"); -diff --git a/mdadm.c b/mdadm.c -index d06e2820..57e8e6fa 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -724,13 +724,12 @@ int main(int argc, char *argv[]) - - case O(ASSEMBLE,'U'): /* update the superblock */ - case O(MISC,'U'): { -- enum update_opt updateopt = map_name(update_options, c.update); - enum update_opt print_mode = UOPT_HELP; - const char *error_addon = "update option"; - - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } - if (mode == MISC && !c.subarray) { -@@ -738,20 +737,20 @@ int main(int argc, char *argv[]) - exit(2); - } - -- c.update = optarg; -+ c.update = map_name(update_options, optarg); - - if (devmode == UpdateSubarray) { - print_mode = UOPT_SUBARRAY_ONLY; - error_addon = "update-subarray option"; - -- if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -- updateopt = UOPT_UNDEFINED; -+ if (c.update > UOPT_SUBARRAY_ONLY && c.update < UOPT_HELP) -+ c.update = UOPT_UNDEFINED; - } - -- switch (updateopt) { -+ switch (c.update) { - case UOPT_UNDEFINED: - pr_err("'--update=%s' is invalid %s. ", -- c.update, error_addon); -+ optarg, error_addon); - outf = stderr; - case UOPT_HELP: - if (!outf) -@@ -776,14 +775,14 @@ int main(int argc, char *argv[]) - } - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } -- c.update = optarg; -- if (strcmp(c.update, "devicesize") != 0 && -- strcmp(c.update, "bbl") != 0 && -- strcmp(c.update, "force-no-bbl") != 0 && -- strcmp(c.update, "no-bbl") != 0) { -+ c.update = map_name(update_options, optarg); -+ if (c.update != UOPT_DEVICESIZE && -+ c.update != UOPT_BBL && -+ c.update != UOPT_NO_BBL && -+ c.update != UOPT_FORCE_NO_BBL) { - pr_err("only 'devicesize', 'bbl', 'no-bbl', and 'force-no-bbl' can be updated with --re-add\n"); - exit(2); - } -@@ -1357,7 +1356,7 @@ int main(int argc, char *argv[]) - } - } - -- if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) { -+ if (c.update && c.update == UOPT_NODES && c.nodes == 0) { - pr_err("Please specify nodes number with --nodes\n"); - exit(1); - } -@@ -1402,22 +1401,10 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found > 1) { -- /* -- * This is temporary and will be removed in next patches -- * Null c.update will cause segfault -- */ -- if (c.update) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- map_name(update_options, c.update), -- c.force); -- else -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- UOPT_UNDEFINED, -- c.force); -- } -+ if (!rv && devs_found > 1) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, -+ c.test, c.update, c.force); - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1937,14 +1924,13 @@ static int misc_list(struct mddev_dev *devlist, - rv |= Kill_subarray(dv->devname, c->subarray, c->verbose); - continue; - case UpdateSubarray: -- if (c->update == NULL) { -+ if (!c->update) { - pr_err("-U/--update must be specified with --update-subarray\n"); - rv |= 1; - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- map_name(update_options, c->update), -- ident, c->verbose); -+ c->update, ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 924f4b63..13f8b4cb 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -616,7 +616,7 @@ struct context { - int export; - int test; - char *subarray; -- char *update; -+ enum update_opt update; - int scan; - int SparcAdjust; - int autof; --- -2.38.1 - diff --git a/0077-mdmon-fix-segfault.patch b/0077-mdmon-fix-segfault.patch deleted file mode 100644 index 980ceda..0000000 --- a/0077-mdmon-fix-segfault.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 9b429fc0a4ffd7028b3b336589d38e32fb9045dc Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:21 +0100 -Subject: [PATCH 77/83] mdmon: fix segfault - -Mdmon crashes if stat2devnm returns null. -Use open_mddev to check if device is mddevice and get name using -fd2devnm. -Refactor container name handling. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Makefile | 2 +- - mdmon.c | 26 ++++++++++++-------------- - 2 files changed, 13 insertions(+), 15 deletions(-) - -diff --git a/Makefile b/Makefile -index ec1f99ed..5eac1a4e 100644 ---- a/Makefile -+++ b/Makefile -@@ -160,7 +160,7 @@ SRCS = $(patsubst %.o,%.c,$(OBJS)) - - INCL = mdadm.h part.h bitmap.h - --MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \ -+MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o config.o mapfile.o mdopen.o\ - policy.o lib.o \ - Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ - super-mbr.o super-gpt.o \ -diff --git a/mdmon.c b/mdmon.c -index e9d035eb..ecf52dc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -363,14 +363,14 @@ int main(int argc, char *argv[]) - } - - if (all == 0 && container_name == NULL) { -- if (argv[optind]) -- container_name = argv[optind]; -+ if (argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ container_name = argv[optind]; -+ } - } - -- if (container_name == NULL) -- usage(); -- -- if (argc - optind > 1) -+ if (container_name == NULL || argc - optind > 1) - usage(); - - if (strcmp(container_name, "/proc/mdstat") == 0) -@@ -402,21 +402,19 @@ int main(int argc, char *argv[]) - free_mdstat(mdstat); - - return status; -- } else if (strncmp(container_name, "md", 2) == 0) { -- int id = devnm2devid(container_name); -- if (id) -- devnm = container_name; - } else { -- struct stat st; -+ int mdfd = open_mddev(container_name, 1); - -- if (stat(container_name, &st) == 0) -- devnm = xstrdup(stat2devnm(&st)); -+ if (mdfd < 0) -+ return 1; -+ devnm = fd2devnm(mdfd); -+ close(mdfd); - } - - if (!devnm) { - pr_err("%s is not a valid md device name\n", - container_name); -- exit(1); -+ return 1; - } - return mdmon(devnm, dofork && do_fork(), takeover); - } --- -2.38.1 - diff --git a/0078-util-remove-obsolete-code-from-get_md_name.patch b/0078-util-remove-obsolete-code-from-get_md_name.patch deleted file mode 100644 index b371d39..0000000 --- a/0078-util-remove-obsolete-code-from-get_md_name.patch +++ /dev/null @@ -1,116 +0,0 @@ -From b938519e7719c992dae2d61c796c45fe49e6b71b Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:22 +0100 -Subject: [PATCH 78/83] util: remove obsolete code from get_md_name - -get_md_name() is used only with mdstat entries. -Remove dead code and simplyfy function. - -Remove redundadnt checks from mdmon.c - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 8 +++----- - util.c | 51 +++++++++++++++++---------------------------------- - 2 files changed, 20 insertions(+), 39 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index ecf52dc8..60ba3182 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -366,7 +366,7 @@ int main(int argc, char *argv[]) - if (argv[optind]) { - container_name = get_md_name(argv[optind]); - if (!container_name) -- container_name = argv[optind]; -+ return 1; - } - } - -@@ -403,11 +403,9 @@ int main(int argc, char *argv[]) - - return status; - } else { -- int mdfd = open_mddev(container_name, 1); -- -- if (mdfd < 0) -- return 1; -+ int mdfd = open_mddev(container_name, 0); - devnm = fd2devnm(mdfd); -+ - close(mdfd); - } - -diff --git a/util.c b/util.c -index 26ffdcea..9cd89fa4 100644 ---- a/util.c -+++ b/util.c -@@ -968,47 +968,30 @@ dev_t devnm2devid(char *devnm) - return 0; - } - -+/** -+ * get_md_name() - Get main dev node of the md device. -+ * @devnm: Md device name or path. -+ * -+ * Function checks if the full name was passed and returns md name -+ * if it is the MD device. -+ * -+ * Return: Main dev node of the md device or NULL if not found. -+ */ - char *get_md_name(char *devnm) - { -- /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ -- /* if dev < 0, want /dev/md/d%d or find mdp in /proc/devices ... */ -- -- static char devname[50]; -+ static char devname[NAME_MAX]; - struct stat stb; -- dev_t rdev = devnm2devid(devnm); -- char *dn; - -- if (rdev == 0) -- return 0; -- if (strncmp(devnm, "md_", 3) == 0) { -- snprintf(devname, sizeof(devname), "/dev/md/%s", -- devnm + 3); -- if (stat(devname, &stb) == 0 && -- (S_IFMT&stb.st_mode) == S_IFBLK && (stb.st_rdev == rdev)) -- return devname; -- } -- snprintf(devname, sizeof(devname), "/dev/%s", devnm); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -+ if (strncmp(devnm, "/dev/", 5) == 0) -+ snprintf(devname, sizeof(devname), "%s", devnm); -+ else -+ snprintf(devname, sizeof(devname), "/dev/%s", devnm); - -- snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -+ if (!is_mddev(devname)) -+ return NULL; -+ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK) - return devname; - -- dn = map_dev(major(rdev), minor(rdev), 0); -- if (dn) -- return dn; -- snprintf(devname, sizeof(devname), "/dev/.tmp.%s", devnm); -- if (mknod(devname, S_IFBLK | 0600, rdev) == -1) -- if (errno != EEXIST) -- return NULL; -- -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -- unlink(devname); - return NULL; - } - --- -2.38.1 - diff --git a/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch b/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch deleted file mode 100644 index f888a09..0000000 --- a/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 24d329fc97a64ec185ef27e59730f3f058c09029 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Thu, 5 Jan 2023 00:29:20 +0800 -Subject: [PATCH 79/83] mdadm/udev: Don't handle change event on raw devices - -The raw devices are ready when add event happpens and the raid -can be assembled. So there is no need to handle change events. -And it can cause some inconvenient problems. - -For example, the OS is installed on md0(/root) and md1(/home). -md0 and md1 are created on partitions. When it wants to re-install -OS, anaconda can't clear the storage configure. It deletes one -partition and does some jobs. The change event happens. Now -the raid device is assembled again. It can't delete the other -partitions. - -So in this patch, we don't handle change event on raw devices -anymore. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - udev-md-raid-assembly.rules | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index 39b4344b..d4a7f0a5 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -11,6 +11,11 @@ SUBSYSTEM!="block", GOTO="md_inc_end" - ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end" - - # handle potential components of arrays (the ones supported by md) -+# For member devices which are md/dm devices, we don't need to -+# handle add event. Because md/dm devices need to do some init jobs. -+# Then the change event happens. -+# When adding md/dm devices, ID_FS_TYPE can only be linux_raid_member -+# after change event happens. - ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc" - - # "noiswmd" on kernel command line stops mdadm from handling -@@ -28,6 +33,9 @@ GOTO="md_inc_end" - - LABEL="md_inc" - -+# Bare disks are ready when add event happens, the raid can be assembled. -+ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end" -+ - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' - ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --- -2.38.1 - diff --git a/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch b/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch deleted file mode 100644 index e2c1179..0000000 --- a/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b3e7b7eb1dfedd7cbd9a3800e884941f67d94c96 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:42 +0100 -Subject: [PATCH 80/83] Manage: do not check array state when drive is removed - -Array state doesn't need to be checked when drive is -removed, but until now clean state was required. Result -of the is_remove_safe() function will be independent -from array state. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Manage.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 594e3d2c..4d6e54b1 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1321,8 +1321,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - sysfs_free(mdi); - - bool is_enough = enough(array->level, array->raid_disks, -- array->layout, (array->state & 1), -- avail); -+ array->layout, 1, avail); - - free(avail); - return is_enough; --- -2.38.1 - diff --git a/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch b/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch deleted file mode 100644 index 4e0169c..0000000 --- a/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 461fae7e7809670d286cc19aac5bfa861c29f93a Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:43 +0100 -Subject: [PATCH 81/83] incremental, manage: do not verify if remove is safe - -Function is_remove_safe() was introduced to verify if removing -member device won't cause failed state of the array. This -verification should be used only with set-faulty command. Add -special mode indicating that Incremental removal was executed. -If this mode is used do not execute is_remove_safe() routine. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Incremental.c | 2 +- - Manage.c | 7 ++++--- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index ff3548c0..09b94b9f 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1744,7 +1744,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - memset(&devlist, 0, sizeof(devlist)); - devlist.devname = devname; -- devlist.disposition = 'f'; -+ devlist.disposition = 'I'; - /* for a container, we must fail each member array */ - if (ent->metadata_version && - strncmp(ent->metadata_version, "external:", 9) == 0) { -diff --git a/Manage.c b/Manage.c -index 4d6e54b1..6184d3f7 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1494,8 +1494,9 @@ int Manage_subdevs(char *devname, int fd, - /* Assume this is a kernel-internal name like 'sda1' */ - int found = 0; - char dname[55]; -- if (dv->disposition != 'r' && dv->disposition != 'f') { -- pr_err("%s only meaningful with -r or -f, not -%c\n", -+ if (dv->disposition != 'r' && dv->disposition != 'f' && -+ dv->disposition != 'I') { -+ pr_err("%s only meaningful with -r, -f or -I, not -%c\n", - dv->devname, dv->disposition); - goto abort; - } -@@ -1647,7 +1648,7 @@ int Manage_subdevs(char *devname, int fd, - close(sysfd); - goto abort; - } -- -+ case 'I': /* incremental fail */ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch b/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch deleted file mode 100644 index 0035c89..0000000 --- a/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 071f839ea549e2a384cd13bba445245cd87e48b1 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 28 Oct 2022 04:51:17 +0200 -Subject: [PATCH 82/83] super-intel: make freesize not required for chunk size - migration - -Freesize is needed to be set for migrations where size of RAID could -be changed - expand. It tells how many free space is determined for -members. In chunk size migartion freesize is not needed to be set, -pointer shouldn't be checked if exists. This commit moves check to -condition which contains size calculations, instead of checking it -always at the first step. -Fix return value when superblock is not set. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - super-intel.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 1f5f6eda..89fac626 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7719,11 +7719,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - struct intel_super *super = st->sb; - - /* -- * Autolayout mode, st->sb and freesize must be set. -+ * Autolayout mode, st->sb must be set. - */ -- if (!super || !freesize) { -- pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -- return 1; -+ if (!super) { -+ pr_vrb("superblock must be set for autolayout, aborting\n"); -+ return 0; - } - - if (!validate_geometry_imsm_orom(st->sb, level, layout, -@@ -7731,7 +7731,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - verbose)) - return 0; - -- if (super->orom) { -+ if (super->orom && freesize) { - imsm_status_t rv; - int count = count_volumes(super->hba, super->orom->dpa, - verbose); --- -2.38.1 - diff --git a/0083-manage-move-comment-with-function-description.patch b/0083-manage-move-comment-with-function-description.patch deleted file mode 100644 index 091854f..0000000 --- a/0083-manage-move-comment-with-function-description.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 36a707824eb1dafbb990f5daf1cbbe0e37dbbefb Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 5 Jan 2023 06:31:25 +0100 -Subject: [PATCH 83/83] manage: move comment with function description - -Move the function description from the function body to outside -to obey kernel coding style. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Manage.c | 72 ++++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 44 insertions(+), 28 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 6184d3f7..fde6aba3 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1327,38 +1327,54 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - return is_enough; - } - -+/** -+ * Manage_subdevs() - Execute operation depending on devmode. -+ * -+ * @devname: name of the device. -+ * @fd: file descriptor. -+ * @devlist: list of sub-devices to manage. -+ * @verbose: verbose level. -+ * @test: test flag. -+ * @update: type of update. -+ * @force: force flag. -+ * -+ * This function executes operation defined by devmode -+ * for each dev from devlist. -+ * Devmode can be: -+ * 'a' - add the device -+ * 'S' - add the device as a spare - don't try re-add -+ * 'j' - add the device as a journal device -+ * 'A' - re-add the device -+ * 'r' - remove the device: HOT_REMOVE_DISK -+ * device can be 'faulty' or 'detached' in which case all -+ * matching devices are removed. -+ * 'f' - set the device faulty SET_DISK_FAULTY -+ * device can be 'detached' in which case any device that -+ * is inaccessible will be marked faulty. -+ * 'I' - remove device by using incremental fail -+ * which is executed when device is removed surprisingly. -+ * 'R' - mark this device as wanting replacement. -+ * 'W' - this device is added if necessary and activated as -+ * a replacement for a previous 'R' device. -+ * ----- -+ * 'w' - 'W' will be changed to 'w' when it is paired with -+ * a 'R' device. If a 'W' is found while walking the list -+ * it must be unpaired, and is an error. -+ * 'M' - this is created by a 'missing' target. It is a slight -+ * variant on 'A' -+ * 'F' - Another variant of 'A', where the device was faulty -+ * so must be removed from the array first. -+ * 'c' - confirm the device as found (for clustered environments) -+ * -+ * For 'f' and 'r', the device can also be a kernel-internal -+ * name such as 'sdb'. -+ * -+ * Return: 0 on success, otherwise 1 or 2. -+ */ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - enum update_opt update, int force) - { -- /* Do something to each dev. -- * devmode can be -- * 'a' - add the device -- * 'S' - add the device as a spare - don't try re-add -- * 'j' - add the device as a journal device -- * 'A' - re-add the device -- * 'r' - remove the device: HOT_REMOVE_DISK -- * device can be 'faulty' or 'detached' in which case all -- * matching devices are removed. -- * 'f' - set the device faulty SET_DISK_FAULTY -- * device can be 'detached' in which case any device that -- * is inaccessible will be marked faulty. -- * 'R' - mark this device as wanting replacement. -- * 'W' - this device is added if necessary and activated as -- * a replacement for a previous 'R' device. -- * ----- -- * 'w' - 'W' will be changed to 'w' when it is paired with -- * a 'R' device. If a 'W' is found while walking the list -- * it must be unpaired, and is an error. -- * 'M' - this is created by a 'missing' target. It is a slight -- * variant on 'A' -- * 'F' - Another variant of 'A', where the device was faulty -- * so must be removed from the array first. -- * 'c' - confirm the device as found (for clustered environments) -- * -- * For 'f' and 'r', the device can also be a kernel-internal -- * name such as 'sdb'. -- */ - mdu_array_info_t array; - unsigned long long array_size; - struct mddev_dev *dv; --- -2.38.1 - diff --git a/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch b/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch deleted file mode 100644 index d824449..0000000 --- a/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 28a083955c6f58f8e582734c8c82aff909a7d461 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 2 Feb 2023 08:56:31 +0100 -Subject: [PATCH 084/120] Revert "mdadm/systemd: remove KillMode=none from - service file" - -This reverts commit 52c67fcdd6dadc4138ecad73e65599551804d445. - -The functionality is marked as deprecated but we don't have alternative -solution yet. Shutdown hangs if OS is installed on external array: - -task:umount state:D stack: 0 pid: 6285 ppid: flags:0x00004084 -Call Trace: -__schedule+0x2d1/0x830 -? finish_wait+0x80/0x80 -schedule+0x35/0xa0 -md_write_start+0x14b/0x220 -? finish_wait+0x80/0x80 -raid1_make_request+0x3c/0x90 [raid1] -md_handle_request+0x128/0x1b0 -md_make_request+0x5b/0xb0 -generic_make_request_no_check+0x202/0x330 -submit_bio+0x3c/0x160 - -Use it until new solution is implemented. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdmon@.service | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 64b8254a..9ccadca3 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,3 +15,4 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null -+KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 97a1acd9..cb6482d9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -26,3 +26,4 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid -+KillMode=none --- -2.38.1 - diff --git a/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch b/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch deleted file mode 100644 index 0bc1069..0000000 --- a/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Thu, 23 Feb 2023 22:39:39 +0800 -Subject: [PATCH 085/120] Grow: fix can't change bitmap type from none to - clustered. - -Commit a042210648ed ("disallow create or grow clustered bitmap with -writemostly set") introduced this bug. We should use 'true' logic not -'== 0' to deny setting up clustered array under WRITEMOSTLY condition. - -How to trigger - -``` -~/mdadm # ./mdadm -Ss && ./mdadm --zero-superblock /dev/sd{a,b} -~/mdadm # ./mdadm -C /dev/md0 -l mirror -b clustered -e 1.2 -n 2 \ -/dev/sda /dev/sdb --assume-clean -mdadm: array /dev/md0 started. -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=none -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=clustered -mdadm: /dev/md0 disks marked write-mostly are not supported with clustered bitmap -``` - -Signed-off-by: Heming Zhao -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8f5cf07d..bb5fe45c 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -429,7 +429,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - dv = map_dev(disk.major, disk.minor, 1); - if (!dv) - continue; -- if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && -+ if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); - free(mdi); --- -2.38.1 - diff --git a/0086-Fix-NULL-dereference-in-super_by_fd.patch b/0086-Fix-NULL-dereference-in-super_by_fd.patch deleted file mode 100644 index 95cb79a..0000000 --- a/0086-Fix-NULL-dereference-in-super_by_fd.patch +++ /dev/null @@ -1,76 +0,0 @@ -From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001 -From: Li Xiao Keng -Date: Mon, 27 Feb 2023 11:12:07 +0800 -Subject: [PATCH 086/120] Fix NULL dereference in super_by_fd - -When we create 100 partitions (major is 259 not 254) in a raid device, -mdadm may coredump: - -Core was generated by `/usr/sbin/mdadm --detail --export /dev/md1p7'. -Program terminated with signal SIGSEGV, Segmentation fault. -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -74 VPCMPEQ (%rdi), %ymm0, %ymm1 -(gdb) bt -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -#1 0x00007fbb9a7e4139 in __strcpy_chk (dest=dest@entry=0x55d55d6a13ac "", src=0x0, destlen=destlen@entry=32) at strcpy_chk.c:28 -#2 0x000055d55ba1766d in strcpy (__src=, __dest=0x55d55d6a13ac "") at /usr/include/bits/string_fortified.h:79 -#3 super_by_fd (fd=fd@entry=3, subarrayp=subarrayp@entry=0x7fff44dfcc48) at util.c:1289 -#4 0x000055d55ba273a6 in Detail (dev=0x7fff44dfef0b "/dev/md1p7", c=0x7fff44dfe440) at Detail.c:101 -#5 0x000055d55ba0de61 in misc_list (c=, ss=, dump_directory=, ident=, devlist=) at mdadm.c:1959 -#6 main (argc=, argv=) at mdadm.c:1629 - -The direct cause is fd2devnm returning NULL, so add a check. - -Signed-off-by: Li Xiao Keng -Signed-off-by: Wu Guang Hao -Acked-by: Coly Li -Acked-by: Coly Li > -Signed-off-by: Jes Sorensen ---- - mapfile.c | 4 ++++ - util.c | 7 ++++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/mapfile.c b/mapfile.c -index 6b2207dd..ac351768 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -292,6 +292,10 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) - struct map_ent *map_by_devnm(struct map_ent **map, char *devnm) - { - struct map_ent *mp; -+ -+ if (!devnm) -+ return NULL; -+ - if (!*map) - map_read(map); - -diff --git a/util.c b/util.c -index 9cd89fa4..8c7f3fd5 100644 ---- a/util.c -+++ b/util.c -@@ -1160,6 +1160,11 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - int i; - char *subarray = NULL; - char container[32] = ""; -+ char *devnm = NULL; -+ -+ devnm = fd2devnm(fd); -+ if (!devnm) -+ return NULL; - - sra = sysfs_read(fd, NULL, GET_VERSION); - -@@ -1205,7 +1210,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - if (subarrayp) - *subarrayp = subarray; - strcpy(st->container_devnm, container); -- strcpy(st->devnm, fd2devnm(fd)); -+ strncpy(st->devnm, devnm, MD_NAME_MAX - 1); - } else - free(subarray); - --- -2.38.1 - diff --git a/0087-Mdmonitor-Make-alert_info-global.patch b/0087-Mdmonitor-Make-alert_info-global.patch deleted file mode 100644 index c8da02b..0000000 --- a/0087-Mdmonitor-Make-alert_info-global.patch +++ /dev/null @@ -1,369 +0,0 @@ -From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:26:59 +0100 -Subject: [PATCH 087/120] Mdmonitor: Make alert_info global - -Move information about --test flag and hostname into alert_info. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 124 +++++++++++++++++++++++++++--------------------------- - 1 file changed, 61 insertions(+), 63 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 188cb8be..9ef4dab8 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -58,21 +58,20 @@ struct state { - }; - - struct alert_info { -+ char hostname[HOST_NAME_MAX]; - char *mailaddr; - char *mailfrom; - char *alert_cmd; - int dosyslog; --}; -+ int test; -+} info; - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); --static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *info, -- int increments, char *prefer); --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info); --static void try_spare_migration(struct state *statelist, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); -+static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV -@@ -132,7 +131,6 @@ int Monitor(struct mddev_dev *devlist, - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -- struct alert_info info; - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -@@ -166,6 +164,13 @@ int Monitor(struct mddev_dev *devlist, - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; - info.dosyslog = dosyslog; -+ info.test = c->test; -+ -+ if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { -+ pr_err("Cannot get hostname.\n"); -+ return 1; -+ } -+ info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ - if (check_one_sharer(c->scan)) -@@ -241,8 +246,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat = mdstat_read(oneshot ? 0 : 1, 0); - - for (st = statelist; st; st = st->next) { -- if (check_array(st, mdstat, c->test, &info, -- increments, c->prefer)) -+ if (check_array(st, mdstat, increments, c->prefer)) - anydegraded = 1; - /* for external arrays, metadata is filled for - * containers only -@@ -255,15 +259,14 @@ int Monitor(struct mddev_dev *devlist, - - /* now check if there are any new devices found in mdstat */ - if (c->scan) -- new_found = add_new_arrays(mdstat, &statelist, c->test, -- &info); -+ new_found = add_new_arrays(mdstat, &statelist); - - /* If an array has active < raid && spare == 0 && spare_group != NULL - * Look for another array with spare > 0 and active == raid and same spare_group - * if found, choose a device and hotremove/hotadd - */ - if (share && anydegraded) -- try_spare_migration(statelist, &info); -+ try_spare_migration(statelist); - if (!new_found) { - if (oneshot) - break; -@@ -294,7 +297,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat_close(); - } - } -- c->test = 0; -+ info.test = 0; - - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { -@@ -412,7 +415,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -424,15 +427,14 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void send_event_email(const char *event, const char *dev, const char *disc) - { - FILE *mp, *mdstat; -- char hname[256]; - char buf[BUFSIZ]; - int n; - -@@ -442,14 +444,13 @@ static void send_event_email(const char *event, const char *dev, const char *dis - return; - } - -- gethostname(hname, sizeof(hname)); - signal(SIGPIPE, SIG_IGN); -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -+ if (info.mailfrom) -+ fprintf(mp, "From: %s\n", info.mailfrom); - else - fprintf(mp, "From: %s monitoring \n", Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "To: %s\n", info.mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); - fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); - -@@ -501,37 +502,36 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - syslog(priority, "%s event detected on md device %s", event, dev); - } - --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void alert(const char *event, const char *dev, const char *disc) - { -- if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { -+ if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) -- execute_alert_cmd(event, dev, disc, info); -+ if (info.alert_cmd) -+ execute_alert_cmd(event, dev, disc); - -- if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || -+ if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc, info); -+ send_event_email(event, dev, disc); - } - -- if (info->dosyslog) -+ if (info.dosyslog) - log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *ainfo, - int increments, char *prefer) - { - /* Update the state 'st' to reflect any changes shown in mdstat, - * or found by directly examining the array, and return - * '1' if the array is degraded, or '0' if it is optimal (or dead). - */ -- struct { int state, major, minor; } info[MAX_DISKS]; -+ struct { int state, major, minor; } disks_info[MAX_DISKS]; - struct mdinfo *sra = NULL; - mdu_array_info_t array; - struct mdstat_ent *mse = NULL, *mse2; -@@ -545,8 +545,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int is_container = 0; - unsigned long redundancy_only_flags = 0; - -- if (test) -- alert("TestMessage", dev, NULL, ainfo); -+ if (info.test) -+ alert("TestMessage", dev, NULL); - - retval = 0; - -@@ -595,7 +595,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); -+ alert("DeviceDisappeared", dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +612,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL, ainfo); -+ alert("NewArray", st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,14 +625,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL, ainfo); -+ alert("DegradedArray", dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL, ainfo); -+ alert("SparesMissing", dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL, ainfo); -+ alert("RebuildStarted", dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - char percentalert[18]; -@@ -647,7 +647,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(percentalert, sizeof(percentalert), - "Rebuild%02d", mse->percent); - -- alert(percentalert, dev, NULL, ainfo); -+ alert(percentalert, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +660,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt, ainfo); -+ alert("RebuildFinished", dev, cnt); - } else -- alert("RebuildFinished", dev, NULL, ainfo); -+ alert("RebuildFinished", dev, NULL); - } - st->percent = mse->percent; - -@@ -671,13 +671,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - mdu_disk_info_t disc; - disc.number = i; - if (md_get_disk_info(fd, &disc) >= 0) { -- info[i].state = disc.state; -- info[i].major = disc.major; -- info[i].minor = disc.minor; -+ disks_info[i].state = disc.state; -+ disks_info[i].major = disc.major; -+ disks_info[i].minor = disc.minor; - if (disc.major || disc.minor) - remaining_disks --; - } else -- info[i].major = info[i].minor = 0; -+ disks_info[i].major = disks_info[i].minor = 0; - } - last_disk = i; - -@@ -700,13 +700,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int change; - char *dv = NULL; - disc.number = i; -- if (i < last_disk && (info[i].major || info[i].minor)) { -- newstate = info[i].state; -- dv = map_dev_preferred(info[i].major, info[i].minor, 1, -+ if (i < last_disk && (disks_info[i].major || disks_info[i].minor)) { -+ newstate = disks_info[i].state; -+ dv = map_dev_preferred(disks_info[i].major, disks_info[i].minor, 1, - prefer); - disc.state = newstate; -- disc.major = info[i].major; -- disc.minor = info[i].minor; -+ disc.major = disks_info[i].major; -+ disc.minor = disks_info[i].minor; - } else - newstate = (1 << MD_DISK_REMOVED); - -@@ -716,14 +716,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv, ainfo); -+ alert("Fail", dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv, ainfo); -+ alert("FailSpare", dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv, ainfo); -+ alert("SpareActive", dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,13 +747,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL, ainfo); -+ alert("DeviceDisappeared", dev, NULL); - st->err++; - goto out; - } - --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info) -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - { - struct mdstat_ent *mse; - int new_found = 0; -@@ -806,8 +805,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - } else - st->parent_devnm[0] = 0; - *statelist = st; -- if (test) -- alert("TestMessage", st->devname, NULL, info); -+ if (info.test) -+ alert("TestMessage", st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -971,7 +970,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to, - return dev; - } - --static void try_spare_migration(struct state *statelist, struct alert_info *info) -+static void try_spare_migration(struct state *statelist) - { - struct state *from; - struct state *st; -@@ -1030,8 +1029,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, -- from->devname, info); -+ alert("MoveSpare", to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch b/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch deleted file mode 100644 index c5f2b97..0000000 --- a/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch +++ /dev/null @@ -1,313 +0,0 @@ -From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:00 +0100 -Subject: [PATCH 088/120] Mdmonitor: Pass events to alert() using enums instead - of strings - -Add events enum, and mapping_t struct, that maps them to strings, so -that enums are passed around instead of strings. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 136 +++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 83 insertions(+), 53 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 9ef4dab8..029e9efd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,8 @@ - #include - #endif - -+#define EVENT_NAME_MAX 32 -+ - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ - char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ -@@ -65,10 +67,43 @@ struct alert_info { - int dosyslog; - int test; - } info; -+ -+enum event { -+ EVENT_SPARE_ACTIVE = 0, -+ EVENT_NEW_ARRAY, -+ EVENT_MOVE_SPARE, -+ EVENT_TEST_MESSAGE, -+ EVENT_REBUILD_STARTED, -+ EVENT_REBUILD, -+ EVENT_REBUILD_FINISHED, -+ EVENT_SPARES_MISSING, -+ EVENT_DEVICE_DISAPPEARED, -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_UNKNOWN -+}; -+ -+mapping_t events_map[] = { -+ {"SpareActive", EVENT_SPARE_ACTIVE}, -+ {"NewArray", EVENT_NEW_ARRAY}, -+ {"MoveSpare", EVENT_MOVE_SPARE}, -+ {"TestMessage", EVENT_TEST_MESSAGE}, -+ {"RebuildStarted", EVENT_REBUILD_STARTED}, -+ {"Rebuild", EVENT_REBUILD}, -+ {"RebuildFinished", EVENT_REBUILD_FINISHED}, -+ {"SparesMissing", EVENT_SPARES_MISSING}, -+ {"DeviceDisappeared", EVENT_DEVICE_DISAPPEARED}, -+ {"Fail", EVENT_FAIL}, -+ {"FailSpare", EVENT_FAIL_SPARE}, -+ {"DegradedArray", EVENT_DEGRADED_ARRAY}, -+ {NULL, EVENT_UNKNOWN} -+}; -+ - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc); -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); - static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); -@@ -415,7 +450,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc) -+static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -427,12 +462,12 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc) -+static void send_event_email(const char *event_name, const char *dev, const char *disc) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -450,9 +485,9 @@ static void send_event_email(const char *event, const char *dev, const char *dis - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); - - if (disc && disc[0] != ' ') - fprintf(mp, -@@ -474,20 +509,20 @@ static void send_event_email(const char *event, const char *dev, const char *dis - pclose(mp); - } - --static void log_event_to_syslog(const char *event, const char *dev, const char *disc) -+static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) - { - int priority; - /* Log at a different severity depending on the event. - * - * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -+ if (event_enum == EVENT_FAIL || -+ event_enum == EVENT_DEGRADED_ARRAY || -+ event_enum == EVENT_DEVICE_DISAPPEARED) - priority = LOG_CRIT; - /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -+ else if (event_enum == EVENT_REBUILD || -+ event_enum == EVENT_MOVE_SPARE || -+ event_enum == EVENT_SPARES_MISSING) - priority = LOG_WARNING; - /* Everything else: */ - else -@@ -495,33 +530,37 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - - if (disc && disc[0] != ' ') - syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -+ "%s event detected on md device %s, component device %s", -+ event_name, dev, disc); - else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); - else -- syslog(priority, "%s event detected on md device %s", event, dev); -+ syslog(priority, "%s event detected on md device %s", event_name, dev); - } - --static void alert(const char *event, const char *dev, const char *disc) -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) - { -- if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { -- time_t now = time(0); -+ char event_name[EVENT_NAME_MAX]; - -- printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, -- event, dev, disc?disc:"unknown device"); -+ if (event_enum == EVENT_REBUILD) { -+ snprintf(event_name, sizeof(event_name), "%s%02d", -+ map_num_s(events_map, EVENT_REBUILD), progress); -+ } else { -+ snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); - } -+ - if (info.alert_cmd) -- execute_alert_cmd(event, dev, disc); -+ execute_alert_cmd(event_name, dev, disc); - -- if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Test", 4) == 0 || -- strncmp(event, "Spares", 6) == 0 || -- strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc); -+ if (info.mailaddr && (event_enum == EVENT_FAIL || -+ event_enum == EVENT_TEST_MESSAGE || -+ event_enum == EVENT_SPARES_MISSING || -+ event_enum == EVENT_DEGRADED_ARRAY)) { -+ send_event_email(event_name, dev, disc); - } - - if (info.dosyslog) -- log_event_to_syslog(event, dev, disc); -+ log_event_to_syslog(event_enum, event_name, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -546,7 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert("TestMessage", dev, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, dev, NULL); - - retval = 0; - -@@ -595,7 +634,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +651,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,29 +664,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL); -+ alert(EVENT_SPARES_MISSING, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { -- char percentalert[18]; -- /* -- * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) -- */ -- - if((mse->percent / increments) == 0) -- snprintf(percentalert, sizeof(percentalert), -- "RebuildStarted"); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - else -- snprintf(percentalert, sizeof(percentalert), -- "Rebuild%02d", mse->percent); -- -- alert(percentalert, dev, NULL); -+ alert(EVENT_REBUILD, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +690,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); - } else -- alert("RebuildFinished", dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -716,14 +746,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv); -+ alert(EVENT_FAIL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv); -+ alert(EVENT_FAIL_SPARE, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv); -+ alert(EVENT_SPARE_ACTIVE, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,7 +777,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); - st->err++; - goto out; - } -@@ -806,7 +836,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert("TestMessage", st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1029,7 +1059,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/0089-Mdmonitor-Add-helper-functions.patch b/0089-Mdmonitor-Add-helper-functions.patch deleted file mode 100644 index b8fc968..0000000 --- a/0089-Mdmonitor-Add-helper-functions.patch +++ /dev/null @@ -1,406 +0,0 @@ -From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:01 +0100 -Subject: [PATCH 089/120] Mdmonitor: Add helper functions - -Add functions: -- is_email_event(), -- get_syslog_event_priority(), -- sprint_event_message(), -with kernel style comments containing more detailed descriptions. - -Also update event syslog priorities to be consistent with man. MoveSpare event was described in man as priority info, while implemented as warning. Move event data into a struct, so that it is passed between different functions if needed. -Sort function declarations alphabetically and remove redundant alert() declaration. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 228 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 158 insertions(+), 70 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 029e9efd..39598ba0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -73,10 +73,12 @@ enum event { - EVENT_NEW_ARRAY, - EVENT_MOVE_SPARE, - EVENT_TEST_MESSAGE, -+ __SYSLOG_PRIORITY_WARNING, - EVENT_REBUILD_STARTED, - EVENT_REBUILD, - EVENT_REBUILD_FINISHED, - EVENT_SPARES_MISSING, -+ __SYSLOG_PRIORITY_CRITICAL, - EVENT_DEVICE_DISAPPEARED, - EVENT_FAIL, - EVENT_FAIL_SPARE, -@@ -100,18 +102,31 @@ mapping_t events_map[] = { - {NULL, EVENT_UNKNOWN} - }; - --static int make_daemon(char *pidfile); --static int check_one_sharer(int scan); --static void write_autorebuild_pid(void); --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); --static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+struct event_data { -+ enum event event_enum; -+ /* -+ * @event_name: Rebuild event name must be in form "RebuildXX", where XX is rebuild progress. -+ */ -+ char event_name[EVENT_NAME_MAX]; -+ char message[BUFSIZ]; -+ const char *description; -+ const char *dev; -+ const char *disc; -+}; -+ - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int check_one_sharer(int scan); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -+static void link_containers_with_subarrays(struct state *list); -+static int make_daemon(char *pidfile); -+static void try_spare_migration(struct state *statelist); -+static void write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -450,7 +465,80 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) -+#define BASE_MESSAGE "%s event detected on md device %s" -+#define COMPONENT_DEVICE_MESSAGE ", component device %s" -+#define DESCRIPTION_MESSAGE ": %s" -+/* -+ * sprint_event_message() - Writes basic message about detected event to destination ptr. -+ * @dest: message destination, should be at least the size of BUFSIZ -+ * @data: event data -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int sprint_event_message(char *dest, const struct event_data *data) -+{ -+ if (!dest || !data) -+ return 1; -+ -+ if (data->disc && data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->disc, data->description); -+ else if (data->disc) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE, -+ data->event_name, data->dev, data->disc); -+ else if (data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->description); -+ else -+ snprintf(dest, BUFSIZ, BASE_MESSAGE, data->event_name, data->dev); -+ -+ return 0; -+} -+ -+/* -+ * get_syslog_event_priority() - Determines event priority. -+ * @event_enum: event to be checked -+ * -+ * Return: LOG_CRIT, LOG_WARNING or LOG_INFO -+ */ -+static int get_syslog_event_priority(const enum event event_enum) -+{ -+ if (event_enum > __SYSLOG_PRIORITY_CRITICAL) -+ return LOG_CRIT; -+ if (event_enum > __SYSLOG_PRIORITY_WARNING) -+ return LOG_WARNING; -+ return LOG_INFO; -+} -+ -+/* -+ * is_email_event() - Determines whether email for event should be sent or not. -+ * @event_enum: event to be checked -+ * -+ * Return: true if email should be sent, false otherwise -+ */ -+static bool is_email_event(const enum event event_enum) -+{ -+ static const enum event email_events[] = { -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_SPARES_MISSING, -+ EVENT_TEST_MESSAGE -+ }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(email_events); ++i) { -+ if (event_enum == email_events[i]) -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * execute_alert_cmd() - Forks and executes command provided as alert_cmd. -+ * @data: event data -+ */ -+static void execute_alert_cmd(const struct event_data *data) - { - int pid = fork(); - -@@ -462,12 +550,16 @@ static void execute_alert_cmd(const char *event_name, const char *dev, const cha - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, data->event_name, data->dev, data->disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event_name, const char *dev, const char *disc) -+/* -+ * send_event_email() - Sends an email about event detected by monitor. -+ * @data: event data -+ */ -+static void send_event_email(const struct event_data *data) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -485,15 +577,9 @@ static void send_event_email(const char *event_name, const char *dev, const char - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); -- fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", data->event_name, data->dev, info.hostname); -+ fprintf(mp, "This is an automatically generated mail message.\n"); -+ fprintf(mp, "%s\n", data->message); - - mdstat = fopen("/proc/mdstat", "r"); - if (!mdstat) { -@@ -509,58 +595,60 @@ static void send_event_email(const char *event_name, const char *dev, const char - pclose(mp); - } - --static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) -+/* -+ * log_event_to_syslog() - Logs an event into syslog. -+ * @data: event data -+ */ -+static void log_event_to_syslog(const struct event_data *data) - { - int priority; -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (event_enum == EVENT_FAIL || -- event_enum == EVENT_DEGRADED_ARRAY || -- event_enum == EVENT_DEVICE_DISAPPEARED) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (event_enum == EVENT_REBUILD || -- event_enum == EVENT_MOVE_SPARE || -- event_enum == EVENT_SPARES_MISSING) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", -- event_name, dev, disc); -- else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); -- else -- syslog(priority, "%s event detected on md device %s", event_name, dev); -+ -+ priority = get_syslog_event_priority(data->event_enum); -+ -+ syslog(priority, "%s\n", data->message); - } - --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) -+/* -+ * alert() - Alerts about the monitor event. -+ * @event_enum: event to be sent -+ * @description: event description -+ * @progress: rebuild progress -+ * @dev: md device name -+ * @disc: component device -+ * -+ * If needed function executes alert command, sends an email or logs event to syslog. -+ */ -+static void alert(const enum event event_enum, const char *description, const uint8_t progress, -+ const char *dev, const char *disc) - { -- char event_name[EVENT_NAME_MAX]; -+ struct event_data data = {.dev = dev, .disc = disc, .description = description}; -+ -+ if (!dev) -+ return; - - if (event_enum == EVENT_REBUILD) { -- snprintf(event_name, sizeof(event_name), "%s%02d", -+ snprintf(data.event_name, sizeof(data.event_name), "%s%02d", - map_num_s(events_map, EVENT_REBUILD), progress); - } else { -- snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); -+ snprintf(data.event_name, sizeof(data.event_name), "%s", map_num_s(events_map, event_enum)); - } - -- if (info.alert_cmd) -- execute_alert_cmd(event_name, dev, disc); -+ data.event_enum = event_enum; - -- if (info.mailaddr && (event_enum == EVENT_FAIL || -- event_enum == EVENT_TEST_MESSAGE || -- event_enum == EVENT_SPARES_MISSING || -- event_enum == EVENT_DEGRADED_ARRAY)) { -- send_event_email(event_name, dev, disc); -+ if (sprint_event_message(data.message, &data) != 0) { -+ pr_err("Cannot create event message.\n"); -+ return; - } -+ pr_err("%s\n", data.message); -+ -+ if (info.alert_cmd) -+ execute_alert_cmd(&data); -+ -+ if (info.mailaddr && is_email_event(event_enum)) -+ send_event_email(&data); - - if (info.dosyslog) -- log_event_to_syslog(event_enum, event_name, dev, disc); -+ log_event_to_syslog(&data); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -585,7 +673,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, dev, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, dev, NULL); - - retval = 0; - -@@ -634,7 +722,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, "Wrong-Level", 0, dev, NULL); - st->err++; - goto out; - } -@@ -651,7 +739,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, NULL, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -664,20 +752,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, NULL, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert(EVENT_SPARES_MISSING, 0, dev, NULL); -+ alert(EVENT_SPARES_MISSING, NULL, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - if((mse->percent / increments) == 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - else -- alert(EVENT_REBUILD, mse->percent, dev, NULL); -+ alert(EVENT_REBUILD, NULL, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -690,9 +778,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, cnt); - } else -- alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -746,14 +834,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_FAIL, 0, dev, dv); -+ alert(EVENT_FAIL, NULL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert(EVENT_FAIL_SPARE, 0, dev, dv); -+ alert(EVENT_FAIL_SPARE, NULL, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_SPARE_ACTIVE, 0, dev, dv); -+ alert(EVENT_SPARE_ACTIVE, NULL, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -777,7 +865,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, NULL, 0, dev, NULL); - st->err++; - goto out; - } -@@ -836,7 +924,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1059,7 +1147,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, NULL, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/0090-Add-helpers-to-determine-whether-directories-or-file.patch b/0090-Add-helpers-to-determine-whether-directories-or-file.patch deleted file mode 100644 index 7d7ecdd..0000000 --- a/0090-Add-helpers-to-determine-whether-directories-or-file.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:02 +0100 -Subject: [PATCH 090/120] Add helpers to determine whether directories or files - are soft links - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.h | 2 ++ - util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/mdadm.h b/mdadm.h -index 13f8b4cb..1674ce13 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1777,6 +1777,8 @@ extern void set_dlm_hooks(void); - #define MSEC_TO_NSEC(msec) ((msec) * 1000000) - #define USEC_TO_NSEC(usec) ((usec) * 1000) - extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+extern bool is_directory(const char *path); -+extern bool is_file(const char *path); - - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) -diff --git a/util.c b/util.c -index 8c7f3fd5..7fc881bf 100644 ---- a/util.c -+++ b/util.c -@@ -2401,3 +2401,48 @@ void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) - } - } while (!wake_after_interrupt && errno == EINTR); - } -+ -+/* is_directory() - Checks if directory provided by path is indeed a regular directory. -+ * @path: directory path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a directory, false if not -+ */ -+bool is_directory(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISDIR(st.st_mode)) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * is_file() - Checks if file provided by path is indeed a regular file. -+ * @path: file path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a file, false if not -+ */ -+bool is_file(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISREG(st.st_mode)) -+ return false; -+ -+ return true; -+} --- -2.38.1 - diff --git a/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch b/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch deleted file mode 100644 index 0985905..0000000 --- a/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:03 +0100 -Subject: [PATCH 091/120] Mdmonitor: Refactor write_autorebuild_pid() - -Add better error handling and check for symlinks when opening MDMON_DIR. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 55 ++++++++++++++++++++++++++++++++++++------------------- - 1 file changed, 36 insertions(+), 19 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 39598ba0..14a2dfe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,6 +33,7 @@ - #endif - - #define EVENT_NAME_MAX 32 -+#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -@@ -126,7 +127,7 @@ static int check_udev_activity(void); - static void link_containers_with_subarrays(struct state *list); - static int make_daemon(char *pidfile); - static void try_spare_migration(struct state *statelist); --static void write_autorebuild_pid(void); -+static int write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -234,7 +235,8 @@ int Monitor(struct mddev_dev *devlist, - } - - if (share) -- write_autorebuild_pid(); -+ if (write_autorebuild_pid() != 0) -+ return 1; - - if (devlist == NULL) { - mdlist = conf_get_ident(NULL); -@@ -440,29 +442,44 @@ static int check_one_sharer(int scan) - return 0; - } - --static void write_autorebuild_pid() -+/* -+ * write_autorebuild_pid() - Writes pid to autorebuild.pid file. -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int write_autorebuild_pid(void) - { -- char path[PATH_MAX]; -- int pid; -- FILE *fp = NULL; -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -+ FILE *fp; -+ int fd; - - if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) { -- pr_err("Can't create autorebuild.pid file\n"); -- } else { -- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ pr_err("%s: %s\n", strerror(errno), MDMON_DIR); -+ return 1; -+ } - -- if (fd >= 0) -- fp = fdopen(fd, "w"); -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ return 1; -+ } - -- if (!fp) -- pr_err("Can't create autorebuild.pid file\n"); -- else { -- pid = getpid(); -- fprintf(fp, "%d\n", pid); -- fclose(fp); -- } -+ fd = open(AUTOREBUILD_PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ -+ if (fd < 0) { -+ pr_err("Error opening %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; - } -+ -+ fp = fdopen(fd, "w"); -+ -+ if (!fp) { -+ pr_err("Error opening fd for %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; -+ } -+ -+ fprintf(fp, "%d\n", getpid()); -+ -+ fclose(fp); -+ return 0; - } - - #define BASE_MESSAGE "%s event detected on md device %s" --- -2.38.1 - diff --git a/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch b/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch deleted file mode 100644 index a7de95e..0000000 --- a/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:04 +0100 -Subject: [PATCH 092/120] Mdmonitor: Refactor check_one_sharer() for better - error handling - -Also check if autorebuild.pid is a symlink, which we shouldn't accept. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 89 ++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 62 insertions(+), 27 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 14a2dfe5..44918184 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,7 @@ - #include - #endif - -+#define TASK_COMM_LEN 16 - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - -@@ -224,7 +225,7 @@ int Monitor(struct mddev_dev *devlist, - info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ -- if (check_one_sharer(c->scan)) -+ if (check_one_sharer(c->scan) == 2) - return 1; - } - -@@ -406,39 +407,73 @@ static int make_daemon(char *pidfile) - return -1; - } - -+/* -+ * check_one_sharer() - Checks for other mdmon processes running. -+ * -+ * Return: -+ * 0 - no other processes running, -+ * 1 - warning, -+ * 2 - error, or when scan mode is enabled, and one mdmon process already exists -+ */ - static int check_one_sharer(int scan) - { - int pid; -- FILE *comm_fp; -- FILE *fp; -+ FILE *fp, *comm_fp; - char comm_path[PATH_MAX]; -- char path[PATH_MAX]; -- char comm[20]; -- -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -- fp = fopen(path, "r"); -- if (fp) { -- if (fscanf(fp, "%d", &pid) != 1) -- pid = -1; -- snprintf(comm_path, sizeof(comm_path), -- "/proc/%d/comm", pid); -- comm_fp = fopen(comm_path, "r"); -- if (comm_fp) { -- if (fscanf(comm_fp, "%19s", comm) && -- strncmp(basename(comm), Name, strlen(Name)) == 0) { -- if (scan) { -- pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); -- fclose(comm_fp); -- fclose(fp); -- return 1; -- } else { -- pr_err("Warning: One autorebuild process already running.\n"); -- } -- } -+ char comm[TASK_COMM_LEN]; -+ -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ 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 (fscanf(fp, "%d", &pid) != 1) { -+ pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); -+ fclose(fp); -+ return 2; -+ } -+ -+ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid); -+ -+ comm_fp = fopen(comm_path, "r"); -+ if (!comm_fp) { -+ dprintf("Warning: Cannot open %s, continuing\n", comm_path); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (fscanf(comm_fp, "%15s", comm) == 0) { -+ dprintf("Warning: Cannot read comm from %s, continuing\n", comm_path); -+ fclose(comm_fp); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (strncmp(basename(comm), Name, strlen(Name)) == 0) { -+ if (scan) { -+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); - fclose(comm_fp); -+ fclose(fp); -+ return 2; - } -- fclose(fp); -+ pr_err("Warning: One autorebuild process already running.\n"); - } -+ fclose(comm_fp); -+ fclose(fp); - return 0; - } - --- -2.38.1 - diff --git a/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch b/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch deleted file mode 100644 index b040ba7..0000000 --- a/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Sat, 4 Mar 2023 00:21:30 +0800 -Subject: [PATCH 093/120] util.c: reorder code lines in parse_layout_faulty() - -Resort the code lines in parse_layout_faulty() to make it more -comfortable, no logic change. - -Signed-off-by: Coly Li -Reviewed-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - util.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/util.c b/util.c -index 7fc881bf..b0b7aec4 100644 ---- a/util.c -+++ b/util.c -@@ -421,12 +421,15 @@ int parse_layout_10(char *layout) - - int parse_layout_faulty(char *layout) - { -+ int ln, mode; -+ char *m; -+ - if (!layout) - return -1; -+ - /* Parse the layout string for 'faulty' */ -- int ln = strcspn(layout, "0123456789"); -- char *m = xstrdup(layout); -- int mode; -+ ln = strcspn(layout, "0123456789"); -+ m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); - if (mode == UnSet) --- -2.38.1 - diff --git a/0094-util.c-fix-memleak-in-parse_layout_faulty.patch b/0094-util.c-fix-memleak-in-parse_layout_faulty.patch deleted file mode 100644 index b5d0d09..0000000 --- a/0094-util.c-fix-memleak-in-parse_layout_faulty.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:31 +0800 -Subject: [PATCH 094/120] util.c: fix memleak in parse_layout_faulty() - -char *m is allocated by xstrdup but not free() before return, will cause -a memory leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util.c b/util.c -index b0b7aec4..9f1e1f7c 100644 ---- a/util.c -+++ b/util.c -@@ -432,6 +432,8 @@ int parse_layout_faulty(char *layout) - m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); -+ free(m); -+ - if (mode == UnSet) - return -1; - --- -2.38.1 - diff --git a/0095-Detail.c-fix-memleak-in-Detail.patch b/0095-Detail.c-fix-memleak-in-Detail.patch deleted file mode 100644 index 0e9b700..0000000 --- a/0095-Detail.c-fix-memleak-in-Detail.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:32 +0800 -Subject: [PATCH 095/120] Detail.c: fix memleak in Detail() - -char *sysdev = xstrdup() but not free() in for loop, will cause memory -leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Detail.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Detail.c b/Detail.c -index ce7a8445..4ef26460 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -303,6 +303,7 @@ int Detail(char *dev, struct context *c) - if (path) - printf("MD_DEVICE_%s_DEV=%s\n", - sysdev, path); -+ free(sysdev); - } - } - goto out; --- -2.38.1 - diff --git a/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch b/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch deleted file mode 100644 index bf71aa0..0000000 --- a/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:33 +0800 -Subject: [PATCH 096/120] isuper-intel.c: fix double free in load_imsm_mpb() - -In load_imsm_mpb() there is potential double free issue on super->buf. - -The first location to free super->buf is from get_super_block() <== -load_and_parse_mpb() <== load_imsm_mpb(): - 4514 if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE, - 4515 MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - 4516 pr_err("could not allocate migr_rec buffer\n"); - 4517 free(super->buf); - 4518 return 2; - 4519 } - -If the above error condition happens, super->buf is freed and value 2 -is returned to get_super_block() eventually. Then in the following code -block inside load_imsm_mpb(), - 5289 error: - 5290 if (!err) { - 5291 s->next = *super_list; - 5292 *super_list = s; - 5293 } else { - 5294 if (s) - 5295 free_imsm(s); - 5296 close_fd(&dfd); - 5297 } -at line 5295 when free_imsm() is called, super->buf is freed again from -the call chain free_imsm() <== __free_imsm(), in following code block, - 4651 if (super->buf) { - 4652 free(super->buf); - 4653 super->buf = NULL; - 4654 } - -This patch sets super->buf as NULL after line 4517 in load_imsm_mpb() -to avoid the potential double free(). - -(Coly Li helps to re-compose the commit log) - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/super-intel.c b/super-intel.c -index 89fac626..4a3da847 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -4515,6 +4515,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) - MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - pr_err("could not allocate migr_rec buffer\n"); - free(super->buf); -+ super->buf = NULL; - return 2; - } - super->clean_migration_record_by_mdmon = 0; --- -2.38.1 - diff --git a/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch b/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch deleted file mode 100644 index fd60fe2..0000000 --- a/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:34 +0800 -Subject: [PATCH 097/120] super-intel.c: fix memleak in - find_disk_attached_hba() - -If disk_path = diskfd_to_devpath(), we need free(disk_path) before -return, otherwise there will be a memory leak - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 4a3da847..e155a8ae 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -713,12 +713,12 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) - - for (elem = list; elem; elem = elem->next) - if (path_attached_to_hba(disk_path, elem->path)) -- return elem; -+ break; - - if (disk_path != devname) - free(disk_path); - -- return NULL; -+ return elem; - } - - static int find_intel_hba_capability(int fd, struct intel_super *super, --- -2.38.1 - diff --git a/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch b/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch deleted file mode 100644 index d781036..0000000 --- a/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:35 +0800 -Subject: [PATCH 098/120] super-ddf.c: fix memleak in get_vd_num_of_subarray() - -sra = sysfs_read() should be free before return in -get_vd_num_of_subarray() - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 309812df..b86c6acd 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1592,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st) - sra = sysfs_read(-1, st->devnm, GET_VERSION); - if (!sra || sra->array.major_version != -1 || - sra->array.minor_version != -2 || -- !is_subarray(sra->text_version)) -+ !is_subarray(sra->text_version)) { -+ if (sra) -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - sub = strchr(sra->text_version + 1, '/'); - if (sub != NULL) - vcnum = strtoul(sub + 1, &end, 10); - if (sub == NULL || *sub == '\0' || *end != '\0' || -- vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) -+ vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) { -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - return vcnum; - } --- -2.38.1 - diff --git a/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch b/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch deleted file mode 100644 index 4fb641f..0000000 --- a/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:29 -0700 -Subject: [PATCH 099/120] Create: goto abort_locked instead of return 1 in - error path - -The return 1 after the fstat_is_blkdev() check should be replaced -with an error return that goes through the error path to unlock -resources locked by this function. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index 953e7372..2e8203ec 100644 ---- a/Create.c -+++ b/Create.c -@@ -939,7 +939,7 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- return 1; -+ goto abort_locked; - inf->disk.major = major(rdev); - inf->disk.minor = minor(rdev); - } --- -2.38.1 - diff --git a/0100-Create-remove-safe_mode_delay-local-variable.patch b/0100-Create-remove-safe_mode_delay-local-variable.patch deleted file mode 100644 index 4b826a8..0000000 --- a/0100-Create-remove-safe_mode_delay-local-variable.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:30 -0700 -Subject: [PATCH 100/120] Create: remove safe_mode_delay local variable - -All .getinfo_super() call sets the info.safe_mode_delay variables -to a constant value, so no matter what the current state is -that function will always set it to the same value. - -Create() calls .getinfo_super() multiple times while creating the array. -The value is stored in a local variable for every disk in the loop -to add disks (so the last disc call takes precedence). The local -variable is then used in the call to sysfs_set_safemode(). - -This can be simplified by using info.safe_mode_delay directly. The info -variable had .getinfo_super() called on it early in the function so, by the -reasoning above, it will have the same value as the local variable which -can thus be removed. - -Doing this allows for factoring out code from Create() in a subsequent -patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 2e8203ec..8ded81dc 100644 ---- a/Create.c -+++ b/Create.c -@@ -137,7 +137,6 @@ int Create(struct supertype *st, char *mddev, - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -- unsigned long safe_mode_delay = 0; - char chosen_name[1024]; - struct map_ent *map = NULL; - unsigned long long newsize; -@@ -952,7 +951,6 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - st->ss->getinfo_super(st, inf, NULL); -- safe_mode_delay = inf->safe_mode_delay; - - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", -@@ -1065,7 +1063,7 @@ int Create(struct supertype *st, char *mddev, - "readonly"); - break; - } -- sysfs_set_safemode(&info, safe_mode_delay); -+ sysfs_set_safemode(&info, info.safe_mode_delay); - if (err) { - pr_err("failed to activate array.\n"); - ioctl(mdfd, STOP_ARRAY, NULL); --- -2.38.1 - diff --git a/0101-Create-Factor-out-add_disks-helpers.patch b/0101-Create-Factor-out-add_disks-helpers.patch deleted file mode 100644 index c4bfcc5..0000000 --- a/0101-Create-Factor-out-add_disks-helpers.patch +++ /dev/null @@ -1,452 +0,0 @@ -From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:31 -0700 -Subject: [PATCH 101/120] Create: Factor out add_disks() helpers - -The Create function is massive with a very large number of variables. -Reading and understanding the function is almost impossible. To help -with this, factor out the two pass loop that adds the disks to the array. - -This moves about 160 lines into three new helper functions and removes -a bunch of local variables from the main Create function. The main new -helper function add_disks() does the two pass loop and calls into -add_disk_to_super() and update_metadata(). Factoring out the -latter two helpers also helps to reduce a ton of indentation. - -No functional changes intended. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 382 +++++++++++++++++++++++++++++++------------------------ - 1 file changed, 213 insertions(+), 169 deletions(-) - -diff --git a/Create.c b/Create.c -index 8ded81dc..6a044664 100644 ---- a/Create.c -+++ b/Create.c -@@ -91,6 +91,214 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, -+ struct supertype *st, struct mddev_dev *dv, -+ struct mdinfo *info, int have_container, int major_num) -+{ -+ dev_t rdev; -+ int fd; -+ -+ if (dv->disposition == 'j') { -+ info->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -+ info->disk.state = (1<disk.raid_disk < s->raiddisks) { -+ info->disk.state = (1<disk.state = 0; -+ } -+ -+ if (dv->writemostly == FlagSet) { -+ if (major_num == BITMAP_MAJOR_CLUSTERED) { -+ pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -+ return 1; -+ } else { -+ info->disk.state |= (1<failfast == FlagSet) -+ info->disk.state |= (1<ss->external && st->container_devnm[0]) -+ fd = open(dv->devname, O_RDWR); -+ else -+ fd = open(dv->devname, O_RDWR|O_EXCL); -+ -+ if (fd < 0) { -+ pr_err("failed to open %s after earlier success - aborting\n", -+ dv->devname); -+ return 1; -+ } -+ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -+ return 1; -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ if (fd >= 0) -+ remove_partitions(fd); -+ if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, -+ dv->data_offset)) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ st->ss->getinfo_super(st, info, NULL); -+ -+ if (have_container && c->verbose > 0) -+ pr_err("Using %s for device %d\n", -+ map_dev(info->disk.major, info->disk.minor, 0), -+ info->disk.number); -+ -+ if (!have_container) { -+ /* getinfo_super might have lost these ... */ -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ -+ return 0; -+} -+ -+static int update_metadata(int mdfd, struct shape *s, struct supertype *st, -+ struct map_ent **map, struct mdinfo *info, -+ char *chosen_name) -+{ -+ struct mdinfo info_new; -+ struct map_ent *me = NULL; -+ -+ /* check to see if the uuid has changed due to these -+ * metadata changes, and if so update the member array -+ * and container uuid. Note ->write_init_super clears -+ * the subarray cursor such that ->getinfo_super once -+ * again returns container info. -+ */ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ if (st->ss->external && is_container(s->level) && -+ !same_uuid(info_new.uuid, info->uuid, 0)) { -+ map_update(map, fd2devnm(mdfd), -+ info_new.text_version, -+ info_new.uuid, chosen_name); -+ me = map_by_devnm(map, st->container_devnm); -+ } -+ -+ if (st->ss->write_init_super(st)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* -+ * Before activating the array, perform extra steps -+ * required to configure the internal write-intent -+ * bitmap. -+ */ -+ if (info_new.consistency_policy == CONSISTENCY_POLICY_BITMAP && -+ st->ss->set_bitmap && st->ss->set_bitmap(st, info)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* update parent container uuid */ -+ if (me) { -+ char *path = xstrdup(me->path); -+ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ map_update(map, st->container_devnm, info_new.text_version, -+ info_new.uuid, path); -+ free(path); -+ } -+ -+ flush_metadata_updates(st); -+ st->ss->free_super(st); -+ -+ return 0; -+} -+ -+static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, -+ struct context *c, struct supertype *st, -+ struct map_ent **map, struct mddev_dev *devlist, -+ int total_slots, int have_container, int insert_point, -+ int major_num, char *chosen_name) -+{ -+ struct mddev_dev *moved_disk = NULL; -+ int pass, raid_disk_num, dnum; -+ struct mddev_dev *dv; -+ struct mdinfo *infos; -+ int ret = 0; -+ -+ infos = xmalloc(sizeof(*infos) * total_slots); -+ enable_fds(total_slots); -+ for (pass = 1; pass <= 2; pass++) { -+ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -+ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -+ if (dnum >= total_slots) -+ abort(); -+ if (dnum == insert_point) { -+ raid_disk_num += 1; -+ moved_disk = dv; -+ continue; -+ } -+ if (strcasecmp(dv->devname, "missing") == 0) { -+ raid_disk_num += 1; -+ continue; -+ } -+ if (have_container) -+ moved_disk = NULL; -+ if (have_container && dnum < total_slots - 1) -+ /* repeatedly use the container */ -+ moved_disk = dv; -+ -+ switch(pass) { -+ case 1: -+ infos[dnum] = *info; -+ infos[dnum].disk.number = dnum; -+ infos[dnum].disk.raid_disk = raid_disk_num++; -+ -+ if (dv->disposition == 'j') -+ raid_disk_num--; -+ -+ ret = add_disk_to_super(mdfd, s, c, st, dv, -+ &infos[dnum], have_container, -+ major_num); -+ if (ret) -+ goto out; -+ -+ break; -+ case 2: -+ infos[dnum].errors = 0; -+ -+ ret = add_disk(mdfd, st, info, &infos[dnum]); -+ if (ret) { -+ pr_err("ADD_NEW_DISK for %s failed: %s\n", -+ dv->devname, strerror(errno)); -+ if (errno == EINVAL && -+ info->array.level == 0) { -+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -+ pr_err("Either upgrade, or use --layout=dangerous\n"); -+ } -+ goto out; -+ } -+ break; -+ } -+ if (!have_container && -+ dv == moved_disk && dnum != insert_point) break; -+ } -+ -+ if (pass == 1) { -+ ret = update_metadata(mdfd, s, st, map, info, -+ chosen_name); -+ if (ret) -+ goto out; -+ } -+ } -+ -+out: -+ free(infos); -+ return ret; -+} -+ - int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, -@@ -117,7 +325,7 @@ int Create(struct supertype *st, char *mddev, - unsigned long long minsize = 0, maxsize = 0; - char *mindisc = NULL; - char *maxdisc = NULL; -- int dnum, raid_disk_num; -+ int dnum; - struct mddev_dev *dv; - dev_t rdev; - int fail = 0, warn = 0; -@@ -126,14 +334,13 @@ int Create(struct supertype *st, char *mddev, - int missing_disks = 0; - int insert_point = subdevs * 2; /* where to insert a missing drive */ - int total_slots; -- int pass; - int rv; - int bitmap_fd; - int have_container = 0; - int container_fd = -1; - int need_mdmon = 0; - unsigned long long bitmapsize; -- struct mdinfo info, *infos; -+ struct mdinfo info; - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -@@ -869,174 +1076,11 @@ int Create(struct supertype *st, char *mddev, - } - } - -- infos = xmalloc(sizeof(*infos) * total_slots); -- enable_fds(total_slots); -- for (pass = 1; pass <= 2; pass++) { -- struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */ -- -- for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -- dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -- int fd; -- struct mdinfo *inf = &infos[dnum]; -- -- if (dnum >= total_slots) -- abort(); -- if (dnum == insert_point) { -- raid_disk_num += 1; -- moved_disk = dv; -- continue; -- } -- if (strcasecmp(dv->devname, "missing") == 0) { -- raid_disk_num += 1; -- continue; -- } -- if (have_container) -- moved_disk = NULL; -- if (have_container && dnum < info.array.raid_disks - 1) -- /* repeatedly use the container */ -- moved_disk = dv; -- -- switch(pass) { -- case 1: -- *inf = info; -- -- inf->disk.number = dnum; -- inf->disk.raid_disk = raid_disk_num++; -- -- if (dv->disposition == 'j') { -- inf->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -- inf->disk.state = (1<disk.raid_disk < s->raiddisks) -- inf->disk.state = (1<disk.state = 0; -- -- if (dv->writemostly == FlagSet) { -- if (major_num == BITMAP_MAJOR_CLUSTERED) { -- pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -- goto abort_locked; -- } else -- inf->disk.state |= (1<failfast == FlagSet) -- inf->disk.state |= (1<ss->external && -- st->container_devnm[0]) -- fd = open(dv->devname, O_RDWR); -- else -- fd = open(dv->devname, O_RDWR|O_EXCL); -- -- if (fd < 0) { -- pr_err("failed to open %s after earlier success - aborting\n", -- dv->devname); -- goto abort_locked; -- } -- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- goto abort_locked; -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- if (fd >= 0) -- remove_partitions(fd); -- if (st->ss->add_to_super(st, &inf->disk, -- fd, dv->devname, -- dv->data_offset)) { -- ioctl(mdfd, STOP_ARRAY, NULL); -- goto abort_locked; -- } -- st->ss->getinfo_super(st, inf, NULL); -- -- if (have_container && c->verbose > 0) -- pr_err("Using %s for device %d\n", -- map_dev(inf->disk.major, -- inf->disk.minor, -- 0), dnum); -- -- if (!have_container) { -- /* getinfo_super might have lost these ... */ -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- break; -- case 2: -- inf->errors = 0; -- -- rv = add_disk(mdfd, st, &info, inf); -- -- if (rv) { -- pr_err("ADD_NEW_DISK for %s failed: %s\n", -- dv->devname, strerror(errno)); -- if (errno == EINVAL && -- info.array.level == 0) { -- pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -- pr_err("Either upgrade, or use --layout=dangerous\n"); -- } -- goto abort_locked; -- } -- break; -- } -- if (!have_container && -- dv == moved_disk && dnum != insert_point) break; -- } -- if (pass == 1) { -- struct mdinfo info_new; -- struct map_ent *me = NULL; -- -- /* check to see if the uuid has changed due to these -- * metadata changes, and if so update the member array -- * and container uuid. Note ->write_init_super clears -- * the subarray cursor such that ->getinfo_super once -- * again returns container info. -- */ -- st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && !is_container(s->level) && -- !same_uuid(info_new.uuid, info.uuid, 0)) { -- map_update(&map, fd2devnm(mdfd), -- info_new.text_version, -- info_new.uuid, chosen_name); -- me = map_by_devnm(&map, st->container_devnm); -- } -- -- if (st->ss->write_init_super(st)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- /* -- * Before activating the array, perform extra steps -- * required to configure the internal write-intent -- * bitmap. -- */ -- if (info_new.consistency_policy == -- CONSISTENCY_POLICY_BITMAP && -- st->ss->set_bitmap && -- st->ss->set_bitmap(st, &info)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- -- /* update parent container uuid */ -- if (me) { -- char *path = xstrdup(me->path); -- -- st->ss->getinfo_super(st, &info_new, NULL); -- map_update(&map, st->container_devnm, -- info_new.text_version, -- info_new.uuid, path); -- free(path); -- } -+ if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots, -+ have_container, insert_point, major_num, chosen_name)) -+ goto abort_locked; - -- flush_metadata_updates(st); -- st->ss->free_super(st); -- } -- } - map_unlock(&map); -- free(infos); - - if (is_container(s->level)) { - /* No need to start. But we should signal udev to --- -2.38.1 - diff --git a/0102-mdadm-Introduce-pr_info.patch b/0102-mdadm-Introduce-pr_info.patch deleted file mode 100644 index 196624f..0000000 --- a/0102-mdadm-Introduce-pr_info.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:32 -0700 -Subject: [PATCH 102/120] mdadm: Introduce pr_info() - -Feedback was given to avoid informational pr_err() calls that print -to stderr, even though that's done all through out the code. - -Using printf() directly doesn't maintain the same format (an "mdadm" -prefix on every line. - -So introduce pr_info() which prints to stdout with the same format -and use it for a couple informational pr_err() calls in Create(). - -Future work can make this call used in more cases. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Acked-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - Create.c | 7 ++++--- - mdadm.h | 2 ++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 6a044664..4acda30c 100644 ---- a/Create.c -+++ b/Create.c -@@ -984,11 +984,12 @@ int Create(struct supertype *st, char *mddev, - - mdi = sysfs_read(-1, devnm, GET_VERSION); - -- pr_err("Creating array inside %s container %s\n", -+ pr_info("Creating array inside %s container %s\n", - mdi?mdi->text_version:"managed", devnm); - sysfs_free(mdi); - } else -- pr_err("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, -@@ -1145,7 +1146,7 @@ int Create(struct supertype *st, char *mddev, - ioctl(mdfd, RESTART_ARRAY_RW, NULL); - } - if (c->verbose >= 0) -- pr_err("array %s started.\n", mddev); -+ pr_info("array %s started.\n", mddev); - if (st->ss->external && st->container_devnm[0]) { - if (need_mdmon) - start_mdmon(st->container_devnm); -diff --git a/mdadm.h b/mdadm.h -index 1674ce13..4336be4d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1854,6 +1854,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { - #endif - #define cont_err(fmt ...) fprintf(stderr, " " fmt) - -+#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) -+ - void *xmalloc(size_t len); - void *xrealloc(void *ptr, size_t len); - void *xcalloc(size_t num, size_t size); --- -2.38.1 - diff --git a/0103-mdadm-Add-write-zeros-option-for-Create.patch b/0103-mdadm-Add-write-zeros-option-for-Create.patch deleted file mode 100644 index 1e06a73..0000000 --- a/0103-mdadm-Add-write-zeros-option-for-Create.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:33 -0700 -Subject: [PATCH 103/120] mdadm: Add --write-zeros option for Create - -Add the --write-zeros option for Create which will send a write zeros -request to all the disks before assembling the array. After zeroing -the array, the disks will be in a known clean state and the initial -sync may be skipped. - -Writing zeroes is best used when there is a hardware offload method -to zero the data. But even still, zeroing can take several minutes on -a large device. Because of this, all disks are zeroed in parallel using -their own forked process and a message is printed to the user. The main -process will proceed only after all the zeroing processes have completed -successfully. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - ReadMe.c | 2 + - mdadm.c | 9 +++ - mdadm.h | 5 ++ - 4 files changed, 190 insertions(+), 2 deletions(-) - -diff --git a/Create.c b/Create.c -index 4acda30c..bbe9e13d 100644 ---- a/Create.c -+++ b/Create.c -@@ -26,6 +26,10 @@ - #include "md_u.h" - #include "md_p.h" - #include -+#include -+#include -+#include -+#include - - static int round_size_and_verify(unsigned long long *size, int chunk) - { -@@ -91,9 +95,149 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static pid_t write_zeroes_fork(int fd, struct shape *s, struct supertype *st, -+ struct mddev_dev *dv) -+ -+{ -+ const unsigned long long req_size = 1 << 30; -+ unsigned long long offset_bytes, size_bytes, sz; -+ sigset_t sigset; -+ int ret = 0; -+ pid_t pid; -+ -+ size_bytes = KIB_TO_BYTES(s->size); -+ -+ /* -+ * If size_bytes is zero, this is a zoned raid array where -+ * each disk is of a different size and uses its full -+ * disk. Thus zero the entire disk. -+ */ -+ if (!size_bytes && !get_dev_size(fd, dv->devname, &size_bytes)) -+ return -1; -+ -+ if (dv->data_offset != INVALID_SECTORS) -+ offset_bytes = SEC_TO_BYTES(dv->data_offset); -+ else -+ offset_bytes = SEC_TO_BYTES(st->data_offset); -+ -+ pr_info("zeroing data from %lld to %lld on: %s\n", -+ offset_bytes, size_bytes, dv->devname); -+ -+ pid = fork(); -+ if (pid < 0) { -+ pr_err("Could not fork to zero disks: %s\n", strerror(errno)); -+ return pid; -+ } else if (pid != 0) { -+ return pid; -+ } -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_UNBLOCK, &sigset, NULL); -+ -+ while (size_bytes) { -+ /* -+ * Split requests to the kernel into 1GB chunks seeing the -+ * fallocate() call is not interruptible and blocking a -+ * ctrl-c for several minutes is not desirable. -+ * -+ * 1GB is chosen as a compromise: the user may still have -+ * to wait several seconds if they ctrl-c on devices that -+ * zero slowly, but will reduce the number of requests -+ * required and thus the overhead on devices that perform -+ * better. -+ */ -+ sz = size_bytes; -+ if (sz >= req_size) -+ sz = req_size; -+ -+ if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, -+ offset_bytes, sz)) { -+ pr_err("zeroing %s failed: %s\n", dv->devname, -+ strerror(errno)); -+ ret = 1; -+ break; -+ } -+ -+ offset_bytes += sz; -+ size_bytes -= sz; -+ } -+ -+ exit(ret); -+} -+ -+static int wait_for_zero_forks(int *zero_pids, int count) -+{ -+ int wstatus, ret = 0, i, sfd, wait_count = 0; -+ struct signalfd_siginfo fdsi; -+ bool interrupted = false; -+ sigset_t sigset; -+ ssize_t s; -+ -+ for (i = 0; i < count; i++) -+ if (zero_pids[i]) -+ wait_count++; -+ if (!wait_count) -+ return 0; -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigaddset(&sigset, SIGCHLD); -+ sigprocmask(SIG_BLOCK, &sigset, NULL); -+ -+ sfd = signalfd(-1, &sigset, 0); -+ if (sfd < 0) { -+ pr_err("Unable to create signalfd: %s\n", strerror(errno)); -+ return 1; -+ } -+ -+ while (1) { -+ s = read(sfd, &fdsi, sizeof(fdsi)); -+ if (s != sizeof(fdsi)) { -+ pr_err("Invalid signalfd read: %s\n", strerror(errno)); -+ close(sfd); -+ return 1; -+ } -+ -+ if (fdsi.ssi_signo == SIGINT) { -+ printf("\n"); -+ pr_info("Interrupting zeroing processes, please wait...\n"); -+ interrupted = true; -+ } else if (fdsi.ssi_signo == SIGCHLD) { -+ if (!--wait_count) -+ break; -+ } -+ } -+ -+ 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; -+ } -+ -+ if (ret) -+ pr_err("zeroing failed!\n"); -+ else -+ pr_info("zeroing finished\n"); -+ -+ return ret; -+} -+ - static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - struct supertype *st, struct mddev_dev *dv, -- struct mdinfo *info, int have_container, int major_num) -+ struct mdinfo *info, int have_container, int major_num, -+ int *zero_pid) - { - dev_t rdev; - int fd; -@@ -148,6 +292,14 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - } - st->ss->getinfo_super(st, info, NULL); - -+ if (fd >= 0 && s->write_zeroes) { -+ *zero_pid = write_zeroes_fork(fd, s, st, dv); -+ if (*zero_pid <= 0) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ } -+ - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", - map_dev(info->disk.major, info->disk.minor, 0), -@@ -224,10 +376,23 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - { - struct mddev_dev *moved_disk = NULL; - int pass, raid_disk_num, dnum; -+ int zero_pids[total_slots]; - struct mddev_dev *dv; - struct mdinfo *infos; -+ sigset_t sigset, orig_sigset; - int ret = 0; - -+ /* -+ * Block SIGINT so the main thread will always wait for the -+ * zeroing processes when being interrupted. Otherwise the -+ * zeroing processes will finish their work in the background -+ * keeping the disk busy. -+ */ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_BLOCK, &sigset, &orig_sigset); -+ memset(zero_pids, 0, sizeof(zero_pids)); -+ - infos = xmalloc(sizeof(*infos) * total_slots); - enable_fds(total_slots); - for (pass = 1; pass <= 2; pass++) { -@@ -261,7 +426,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - - ret = add_disk_to_super(mdfd, s, c, st, dv, - &infos[dnum], have_container, -- major_num); -+ major_num, &zero_pids[dnum]); - if (ret) - goto out; - -@@ -287,6 +452,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - if (pass == 1) { -+ ret = wait_for_zero_forks(zero_pids, total_slots); -+ if (ret) -+ goto out; -+ - ret = update_metadata(mdfd, s, st, map, info, - chosen_name); - if (ret) -@@ -295,7 +464,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - out: -+ if (ret) -+ wait_for_zero_forks(zero_pids, total_slots); - free(infos); -+ sigprocmask(SIG_SETMASK, &orig_sigset, NULL); - return ret; - } - -diff --git a/ReadMe.c b/ReadMe.c -index bd8d50d2..db251ed2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -138,6 +138,7 @@ struct option long_options[] = { - {"size", 1, 0, 'z'}, - {"auto", 1, 0, Auto}, /* also for --assemble */ - {"assume-clean",0,0, AssumeClean }, -+ {"write-zeroes",0,0, WriteZeroes }, - {"metadata", 1, 0, 'e'}, /* superblock format */ - {"bitmap", 1, 0, Bitmap}, - {"bitmap-chunk", 1, 0, BitmapChunk}, -@@ -390,6 +391,7 @@ char Help_create[] = - " --write-journal= : Specify journal device for RAID-4/5/6 array\n" - " --consistency-policy= : Specify the policy that determines how the array\n" - " -k : maintains consistency in case of unexpected shutdown.\n" -+" --write-zeroes : Write zeroes to the disks before creating. This will bypass initial sync.\n" - "\n" - ; - -diff --git a/mdadm.c b/mdadm.c -index 57e8e6fa..4685ad6b 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -590,6 +590,10 @@ int main(int argc, char *argv[]) - s.assume_clean = 1; - continue; - -+ case O(CREATE, WriteZeroes): -+ s.write_zeroes = 1; -+ continue; -+ - case O(GROW,'n'): - case O(CREATE,'n'): - case O(BUILD,'n'): /* number of raid disks */ -@@ -1251,6 +1255,11 @@ int main(int argc, char *argv[]) - } - } - -+ if (s.write_zeroes && !s.assume_clean) { -+ pr_info("Disk zeroing requested, setting --assume-clean to skip resync\n"); -+ s.assume_clean = 1; -+ } -+ - if (!mode && devs_found) { - mode = MISC; - devmode = 'Q'; -diff --git a/mdadm.h b/mdadm.h -index 4336be4d..b9127f9a 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -275,6 +275,9 @@ static inline void __put_unaligned32(__u32 val, void *p) - - #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -+#define KIB_TO_BYTES(x) ((x) << 10) -+#define SEC_TO_BYTES(x) ((x) << 9) -+ - extern const char Name[]; - - struct md_bb_entry { -@@ -435,6 +438,7 @@ extern char Version[], Usage[], Help[], OptionHelp[], - */ - enum special_options { - AssumeClean = 300, -+ WriteZeroes, - BitmapChunk, - WriteBehind, - ReAdd, -@@ -640,6 +644,7 @@ struct shape { - int bitmap_chunk; - char *bitmap_file; - int assume_clean; -+ bool write_zeroes; - int write_behind; - unsigned long long size; - unsigned long long data_offset; --- -2.38.1 - diff --git a/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch b/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch deleted file mode 100644 index 6c32b5c..0000000 --- a/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c918cf2af993b55bca9f396c79713e54d3f8b6fb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:34 -0700 -Subject: [PATCH 104/120] tests/00raid5-zero: Introduce test to exercise - --write-zeros. - -Attempt to create a raid5 array with --write-zeros. If it is successful -check the array to ensure it is in sync. - -If it is unsuccessful and an unsupported error is printed, skip the -test. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - tests/00raid5-zero | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - create mode 100644 tests/00raid5-zero - -diff --git a/tests/00raid5-zero b/tests/00raid5-zero -new file mode 100644 -index 00000000..7d0f05a1 ---- /dev/null -+++ b/tests/00raid5-zero -@@ -0,0 +1,12 @@ -+ -+if mdadm -CfR $md0 -l 5 -n3 $dev0 $dev1 $dev2 --write-zeroes ; then -+ check nosync -+ echo check > /sys/block/md0/md/sync_action; -+ check wait -+elif grep "zeroing [^ ]* failed: Operation not supported" \ -+ $targetdir/stderr; then -+ echo "write-zeros not supported, skipping" -+else -+ echo >&2 "ERROR: mdadm return failure without not supported message" -+ exit 1 -+fi --- -2.38.1 - diff --git a/0105-manpage-Add-write-zeroes-option-to-manpage.patch b/0105-manpage-Add-write-zeroes-option-to-manpage.patch deleted file mode 100644 index 489faca..0000000 --- a/0105-manpage-Add-write-zeroes-option-to-manpage.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:35 -0700 -Subject: [PATCH 105/120] manpage: Add --write-zeroes option to manpage - -Document the new --write-zeroes option in the manpage. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 64f71ed1..6f0f6c13 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -837,6 +837,22 @@ array is resynced at creation. From Linux version 3.0, - .B \-\-assume\-clean - can be used with that command to avoid the automatic resync. - -+.TP -+.BR \-\-write-zeroes -+When creating an array, send write zeroes requests to all the block -+devices. This should zero the data area on all disks such that the -+initial sync is not necessary and, if successfull, will behave -+as if -+.B \-\-assume\-clean -+was specified. -+.IP -+This is intended for use with devices that have hardware offload for -+zeroing, but despite this zeroing can still take several minutes for -+large disks. Thus a message is printed before and after zeroing and -+each disk is zeroed in parallel with the others. -+.IP -+This is only meaningful with --create. -+ - .TP - .BR \-\-backup\-file= - This is needed when -@@ -1370,7 +1386,7 @@ and - .B layout\-alternate - options are for RAID0 arrays with non-uniform devices size that were in - use before Linux 5.4. If the array was being used with Linux 3.13 or --earlier, then to assemble the array on a new kernel, -+earlier, then to assemble the array on a new kernel, - .B \-\-update=layout\-original - must be given. If the array was created and used with a kernel from Linux 3.14 to - Linux 5.3, then --- -2.38.1 - diff --git a/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch b/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch deleted file mode 100644 index acb55ed..0000000 --- a/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Wed, 18 Jan 2023 00:32:36 -0800 -Subject: [PATCH 106/120] Define alignof using _Alignof when using C11 or newer - -WG14 N2350 made very clear that it is an UB having type definitions -within "offsetof" [1]. This patch enhances the implementation of macro -alignof_slot to use builtin "_Alignof" to avoid undefined behavior on -when using std=c11 or newer - -clang 16+ has started to flag this [2] - -Fixes build when using -std >= gnu11 and using clang16+ - -Older compilers gcc < 4.9 or clang < 8 has buggy _Alignof even though it -may support C11, exclude those compilers too - -[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm -[2] https://reviews.llvm.org/D133574 - -Upstream-Status: Pending -Signed-off-by: Khem Raj -Signed-off-by: Jes Sorensen ---- - sha1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/sha1.c b/sha1.c -index 89b32f46..1e4ad5d9 100644 ---- a/sha1.c -+++ b/sha1.c -@@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) - if (len >= 64) - { - #if !_STRING_ARCH_unaligned --# define alignof(type) offsetof (struct { char c; type x; }, x) -+/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 -+ . -+ clang versions < 8.0.0 have the same bug. */ -+# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ -+ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ -+ && !defined __clang__) \ -+ || (defined __clang__ && __clang_major__ < 8)) -+# define alignof(type) offsetof (struct { char c; type x; }, x) -+# else -+# define alignof(type) _Alignof(type) -+# endif - # define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) --- -2.38.1 - diff --git a/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch b/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch deleted file mode 100644 index f7b06c5..0000000 --- a/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch +++ /dev/null @@ -1,41 +0,0 @@ -From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 107/120] Use existence of /etc/initrd-release to detect - initrd. - -Since v183, systemd has used the existence of /etc/initrd-release to -detect if it is running in an initrd, rather than looking at the magic -number of the root filesystem's device. It is time for mdadm to do the -same. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - util.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/util.c b/util.c -index 9f1e1f7c..509fb43e 100644 ---- a/util.c -+++ b/util.c -@@ -2227,15 +2227,7 @@ int continue_via_systemd(char *devnm, char *service_name) - - int in_initrd(void) - { -- /* This is based on similar function in systemd. */ -- struct statfs s; -- /* statfs.f_type is signed long on s390x and MIPS, causing all -- sorts of sign extension problems with RAMFS_MAGIC being -- defined as 0x858458f6 */ -- return statfs("/", &s) >= 0 && -- ((unsigned long)s.f_type == TMPFS_MAGIC || -- ((unsigned long)s.f_type & 0xFFFFFFFFUL) == -- ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL)); -+ return access("/etc/initrd-release", F_OK) >= 0; - } - - void reopen_mddev(int mdfd) --- -2.38.1 - diff --git a/0108-mdmon-don-t-test-both-all-and-container_name.patch b/0108-mdmon-don-t-test-both-all-and-container_name.patch deleted file mode 100644 index 479e5a5..0000000 --- a/0108-mdmon-don-t-test-both-all-and-container_name.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 108/120] mdmon: don't test both 'all' and 'container_name'. - -If 'all' is not set, then container_name must be NULL, as nothing else -can set it. So simplify the test to ignore container_name. -This makes the purpose of the code more obvious. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdmon.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 60ba3182..f8fd2f0f 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -352,7 +352,6 @@ int main(int argc, char *argv[]) - } - } - -- - if (in_initrd()) { - /* - * set first char of argv[0] to @. This is used by -@@ -362,12 +361,10 @@ int main(int argc, char *argv[]) - argv[0][0] = '@'; - } - -- if (all == 0 && container_name == NULL) { -- if (argv[optind]) { -- container_name = get_md_name(argv[optind]); -- if (!container_name) -- return 1; -- } -+ if (!all && argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ return 1; - } - - if (container_name == NULL || argc - optind > 1) --- -2.38.1 - diff --git a/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch b/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch deleted file mode 100644 index 49240d5..0000000 --- a/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 109/120] mdmon: change systemd unit file to use --foreground - -There is no value in mdmon forking when it is running under systemd - -systemd can still track it anyway. - -So add --foreground option, and remove "Type=forking". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index cb6482d9..bba9b0eb 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -20,8 +20,7 @@ Environment=IMSM_NO_PLATFORM=1 - # 'takeover'. As the '--offroot --takeover' don't hurt when - # not necessary, are are useful with root-on-md in dracut, - # have them always present. --ExecStart=BINDIR/mdmon --offroot --takeover %I --Type=forking -+ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # Don't set the PIDFile. It isn't necessary (systemd can work - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. --- -2.38.1 - diff --git a/0110-mdmon-Remove-need-for-KillMode-none.patch b/0110-mdmon-Remove-need-for-KillMode-none.patch deleted file mode 100644 index 5e6cc63..0000000 --- a/0110-mdmon-Remove-need-for-KillMode-none.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 110/120] mdmon: Remove need for KillMode=none - -mdmon needs to keep running during the switchroot out of (at boot) and -then back into (at shutdown) the initrd. It runs until a new mdmon -takes over. - -Killmode=none is used to achieve this, with the help of --offroot which -sets argv[0][0] to '@' which systemd understands. - -This is needed because mdmon is currently run in system-mdmon.slice -which conflicts with shutdown.target so without Killmode=none mdmon -would get killed early in shutdown when system.mdmon.slice is removed. - -As described in systemd.service(5), this conflict with shutdown can be -resolved by explicitly requesting system.slice, which is a natural -counterpart to DefaultDependencies=no. - -So add that, and also add IgnoreOnIsolate=true to avoid another possible -source of an early death. With these we no longer need KillMode=none -which the systemd developers have marked as "deprecated". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index bba9b0eb..303ad05c 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -10,6 +10,9 @@ Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -+# Allow mdmon to keep running after switchroot, until a new -+# instance is started. -+IgnoreOnIsolate=true - - [Service] - # mdmon should never complain due to lack of a platform, -@@ -25,4 +28,6 @@ ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none -+# The default slice is system-mdmon.slice which Conflicts -+# with shutdown, causing mdmon to exit early. So use system.slice. -+Slice=system.slice --- -2.38.1 - diff --git a/0111-mdmon-Improve-switchroot-interactions.patch b/0111-mdmon-Improve-switchroot-interactions.patch deleted file mode 100644 index 65654a0..0000000 --- a/0111-mdmon-Improve-switchroot-interactions.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 111/120] mdmon: Improve switchroot interactions. - -We need a new mdmon@mdfoo instance to run in the root filesystem after -switch root, as /sys and /dev are removed from the initrd. - -systemd will not start a new unit with the same name running while the -old unit is still active, and we want the two mdmon processes to overlap -in time to avoid any risk of deadlock, which can happen when a write is -attempted with no mdmon running. - -So we need a different unit name in the initrd than in the root. Apart -from the name, everything else should be the same. - -This is easily achieved using a different instance name as the -mdmon@.service unit file already supports multiple instances (for -different arrays). - -So start "mdmon@mdfoo.service" from root, but -"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which -circumstance is the case by looking for /etc/initrd-release. -continue_from_systemd() is enhanced so that the "initrd-" prefix can be -requested. - -Teach mdmon that a container name like "initrd/foo" should be treated -just like "foo". Note that systemd passes the instance name -"initrd-foo" as "initrd/foo". - -We don't need a similar mechanism at shutdown because dracut runs -"mdmon --takeover --all" when appropriate. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - mdadm.h | 2 +- - mdmon.c | 7 ++++++- - systemd/mdmon@.service | 2 +- - udev-md-raid-arrays.rules | 3 ++- - util.c | 7 ++++--- - 6 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/Grow.c b/Grow.c -index bb5fe45c..06001f2d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3516,7 +3516,7 @@ started: - - if (!forked) - if (continue_via_systemd(container ?: sra->sys_name, -- GROW_SERVICE)) { -+ GROW_SERVICE, NULL)) { - free(fdlist); - free(offsets); - sysfs_free(sra); -@@ -3714,7 +3714,7 @@ int reshape_container(char *container, char *devname, - ping_monitor(container); - - if (!forked && !freeze_reshape) -- if (continue_via_systemd(container, GROW_SERVICE)) -+ if (continue_via_systemd(container, GROW_SERVICE, NULL)) - return 0; - - switch (forked ? 0 : fork()) { -diff --git a/mdadm.h b/mdadm.h -index b9127f9a..1e518276 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1608,7 +1608,7 @@ extern int same_dev(char *one, char *two); - extern int compare_paths (char* path1,char* path2); - extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); --extern int continue_via_systemd(char *devnm, char *service_name); -+extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); - -diff --git a/mdmon.c b/mdmon.c -index f8fd2f0f..096b4d76 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -362,7 +362,12 @@ int main(int argc, char *argv[]) - } - - if (!all && argv[optind]) { -- container_name = get_md_name(argv[optind]); -+ static const char prefix[] = "initrd/"; -+ container_name = argv[optind]; -+ if (strncmp(container_name, prefix, -+ sizeof(prefix) - 1) == 0) -+ container_name += sizeof(prefix)-1; -+ container_name = get_md_name(container_name); - if (!container_name) - return 1; - } -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 303ad05c..23a375f6 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -6,7 +6,7 @@ - # (at your option) any later version. - - [Unit] --Description=MD Metadata Monitor on /dev/%I -+Description=MD Metadata Monitor on %I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 2967ace1..4e64b249 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" - - # Tell systemd to run mdmon for our container, if we need it. - ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" --ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" -+ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service" -+ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" - ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" - - LABEL="md_end" -diff --git a/util.c b/util.c -index 509fb43e..d70ca43b 100644 ---- a/util.c -+++ b/util.c -@@ -1916,6 +1916,7 @@ int start_mdmon(char *devnm) - int len; - pid_t pid; - int status; -+ char *prefix = in_initrd() ? "initrd-" : ""; - char pathbuf[1024]; - char *paths[4] = { - pathbuf, -@@ -1926,7 +1927,7 @@ int start_mdmon(char *devnm) - - if (check_env("MDADM_NO_MDMON")) - return 0; -- if (continue_via_systemd(devnm, MDMON_SERVICE)) -+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix)) - return 0; - - /* That failed, try running mdmon directly */ -@@ -2197,7 +2198,7 @@ void manage_fork_fds(int close_all) - * 1- if systemd service has been started - * 0- otherwise - */ --int continue_via_systemd(char *devnm, char *service_name) -+int continue_via_systemd(char *devnm, char *service_name, char *prefix) - { - int pid, status; - char pathbuf[1024]; -@@ -2209,7 +2210,7 @@ int continue_via_systemd(char *devnm, char *service_name) - case 0: - manage_fork_fds(1); - snprintf(pathbuf, sizeof(pathbuf), -- "%s@%s.service", service_name, devnm); -+ "%s@%s%s.service", service_name, prefix ?: "", devnm); - status = execl("/usr/bin/systemctl", "systemctl", "restart", - pathbuf, NULL); - status = execl("/bin/systemctl", "systemctl", "restart", --- -2.38.1 - diff --git a/0112-mdopen-always-try-create_named_array.patch b/0112-mdopen-always-try-create_named_array.patch deleted file mode 100644 index bfd899c..0000000 --- a/0112-mdopen-always-try-create_named_array.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Tue, 14 Mar 2023 11:06:25 +1100 -Subject: [PATCH 112/120] mdopen: always try create_named_array() - -mdopen() will use create_named_array() to ask the kernel to create the -given md array, but only if it is given a number or name. -If it is NOT given a name and is required to choose one itself using -find_free_devnm() it does NOT use create_named_array(). - -On kernels with CONFIG_BLOCK_LEGACY_AUTOLOAD not set, this can result in -failure to assemble an array. This can particularly seen when the -"name" of the array begins with a host name different to the name of the -host running the command. - -So add the missing call to create_named_array(). - -Link: https://bugzilla.kernel.org/show_bug.cgi?id=217074 -Signed-off-by: NeilBrown -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdopen.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/mdopen.c b/mdopen.c -index d18c9319..810f79a3 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - } - if (block_udev) - udev_block(devnm); -+ create_named_array(devnm); - } - - sprintf(devname, "/dev/%s", devnm); --- -2.38.1 - diff --git a/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch b/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch deleted file mode 100644 index d4e6a4f..0000000 --- a/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 20 Mar 2023 14:43:54 +1100 -Subject: [PATCH 113/120] Improvements for IMSM_NO_PLATFORM testing. - -Factor out IMSM_NO_PLATFORM testing into a single function that caches -the result. - -Allow mdmon to explicitly set the result to "1" so that we don't need -the ENV var in the unit file - -Check if the kernel command line contains "mdadm.imsm.test=1" and in -that case assert NO_PLATFORM. This simplifies testing in a virtual -machine. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 5 +++++ - mdadm.h | 2 ++ - mdmon.c | 6 ++++++ - super-intel.c | 45 +++++++++++++++++++++++++++++++++++++++--- - systemd/mdmon@.service | 3 --- - 5 files changed, 55 insertions(+), 6 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 6f0f6c13..b7159509 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -3197,6 +3197,11 @@ 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 -+.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. -+ - .TP - .B MDADM_GROW_ALLOW_OLD - If an array is stopped while it is performing a reshape and that -diff --git a/mdadm.h b/mdadm.h -index 1e518276..0d995445 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1263,6 +1263,8 @@ extern struct superswitch super0, super1; - extern struct superswitch super_imsm, super_ddf; - extern struct superswitch mbr, gpt; - -+void imsm_set_no_platform(int v); -+ - struct metadata_update { - int len; - char *buf; -diff --git a/mdmon.c b/mdmon.c -index 096b4d76..cef5bbc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -318,6 +318,12 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -+ /* -+ * mdmon should never complain due to lack of a platform, -+ * that is mdadm's job if at all. -+ */ -+ imsm_set_no_platform(1); -+ - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -diff --git a/super-intel.c b/super-intel.c -index e155a8ae..a5c86cb2 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -20,6 +20,7 @@ - #define HAVE_STDINT_H 1 - #include "mdadm.h" - #include "mdmon.h" -+#include "dlink.h" - #include "sha1.h" - #include "platform-intel.h" - #include -@@ -629,6 +630,44 @@ static const char *_sys_dev_type[] = { - [SYS_DEV_VMD] = "VMD" - }; - -+static int no_platform = -1; -+ -+static int check_no_platform(void) -+{ -+ static const char search[] = "mdadm.imsm.test=1"; -+ FILE *fp; -+ -+ if (no_platform >= 0) -+ return no_platform; -+ -+ if (check_env("IMSM_NO_PLATFORM")) { -+ no_platform = 1; -+ return 1; -+ } -+ fp = fopen("/proc/cmdline", "r"); -+ if (fp) { -+ char *l = conf_line(fp); -+ char *w = l; -+ -+ do { -+ if (strcmp(w, search) == 0) -+ no_platform = 1; -+ w = dl_next(w); -+ } while (w != l); -+ free_line(l); -+ fclose(fp); -+ if (no_platform >= 0) -+ return no_platform; -+ } -+ no_platform = 0; -+ return 0; -+} -+ -+void imsm_set_no_platform(int v) -+{ -+ no_platform = v; -+} -+ - const char *get_sys_dev_type(enum sys_dev_type type) - { - if (type >= SYS_DEV_MAX) -@@ -2699,7 +2738,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - int result=1; - - if (enumerate_only) { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - list = find_intel_devices(); - if (!list) -@@ -4722,7 +4761,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de - devname); - return 1; - } -- if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) { -+ if (!is_fd_valid(fd) || check_no_platform()) { - super->orom = NULL; - super->hba = NULL; - return 0; -@@ -10697,7 +10736,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks, - ******************************************************************************/ - int validate_container_imsm(struct mdinfo *info) - { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - - struct sys_dev *idev; -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 23a375f6..020cc7e1 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -15,9 +15,6 @@ Documentation=man:mdmon(8) - IgnoreOnIsolate=true - - [Service] --# mdmon should never complain due to lack of a platform, --# that is mdadm's job if at all. --Environment=IMSM_NO_PLATFORM=1 - # The mdmon starting in the initramfs (with dracut at least) - # cannot see sysfs after root is mounted, so we will have to - # 'takeover'. As the '--offroot --takeover' don't hurt when --- -2.38.1 - diff --git a/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch b/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch deleted file mode 100644 index 39b1809..0000000 --- a/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9b6e3b43381245cb128ad98bf117a565ce5defe5 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:13:18 +0100 -Subject: [PATCH 114/120] Revert "Revert "mdadm/systemd: remove KillMode=none - from service file"" - -This reverts commit 28a083955c6f58f8e582734c8c82aff909a7d461. - -Resolved by commit 723d1df4946e ("mdmon: Improve switchroot -interactions.") We are ready to drop it. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9ccadca3..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none --- -2.38.1 - diff --git a/0115-Create-Fix-checking-for-container-in-update_metadata.patch b/0115-Create-Fix-checking-for-container-in-update_metadata.patch deleted file mode 100644 index 0868469..0000000 --- a/0115-Create-Fix-checking-for-container-in-update_metadata.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 23 Mar 2023 12:50:00 +0100 -Subject: [PATCH 115/120] Create: Fix checking for container in update_metadata - -The commit 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -introduced a regression that caused timeouts and udev failing to create -links. - -Steps to reproduce the issue were as following: -$ mdadm -CR imsm -e imsm -n4 /dev/nvme[0-3]n1 -$ mdadm -CR vol -l5 -n4 /dev/nvme[0-3]n1 --assume-clean - -I found the check for container was wrong because negation was missing. - -Fixes: 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index bbe9e13d..0911bf92 100644 ---- a/Create.c -+++ b/Create.c -@@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && is_container(s->level) && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info->uuid, 0)) { - map_update(map, fd2devnm(mdfd), - info_new.text_version, --- -2.38.1 - diff --git a/0116-Fix-null-pointer-for-incremental-in-mdadm.patch b/0116-Fix-null-pointer-for-incremental-in-mdadm.patch deleted file mode 100644 index 53bc051..0000000 --- a/0116-Fix-null-pointer-for-incremental-in-mdadm.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 890212d6800646153210ac264ce73035cc7dd5cc Mon Sep 17 00:00:00 2001 -From: miaoguanqin -Date: Tue, 4 Apr 2023 19:31:24 +0800 -Subject: [PATCH 116/120] Fix null pointer for incremental in mdadm - -when we excute mdadm --assemble, udev-md-raid-assembly.rules is triggered. -Then we stop array, we found an coredump for mdadm --incremental.func -stack are as follows: - -#0 enough (level=10, raid_disks=4, layout=258, clean=1, - avail=avail@entry=0x0) at util.c:555 -#1 0x0000562170c26965 in Incremental (devlist=, - c=, st=0x5621729b6dc0) at Incremental.c:514 -#2 0x0000562170bfb6ff in main (argc=, - argv=) at mdadm.c:1762 - -func enough() use array avail,avail allocate space in func count_active, -it may not alloc space, causing a coredump.We fix this coredump. - -Signed-off-by: Guanqin Miao -Signed-off-by: lixiaokeng -Signed-off-by: Jes Sorensen ---- - Incremental.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Incremental.c b/Incremental.c -index 09b94b9f..49a71f72 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -507,6 +507,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - GET_OFFSET | GET_SIZE)); - active_disks = count_active(st, sra, mdfd, &avail, &info); - -+ if (!avail) -+ goto out_unlock; -+ - journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); - - if (info.consistency_policy == CONSISTENCY_POLICY_PPL) --- -2.38.1 - diff --git a/0117-super1-fix-truncation-check-for-journal-device.patch b/0117-super1-fix-truncation-check-for-journal-device.patch deleted file mode 100644 index bf985c8..0000000 --- a/0117-super1-fix-truncation-check-for-journal-device.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1c6f2a1dbfe17df14dd5b062fc53a60c5c387e47 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Sat, 1 Apr 2023 23:01:35 +0300 -Subject: [PATCH 117/120] super1: fix truncation check for journal device - -The journal device can be smaller than the component devices. - -Fixes: 171e9743881e ("super1: report truncated device") -Signed-off-by: Hristo Venev -Signed-off-by: Jes Sorensen ---- - super1.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/super1.c b/super1.c -index f7020320..44d6ecad 100644 ---- a/super1.c -+++ b/super1.c -@@ -2359,8 +2359,9 @@ static int load_super1(struct supertype *st, int fd, char *devname) - - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && -- (dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size)) -+ ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) - || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { --- -2.38.1 - diff --git a/0118-Fix-some-cases-eyesore-formatting.patch b/0118-Fix-some-cases-eyesore-formatting.patch deleted file mode 100644 index 4da8078..0000000 --- a/0118-Fix-some-cases-eyesore-formatting.patch +++ /dev/null @@ -1,433 +0,0 @@ -From d3bb888d885fc96fc6239fbf6c22c63143eba461 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:40:42 -0400 -Subject: [PATCH 118/120] Fix some cases eyesore formatting - -Summary: No functional change .... just make it more readable. - -Signed-off-by: Jes Sorensen ---- - super1.c | 117 ++++++++++++++++++++++++++++--------------------------- - 1 file changed, 60 insertions(+), 57 deletions(-) - -diff --git a/super1.c b/super1.c -index 44d6ecad..1d20ef55 100644 ---- a/super1.c -+++ b/super1.c -@@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - unsigned int disk_csum, csum; - unsigned long long newcsum; - int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2; -- unsigned int *isuper = (unsigned int*)sb; -+ unsigned int *isuper = (unsigned int *)sb; - - /* make sure I can count... */ - if (offsetof(struct mdp_superblock_1,data_offset) != 128 || -@@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - disk_csum = sb->sb_csum; - sb->sb_csum = 0; - newcsum = 0; -- for (; size>=4; size -= 4 ) { -+ for (; size >= 4; size -= 4) { - newcsum += __le32_to_cpu(*isuper); - isuper++; - } -@@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk) - static void examine_super1(struct supertype *st, char *homehost) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - time_t atime; - unsigned int d; - int role; -@@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost) - printf(".0\n"); - printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map)); - printf(" Array UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) printf(":"); -+ for (i = 0; i < 16; i++) { -+ if ((i & 3) == 0 && i != 0) -+ printf(":"); - printf("%02x", sb->set_uuid[i]); - } - printf("\n"); -@@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost) - UINT64_MAX - info.space_after); - } - printf(" State : %s%s\n", -- (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (__le64_to_cpu(sb->resync_offset) + 1) ? "active":"clean", - (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) -+ for (i = 0; i < 16; i++) { -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This turns out to just be confusing */ - printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number)); -- for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--) -+ for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--) - if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE) - break; - for (d = 0; d < i; d++) { -@@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This is confusing too */ - faulty = 0; -- for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { -+ for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { - int role = __le16_to_cpu(sb->dev_roles[i]); - if (role == MD_DISK_ROLE_FAULTY) - faulty++; -@@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost) - if (inconsistent) { - printf("WARNING Array state is inconsistent - each number should appear only once\n"); - for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) -- if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY) -+ if (__le16_to_cpu(sb->dev_roles[d]) >= -+ MD_DISK_ROLE_FAULTY) - printf(" %d:-", d); - else -- printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d])); -+ printf(" %d:%d", d, -+ __le16_to_cpu(sb->dev_roles[d])); - printf("\n"); - } - } -@@ -659,7 +662,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) - printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks)); - printf("UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3)==0 && i != 0) -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -713,7 +716,7 @@ static void export_examine_super1(struct supertype *st) - } - printf("MD_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -722,7 +725,7 @@ static void export_examine_super1(struct supertype *st) - __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL); - printf("MD_DEV_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -812,7 +815,7 @@ static int copy_metadata1(struct supertype *st, int from, int to) - /* have the header, can calculate - * correct bitmap bytes */ - bitmap_super_t *bms; -- bms = (void*)buf; -+ bms = (void *)buf; - bytes = calc_bitmap_size(bms, 512); - if (n > bytes) - n = bytes; -@@ -867,7 +870,7 @@ err: - static void detail_super1(struct supertype *st, char *homehost, char *subarray) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int i; - int l = homehost ? strlen(homehost) : 0; - -@@ -880,7 +883,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray) - printf("\n Cluster Name : %-64s", bms->cluster_name); - printf("\n UUID : "); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -939,7 +942,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) - } - - size = __le16_to_cpu(sb->bblog_size)* 512; -- if (posix_memalign((void**)&bbl, 4096, size) != 0) { -+ if (posix_memalign((void **)&bbl, 4096, size) != 0) { - pr_err("could not allocate badblocks list\n"); - return 0; - } -@@ -987,7 +990,7 @@ static int match_home1(struct supertype *st, char *homehost) - static void uuid_from_super1(struct supertype *st, int uuid[4]) - { - struct mdp_superblock_1 *super = st->sb; -- char *cuuid = (char*)uuid; -+ char *cuuid = (char *)uuid; - int i; - for (i = 0; i < 16; i++) - cuuid[i] = super->set_uuid[i]; -@@ -996,9 +999,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) - static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - { - struct mdp_superblock_1 *sb = st->sb; -- struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE); - struct misc_dev_info *misc = -- (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE); - int working = 0; - unsigned int i; - unsigned int role; -@@ -1166,7 +1169,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - info->recovery_blocked = info->reshape_active; - - if (map) -- for (i=0; imax_dev); i++) { - role = __le16_to_cpu(sb->dev_roles[i]); -@@ -1217,7 +1220,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - */ - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - - if (update == UOPT_HOMEHOST && homehost) { - /* -@@ -1228,9 +1231,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- snprintf(info->name, sizeof(info->name), "%s", c+1); -+ snprintf(info->name, sizeof(info->name), "%s", c + 1); - else -- snprintf(info->name, sizeof(info->name), "%s", sb->set_name); -+ snprintf(info->name, sizeof(info->name), "%s", -+ sb->set_name); - } - - switch (update) { -@@ -1331,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->dev_number = __cpu_to_le32(i); - - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - if (i > max) - return -2; - -@@ -1350,8 +1354,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); - } else { -- ds -= 8*2; -- ds &= ~(unsigned long long)(4*2-1); -+ ds -= 8 * 2; -+ ds &= ~(unsigned long long)(4 * 2 - 1); - sb->super_offset = __cpu_to_le64(ds); - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); -@@ -1367,7 +1371,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - if (i > max) - return -2; - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -@@ -1645,7 +1649,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - char defname[10]; - int sbsize; - -- if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 0; - } -@@ -1679,8 +1683,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - name = defname; - } - if (homehost && -- strchr(name, ':')== NULL && -- strlen(homehost)+1+strlen(name) < 32) { -+ strchr(name, ':') == NULL && -+ strlen(homehost) + 1 + strlen(name) < 32) { - strcpy(sb->set_name, homehost); - strcat(sb->set_name, ":"); - strcat(sb->set_name, name); -@@ -1759,7 +1763,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, - - if (dk->number >= (int)__le32_to_cpu(sb->max_dev) && - __le32_to_cpu(sb->max_dev) < MAX_DEVS) -- sb->max_dev = __cpu_to_le32(dk->number+1); -+ sb->max_dev = __cpu_to_le32(dk->number + 1); - - sb->dev_number = __cpu_to_le32(dk->number); - sb->devflags = 0; /* don't copy another disks flags */ -@@ -1840,8 +1844,8 @@ static int store_super1(struct supertype *st, int fd) - return 4; - - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { -- struct bitmap_super_s *bm = (struct bitmap_super_s*) -- (((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bm; -+ bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE); - if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { - locate_bitmap1(st, fd, 0); - if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm)) -@@ -1928,7 +1932,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) - - init_afd(&afd, fd); - -- if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) { -+ if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) { - pr_err("Could not allocate memory for the meta block.\n"); - return 1; - } -@@ -2197,7 +2201,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst, - return 1; - - if (!first) { -- if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2310,7 +2314,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 1; - } - -- if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2349,10 +2353,10 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 2; - } - -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - - misc = (struct misc_dev_info*) -- (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE); - misc->device_size = dsize; - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); -@@ -2360,9 +2364,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && - ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -- dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size))) -- || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { - if (devname) -@@ -2391,8 +2394,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 0; - - no_bitmap: -- super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) -- & ~MD_FEATURE_BITMAP_OFFSET); -+ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & -+ ~MD_FEATURE_BITMAP_OFFSET); - return 0; - } - -@@ -2450,7 +2453,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, - if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) { - /* hot-add. allow for actual size of bitmap */ - struct bitmap_super_s *bsb; -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - bmspace = calc_bitmap_size(bsb, 4096) >> 9; - } else if (md_feature_any_ppl_on(super->feature_map)) { - bmspace = __le16_to_cpu(super->ppl.size); -@@ -2519,7 +2522,7 @@ add_internal_bitmap1(struct supertype *st, - int creating = 0; - int len; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int uuid[4]; - - if (__le64_to_cpu(sb->data_size) == 0) -@@ -2607,10 +2610,10 @@ add_internal_bitmap1(struct supertype *st, - max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8; - - min_chunk = 4096; /* sub-page chunks don't work yet.. */ -- bits = (size*512)/min_chunk +1; -+ bits = (size * 512) / min_chunk + 1; - while (bits > max_bits) { - min_chunk *= 2; -- bits = (bits+1)/2; -+ bits = (bits + 1) / 2; - } - if (chunk == UnSet) { - /* For practical purpose, 64Meg is a good -@@ -2628,8 +2631,8 @@ add_internal_bitmap1(struct supertype *st, - /* start bitmap on a 4K boundary with enough space for - * the bitmap - */ -- bits = (size*512) / chunk + 1; -- room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096; -+ bits = (size * 512) / chunk + 1; -+ room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096; - room *= 8; /* convert 4K blocks to sectors */ - offset = -room - bbl_size; - } -@@ -2683,7 +2686,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - - offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset); - if (node_num) { -- bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9; - offset += bm_sectors_per_node * node_num; - } -@@ -2696,7 +2699,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int rv = 0; - void *buf; - int towrite, n, len; -@@ -2970,16 +2973,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - sprintf(sb->set_name, "%d", sb0->md_minor); -- sb->ctime = __cpu_to_le32(info->array.ctime+1); -+ sb->ctime = __cpu_to_le32(info->array.ctime + 1); - sb->level = __cpu_to_le32(info->array.level); - sb->layout = __cpu_to_le32(info->array.layout); - sb->size = __cpu_to_le64(info->component_size); -- sb->chunksize = __cpu_to_le32(info->array.chunk_size/512); -+ sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - if (info->array.level > 0) - sb->data_size = sb->size; - else -- sb->data_size = st->ss->avail_size(st, st->devsize/512, 0); -+ sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0); - sb->resync_offset = MaxSector; - sb->max_dev = __cpu_to_le32(MD_SB_DISKS); - sb->dev_number = __cpu_to_le32(info->disk.number); --- -2.38.1 - diff --git a/0119-Bump-minimum-kernel-version-to-2.6.32.patch b/0119-Bump-minimum-kernel-version-to-2.6.32.patch deleted file mode 100644 index 7fcbf6c..0000000 --- a/0119-Bump-minimum-kernel-version-to-2.6.32.patch +++ /dev/null @@ -1,136 +0,0 @@ -From f8d2c4286a92b7acb7872271a401ad1efe336096 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:45:34 -0400 -Subject: [PATCH 119/120] Bump minimum kernel version to 2.6.32 - -Summary: At this point it probably is reasonable to drop support for -anything prior to 3.10. - -Signed-off-by: Jes Sorensen ---- - Create.c | 5 ----- - Grow.c | 16 ---------------- - Manage.c | 17 ----------------- - mdadm.c | 4 ++-- - super1.c | 5 ----- - 5 files changed, 2 insertions(+), 45 deletions(-) - -diff --git a/Create.c b/Create.c -index 0911bf92..aa0472dd 100644 ---- a/Create.c -+++ b/Create.c -@@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev, - break; - case LEVEL_LINEAR: - /* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */ -- if (get_linux_version() < 2006016 && s->chunk == 0) { -- s->chunk = 64; -- if (c->verbose > 0) -- pr_err("chunk size defaults to 64K\n"); -- } - break; - case 1: - case LEVEL_FAULTY: -diff --git a/Grow.c b/Grow.c -index 06001f2d..8fa97875 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) - return NULL; - } - -- if (re->after.data_disks == re->before.data_disks && -- get_linux_version() < 2006032) -- return "in-place reshape is not safe before 2.6.32 - sorry."; -- -- if (re->after.data_disks < re->before.data_disks && -- get_linux_version() < 2006030) -- return "reshape to fewer devices is not supported before 2.6.30 - sorry."; -- - re->backup_blocks = compute_backup_blocks( - info->new_chunk, info->array.chunk_size, - re->after.data_disks, re->before.data_disks); -@@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (s->raiddisks && s->raiddisks < array.raid_disks && -- array.level > 1 && get_linux_version() < 2006032 && -- !check_env("MDADM_FORCE_FEWER")) { -- pr_err("reducing the number of devices is not safe before Linux 2.6.32\n" -- " Please use a newer kernel\n"); -- return 1; -- } -- - if (array.level > 1 && s->size > 1 && - (unsigned long long) (array.chunk_size / 1024) > s->size) { - pr_err("component size must be larger than chunk size.\n"); -diff --git a/Manage.c b/Manage.c -index fde6aba3..f54de7c6 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -461,17 +461,6 @@ done: - goto out; - } - -- if (get_linux_version() < 2006028) { -- /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array -- * was stopped, so We'll do it here just to be sure. Drop any -- * partitions as well... -- */ -- if (fd >= 0) -- ioctl(fd, BLKRRPART, 0); -- if (mdi) -- sysfs_uevent(mdi, "change"); -- } -- - if (devnm[0] && use_udev()) { - struct map_ent *mp = map_by_devnm(&map, devnm); - remove_devices(devnm, mp ? mp->path : NULL); -@@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - * though. - */ - mdu_disk_info_t disc; -- /* re-add doesn't work for version-1 superblocks -- * before 2.6.18 :-( -- */ -- if (array->major_version == 1 && -- get_linux_version() <= 2006018) -- goto skip_re_add; - disc.number = mdi.disk.number; - if (md_get_disk_info(fd, &disc) != 0 || - disc.major != 0 || disc.minor != 0) -diff --git a/mdadm.c b/mdadm.c -index 4685ad6b..2296911d 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,8 +107,8 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- if (get_linux_version() < 2006015) { -- pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); -+ if (get_linux_version() < 2006032) { -+ pr_err("This version of mdadm does not support kernels older than 2.6.32\n"); - exit(1); - } - -diff --git a/super1.c b/super1.c -index 1d20ef55..938c3a68 100644 ---- a/super1.c -+++ b/super1.c -@@ -2033,11 +2033,6 @@ static int write_init_super1(struct supertype *st) - /* same array, so preserve events and - * dev_number */ - sb->events = refsb->events; -- /* bugs in 2.6.17 and earlier mean the -- * dev_number chosen in Manage must be preserved -- */ -- if (get_linux_version() >= 2006018) -- sb->dev_number = refsb->dev_number; - } - free_super1(refst); - } --- -2.38.1 - diff --git a/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch b/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch deleted file mode 100644 index cb73179..0000000 --- a/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 7 Apr 2023 08:45:28 +0800 -Subject: [PATCH 120/120] Remove the config files in mdcheck_start|continue - service - -We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files. -And mdcheck doesn't use any configs from the config file. So we can remove -the dependencies. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdcheck_continue.service | 2 -- - systemd/mdcheck_start.service | 2 -- - 2 files changed, 4 deletions(-) - -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index f5324905..70892a1f 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 703a6583..fc4fc438 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} --- -2.38.1 - diff --git a/disable-Werror.patch b/disable-Werror.patch deleted file mode 100644 index 2d52c67..0000000 --- a/disable-Werror.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- mdadm/Makefile.orig 2021-07-28 21:39:23.887433859 +0800 -+++ mdadm/Makefile 2021-07-28 21:39:37.989432841 +0800 -@@ -50,7 +50,7 @@ - CC := $(CROSS_COMPILE)gcc - endif - CXFLAGS ?= -ggdb --CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -+CWFLAGS = -Wall -Wstrict-prototypes -Wextra -Wno-unused-parameter - ifdef WARN_UNUSED - CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 - endif diff --git a/mdadm.spec b/mdadm.spec index e0c4a56..7a3c83b 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,11 +1,11 @@ Name: mdadm -Version: 4.2 -Release: 9%{?dist} +Version: 4.3 +Release: 1%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ -License: GPLv2+ +License: GPL-2.0-or-later -Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}%{?subversion:-%{subversion}}.tar.xz +Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz Source1: raid-check Source2: mdadm-raid-check-sysconfig Source3: mdmonitor.service @@ -15,202 +15,97 @@ Source6: raid-check.timer Source7: raid-check.service Source8: mdcheck -Patch000: 0001-Unify-error-message.patch -Patch001: 0002-mdadm-Fix-double-free.patch -Patch002: 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch -Patch003: 0004-udev-adapt-rules-to-systemd-v247.patch -Patch004: 0005-Replace-error-prone-signal-with-sigaction.patch -Patch005: 0006-mdadm-Respect-config-file-location-in-man.patch -Patch006: 0007-mdadm-Update-ReadMe.patch -Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch -Patch008: 0009-mdadm-Update-config-manual.patch -Patch009: 0010-Create-Build-use-default_layout.patch -Patch010: 0011-mdadm-add-map_num_s.patch -Patch011: 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch -Patch012: 0013-mdmon-Stop-parsing-duplicate-options.patch -Patch013: 0014-Grow-block-n-on-external-volumes.patch -Patch014: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch -Patch015: 0016-Mdmonitor-Fix-segfault.patch -Patch016: 0017-Mdmonitor-Improve-logging-method.patch -Patch017: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch -Patch018: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch -Patch019: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch -Patch020: 0021-util-replace-ioctl-use-with-function.patch -Patch021: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch -Patch022: 0023-imsm-introduce-get_disk_slot_in_dev.patch -Patch023: 0024-imsm-use-same-slot-across-container.patch -Patch024: 0025-imsm-block-changing-slots-during-creation.patch -Patch025: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch -Patch026: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch -Patch027: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch -Patch028: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch -Patch029: 0030-Monitor-use-snprintf-to-fill-device-name.patch -Patch030: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch -Patch031: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch -Patch032: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch -Patch033: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch -Patch034: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch -Patch035: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch -Patch036: 0037-mdadm-Fix-optional-write-behind-parameter.patch -Patch037: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch -Patch038: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch -Patch039: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch -Patch040: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch -Patch041: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch -Patch042: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch -Patch043: 0044-tests-Add-broken-files-for-all-broken-tests.patch -Patch044: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch -Patch045: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch -Patch046: 0047-tests-add-test-for-names.patch -Patch047: 0048-mdadm-remove-symlink-option.patch -Patch048: 0049-mdadm-move-data_offset-to-struct-shape.patch -Patch049: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch -Patch050: 0051-Grow-Split-Grow_reshape-into-helper-function.patch -Patch051: 0052-Assemble-check-if-device-is-container-before-schedul.patch -Patch052: 0053-super1-report-truncated-device.patch -Patch053: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch -Patch054: 0055-Manage-Block-unsafe-member-failing.patch -Patch055: 0056-Monitor-Fix-statelist-memory-leaks.patch -Patch056: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch -Patch057: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch -Patch058: 0059-ReadMe-fix-command-line-help.patch -Patch059: 0060-mdadm-replace-container-level-checking-with-inline.patch -Patch060: 0061-Mdmonitor-Omit-non-md-devices.patch -Patch061: 0062-Mdmonitor-Split-alert-into-separate-functions.patch -Patch062: 0063-Monitor-block-if-monitor-modes-are-combined.patch -Patch063: 0064-Update-mdadm-Monitor-manual.patch -Patch064: 0065-Grow-fix-possible-memory-leak.patch -Patch065: 0066-mdadm-create-ident_init.patch -Patch066: 0067-mdadm-Add-option-validation-for-update-subarray.patch -Patch067: 0068-Fix-update-subarray-on-active-volume.patch -Patch068: 0069-Add-code-specific-update-options-to-enum.patch -Patch069: 0070-super-ddf-Remove-update_super_ddf.patch -Patch070: 0071-super0-refactor-the-code-for-enum.patch -Patch071: 0072-super1-refactor-the-code-for-enum.patch -Patch072: 0073-super-intel-refactor-the-code-for-enum.patch -Patch073: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch -Patch074: 0075-Manage-Incremental-code-refactor-string-to-enum.patch -Patch075: 0076-Change-char-to-enum-in-context-update-refactor-code.patch -Patch076: 0077-mdmon-fix-segfault.patch -Patch077: 0078-util-remove-obsolete-code-from-get_md_name.patch -Patch078: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch -Patch079: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch -Patch080: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch -Patch081: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch -Patch082: 0083-manage-move-comment-with-function-description.patch -Patch083: 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch -Patch084: 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch -Patch085: 0086-Fix-NULL-dereference-in-super_by_fd.patch -Patch086: 0087-Mdmonitor-Make-alert_info-global.patch -Patch087: 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch -Patch088: 0089-Mdmonitor-Add-helper-functions.patch -Patch089: 0090-Add-helpers-to-determine-whether-directories-or-file.patch -Patch090: 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch -Patch091: 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch -Patch092: 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch -Patch093: 0094-util.c-fix-memleak-in-parse_layout_faulty.patch -Patch094: 0095-Detail.c-fix-memleak-in-Detail.patch -Patch095: 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch -Patch096: 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch -Patch097: 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch -Patch098: 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch -Patch099: 0100-Create-remove-safe_mode_delay-local-variable.patch -Patch100: 0101-Create-Factor-out-add_disks-helpers.patch -Patch101: 0102-mdadm-Introduce-pr_info.patch -Patch102: 0103-mdadm-Add-write-zeros-option-for-Create.patch -Patch103: 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch -Patch104: 0105-manpage-Add-write-zeroes-option-to-manpage.patch -Patch105: 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch -Patch106: 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch -Patch107: 0108-mdmon-don-t-test-both-all-and-container_name.patch -Patch108: 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch -Patch109: 0110-mdmon-Remove-need-for-KillMode-none.patch -Patch110: 0111-mdmon-Improve-switchroot-interactions.patch -Patch111: 0112-mdopen-always-try-create_named_array.patch -Patch112: 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch -Patch113: 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch -Patch114: 0115-Create-Fix-checking-for-container-in-update_metadata.patch -Patch115: 0116-Fix-null-pointer-for-incremental-in-mdadm.patch -Patch116: 0117-super1-fix-truncation-check-for-journal-device.patch -Patch117: 0118-Fix-some-cases-eyesore-formatting.patch -Patch118: 0119-Bump-minimum-kernel-version-to-2.6.32.patch -Patch119: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch - # Fedora customization patches -Patch197: mdadm-udev.patch -Patch198: mdadm-2.5.2-static.patch -# Build without -Werror. -Patch199: disable-Werror.patch +Patch: mdadm-udev.patch +Patch: mdadm-2.5.2-static.patch -BuildRequires: make -BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel -Requires: libreport-filesystem -Requires(post): systemd coreutils -Requires(preun): systemd -Requires(postun): systemd coreutils +BuildRequires: make +BuildRequires: systemd-rpm-macros +BuildRequires: binutils-devel +BuildRequires: gcc +BuildRequires: systemd-devel +Requires: libreport-filesystem +Requires(post): coreutils +Requires(postun): coreutils -%description + +%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}} +%autosetup -p1 + %build -make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon +%make_build CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon + %install -make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} UDEVDIR=/usr/lib/udev/ install install-systemd +%make_install MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} UDEVDIR=%{_prefix}/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 +mkdir -p -m 710 %{buildroot}/run/%{name} +mkdir -p -m 700 %{buildroot}%{_datadir}/%{name} +install -Dp -m 755 %{SOURCE8} %{buildroot}%{_datadir}/%{name}/mdcheck # systemd -mkdir -p %{buildroot}%{_unitdir} -install -m644 %{SOURCE3} %{buildroot}%{_unitdir} -install -m644 %{SOURCE6} %{buildroot}%{_unitdir} -install -m644 %{SOURCE7} %{buildroot}%{_unitdir} +install -Dm644 %{SOURCE3} %{buildroot}%{_unitdir} +install -Dm644 %{SOURCE6} %{buildroot}%{_unitdir} +install -Dm644 %{SOURCE7} %{buildroot}%{_unitdir} # tmpfile -mkdir -p %{buildroot}%{_tmpfilesdir} -install -m 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf +install -Dm 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf mkdir -p %{buildroot}%{_localstatedir}/run/ install -d -m 0710 %{buildroot}/run/%{name}/ # abrt -mkdir -p %{buildroot}/etc/libreport/events.d -install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d +install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_event.conf + %post %systemd_post mdmonitor.service raid-check.timer +# leftover from this service removal years ago (f18 era). +# we probably don't really need this anymore. +# https://bugzilla.redhat.com/show_bug.cgi?id=901651 %{_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 mdadm.conf-example misc/* -%{_udevrulesdir}/* -%{_sbindir}/* -%{_unitdir}/* +%{_udevrulesdir}/*-md-* +%{_sbindir}/%{name} +%{_sbindir}/mdmon +%{_sbindir}/raid-check +%{_unitdir}/md* +%{_unitdir}/raid-check.* %{_mandir}/man*/md* -%{_prefix}/lib/systemd/system-shutdown/* -%config(noreplace) %{_sysconfdir}/sysconfig/* +%{_prefix}/lib/systemd/system-shutdown/mdadm.shutdown +%config(noreplace) %{_sysconfdir}/sysconfig/raid-check %{_rundir}/%{name}/ %config(noreplace) %{_tmpfilesdir}/%{name}.conf -%{_sysconfdir}/libreport/events.d/* +%{_sysconfdir}/libreport/events.d/mdadm_event.conf %{_datadir}/%{name}/ + %changelog +* Wed May 08 2024 Jonathan Wright - 4.3-1 +- update to 4.3 rhbz#2267100 +- modernize spec + * Wed May 08 2024 Jonathan Wright - 4.2-9 - Fixes rhbz#2279743 - Use more macros in %files definitions diff --git a/sources b/sources index 6b62e85..3b91d12 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (mdadm-4.2.tar.xz) = 57897a2b7fb8b0b88bece50501099872bb45ddb076cfc323d563588096d2b66b1ecba3724534943f651ace2bfe591482570700616500dc3398552e4f9ff0c37d +SHA512 (mdadm-4.3.tar.xz) = e44977f2f80d2471cb313803a60c92dafe8282ac06bbbfd41ae90ca493c64a3da94db924538788d045fd7f0667333912dabedb0b070f9abf5c0540b32e0fa08f From c8d54b071aea9605ab75f3c5ff67d44d306e7fb2 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Wed, 8 May 2024 16:15:14 -0500 Subject: [PATCH 13/22] add source sig verification. change url to https --- .gitignore | 1 + 6F9E3E9D4EDEBB11.asc | 72 ++++++++++++++++++++++++++++++++++++++++++++ mdadm.spec | 15 +++++++-- sources | 1 + 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 6F9E3E9D4EDEBB11.asc diff --git a/.gitignore b/.gitignore index 34fb3da..3b6b56f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ clog *.src.rpm */ /mdadm-4.*.tar.xz +/mdadm-4.3.tar.sign diff --git a/6F9E3E9D4EDEBB11.asc b/6F9E3E9D4EDEBB11.asc new file mode 100644 index 0000000..7f7afe8 --- /dev/null +++ b/6F9E3E9D4EDEBB11.asc @@ -0,0 +1,72 @@ +pub rsa2048 2023-11-03 [SC] + EED84966493AEEAF4B466F696F9E3E9D4EDEBB11 +uid Mariusz Tkaczyk (First Key) +sub rsa2048 2023-11-03 [E] + F07BC7F109D51D72E3A4B8779CF5038718DB4BA7 +sub ed25519 2023-11-03 [S] + A2320B82F9D51E3BB0E2B3B201C8BB2357D15E24 + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBGVE65YBCADQsm/xGlWh9vid1zLH4fGNA74rlvlE3X7Lbq8KLzufFOpV7+y0 +E0btNHs8ur0lt+3Emj3T9rh0lDC1ikYrEzQiwtGGSFoo30MRE6dqHyZPPzXVeI9c +8SAcz2LNwTPP3WQYv3b+ZxJrhOMyIqXD+upAZYRHVI02GpixJa8XavUtD5GglfIU +yRnF3KNkZRnYeJ1qRMe0WoaAl2W9IAM4rKWJq+xDNZCeGEX5zqAeHO/aNgA2m1Oo +2kDZz+GO0+W1zeMOiHJwWyGMD3KFx+00TBf5n2ULq6+9JwfATi9wxB8E/btQmSl9 +T9QU1wCHSM3Y92uqXbrEFNUdxZDLD9n7xnbFABEBAAG0PU1hcml1c3ogVGthY3p5 +ayAoRmlyc3QgS2V5KSA8bWFyaXVzei50a2FjenlrQGxpbnV4LmludGVsLmNvbT6J +AU4EEwEIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTu2ElmSTrur0tG +b2lvnj6dTt67EQUCZUpG+QAKCRBvnj6dTt67Ed+yCACayli/kd5f9YljcVfEo0xU +BXBDsEny2NbE3yICE13DvHT0Yg5YdwWBeKCf5Qt3d5GgFSt7PzEaOlNuRaIruSXQ +L0Xa91ZOi6rDQsaIfQtk3mps7ABrMK9h0EUIwDD7AWhN5DmoG4rd73wppkst+VG6 +nP4VUyuyQJV+tMb5p5BirGYVU2Hi5noWRXNHLWGzq1QwHu2enzp8b+UqO0FQX0zi +UsPDNnQ6LV7Jnl9gg4bkWWzTXw5Of0kDdHBAATPW3sdZCj90CSGniMsa6CzFwvEf +YUN3CHkNDTSPu3ZPkE080xuPnC+WkKgPs38KLwMsM+Ys0gL6dk/AJ2tBR3RKrA8n +iQIzBBIBCAAdFiEE5DAy15EJMCV1R6v9YGjFFmlTOEoFAmVKZgkACgkQYGjFFmlT +OEpdNBAAkOaWbs7TV2AdZ8tLGTnrbUo7U/a4/gpKq2yetcmxWelLUnI1bfiv+hAx +pqrhmsbIoffxJIEeHulzQonM3USNdXRf3RnvMx/6oUlkf1t05lPuf6odEaZMJbiC +kVRU9/6AjfhktJAuSgQAepqlHU6ie/5hvn1+UxDZ9+A4NxoqSFpW8rywntUkGPcv +x6GZpoTiUx8dw0ULgrL2ZayE3Ul+N9by3FP8CGfh7+TJmTOdDWvgpfh02pvVQKHw +S6Jvfe8cua3jPALhM7+r08AT/X4z3A8FI8GAKUxhkTSNpU/xVeBWCDrr0gQ+LNzk +Mu8YDUzWQZH0oIvUoezxDMvZHaA6xHRcK4Z4gZlyB5US9vI0WkxG2vJ8CE+0Qj6z +eI53UWK3viM4yYOubtb9X1MUB0BFXaSIs7WlvWlHCwUoA9HXtaJf0kXV36usqBta +ZQ/6JZat8fRcYLDC438RW5TStT2LXtv/2XY2dBtNLtrHRA008nkurZBswct/Okws +E9CZLAy/PkwgYvpVSHS3NsiSScpFL4sz9Cwxk2HbPJxcxfxcFqi1ULQZhCJezKWz +4WKUJV/OiLUzNg3p+PIlomZ9jlxgq6IqMnXYLtrsOOSklJxNeWNgMP8SSBXXPcTm +6YNrScKabhbchJqjIDSIh8uMIX/b4tXVTz5Pd6XWwvkERKQOj/SJAjMEEAEIAB0W +IQT4aCvhNMZ6EjMqLtB6+mG+o7hN/wUCZVPVAQAKCRB6+mG+o7hN/9yuD/4pzZ+N +rqVsB7XoDBdPK+8kRo/ktd0Hp4N0H2pk1728Vu/MB/aGrH3Vv/wKyGO6EgQP+BPh +ofetMtSGPFDOcNkBg+OgzfuUjf6Wm87Ti+hStehsh6VTGEEnFQ8gCKPXB+cZnbLm +pLetBwsd20/C+8FofihYXu6eYPnrpanvnwR8atJMV1zAqtv44D/ANFi32chZjdIN +49EFYwroIEcs3Wbrm+hF9ntpzxFjtHPp44wkrFACS7WRmpbW6Fm6wExzKnHvvArX +GpfAOPGUvkWb1QGgWQ6yc74I6D56M6vGGiTgqz7A+YXaaErWq/j3YtShrNFiMs+Z +NOgTy2luLXOSttB9z9WzVrlAaHumKd9KCqQgMTt1FycVEtIm28XqIHkA9te6f767 +HVic90UI+INp4aH1c4xZYUZdmR6HrN3rfredACFxD32TRZSf9rvuFKt6qM10iMfa +CXYc56m9ihsFm0XhQqBaQ3cCEAr5AYpqoNoEip1CSUdCSP7jub1v7qEJYLyVueSK +0yW9FwmA/cw0KBGmmZwgfQfZHWnzO5kU4przT99IUPAKRjip/6pltKSznHRX9bIf +PE3edcBYkk5JXnPGBkx5EuOHZKN5lPqtq4k6Tg0xL/OGdnMuWAvZksnCIiD44Gyg +Ro1YGeSsExdyeNF10UX4Zt39ZEm5cKvEasWqc7kBDQRlROuWAQgA1DEoJH8CEZFW +EoO3roijbv1jyGI9BvvFDNTpkaL3UpDX4FQOFrGOoz+UBUCHQVxBFGARlc2NpG3i +yDa2HwW0UeQbsUb3ge8xDySF8S//vZuSEDwwOTDA1+EEpFSUrjkkn9I8rhF/y+qx +22ExuzSEGBmVsAd11JuYQi7AZR4SWya6hFizrUMusnhcj1WZcG2YBZ8M6rL+WRki +tWLrzob0mY4OEXeH3/qarZB1XYtUKHQ1g/W0SqNczbPIf4u6n/GpGTIquq/qB2kW +5kONsAFJKQEGrs+wXfFICQhcHBYPJVRopt9JRu/HLHIshlZ+gyVlRHfuEli3nNV0 +ZDoedNlnqQARAQABiQE2BBgBCAAgAhsMFiEE7thJZkk67q9LRm9pb54+nU7euxEF +AmVKRzwACgkQb54+nU7euxEgUggAqMvUugVsSn6AJ2gokyJrtEfjXicEci1u2RBU +5+HtzqRYXaPBnjhfBZT9iDZnu/H8KSGH3eJ+QqiB7nBJLSkzyrn07yuIvy2/KBOh +v1kXz4MfKg2vQjrFgoGQkaUmnDDKPl/Qda+yuI8RzDItHRTN0mHnDT+4wNCPEzzi +hHKtcbxEdS+5SVnMC+8mnUPqOUp74lMh56I22+Gnf0BdHHDKN8of2B/QmfWegZLC +qO+YsDSG0GcAv8u+ZMls6EdIhO+STJAMZpbM7Gx0XuJ08IhN+OglVp6WJ3vfCX4B +O9P2KYQE/8TF386HaNMq1CranRihHGaz1YOOV0Skxe2stP5UsbgzBGVE72IWCSsG +AQQB2kcPAQEHQKRrcOlY4p7NVvwJD+vnKwUtvmSAKuK1UrsXcBrBKDaWiQGtBBgB +CAAgFiEE7thJZkk67q9LRm9pb54+nU7euxEFAmVE72ICGwIAgQkQb54+nU7euxF2 +IAQZFggAHRYhBKIyC4L51R47sOKzsgHIuyNX0V4kBQJlRO9iAAoJEAHIuyNX0V4k +f7kBAKzN7tapBxMbORYyONkYv7hSbu08b3DEDZxJgV27dUSkAP49HZEfFwFR7IGL +Rmvpq3F+RBALah9F0YuTTU4Ixz1qBUvPCACFwmg8zxoqd2nf2t05vjtdeFbahRqu +3Gu5b5QqzCRB4zGBNVSX110SvDOtCJ0xNUAHU0Gh0o2meCREc9xg/qCujs7CKD5u +OzukbPpIZ++cXg5gPJ7+H1L20VrbFjiz/wdzV0iNBPfQ7mP+CeqjmpNyZKUqGF1t +xTHbJ99Ls2/hS1o1P1aktfOj2WBTND3Xx2oysczhqyGpaciDR30A2SEhcutjcPUl +mUPaTp7+nP/5+v8u2drlkyhzxCyQbcIwNQEaIWxQq5pKrq8HpQ8u/SUW6ERKZISV +Y6o0MdrugFPqAmerHvL2hCrMelqHCCVInJIXBL0SSCgHZyh9NTuo2OUQ +=PmkW +-----END PGP PUBLIC KEY BLOCK----- diff --git a/mdadm.spec b/mdadm.spec index 7a3c83b..375482d 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,11 +1,11 @@ Name: mdadm Version: 4.3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later -Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz +Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz Source1: raid-check Source2: mdadm-raid-check-sysconfig Source3: mdmonitor.service @@ -14,6 +14,8 @@ Source5: mdadm_event.conf Source6: raid-check.timer Source7: raid-check.service Source8: mdcheck +Source10: %{name}-%{version}.tar.sign +Source11: 6F9E3E9D4EDEBB11.asc # Fedora customization patches Patch: mdadm-udev.patch @@ -24,6 +26,7 @@ BuildRequires: systemd-rpm-macros BuildRequires: binutils-devel BuildRequires: gcc BuildRequires: systemd-devel +BuildRequires: gnupg2 Requires: libreport-filesystem Requires(post): coreutils Requires(postun): coreutils @@ -38,6 +41,10 @@ file can be used to help with some common tasks. %prep +# because the tarball is what is signed, not the compressed tarball +# keyring should be one from https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/plain/keys +# which will vary depending on who did the release +%{_bindir}/xz -dcT0 %{SOURCE0} | %{gpgverify} --keyring='%{SOURCE11}' --signature='%{SOURCE10}' --data=- %autosetup -p1 @@ -102,6 +109,10 @@ install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_ %changelog +* Wed May 08 2024 Jonathan Wright - 4.3-2 +- add source signature verification +- change source URL to https + * Wed May 08 2024 Jonathan Wright - 4.3-1 - update to 4.3 rhbz#2267100 - modernize spec diff --git a/sources b/sources index 3b91d12..1c4b506 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ SHA512 (mdadm-4.3.tar.xz) = e44977f2f80d2471cb313803a60c92dafe8282ac06bbbfd41ae90ca493c64a3da94db924538788d045fd7f0667333912dabedb0b070f9abf5c0540b32e0fa08f +SHA512 (mdadm-4.3.tar.sign) = c0ae042399974c360ffbf4f15928e59591eb88f97faac1d7892066fefb8f8c525fe0948a4fd6ddd3781d0b27d8891e1bd2e0cd9e6a2dbf17b9f8d8c4879dc6b1 From 4a672c15a66e1f6acbfda96ede581570252fabea Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Wed, 8 May 2024 17:00:36 -0500 Subject: [PATCH 14/22] use full urls for gpg-related sources build and install raid6check and its man page --- mdadm.spec | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/mdadm.spec b/mdadm.spec index 375482d..f0663d1 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Name: mdadm Version: 4.3 -Release: 2%{?dist} +Release: 3%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -14,8 +14,8 @@ Source5: mdadm_event.conf Source6: raid-check.timer Source7: raid-check.service Source8: mdcheck -Source10: %{name}-%{version}.tar.sign -Source11: 6F9E3E9D4EDEBB11.asc +Source10: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.sign +Source11: https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/plain/keys/6F9E3E9D4EDEBB11.asc # Fedora customization patches Patch: mdadm-udev.patch @@ -27,6 +27,7 @@ BuildRequires: binutils-devel BuildRequires: gcc BuildRequires: systemd-devel BuildRequires: gnupg2 +BuildRequires: mandoc Requires: libreport-filesystem Requires(post): coreutils Requires(postun): coreutils @@ -49,7 +50,7 @@ file can be used to help with some common tasks. %build -%make_build CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon +%make_build CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon raid6check raid6check.man %install @@ -73,6 +74,9 @@ install -d -m 0710 %{buildroot}/run/%{name}/ # abrt install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_event.conf +# raid6check +install -Dm755 raid6check %{buildroot}/%{_sbindir}/raid6check +install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %post %systemd_post mdmonitor.service raid-check.timer @@ -97,9 +101,11 @@ install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_ %{_sbindir}/%{name} %{_sbindir}/mdmon %{_sbindir}/raid-check +%{_sbindir}/raid6check %{_unitdir}/md* %{_unitdir}/raid-check.* %{_mandir}/man*/md* +%{_mandir}/man8/raid6check* %{_prefix}/lib/systemd/system-shutdown/mdadm.shutdown %config(noreplace) %{_sysconfdir}/sysconfig/raid-check %{_rundir}/%{name}/ @@ -109,6 +115,10 @@ install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_ %changelog +* Wed May 08 2024 Jonathan Wright - 4.3-3 +- use URLs for signature and pub key +- build and install raid6check and man page rhbz#2264741 + * Wed May 08 2024 Jonathan Wright - 4.3-2 - add source signature verification - change source URL to https From 869407bc94d13364fd62f566cbba87bdaffb7fb1 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Fri, 5 Jul 2024 16:36:34 -0400 Subject: [PATCH 15/22] Avoid libreport dependency on RHEL RHEL does not include abrt or libreport. --- mdadm.spec | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mdadm.spec b/mdadm.spec index f0663d1..4ca20a8 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,3 +1,5 @@ +%bcond abrt %{undefined rhel} + Name: mdadm Version: 4.3 Release: 3%{?dist} @@ -28,7 +30,9 @@ BuildRequires: gcc BuildRequires: systemd-devel BuildRequires: gnupg2 BuildRequires: mandoc +%if %{with abrt} Requires: libreport-filesystem +%endif Requires(post): coreutils Requires(postun): coreutils @@ -72,7 +76,9 @@ mkdir -p %{buildroot}%{_localstatedir}/run/ install -d -m 0710 %{buildroot}/run/%{name}/ # abrt +%if %{with abrt} install -Dm644 %{SOURCE5} %{buildroot}%{_sysconfdir}/libreport/events.d/%{name}_event.conf +%endif # raid6check install -Dm755 raid6check %{buildroot}/%{_sbindir}/raid6check @@ -110,7 +116,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %config(noreplace) %{_sysconfdir}/sysconfig/raid-check %{_rundir}/%{name}/ %config(noreplace) %{_tmpfilesdir}/%{name}.conf +%if %{with abrt} %{_sysconfdir}/libreport/events.d/mdadm_event.conf +%endif %{_datadir}/%{name}/ From 1fd89275e619a50fe2fc92881e0136f7259aa812 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 17:05:27 +0000 Subject: [PATCH 16/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 4ca20a8..4e82d4f 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 3%{?dist} +Release: 4%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -123,6 +123,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Thu Jul 18 2024 Fedora Release Engineering - 4.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed May 08 2024 Jonathan Wright - 4.3-3 - use URLs for signature and pub key - build and install raid6check and man page rhbz#2264741 From 6deed29770aea67f0fea57ec48482476a4497328 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 17:19:42 +0000 Subject: [PATCH 17/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 4e82d4f..2e689fd 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 4%{?dist} +Release: 5%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -123,6 +123,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Fri Jan 17 2025 Fedora Release Engineering - 4.3-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Thu Jul 18 2024 Fedora Release Engineering - 4.3-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From cfb3b4ae5ec3bb5e382bfd50259b838a335d3458 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Thu, 23 Jan 2025 11:29:51 -0600 Subject: [PATCH 18/22] fix ftbfs on gcc15 rhbz#2340833 --- mdadm.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mdadm.spec b/mdadm.spec index 2e689fd..4da5ce6 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 5%{?dist} +Release: 6%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -54,7 +54,8 @@ file can be used to help with some common tasks. %build -%make_build CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon raid6check raid6check.man +# CXFLAGS is NOT a typo, it's baked into the makefile, not to be confused with CXXFLAGS +%make_build CXFLAGS="%{optflags} -std=gnu17 -Wno-error=unterminated-string-initialization" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon raid6check raid6check.man %install @@ -123,6 +124,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Thu Jan 23 2025 Jonathan Wright - 4.3-6 +- fix FTBFS on gcc15 rhbz#2340833 + * Fri Jan 17 2025 Fedora Release Engineering - 4.3-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 7cf27b147964239be73651c304fa73281b7f33e0 Mon Sep 17 00:00:00 2001 From: Jonathan Wright Date: Thu, 23 Jan 2025 11:30:31 -0600 Subject: [PATCH 19/22] fix permissions on /usr/share/mdadm to be world-readable rhbz#2322402 --- mdadm.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index 4da5ce6..476e632 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -63,7 +63,7 @@ file can be used to help with some common tasks. 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/%{name} -mkdir -p -m 700 %{buildroot}%{_datadir}/%{name} +mkdir -p -m 755 %{buildroot}%{_datadir}/%{name} install -Dp -m 755 %{SOURCE8} %{buildroot}%{_datadir}/%{name}/mdcheck # systemd @@ -126,6 +126,7 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog * Thu Jan 23 2025 Jonathan Wright - 4.3-6 - fix FTBFS on gcc15 rhbz#2340833 +- fix permissions on /usr/share/mdadm to be world-readable rhbz#2322402 * Fri Jan 17 2025 Fedora Release Engineering - 4.3-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From faab6a79dffa1252a2a1afe13c2e9f3197a49c6c Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Sun, 6 Apr 2025 17:50:12 -0700 Subject: [PATCH 20/22] revert 'posix' name check to fix rhbz#2325906 --- ...-Follow-POSIX-Portable-Character-Set.patch | 428 ++++++++++++++++++ mdadm.spec | 13 +- 2 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch diff --git a/0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch b/0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch new file mode 100644 index 0000000..e5cd419 --- /dev/null +++ b/0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch @@ -0,0 +1,428 @@ +From 857ad175fe025f026a1173e38de0b482110fdce5 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Sun, 6 Apr 2025 14:13:45 -0700 +Subject: [PATCH] Revert "mdadm: Follow POSIX Portable Character Set" + +This reverts commit e2eb503bd797908f515b58428b274f1ba6a05349. +--- + Detail.c | 17 +++++++----- + config.c | 13 +++------ + lib.c | 58 +++++++++++----------------------------- + mdadm.8.in | 70 ++++++++++++++++++++++++++++--------------------- + mdadm.conf.5.in | 4 +++ + mdadm.h | 2 +- + super-intel.c | 47 +++++++++++++++++---------------- + 7 files changed, 100 insertions(+), 111 deletions(-) + +diff --git a/Detail.c b/Detail.c +index aaa3dd6e..6d675152 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -254,9 +254,11 @@ int Detail(char *dev, struct context *c) + fname_from_uuid(st, info, nbuf, ':'); + printf("MD_UUID=%s\n", nbuf + 5); + mp = map_by_uuid(&map, info->uuid); +- +- 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); ++ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { ++ printf("MD_DEVNAME="); ++ print_escape(mp->path + DEV_MD_DIR_LEN); ++ putchar('\n'); ++ } + + if (st->ss->export_detail_super) + st->ss->export_detail_super(st); +@@ -269,9 +271,12 @@ int Detail(char *dev, struct context *c) + __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); +- ++ if (mp && mp->path && ++ strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { ++ printf("MD_DEVNAME="); ++ print_escape(mp->path + DEV_MD_DIR_LEN); ++ putchar('\n'); ++ } + map_free(map); + } + if (!c->no_devices && sra) { +diff --git a/config.c b/config.c +index 44f7dd2f..0a80eedb 100644 +--- a/config.c ++++ b/config.c +@@ -199,9 +199,9 @@ inline void ident_init(struct mddev_ident *ident) + * /dev/md_d{number} (legacy) + * /dev/md_{name} + * /dev/md/{name} +- * {name} ++ * {name} - anything that doesn't start from '/' or '<'. + * +- * {name} must follow name's criteria and be POSIX compatible. ++ * {name} must follow name's criteria. + * If criteria passed, duplicate memory and set devname in @ident. + * + * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. +@@ -241,8 +241,8 @@ 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); ++ if (*name == '/' || *name == '<') { ++ ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline); + return MDADM_STATUS_ERROR; + } + +@@ -284,11 +284,6 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam + return MDADM_STATUS_ERROR; + } + +- if (is_name_posix_compatible(name) == false) { +- ident_log(prop_name, name, "Not POSIX compatible", cmdline); +- return MDADM_STATUS_ERROR; +- } +- + snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); + return MDADM_STATUS_SUCCESS; + } +diff --git a/lib.c b/lib.c +index 2b09293c..95e3511f 100644 +--- a/lib.c ++++ b/lib.c +@@ -454,50 +454,24 @@ void print_quoted(char *str) + putchar(q); + } + +-/** +- * is_alphanum() - Check if sign is letter or digit. +- * @c: char to analyze. +- * +- * Similar to isalnum() but additional locales are excluded. +- * +- * Return: %true on success, %false otherwise. +- */ +-bool is_alphanum(const char c) +-{ +- if (isupper(c) || islower(c) || isdigit(c) != 0) +- return true; +- return false; +-} +- +-/** +- * is_name_posix_compatible() - Check if name is POSIX compatible. +- * @name: name to check. +- * +- * POSIX portable file name character set contains ASCII letters, +- * digits, '_', '.', and '-'. Also forbid leading '-'. +- * The length of the name cannot exceed NAME_MAX - 1 (ensure NULL ending). +- * +- * Return: %true on success, %false otherwise. +- */ +-bool is_name_posix_compatible(const char * const name) ++void print_escape(char *str) + { +- assert(name); +- +- char allowed_symbols[] = "-_."; +- const char *n = name; +- +- if (!is_string_lq(name, NAME_MAX)) +- return false; +- +- if (*n == '-') +- return false; +- +- while (*n != '\0') { +- if (!is_alphanum(*n) && !strchr(allowed_symbols, *n)) +- return false; +- n++; ++ /* print str, but change space and tab to '_' ++ * as is suitable for device names ++ */ ++ for (; *str; str++) { ++ switch (*str) { ++ case ' ': ++ case '\t': ++ putchar('_'); ++ break; ++ case '/': ++ putchar('-'); ++ break; ++ default: ++ putchar(*str); ++ } + } +- return true; + } + + int check_env(char *name) +diff --git a/mdadm.8.in b/mdadm.8.in +index 96a4a08e..4af90c48 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -364,7 +364,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a + which is managed in a similar manner to DDF, and is supported by an + option-rom on some platforms: + .IP +-.B https://www.intel.com/content/www/us/en/support/products/122484 ++.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html + .PP + .RE + +@@ -932,14 +932,17 @@ option will be ignored. + .BR \-N ", " \-\-name= + Set a + .B name +-for the array. It must be +-.BR "POSIX PORTABLE NAME" +-compatible and cannot be longer than 32 chars. This is effective when creating an array +-with a v1 metadata, or an external array. +- +-If name is needed but not specified, it is taken from the basename of the device +-that is being created. See +-.BR "DEVICE NAMES" ++for the array. This is currently only effective when creating an ++array with a version-1 superblock, or an array in a DDF container. ++The name is a simple textual string that can be used to identify array ++components when assembling. If name is needed but not specified, it ++is taken from the basename of the device that is being created. ++e.g. when creating ++.I /dev/md/home ++the ++.B name ++will default to ++.IR home . + + .TP + .BR \-R ", " \-\-run +@@ -1129,10 +1132,8 @@ is much safer. + + .TP + .BR \-N ", " \-\-name= +-Specify the name of the array to assemble. It must be +-.BR "POSIX PORTABLE NAME" +-compatible and cannot be longer than 32 chars. This must be the name +-that was specified when creating the array. It must either match ++Specify the name of the array to assemble. This must be the name ++that was specified when creating the array. It must either match + the name stored in the superblock exactly, or it must match + with the current + .I homehost +@@ -2178,17 +2179,14 @@ Usage: + .I md-device + .BI \-\-chunk= X + .BI \-\-level= Y ++.br + .BI \-\-raid\-devices= Z + .I devices + + .PP +-This usage will initialize a new md array, associate some devices with ++This usage will initialise a new md array, associate some devices with + it, and activate the array. + +-.I md-device +-is a new device. This could be standard name or chosen name. For details see: +-.BR "DEVICE NAMES" +- + The named device will normally not exist when + .I "mdadm \-\-create" + is run, but will be created by +@@ -2229,6 +2227,24 @@ array. This feature can be overridden with the + .B \-\-force + option. + ++When creating an array with version-1 metadata a name for the array is ++required. ++If this is not given with the ++.B \-\-name ++option, ++.I mdadm ++will choose a name based on the last component of the name of the ++device being created. So if ++.B /dev/md3 ++is being created, then the name ++.B 3 ++will be chosen. ++If ++.B /dev/md/home ++is being created, then the name ++.B home ++will be used. ++ + When creating a partition based array, using + .I mdadm + with version-1.x metadata, the partition type should be set to +@@ -2413,10 +2429,12 @@ and + + The + .B name +-option updates the subarray name in the metadata. It must be +-.BR "POSIX PORTABLE NAME" +-compatible and cannot be longer than 32 chars. If successes, new value will be respected after +-next assembly. ++option updates the subarray name in the metadata, it may not affect the ++device node name or the device node symlink until the subarray is ++re\-assembled. If updating ++.B name ++would change the UUID of an active subarray this operation is blocked, ++and the command will end in an error. + + The + .B ppl +@@ -3377,10 +3395,6 @@ When + .B \-\-incremental + mode is used, this file gets a list of arrays currently being created. + +-.SH POSIX PORTABLE NAME +-A valid name can only consist of characters "A-Za-z0-9.-_". +-The name cannot start with a leading "-" and cannot exceed 255 chars. +- + .SH DEVICE NAMES + + .I mdadm +@@ -3402,10 +3416,6 @@ can be given, or just the suffix of the second sort of name, such as + .I home + can be given. + +-In every style, raw name must be compatible with +-.BR "POSIX PORTABLE NAME" +-and has to be no longer than 32 chars. +- + When + .I mdadm + chooses device names during auto-assembly or incremental assembly, it +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index 787e51e9..032b8010 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -710,6 +710,10 @@ ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b + .br + auto=part + .br ++# The name of this array contains a space. ++.br ++ARRAY /dev/md9 name='Data Storage' ++.sp + POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* + .br + action=spare +diff --git a/mdadm.h b/mdadm.h +index 1f28b3e7..3b3168d4 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1623,7 +1623,6 @@ extern int check_raid(int fd, char *name); + extern int check_partitions(int fd, char *dname, + unsigned long long freesize, + unsigned long long size); +-extern bool is_name_posix_compatible(const char *path); + extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); + extern int stat_is_blkdev(char *devname, dev_t *rdev); + +@@ -1664,6 +1663,7 @@ extern int conf_get_monitor_delay(void); + extern char *conf_line(FILE *file); + extern char *conf_word(FILE *file, int allow_key); + extern void print_quoted(char *str); ++extern void print_escape(char *str); + extern int use_udev(void); + extern void print_escape(char *str); + extern unsigned long GCD(unsigned long a, unsigned long b); +diff --git a/super-intel.c b/super-intel.c +index dbea235d..33f1469f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5533,37 +5533,40 @@ static void imsm_update_version_info(struct intel_super *super) + } + } + +-/** +- * imsm_check_name() - check imsm naming criteria. +- * @super: &intel_super pointer, not NULL. +- * @name: name to check. +- * @verbose: verbose level. +- * +- * Name must be no longer than &MAX_RAID_SERIAL_LEN and must be unique across volumes. +- * +- * Returns: &true if @name matches, &false otherwise. +- */ +-static bool imsm_is_name_allowed(struct intel_super *super, const char * const name, +- const int verbose) ++static int check_name(struct intel_super *super, char *name, int quiet) + { + struct imsm_super *mpb = super->anchor; ++ char *reason = NULL; ++ char *start = name; ++ size_t len = strlen(name); + int i; + +- if (is_string_lq(name, MAX_RAID_SERIAL_LEN + 1) == false) { +- pr_vrb("imsm: Name \"%s\" is too long\n", name); +- return false; ++ if (len > 0) { ++ while (isspace(start[len - 1])) ++ start[--len] = 0; ++ while (*start && isspace(*start)) ++ ++start, --len; ++ memmove(name, start, len + 1); + } + ++ if (len > MAX_RAID_SERIAL_LEN) ++ reason = "must be 16 characters or less"; ++ else if (len == 0) ++ reason = "must be a non-empty string"; ++ + for (i = 0; i < mpb->num_raid_devs; i++) { + struct imsm_dev *dev = get_imsm_dev(super, i); + + if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) { +- pr_vrb("imsm: Name \"%s\" already exists\n", name); +- return false; ++ reason = "already exists"; ++ break; + } + } + +- return true; ++ if (reason && !quiet) ++ pr_err("imsm volume name %s\n", reason); ++ ++ return !reason; + } + + static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, +@@ -5658,9 +5661,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + } + } + +- if (imsm_is_name_allowed(super, name, 1) == false) ++ if (!check_name(super, name, 0)) + return 0; +- + dv = xmalloc(sizeof(*dv)); + dev = xcalloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1)); + /* +@@ -7988,7 +7990,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + char *ep; + int vol; + +- if (imsm_is_name_allowed(super, name, 1) == false) ++ if (!check_name(super, name, 0)) + return 2; + + vol = strtoul(subarray, &ep, 10); +@@ -10298,8 +10300,7 @@ static void imsm_process_update(struct supertype *st, + if (a->info.container_member == target) + break; + dev = get_imsm_dev(super, u->dev_idx); +- +- if (a || !dev || imsm_is_name_allowed(super, name, 0) == false) { ++ if (a || !check_name(super, name, 1)) { + dprintf("failed to rename subarray-%d\n", target); + break; + } +-- +2.49.0 + diff --git a/mdadm.spec b/mdadm.spec index 476e632..f942712 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 6%{?dist} +Release: 7%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -19,6 +19,14 @@ Source8: mdcheck Source10: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.sign Source11: https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/plain/keys/6F9E3E9D4EDEBB11.asc +# https://bugzilla.redhat.com/show_bug.cgi?id=2325906 +# see: https://github.com/md-raid-utilities/mdadm/pull/165 +# https://github.com/md-raid-utilities/mdadm/pull/160 +# https://github.com/md-raid-utilities/mdadm/pull/159 +# this is a reversion of the initial 'posix check' patch +# that causes all the trouble +Patch: 0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch + # Fedora customization patches Patch: mdadm-udev.patch Patch: mdadm-2.5.2-static.patch @@ -124,6 +132,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Sun Apr 06 2025 Adam Williamson - 4.3-7 +- revert 'posix' name check to fix rhbz#2325906 + * Thu Jan 23 2025 Jonathan Wright - 4.3-6 - fix FTBFS on gcc15 rhbz#2340833 - fix permissions on /usr/share/mdadm to be world-readable rhbz#2322402 From bcbad9cf97fa2fe781f14e351350820e247fe49b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 21:29:05 +0000 Subject: [PATCH 21/22] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- mdadm.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mdadm.spec b/mdadm.spec index f942712..5f8b499 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 7%{?dist} +Release: 8%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -132,6 +132,9 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Thu Jul 24 2025 Fedora Release Engineering - 4.3-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Sun Apr 06 2025 Adam Williamson - 4.3-7 - revert 'posix' name check to fix rhbz#2325906 From 8e12c0fe9b3f373a88dafc0db0313da9d9e32f18 Mon Sep 17 00:00:00 2001 From: Xiao Ni Date: Thu, 14 Aug 2025 08:00:13 -0400 Subject: [PATCH 22/22] Don't submit stop ioctl in assemble The kernel commit 9e59d609763f ('md: call del_gendisk in control path') breaks mdadm --assemble command. mdadm pr https://github.com/md-raid-utilities/mdadm/pull/182 fixes this problem. Resolves: bz#2388480 Signed-off-by: Xiao Ni --- 0002-dont-stop-in-assemble.patch | 11 +++++++++++ mdadm.spec | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 0002-dont-stop-in-assemble.patch diff --git a/0002-dont-stop-in-assemble.patch b/0002-dont-stop-in-assemble.patch new file mode 100644 index 0000000..6eaf564 --- /dev/null +++ b/0002-dont-stop-in-assemble.patch @@ -0,0 +1,11 @@ +--- a/Assemble.c~ 2025-08-13 22:05:00.416132027 -0400 ++++ b/Assemble.c 2025-08-13 22:13:16.650837070 -0400 +@@ -1597,8 +1597,6 @@ + goto try_again; + goto out; + } +- /* just incase it was started but has no content */ +- ioctl(mdfd, STOP_ARRAY, NULL); + } + + if (content != &info) { diff --git a/mdadm.spec b/mdadm.spec index 5f8b499..c04bb8c 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -2,7 +2,7 @@ Name: mdadm Version: 4.3 -Release: 8%{?dist} +Release: 9%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPL-2.0-or-later @@ -26,6 +26,7 @@ Source11: https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/plain/keys/6 # this is a reversion of the initial 'posix check' patch # that causes all the trouble Patch: 0001-Revert-mdadm-Follow-POSIX-Portable-Character-Set.patch +Patch: 0002-dont-stop-in-assemble.patch # Fedora customization patches Patch: mdadm-udev.patch @@ -132,6 +133,10 @@ install -Dm644 raid6check.man %{buildroot}/%{_mandir}/man8/raid6check.man %changelog +* Thu Aug 14 2025 Xiao Ni - 4.3-9 +- Don't submit stop ioctl in assemble +- Resolves bz#2388480 + * Thu Jul 24 2025 Fedora Release Engineering - 4.3-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild