Package: mdadm
Version: 3.2.5-1

[version 2 of the patch]

The initramfs hook supplied by mdadm doesn't install mdmon. Also, mdmon
is not included in the .udeb for the installer.

This means that if you have an array with external metadata (ddf or,
more widely used, imsm - Intel Matrix Raid) that it will come up
readonly. This causes the installer to hang or the system not being
able to boot if root is on that array.

The attached patch does the following:

- it makes sure mdadm is included in the initramfs and the udeb package
- it adds a mdadm-waitidle script that runs just before reboot/halt. For
  arrays that are still running, it calls mdadm --wait-clean to wait
  for the array to go idle.  This is needed so that the array is marked
  clean, otherwise it will start to resync at the next boot.
- it adds a few lines to /etc/init.d/mdadm for the start and stop actions:
  o start: if a mdmon pidfile is found in /run/mdadm, restart mdmon
  o stop: link pidfiles of mdmon processes into /run/sendsigs.omit.d,
    and make sure that happens before sendsigs runs.
- RUNDIR in /etc/init.d/mdadm is set to /run. This is sure to be ok:
  mdadm itself is already compiled with rundir hardcoded to /run.

Note that I've made sure that this actually doesn't do /anything/
if you do not have running MD arrays with external metadata. Iow,
this should not break anything, or cause regressions.

I have added support for installation on Intel Matrix raid (imsm)
arrays using mdadm to d-i, and I'll be sending patches to the debian-boot
list soon. Please consider this patch for inclusion in wheezy.

diff -ruN x/mdadm-3.2.5/debian/changelog mdadm-3.2.5/debian/changelog
--- x/mdadm-3.2.5/debian/changelog	2012-05-25 18:05:23.000000000 +0000
+++ mdadm-3.2.5/debian/changelog	2012-09-22 19:25:28.520705389 +0000
@@ -1,3 +1,18 @@
+mdadm (3.2.5-1+1) unstable; urgency=low
+
+  * also install mdmon in udeb and initramfs, so imsm arrays can work
+  * /etc/init.d/mdadm: change RUNDIR to /run instead of /var/run
+  * /etc/init.d/mdadm start: if a mdmon pidfile is found in /run/mdadm,
+    restart mdmon (-t --all)
+  * /etc/init.d/mdadm stop: link pidfiles of mdmon processes into
+    /run/sendsigs.omit.d, and make sure that happens before sendsigs runs.
+  * add script mdadm-waitidle that runs just before reboot/halt. For each
+    array with external metadata that is still running, it sets
+    sync_action to idle, and uses mdadm --wait-clean to wait for the
+    array to go idle (yes it has a short timeout)
+
+ -- Miquel van Smoorenburg <miqu...@debian.org>  Sat, 22 Sep 2012 21:16:22 +0200
+
 mdadm (3.2.5-1) unstable; urgency=low
 
   [ Michael Tokarev ]
diff -ruN x/mdadm-3.2.5/debian/initramfs/hook mdadm-3.2.5/debian/initramfs/hook
--- x/mdadm-3.2.5/debian/initramfs/hook	2012-05-25 17:31:37.000000000 +0000
+++ mdadm-3.2.5/debian/initramfs/hook	2012-08-01 22:32:50.925671675 +0000
@@ -49,6 +49,7 @@
 }
 
 MDADM=/sbin/mdadm
+MDMON=/sbin/mdmon
 [ -x "$MDADM" ] || exit 0
 
 [ -r /usr/share/initramfs-tools/hook-functions ] || exit 0
@@ -56,6 +57,7 @@
 
 # copy the binary as early as possible
 copy_exec $MDADM /sbin
+copy_exec $MDMON /sbin
 
 # copy all modules into the initramfs, just for safety.
 # we copy raid456 / raid5+raid6 because the hook script just won't do
diff -ruN x/mdadm-3.2.5/debian/mdadm-waitidle mdadm-3.2.5/debian/mdadm-waitidle
--- x/mdadm-3.2.5/debian/mdadm-waitidle	1970-01-01 00:00:00.000000000 +0000
+++ mdadm-3.2.5/debian/mdadm-waitidle	2012-09-22 19:14:34.236895943 +0000
@@ -0,0 +1,70 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          mdadm-waitidle
+# Required-Start:
+# Required-Stop:
+# Should-Stop:       halt reboot kexec
+# X-Stop-After:      umountroot
+# Default-Start:
+# Default-Stop:      0 6
+# Short-Description: Wait for MD arrays to become idle
+# Description:       Waits until all MD arrays with external metadata are
+#                    in idle and synced state before halt/reboot.
+### END INIT INFO
+#
+set -eu
+
+MDADM=/sbin/mdadm
+test -x "$MDADM" || exit 0
+test -f /proc/mdstat || exit 0
+
+. /lib/lsb/init-functions
+
+case "${1:-}" in
+  start)
+    ;;
+  stop)
+    # See which arrays have external metadata
+    arrays=
+    cd /sys/block
+    for md in md*
+    do
+      metadata="`cat $md/md/metadata_version 2>/dev/null ||:`"
+      case "$metadata" in
+        external:[-/]*)
+          arrays="$arrays $md"
+          ;;
+      esac
+    done
+
+    # Only take action for arrays with external metadata
+    [ -n "$arrays" ] || exit 0
+    log_action_begin_msg "Waiting for MD arrays to become idle"
+    sync
+    err=
+    for md in $arrays; do
+      # Stop any sync action
+      if [ -w $md/md/sync_action ]; then
+        echo idle > $md/md/sync_action ||:
+      fi
+      # Wait for the array to become idle (max 5 secs)
+      if ! $MDADM --wait-clean /dev/$md >/dev/null 2>&1; then
+        err=1
+      fi
+    done
+    if [ -n "$err" ]
+    then
+      log_action_end_msg 1
+      sleep 1
+    else
+      log_action_end_msg 0
+    fi
+    ;;
+
+  *)
+    echo "Usage: ${0:-} {stop}" >&2
+    exit 1;;
+
+esac
+
+exit 0
diff -ruN x/mdadm-3.2.5/debian/mdadm.init mdadm-3.2.5/debian/mdadm.init
--- x/mdadm-3.2.5/debian/mdadm.init	2012-05-10 20:22:16.000000000 +0000
+++ mdadm-3.2.5/debian/mdadm.init	2012-09-22 19:18:53.401573785 +0000
@@ -9,7 +9,7 @@
 ### BEGIN INIT INFO
 # Provides:          mdadm
 # Required-Start:    $local_fs $syslog mdadm-raid
-# Required-Stop:     $local_fs $syslog mdadm-raid
+# Required-Stop:     $local_fs $syslog sendsigs mdadm-raid
 # Default-Start:     2 3 4 5
 # Default-Stop:      0 1 6
 # Short-Description: MD monitoring daemon
@@ -22,7 +22,8 @@
 set -eu
 
 MDADM=/sbin/mdadm
-RUNDIR=/var/run/mdadm
+MDMON=/sbin/mdmon
+RUNDIR=/run/mdadm
 PIDFILE=$RUNDIR/monitor.pid
 DEBIANCONFIG=/etc/default/mdadm
 
@@ -54,6 +55,12 @@
       log_end_msg $?
       set -e
     fi
+    if [ "`echo $RUNDIR/md[0-9]*.pid`" != "$RUNDIR/md[0-9]*.pid" ]
+    then
+      log_daemon_msg "Restarting MD external metadata monitor" "mdmon -t --all"
+      $MDMON -t --all
+      log_end_msg $?
+    fi
     ;;
   stop)
     if [ -f $PIDFILE ] ; then
@@ -64,6 +71,11 @@
       log_end_msg $?
       set -e
     fi
+    for file in $RUNDIR/md[0-9]*.pid
+    do
+      [ ! -f "$file" ] && continue
+      ln -sf $file /run/sendsigs.omit.d/mdmon-${file##*/}
+    done
     ;;
   status)
     status_of_proc -p $PIDFILE "$MDADM" "mdadm" && exit 0 || exit $?
diff -ruN x/mdadm-3.2.5/debian/rules mdadm-3.2.5/debian/rules
--- x/mdadm-3.2.5/debian/rules	2012-05-25 17:31:37.000000000 +0000
+++ mdadm-3.2.5/debian/rules	2012-08-06 21:26:11.195263083 +0000
@@ -35,7 +35,8 @@
 	dh_testdir
 	$(MAKE) $(FLAGS) all
 	mv mdadm mdadm.udeb
-.PHONY: mdadm.udeb
+	mv mdmon mdmon.udeb
+.PHONY: mdadm.udeb mdmon.udeb
 
 mdadm: FLAGS = CXFLAGS="$(CXFLAGS)" CONFFILE=/etc/mdadm/mdadm.conf CONFFILE2=/etc/mdadm.conf
 mdadm: configure
@@ -50,7 +51,7 @@
 	rm -f $(INTERPOLATED_FILES)
 	rm -f build-stamp
 	[ ! -f Makefile ] || $(MAKE) clean
-	rm -f mdadm.udeb mdadm debian/mdadm-startall.8
+	rm -f mdadm.udeb mdmon.udeb mdadm debian/mdadm-startall.8
 	dh_clean
 	debconf-updatepo
 
@@ -80,6 +81,7 @@
 	install -m0755 debian/mdadm-startall $(DESTDIR)/sbin
 
 	install -m0755 mdadm.udeb $(DESTDIR_UDEB)/sbin/mdadm
+	install -m0755 mdmon.udeb $(DESTDIR_UDEB)/sbin/mdmon
 	install -m0644 udev-md-raid.rules $(DESTDIR_UDEB)/lib/udev/rules.d/64-md-raid.rules
 
 binary-indep: build install
@@ -92,6 +94,7 @@
 	dh_installdocs
 	dh_installexamples debian/mdadd.sh
 	dh_installinit --init-script=mdadm-raid --no-start -- start 25 S . start 60 0 6 .
+	dh_installinit --init-script=mdadm-waitidle --no-start -- stop 98 0 6 .
 	dh_installinit -- defaults 25
 	dh_installman
 	dh_installcron

Reply via email to