mdadm/0057-mdmon-Improve-switchroot-interactions.patch
Coly Li 2e05bd3f7b Accepting request 1082557 from home:colyli:branches:openSUSE:Factory
- Fixes for mdmon to ensure it run at the right time in the
  fight mount namespace.  This fixes various problems with 
  IMSM raid arrays in 15-SP4 (bsc#1205493, bsc#1205830)
  - mdmon: fix segfault
    0052-mdmon-fix-segfault.patch
  - util: remove obsolete code from get_md_name
    0053-util-remove-obsolete-code-from-get_md_name.patch
  - mdmon: don't test both 'all' and 'container_name'.
    0054-mdmon-don-t-test-both-all-and-container_name.patch
  - mdmon: change systemd unit file to use --foreground
    0055-mdmon-change-systemd-unit-file-to-use-foreground.patch
  - mdmon: Remove need for KillMode=none
    0056-mdmon-Remove-need-for-KillMode-none.patch
  - mdmon: Improve switchroot interactions.
    0057-mdmon-Improve-switchroot-interactions.patch
  - mdopen: always try create_named_array()
    0058-mdopen-always-try-create_named_array.patch
  - Improvements for IMSM_NO_PLATFORM testing
    0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch

OBS-URL: https://build.opensuse.org/request/show/1082557
OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=223
2023-04-26 15:45:39 +00:00

164 lines
6.1 KiB
Diff

From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 13 Mar 2023 14:42:58 +1100
Subject: [PATCH] mdmon: Improve switchroot interactions.
We need a new mdmon@mdfoo instance to run in the root filesystem after
switch root, as /sys and /dev are removed from the initrd.
systemd will not start a new unit with the same name running while the
old unit is still active, and we want the two mdmon processes to overlap
in time to avoid any risk of deadlock, which can happen when a write is
attempted with no mdmon running.
So we need a different unit name in the initrd than in the root. Apart
from the name, everything else should be the same.
This is easily achieved using a different instance name as the
mdmon@.service unit file already supports multiple instances (for
different arrays).
So start "mdmon@mdfoo.service" from root, but
"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which
circumstance is the case by looking for /etc/initrd-release.
continue_from_systemd() is enhanced so that the "initrd-" prefix can be
requested.
Teach mdmon that a container name like "initrd/foo" should be treated
just like "foo". Note that systemd passes the instance name
"initrd-foo" as "initrd/foo".
We don't need a similar mechanism at shutdown because dracut runs
"mdmon --takeover --all" when appropriate.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
Grow.c | 4 ++--
mdadm.h | 2 +-
mdmon.c | 7 ++++++-
systemd/mdmon@.service | 2 +-
udev-md-raid-arrays.rules | 3 ++-
util.c | 7 ++++---
6 files changed, 16 insertions(+), 9 deletions(-)
Index: mdadm-4.2/Grow.c
===================================================================
--- mdadm-4.2.orig/Grow.c
+++ mdadm-4.2/Grow.c
@@ -3513,7 +3513,7 @@ started:
if (!forked)
if (continue_via_systemd(container ?: sra->sys_name,
- GROW_SERVICE)) {
+ GROW_SERVICE, NULL)) {
free(fdlist);
free(offsets);
sysfs_free(sra);
@@ -3711,7 +3711,7 @@ int reshape_container(char *container, c
ping_monitor(container);
if (!forked && !freeze_reshape)
- if (continue_via_systemd(container, GROW_SERVICE))
+ if (continue_via_systemd(container, GROW_SERVICE, NULL))
return 0;
switch (forked ? 0 : fork()) {
Index: mdadm-4.2/mdadm.h
===================================================================
--- mdadm-4.2.orig/mdadm.h
+++ mdadm-4.2/mdadm.h
@@ -1550,7 +1550,7 @@ extern int same_dev(char *one, char *two
extern int compare_paths (char* path1,char* path2);
extern void enable_fds(int devices);
extern void manage_fork_fds(int close_all);
-extern int continue_via_systemd(char *devnm, char *service_name);
+extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
extern int parse_auto(char *str, char *msg, int config);
extern struct mddev_ident *conf_get_ident(char *dev);
Index: mdadm-4.2/mdmon.c
===================================================================
--- mdadm-4.2.orig/mdmon.c
+++ mdadm-4.2/mdmon.c
@@ -362,7 +362,12 @@ int main(int argc, char *argv[])
}
if (!all && argv[optind]) {
- container_name = get_md_name(argv[optind]);
+ static const char prefix[] = "initrd/";
+ container_name = argv[optind];
+ if (strncmp(container_name, prefix,
+ sizeof(prefix) - 1) == 0)
+ container_name += sizeof(prefix)-1;
+ container_name = get_md_name(container_name);
if (!container_name)
return 1;
}
Index: mdadm-4.2/systemd/mdmon@.service
===================================================================
--- mdadm-4.2.orig/systemd/mdmon@.service
+++ mdadm-4.2/systemd/mdmon@.service
@@ -6,7 +6,7 @@
# (at your option) any later version.
[Unit]
-Description=MD Metadata Monitor on /dev/%I
+Description=MD Metadata Monitor on %I
DefaultDependencies=no
Before=initrd-switch-root.target
Documentation=man:mdmon(8)
Index: mdadm-4.2/udev-md-raid-arrays.rules
===================================================================
--- mdadm-4.2.orig/udev-md-raid-arrays.rules
+++ mdadm-4.2/udev-md-raid-arrays.rules
@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD
# Tell systemd to run mdmon for our container, if we need it.
ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
-ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
+ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service"
+ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
LABEL="md_end"
Index: mdadm-4.2/util.c
===================================================================
--- mdadm-4.2.orig/util.c
+++ mdadm-4.2/util.c
@@ -1906,6 +1906,7 @@ int start_mdmon(char *devnm)
int len;
pid_t pid;
int status;
+ char *prefix = in_initrd() ? "initrd-" : "";
char pathbuf[1024];
char *paths[4] = {
pathbuf,
@@ -1916,7 +1917,7 @@ int start_mdmon(char *devnm)
if (check_env("MDADM_NO_MDMON"))
return 0;
- if (continue_via_systemd(devnm, MDMON_SERVICE))
+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix))
return 0;
/* That failed, try running mdmon directly */
@@ -2187,7 +2188,7 @@ void manage_fork_fds(int close_all)
* 1- if systemd service has been started
* 0- otherwise
*/
-int continue_via_systemd(char *devnm, char *service_name)
+int continue_via_systemd(char *devnm, char *service_name, char *prefix)
{
int pid, status;
char pathbuf[1024];
@@ -2199,7 +2200,7 @@ int continue_via_systemd(char *devnm, ch
case 0:
manage_fork_fds(1);
snprintf(pathbuf, sizeof(pathbuf),
- "%s@%s.service", service_name, devnm);
+ "%s@%s%s.service", service_name, prefix ?: "", devnm);
status = execl("/usr/bin/systemctl", "systemctl", "restart",
pathbuf, NULL);
status = execl("/bin/systemctl", "systemctl", "restart",