[packages/mdadm] - added upstream patches (from Fedora)

mrozowik mrozowik at pld-linux.org
Sun Jul 23 12:35:52 CEST 2023


commit 182b480713180e437630a05018bfdb2471767226
Author: Krzysztof Mrozowicz <mrozowik at pld-linux.org>
Date:   Sun Jul 23 09:34:29 2023 +0000

    - added upstream patches (from Fedora)

 0001-Unify-error-message.patch                     |   47 +
 0002-mdadm-Fix-double-free.patch                   |   33 +
 ...e-Add-r0-grow-size-error-message-and-upda.patch |   83 ++
 0004-udev-adapt-rules-to-systemd-v247.patch        |   67 +
 ...Replace-error-prone-signal-with-sigaction.patch |  252 ++++
 ...mdadm-Respect-config-file-location-in-man.patch | 1533 ++++++++++++++++++++
 0007-mdadm-Update-ReadMe.patch                     |   48 +
 ...e-config-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 +++++
 ...md-remove-KillMode-none-from-service-file.patch |   69 +
 0013-mdmon-Stop-parsing-duplicate-options.patch    |  122 ++
 0014-Grow-block-n-on-external-volumes.patch        |   41 +
 ...al-Fix-possible-memory-and-resource-leaks.patch |   90 ++
 0016-Mdmonitor-Fix-segfault.patch                  |   98 ++
 0017-Mdmonitor-Improve-logging-method.patch        |   61 +
 ...le-NULL-ptr-dereferences-and-memory-leaks.patch |   73 +
 ...-possibility-for-get_imsm_dev-to-return-N.patch |  301 ++++
 ...ert-mdadm-fix-coredump-of-mdadm-monitor-r.patch |   85 ++
 0021-util-replace-ioctl-use-with-function.patch    |   31 +
 ...1-restore-commit-45a87c2f31335-to-fix-clu.patch |  110 ++
 0023-imsm-introduce-get_disk_slot_in_dev.patch     |  122 ++
 0024-imsm-use-same-slot-across-container.patch     |  252 ++++
 ...imsm-block-changing-slots-during-creation.patch |  122 ++
 ...m-block-update-ppl-for-non-raid456-levels.patch |  177 +++
 ...-mdadm-Fix-array-size-mismatch-after-grow.patch |   30 +
 ...emove-dead-code-in-imsm_fix_size_mismatch.patch |   34 +
 ...-devname-as-char-array-instead-of-pointer.patch |   40 +
 ...-Monitor-use-snprintf-to-fill-device-name.patch |  133 ++
 ...n-t-build-static-build-with-everything-an.patch |   42 +
 ...F-Cleanup-validate_geometry_ddf_container.patch |  141 ++
 ...L-pointer-dereference-in-validate_geometr.patch |   49 +
 ...Fix-use-after-close-bug-by-closing-after-.patch |   85 ++
 ...id-segfault-when-calling-NULL-get_bad_blo.patch |   36 +
 ...dadm-Fix-mdadm-r-remove-option-regression.patch |   78 +
 ...mdadm-Fix-optional-write-behind-parameter.patch |   42 +
 ...d0-add-a-test-that-validates-raid0-with-l.patch |   38 +
 0039-tests-fix-raid0-tests-for-0.90-metadata.patch |   99 ++
 ...ate-metadata-avoid-passing-chunk-size-to-.patch |   39 +
 ...eargrow-clear-the-superblock-at-every-ite.patch |   31 +
 ...test-Add-a-mode-to-repeat-specified-tests.patch |   88 ++
 ...test-Mark-and-ignore-broken-test-failures.patch |  120 ++
 ...sts-Add-broken-files-for-all-broken-tests.patch |  447 ++++++
 ...dm-Replace-obsolete-usleep-with-nanosleep.patch |  316 ++++
 ...donly-Run-udevadm-settle-before-setting-r.patch |   36 +
 0047-tests-add-test-for-names.patch                |  119 ++
 0048-mdadm-remove-symlink-option.patch             |  176 +++
 0049-mdadm-move-data_offset-to-struct-shape.patch  |  232 +++
 ...-t-open-md-device-for-CREATE-and-ASSEMBLE.patch |  162 +++
 ...w-Split-Grow_reshape-into-helper-function.patch |  231 +++
 ...eck-if-device-is-container-before-schedul.patch |   36 +
 0053-super1-report-truncated-device.patch          |  112 ++
 ...rect-typos-punctuation-and-grammar-in-man.patch |  616 ++++++++
 0055-Manage-Block-unsafe-member-failing.patch      |   91 ++
 0056-Monitor-Fix-statelist-memory-leaks.patch      |  112 ++
 ...-support-for-Intel-Alderlake-RST-on-VMD-p.patch |   64 +
 ...Documentation-entries-to-systemd-services.patch |  111 ++
 0059-ReadMe-fix-command-line-help.patch            |   32 +
 ...lace-container-level-checking-with-inline.patch |  257 ++++
 0061-Mdmonitor-Omit-non-md-devices.patch           |   58 +
 ...nitor-Split-alert-into-separate-functions.patch |  233 +++
 ...nitor-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 ++
 ...Add-option-validation-for-update-subarray.patch |  287 ++++
 0068-Fix-update-subarray-on-active-volume.patch    |   54 +
 ...-Add-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 ++++
 0073-super-intel-refactor-the-code-for-enum.patch  |  106 ++
 ...te-to-enum-in-update_super-and-update_sub.patch |  424 ++++++
 ...-Incremental-code-refactor-string-to-enum.patch |  279 ++++
 ...r-to-enum-in-context-update-refactor-code.patch |  289 ++++
 0077-mdmon-fix-segfault.patch                      |   86 ++
 ...til-remove-obsolete-code-from-get_md_name.patch |  116 ++
 ...-Don-t-handle-change-event-on-raw-devices.patch |   54 +
 ...ot-check-array-state-when-drive-is-remove.patch |   33 +
 ...al-manage-do-not-verify-if-remove-is-safe.patch |   59 +
 ...-make-freesize-not-required-for-chunk-siz.patch |   52 +
 ...ge-move-comment-with-function-description.patch |  105 ++
 ...m-systemd-remove-KillMode-none-from-servi.patch |   54 +
 ...n-t-change-bitmap-type-from-none-to-clust.patch |   45 +
 0086-Fix-NULL-dereference-in-super_by_fd.patch     |   76 +
 0087-Mdmonitor-Make-alert_info-global.patch        |  369 +++++
 ...ass-events-to-alert-using-enums-instead-o.patch |  313 ++++
 0089-Mdmonitor-Add-helper-functions.patch          |  406 ++++++
 ...-to-determine-whether-directories-or-file.patch |   83 ++
 ...-Mdmonitor-Refactor-write_autorebuild_pid.patch |  110 ++
 ...efactor-check_one_sharer-for-better-error.patch |  139 ++
 ...reorder-code-lines-in-parse_layout_faulty.patch |   41 +
 ...util.c-fix-memleak-in-parse_layout_faulty.patch |   32 +
 0095-Detail.c-fix-memleak-in-Detail.patch          |   31 +
 ...-intel.c-fix-double-free-in-load_imsm_mpb.patch |   63 +
 ...l.c-fix-memleak-in-find_disk_attached_hba.patch |   39 +
 ...f.c-fix-memleak-in-get_vd_num_of_subarray.patch |   46 +
 ...-abort_locked-instead-of-return-1-in-erro.patch |   36 +
 ...ate-remove-safe_mode_delay-local-variable.patch |   64 +
 0101-Create-Factor-out-add_disks-helpers.patch     |  452 ++++++
 0102-mdadm-Introduce-pr_info.patch                 |   72 +
 0103-mdadm-Add-write-zeros-option-for-Create.patch |  346 +++++
 ...d5-zero-Introduce-test-to-exercise-write-.patch |   44 +
 ...anpage-Add-write-zeroes-option-to-manpage.patch |   56 +
 ...nof-using-_Alignof-when-using-C11-or-newe.patch |   53 +
 ...ce-of-etc-initrd-release-to-detect-initrd.patch |   41 +
 ...on-don-t-test-both-all-and-container_name.patch |   47 +
 ...hange-systemd-unit-file-to-use-foreground.patch |   33 +
 0110-mdmon-Remove-need-for-KillMode-none.patch     |   55 +
 0111-mdmon-Improve-switchroot-interactions.patch   |  166 +++
 0112-mdopen-always-try-create_named_array.patch    |   40 +
 ...Improvements-for-IMSM_NO_PLATFORM-testing.patch |  172 +++
 ...rt-mdadm-systemd-remove-KillMode-none-fro.patch |   29 +
 ...checking-for-container-in-update_metadata.patch |   38 +
 ...Fix-null-pointer-for-incremental-in-mdadm.patch |   43 +
 ...1-fix-truncation-check-for-journal-device.patch |   33 +
 0118-Fix-some-cases-eyesore-formatting.patch       |  433 ++++++
 0119-Bump-minimum-kernel-version-to-2.6.32.patch   |  136 ++
 ...config-files-in-mdcheck_start-continue-se.patch |   42 +
 mdadm.spec                                         |  243 +++-
 121 files changed, 16673 insertions(+), 1 deletion(-)
---
diff --git a/mdadm.spec b/mdadm.spec
index bd09d13..5d284dd 100644
--- a/mdadm.spec
+++ b/mdadm.spec
@@ -8,7 +8,7 @@ Summary:	Tool for creating and maintaining software RAID devices
 Summary(pl.UTF-8):	Narzędzie do tworzenia i obsługi programowych macierzy RAID
 Name:		mdadm
 Version:	4.2
-Release:	0.1
+Release:	0.2
 License:	GPL v2+
 Group:		Base
 Source0:	https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz
@@ -20,6 +20,127 @@ Source4:	%{name}-checkarray
 Source5:	cronjob-%{name}.timer
 Source6:	cronjob-%{name}.service
 URL:		https://www.kernel.org/pub/linux/utils/raid/mdadm/
+# Upstream patches
+Patch000:	0001-Unify-error-message.patch
+Patch001:	0002-%{name}-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-%{name}-Respect-config-file-location-in-man.patch
+Patch006:	0007-%{name}-Update-ReadMe.patch
+Patch007:	0008-%{name}-Update-config-man-regarding-default-files-and-.patch
+Patch008:	0009-%{name}-Update-config-manual.patch
+Patch009:	0010-Create-Build-use-default_layout.patch
+Patch010:	0011-%{name}-add-map_num_s.patch
+Patch011:	0012-%{name}-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-%{name}-fix-coredump-of-mdadm-monitor-r.patch
+Patch020:	0021-util-replace-ioctl-use-with-function.patch
+Patch021:	0022-%{name}-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-%{name}-block-update-ppl-for-non-raid456-levels.patch
+Patch026:	0027-%{name}-Fix-array-size-mismatch-after-grow.patch
+Patch027:	0028-%{name}-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-%{name}-Grow-Fix-use-after-close-bug-by-closing-after-.patch
+Patch034:	0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch
+Patch035:	0036-%{name}-Fix-mdadm-r-remove-option-regression.patch
+Patch036:	0037-%{name}-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-%{name}-test-Add-a-mode-to-repeat-specified-tests.patch
+Patch042:	0043-%{name}-test-Mark-and-ignore-broken-test-failures.patch
+Patch043:	0044-tests-Add-broken-files-for-all-broken-tests.patch
+Patch044:	0045-%{name}-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-%{name}-remove-symlink-option.patch
+Patch048:	0049-%{name}-move-data_offset-to-struct-shape.patch
+Patch049:	0050-%{name}-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-%{name}-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-%{name}-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch
+Patch057:	0058-%{name}-Add-Documentation-entries-to-systemd-services.patch
+Patch058:	0059-ReadMe-fix-command-line-help.patch
+Patch059:	0060-%{name}-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-%{name}-Monitor-manual.patch
+Patch064:	0065-Grow-fix-possible-memory-leak.patch
+Patch065:	0066-%{name}-create-ident_init.patch
+Patch066:	0067-%{name}-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-%{name}-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-%{name}-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-%{name}-Introduce-pr_info.patch
+Patch102:	0103-%{name}-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-%{name}-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-%{name}.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
 BuildRequires:	corosync-devel
 BuildRequires:	dlm-devel
 BuildRequires:	groff
@@ -70,6 +191,126 @@ skonsolidowane na potrzeby initrd.
 
 %prep
 %setup -q
+%patch000 -p1
+%patch001 -p1
+%patch002 -p1
+%patch003 -p1
+%patch004 -p1
+%patch005 -p1
+%patch006 -p1
+%patch007 -p1
+%patch008 -p1
+%patch009 -p1
+%patch010 -p1
+%patch011 -p1
+%patch012 -p1
+%patch013 -p1
+%patch014 -p1
+%patch015 -p1
+%patch016 -p1
+%patch017 -p1
+%patch018 -p1
+%patch019 -p1
+%patch020 -p1
+%patch021 -p1
+%patch022 -p1
+%patch023 -p1
+%patch024 -p1
+%patch025 -p1
+%patch026 -p1
+%patch027 -p1
+%patch028 -p1
+%patch029 -p1
+%patch030 -p1
+%patch031 -p1
+%patch032 -p1
+%patch033 -p1
+%patch034 -p1
+%patch035 -p1
+%patch036 -p1
+%patch037 -p1
+%patch038 -p1
+%patch039 -p1
+%patch040 -p1
+%patch041 -p1
+%patch042 -p1
+%patch043 -p1
+%patch044 -p1
+%patch045 -p1
+%patch046 -p1
+%patch047 -p1
+%patch048 -p1
+%patch049 -p1
+%patch050 -p1
+%patch051 -p1
+%patch052 -p1
+%patch053 -p1
+%patch054 -p1
+%patch055 -p1
+%patch056 -p1
+%patch057 -p1
+%patch058 -p1
+%patch059 -p1
+%patch060 -p1
+%patch061 -p1
+%patch062 -p1
+%patch063 -p1
+%patch064 -p1
+%patch065 -p1
+%patch066 -p1
+%patch067 -p1
+%patch068 -p1
+%patch069 -p1
+%patch070 -p1
+%patch071 -p1
+%patch072 -p1
+%patch073 -p1
+%patch074 -p1
+%patch075 -p1
+%patch076 -p1
+%patch077 -p1
+%patch078 -p1
+%patch079 -p1
+%patch080 -p1
+%patch081 -p1
+%patch082 -p1
+%patch083 -p1
+%patch084 -p1
+%patch085 -p1
+%patch086 -p1
+%patch087 -p1
+%patch088 -p1
+%patch089 -p1
+%patch090 -p1
+%patch091 -p1
+%patch092 -p1
+%patch093 -p1
+%patch094 -p1
+%patch095 -p1
+%patch096 -p1
+%patch097 -p1
+%patch098 -p1
+%patch099 -p1
+%patch100 -p1
+%patch101 -p1
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+%patch118 -p1
+%patch119 -p1
 
 %build
 %if %{with initrd}
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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mateusz.kusiak at intel.com>
+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 <mateusz.kusiak at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mariusz.tkaczyk at linux.intel.com>
+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 <mariusz.tkaczyk at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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	<sys/mman.h>
+ #include	<stddef.h>
+ #include	<stdint.h>
+-#include	<signal.h>
+ #include	<sys/wait.h>
+ 
+ #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	<sys/wait.h>
+-#include	<signal.h>
+ #include	<limits.h>
+ #include	<syslog.h>
+ #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	<sys/syscall.h>
+ #include	<sys/socket.h>
+-#include	<signal.h>
+ 
+ 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	<string.h>
+ #include	<syslog.h>
+ #include	<stdbool.h>
++#include	<signal.h>
+ /* Newer glibc requires sys/sysmacros.h directly for makedev() */
+ #include	<sys/sysmacros.h>
+ #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	<errno.h>
+ #include	<string.h>
+ #include	<fcntl.h>
+-#include	<signal.h>
+ #include	<dirent.h>
+ #ifdef USE_PTHREADS
+ #include	<pthread.h>
+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 <sys/syscall.h>
+ #include <sys/select.h>
+-#include <signal.h>
+ 
+ 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 <unistd.h>
+-#include <signal.h>
+ #include <fcntl.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+@@ -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 <stdint.h>
+-#include <signal.h>
+ #include <sys/mman.h>
+ 
+ #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	<poll.h>
+ #include	<ctype.h>
+ #include	<dirent.h>
+-#include	<signal.h>
+ #include	<dlfcn.h>
+ 
+ 
+-- 
+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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Acked-by: Coly Li <colyli at suse.de>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ .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 <ignore>
+-(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 <system>,
+-.B <none>
+-and
+-.BR <ignore> .
+-If
+-.B <system>
+-is given, then the
+-.BR gethostname ( 2 )
+-systemcall is used to get the host name.  This is the default.
+-
+-If
+-.B <ignore>
+-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 <ignore>
+-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 <none>
+-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 at mydomain.tld
+-.br
+-PROGRAM /usr/sbin/handle\-mdadm\-events
+-.br
+-CREATE group=system mode=0640 auto=part\-8
+-.br
+-HOMEHOST <system>
+-.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 <ignore>
++(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 <system>,
++.B <none>
++and
++.BR <ignore> .
++If
++.B <system>
++is given, then the
++.BR gethostname ( 2 )
++systemcall is used to get the host name.  This is the default.
++
++If
++.B <ignore>
++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 <ignore>
++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 <none>
++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 at mydomain.tld
++.br
++PROGRAM /usr/sbin/handle\-mdadm\-events
++.br
++CREATE group=system mode=0640 auto=part\-8
++.br
++HOMEHOST <system>
++.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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Acked-by: Coly Li <colyli at suse.de>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Acked-by: Coly Li <colyli at suse.de>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Acked-by: Coly Li <colyli at suse.de>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mariusz.tkaczyk at linux.intel.com>
+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 <mariusz.tkaczyk at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mariusz.tkaczyk at linux.intel.com>
+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 <mariusz.tkaczyk at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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
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 <colyli at suse.de>
+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 at .service
+- mdmon at .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 <colyli at suse.de>
+Cc: Benjamin Brunner <bbrunner at suse.com>
+Cc: Franck Bui <fbui at suse.de>
+Cc: Jes Sorensen <jes at trained-monkey.org>
+Cc: Mariusz Tkaczyk <mariusz.tkaczyk at linux.intel.com>
+Cc: Neil Brown <neilb at suse.de>
+Cc: Xiao Ni <xni at redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ systemd/mdadm-grow-continue at .service | 1 -
+ systemd/mdmon at .service               | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/systemd/mdadm-grow-continue at .service b/systemd/mdadm-grow-continue at .service
+index 5c667d2a..9fdc8ec7 100644
+--- a/systemd/mdadm-grow-continue at .service
++++ b/systemd/mdadm-grow-continue at .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 at .service b/systemd/mdmon at .service
+index 85a3a7c5..77533958 100644
+--- a/systemd/mdmon at .service
++++ b/systemd/mdmon at .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
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 <lukasz.florczak at linux.intel.com>
+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 <lukasz.florczak at linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mateusz.kusiak at intel.com>
+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 <mateusz.kusiak at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mateusz.grzonka at intel.com>
+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 <mateusz.grzonka at intel.com>
+Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <kinga.tanska at intel.com>
+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 <kinga.tanska at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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, "<ignore>") == 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 <kinga.tanska at intel.com>
+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 <kinga.tanska at intel.com>
+Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mateusz.grzonka at intel.com>
+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 <mateusz.grzonka at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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 <mateusz.grzonka at intel.com>
+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 <mateusz.grzonka at intel.com>
+Signed-off-by: Jes Sorensen <jsorensen at fb.com>
+---
+ 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.
<Skipped 13562 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/mdadm.git/commitdiff/182b480713180e437630a05018bfdb2471767226



More information about the pld-cvs-commit mailing list