From c56de49a0bb7e9a8803c8b00f1396c7938b4f5f1ee267f8af35a8566c43696b7 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 20 Aug 2012 06:57:35 +0000 Subject: [PATCH] - mdmon-takeover.fix find-free-devnum.fix mapfile-rebuild.fix udev-offroot Fix various issues will installation on IMSM RAID arrays, booting from those arrays, and clean shutdown when such an array is used for '/'. (bnc#752107 bnc#732294 bnc#770351) OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=69 --- boot.md | 2 +- find-free-devnum.fix | 32 ++++++++++++++++++++++++++++++++ mapfile-rebuild.fix | 29 +++++++++++++++++++++++++++++ mdadm.changes | 12 ++++++++++++ mdadm.shutdown | 4 ++++ mdadm.spec | 14 ++++++++++++++ mdmon-takeover.fix | 31 +++++++++++++++++++++++++++++++ mkinitrd-boot.sh | 12 ++++++------ mkinitrd-setup.sh | 11 +++++++++-- udev-offroot | 18 ++++++++++++++++++ 10 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 find-free-devnum.fix create mode 100644 mapfile-rebuild.fix create mode 100644 mdadm.shutdown create mode 100644 mdmon-takeover.fix create mode 100644 udev-offroot diff --git a/boot.md b/boot.md index aa539cd..e76756f 100644 --- a/boot.md +++ b/boot.md @@ -100,7 +100,7 @@ case "$1" in mkdir -p /run/mdadm # restart mdmon (exits silently if there is nothing to monitor) - /sbin/mdmon --all --takeover + /sbin/mdmon --all --takeover --offroot # Check for existence of needed config file and read it [ -r $mdadm_SYSCONFIG ] || _rc_exit 6 "... $mdadm_SYSCONFIG not existing " diff --git a/find-free-devnum.fix b/find-free-devnum.fix new file mode 100644 index 0000000..3462a45 --- /dev/null +++ b/find-free-devnum.fix @@ -0,0 +1,32 @@ +From fb52f2457a4df4f7061be7a0524763193a6355a7 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 20 Aug 2012 10:50:42 +1000 +Subject: [PATCH] find_free_devnum: avoid auto-using names in /etc/mdadm.conf + +high-number names like "/dev/md126" shouldn't be in /etc/mdadm.conf, +but if they are they should be ignored when choosing an +unused number. + +Signed-off-by: NeilBrown + +--- + util.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- mdadm-3.2.5.orig/util.c ++++ mdadm-3.2.5/util.c +@@ -796,10 +796,14 @@ int find_free_devnum(int use_partitions) + devnum = devnum ? devnum-1 : (1<<20)-1) { + char *dn; + int _devnum; ++ char nbuf[50]; + + _devnum = use_partitions ? (-1-devnum) : devnum; + if (mddev_busy(_devnum)) + continue; ++ sprintf(nbuf, "%s%d", use_partitions?"mdp":"md", devnum); ++ if (!conf_name_is_free(nbuf)) ++ continue; + /* make sure it is new to /dev too, at least as a + * non-standard */ + dn = map_dev(dev2major(_devnum), dev2minor(_devnum), 0); diff --git a/mapfile-rebuild.fix b/mapfile-rebuild.fix new file mode 100644 index 0000000..888d9dc --- /dev/null +++ b/mapfile-rebuild.fix @@ -0,0 +1,29 @@ +From a74e5731ba8c32f74c60e45c244735d602d14dca Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 20 Aug 2012 12:34:28 +1000 +Subject: [PATCH] mapfile: fix mapfile rebuild for containers + +When recreating the mapfile entry for a container we need to +use ->getinfo_super, not ->container_content, just like we +do in Detail(). + +Signed-off-by: NeilBrown + +diff --git a/mapfile.c b/mapfile.c +index fa23883..6712733 100644 +--- a/mapfile.c ++++ b/mapfile.c +@@ -403,7 +403,12 @@ void RebuildMap(void) + close(dfd); + if (ok != 0) + continue; +- info = st->ss->container_content(st, subarray); ++ if (subarray) ++ info = st->ss->container_content(st, subarray); ++ else { ++ info = malloc(sizeof(*info)); ++ st->ss->getinfo_super(st, info, NULL); ++ } + if (!info) + continue; + diff --git a/mdadm.changes b/mdadm.changes index 8006ca4..16b7419 100644 --- a/mdadm.changes +++ b/mdadm.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Mon Aug 20 06:53:24 UTC 2012 - nfbrown@suse.com + +- mdmon-takeover.fix + find-free-devnum.fix + mapfile-rebuild.fix + udev-offroot + Fix various issues will installation on IMSM + RAID arrays, booting from those arrays, and + clean shutdown when such an array is used for '/'. + (bnc#752107 bnc#732294 bnc#770351) + ------------------------------------------------------------------- Thu Jul 26 16:50:03 UTC 2012 - fcrozat@suse.com diff --git a/mdadm.shutdown b/mdadm.shutdown new file mode 100644 index 0000000..38b5c5b --- /dev/null +++ b/mdadm.shutdown @@ -0,0 +1,4 @@ +#!/bin/sh +# We need to ensure all md array with external metadata +# (e.g. IMSM) are clean before completing the shutdown. +/sbin/mdadm --wait-clean --scan diff --git a/mdadm.spec b/mdadm.spec index 44099ed..6b4ea5b 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -38,9 +38,14 @@ Source4: boot.md Source5: mkinitrd-setup.sh Source6: mkinitrd-boot.sh Source7: mdadm.cron +Source8: mdadm.shutdown Patch1: udev-rules.fix Patch2: mdmon-arg.fix Patch3: blkid-builtin.patch +Patch4: mdmon-takeover.fix +Patch5: find-free-devnum.fix +Patch6: mapfile-rebuild.fix +Patch7: udev-offroot %description Mdadm is a program that can be used to control Linux md devices. It is @@ -52,6 +57,10 @@ programs but with a very different interface. %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error" @@ -76,6 +85,8 @@ rm -rf $RPM_BUILD_ROOT/run/mdadm mkdir -p $RPM_BUILD_ROOT/run/mdadm install -d $RPM_BUILD_ROOT/lib/udev/rules.d install -m 644 udev-md-raid.rules $RPM_BUILD_ROOT/lib/udev/rules.d/64-md-raid.rules +install -d $RPM_BUILD_ROOT/lib/systemd/system-shutdown +install -m 755 %{S:8} $RPM_BUILD_ROOT/lib/systemd/system-shutdown/mdadm.shutdown %post [ -x /sbin/mkinitrd_setup ] && mkinitrd_setup @@ -130,5 +141,8 @@ rm -rf $RPM_BUILD_ROOT %dir /etc %dir /etc/cron.daily /etc/cron.daily/mdadm +%dir /lib/systemd +%dir /lib/systemd/system-shutdown +/lib/systemd/system-shutdown/mdadm.shutdown %changelog diff --git a/mdmon-takeover.fix b/mdmon-takeover.fix new file mode 100644 index 0000000..93ef363 --- /dev/null +++ b/mdmon-takeover.fix @@ -0,0 +1,31 @@ +From a99d3469713138f050cccb8657c24a05ffa7057e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 20 Aug 2012 10:37:21 +1000 +Subject: [PATCH] mdmon: allow --takeover when original was started with + --offroot + +As --offroot causes ARGV[0] to be changed, we need to be more +lenient when checking that the mdmon we are about to kill really +is mdmon. i.e. allow name to be "@dmon" instead. + +Signed-off-by: NeilBrown + +--- + mdmon.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- mdadm-3.2.5.orig/mdmon.c ++++ mdadm-3.2.5/mdmon.c +@@ -184,7 +184,11 @@ static void try_kill_monitor(pid_t pid, + buf[sizeof(buf)-1] = 0; + close(fd); + +- if (n < 0 || !strstr(buf, "mdmon")) ++ /* Note that if started with --offroot, the name ++ * might be "@dmon" ++ */ ++ if (n < 0 || !(strstr(buf, "mdmon") || ++ strstr(buf, "@dmon"))) + return; + + kill(pid, SIGTERM); diff --git a/mkinitrd-boot.sh b/mkinitrd-boot.sh index 3cca304..255ea0d 100644 --- a/mkinitrd-boot.sh +++ b/mkinitrd-boot.sh @@ -102,34 +102,34 @@ md_assemble() "") ;; /dev/*) - $mdadm -A $mdconf $container + $mdadm -A $mdconf $container --offroot ;; [0-9a-f]*[0-9a-f]) container_name=$(get_md_name "$container") if test -z "$container_name"; then container_name=/dev/md/container fi - $mdadm -A $mdconf --uuid="$container" "$container_name" + $mdadm -A $mdconf --uuid="$container" "$container_name" --offroot ;; *) echo "unrecognized container for $dev: $container" esac if test -n "$dev"; then - $mdadm -A $mdconf "$dev" + $mdadm -A $mdconf "$dev" --offroot else dev=$(get_md_name "$uuid") if test -z "$dev"; then # mdadm will pick a device name - $mdadm -A $mdconf --uuid=$uuid + $mdadm -A $mdconf --uuid=$uuid --offroot else - $mdadm -A $mdconf --uuid=$uuid "$dev" + $mdadm -A $mdconf --uuid=$uuid "$dev" --offroot fi fi } # run any degraded arrays assembled incrementally wait_for_events -$mdadm --incremental --run --scan +$mdadm --incremental --run --scan --offroot md_assemble "$resumedev" md_assemble "$rootdev" if [ -n "$md_dev" ] ; then diff --git a/mkinitrd-setup.sh b/mkinitrd-setup.sh index 27837ce..39bd043 100644 --- a/mkinitrd-setup.sh +++ b/mkinitrd-setup.sh @@ -28,7 +28,12 @@ for bd in $blockdev ; do ;; esac # Check if this device is already added (possible for partitionable). - md_dev=${bd##/dev/} + md_dev=`mdadm -D --export $bd | sed -n -e 's/^MD_DEVNAME=//p'` + if [ -z "$md_dev" ]; then + md_dev=${bd##/dev/} + else + bd="/dev/md/$md_dev" + fi dup_found=false for dup in $md_devs; do if [ x"$dup" = x"$md_dev" ]; then @@ -52,7 +57,7 @@ for bd in $blockdev ; do md_devs="$md_devs $md_dev" container=$(echo "$mdconf" | sed -rn 's/.* container=([^ ]*) .*/\1/p') for cnt in $cont_list; do - if [ x"$container"= x"$cnt" ]; then + if [ x"$container" = x"$cnt" ]; then container= break fi @@ -62,12 +67,14 @@ for bd in $blockdev ; do ;; /dev/*) mdconf="$(mdadm -Db "$container")\\n$mdconf" + cont_list="$cont_list $container" ;; [0-9a-f]*[0-9a-f]) if test -z "$mdadm_conf"; then mdadm_conf=$(mdadm --examine --brief --scan) fi mdconf="$(echo "$mdadm_conf" | grep "UUID=$container")\\n$mdconf" + cont_list="$cont_list $container" ;; *) echo "unrecognized container for $md_dev: $container" diff --git a/udev-offroot b/udev-offroot new file mode 100644 index 0000000..09de0a7 --- /dev/null +++ b/udev-offroot @@ -0,0 +1,18 @@ +Use --offroot flag when assembling md arrays. + +This ensures that mdmon won't be killed by systemd. +--- + udev-md-raid.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- mdadm-3.2.5.orig/udev-md-raid.rules ++++ mdadm-3.2.5/udev-md-raid.rules +@@ -10,7 +10,7 @@ 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", RUN+="/sbin/mdadm --incremental $tempnode" ++ACTION=="add", RUN+="/sbin/mdadm --incremental $tempnode --offroot" + ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}" + ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name" +