From d8b5e192c9ec7f4e3081a24408b0de6b95781bc5 Mon Sep 17 00:00:00 2001 From: Andrew Lukoshko Date: Tue, 28 Jul 2026 12:26:20 +0200 Subject: [PATCH] Set md_mod parameter legacy_async_del_gendisk only when the running kernel provides it --- config.yaml | 23 ++++++ .../mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch | 72 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 config.yaml create mode 100644 files/mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..4cfd774 --- /dev/null +++ b/config.yaml @@ -0,0 +1,23 @@ +actions: + - delete_line: + - target: "spec" + lines: + - "Patch202: mdadm-get-rhel-version.patch" + + - delete_files: + - file_name: "mdadm-get-rhel-version.patch" + + - modify_release: + - suffix: ".alma.1" + enabled: true + + - changelog_entry: + - name: "Andrew Lukoshko" + email: "alukoshko@almalinux.org" + line: + - "Set md_mod parameter legacy_async_del_gendisk only when the running kernel provides it" + + - add_files: + - type: "patch" + name: "mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch" + number: 202 diff --git a/files/mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch b/files/mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch new file mode 100644 index 0000000..848adfc --- /dev/null +++ b/files/mdadm-get-MD_MOD_ASYNC_DEL_GENDISK.patch @@ -0,0 +1,72 @@ +Subject: Set legacy_async_del_gendisk only when the kernel supports it + +0042-mdadm-Create-array-with-sync-del-gendisk-mode.patch switches mdadm to +the sync del_gendisk mode by writing N to the md_mod parameter +legacy_async_del_gendisk. Upstream gates this on get_linux_version() >= +6018000, which never matches a RHEL 9 kernel (5.14.0), and the RHEL patch +mdadm-get-rhel-version.patch replaced it with a check for the z-stream +number of the running kernel (>= 28), assuming kernel-5.14.0-611.28.1.el9_7 +or newer. + +Both variants are wrong for AlmaLinux 9: + +- the z-stream number is only comparable within a single minor release, so + 9.6 kernels (5.14.0-570.x) and 9.8 kernels (5.14.0-6xx.y, y restarting + from a low number) are misdetected; +- when the check passes but the running kernel does not provide the + parameter, set_md_mod_parameter() fails and init_md_mod() returns false, + which makes create_mddev() fail, i.e. arrays can't be created or + assembled at all. + +The parameter is added by kernel commit 25db5f284fb8 ("md: add +legacy_async_del_gendisk mod"), which comes together with 9e59d609763f +("md: call del_gendisk in control path"). Its presence in sysfs is +therefore the exact condition mdadm needs, and it works for every kernel +regardless of upstream or downstream versioning. If the parameter is not +there, the kernel has the old async-only behaviour and nothing has to be +set. + +--- a/util.c ++++ b/util.c +@@ -2580,6 +2580,21 @@ bool set_md_mod_parameter(const char *name, const char *value) + return ret; + } + ++/* ++ * Check if md_mod parameter is supported by the running kernel ++ * @name: name of the parameter ++ * ++ * Return: true if /sys/module/md_mod/parameters/ exists, false if not ++ */ ++static bool md_mod_parameter_exists(const char *name) ++{ ++ char path[256]; ++ ++ snprintf(path, sizeof(path), "/sys/module/md_mod/parameters/%s", name); ++ ++ return access(path, F_OK) == 0; ++} ++ + /* Init kernel md_mod and parameters here if needed */ + bool init_md_mod(void) + { +@@ -2624,10 +2639,16 @@ bool init_md_mod(void) + * update mdadm and update to new kernel, they can't assemble array + * anymore. So kernel adds a kernel parameter legacy_async_del_gendisk + * and uses async as default. +- * We'll use sync mode since 6.18 rather than async mode. So in future +- * the kernel parameter will be removed. ++ * We'll use sync mode rather than async mode. So in future the kernel ++ * parameter will be removed. ++ * ++ * The kernel version can't be used to decide whether the parameter is ++ * supported, because the two commits mentioned above are backported to ++ * various downstream kernels which keep their own versioning. Check ++ * sysfs to know if the running kernel provides the parameter and only ++ * set it then, otherwise keep the kernel default. + */ +- if (get_linux_version() >= 6018000) ++ if (md_mod_parameter_exists(MD_MOD_ASYNC_DEL_GENDISK)) + ret = set_md_mod_parameter(MD_MOD_ASYNC_DEL_GENDISK, "N"); + + return ret;