summaryrefslogtreecommitdiffstats
path: root/debian/local/bin
diff options
context:
space:
mode:
Diffstat (limited to 'debian/local/bin')
-rwxr-xr-xdebian/local/bin/checkarray221
-rwxr-xr-xdebian/local/bin/mkconf104
2 files changed, 325 insertions, 0 deletions
diff --git a/debian/local/bin/checkarray b/debian/local/bin/checkarray
new file mode 100755
index 0000000..2fb7ee7
--- /dev/null
+++ b/debian/local/bin/checkarray
@@ -0,0 +1,221 @@
+#!/bin/sh
+#
+# checkarray -- initiates a check run of an MD array's redundancy information.
+#
+# Copyright © martin f. krafft <madduck@debian.org>
+# distributed under the terms of the Artistic Licence 2.0
+#
+set -eu
+
+PROGNAME=${0##*/}
+
+about()
+{
+ echo "\
+$PROGNAME -- MD array (RAID) redundancy checker tool
+Copyright © martin f. krafft <madduck@debian.org>
+Released under the terms of the Artistic Licence 2.0"
+}
+
+usage()
+{
+ about
+ echo "
+Usage: $PROGNAME [options] [arrays]
+
+Valid options are:
+ -a|--all check all assembled arrays (ignores arrays in command line).
+ -s|--status print redundancy check status of devices.
+ -x|--cancel queue a request to cancel a running redundancy check.
+ -r|--repair repair instead of check
+ -i|--idle perform check in a lowest scheduling class (idle)
+ -l|--slow perform check in a lower-than-standard scheduling class
+ -f|--fast perform check in higher-than-standard scheduling class
+ --realtime perform check in real-time scheduling class (DANGEROUS!)
+ -c|--cron honour AUTOCHECK setting in /etc/default/mdadm.
+ -q|--quiet suppress informational messages
+ (use twice to suppress error messages too).
+ -h|--help show this output.
+ -V|--version show version information.
+
+Examples:
+ $PROGNAME --all --idle
+ $PROGNAME --quiet /dev/md[123]
+ $PROGNAME -sa
+ $PROGNAME -x --all
+
+Devices can be specified in almost any format. The following are equivalent:
+ /dev/md0, md0, /dev/md/0, /sys/block/md0
+
+You can also control the status of a check/repair with /proc/mdstat file."
+}
+
+SHORTOPTS=achVqQsxrilf
+LONGOPTS=all,cron,help,version,quiet,real-quiet,status,cancel,repair,idle,slow,fast,realtime
+
+eval set -- $(getopt -o $SHORTOPTS -l $LONGOPTS -n $PROGNAME -- "$@")
+
+arrays=''
+cron=0
+all=0
+quiet=0
+status=0
+action=check
+ionice=
+
+for opt in $@; do
+ case "$opt" in
+ -a|--all) all=1;;
+ -s|--status) action=status;;
+ -x|--cancel) action=idle;;
+ -r|--repair) action=repair;;
+ -i|--idle) ionice=idle;;
+ -l|--slow) ionice=low;;
+ -f|--fast) ionice=high;;
+ --realtime) ionice=realtime;;
+ -c|--cron) cron=1;;
+ -q|--quiet) quiet=$(($quiet+1));;
+ -Q|--real-quiet) quiet=$(($quiet+2));; # for compatibility
+ -h|--help) usage; exit 0;;
+ -V|--version) about; exit 0;;
+ /dev/md/*|md/*) arrays="${arrays:+$arrays }md${opt#*md/}";;
+ /dev/md*|md*) arrays="${arrays:+$arrays }${opt#/dev/}";;
+ /sys/block/md*) arrays="${arrays:+$arrays }${opt#/sys/block/}";;
+ --) :;;
+ *) echo "$PROGNAME: E: invalid option: $opt. Try --help." >&2; exit 1;;
+ esac
+done
+
+is_true()
+{
+ case "${1:-}" in
+ [Yy]es|[Yy]|1|[Tt]rue|[Tt]) return 0;;
+ *) return 1;
+ esac
+}
+
+DEBIANCONFIG=/etc/default/mdadm
+[ -r $DEBIANCONFIG ] && . $DEBIANCONFIG
+if [ $cron = 1 ] && ! is_true ${AUTOCHECK:-false}; then
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: disabled in $DEBIANCONFIG ." >&2
+ exit 0
+fi
+
+if [ ! -f /proc/mdstat ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: E: MD subsystem not loaded, or /proc unavailable." >&2
+ exit 2
+fi
+
+if [ ! -d /sys/block ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: E: /sys filesystem not available." >&2
+ exit 7
+fi
+
+if [ -z "$(ls /sys/block/md* 2>/dev/null)" ]; then
+ if [ $quiet -lt 2 ] && [ $cron != 1 ]; then
+ echo "$PROGNAME: W: no active MD arrays found." >&2
+ echo "$PROGNAME: W: (maybe uninstall the mdadm package?)" >&2
+ fi
+ exit 0
+fi
+
+if [ -z "$(ls /sys/block/md*/md/level 2>/dev/null)" ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: E: kernel too old, no support for redundancy checks." >&2
+ exit 6
+fi
+
+if ! egrep -q '^raid([1456]|10)$' /sys/block/md*/md/level 2>/dev/null; then
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: no redundant arrays present; skipping checks..." >&2
+ exit 0
+fi
+
+if [ -z "$(ls /sys/block/md*/md/sync_action 2>/dev/null)" ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: E: no kernel support for redundancy checks." >&2
+ exit 3
+fi
+
+[ $all = 1 ] && arrays="$(ls -d1 /sys/block/md* | cut -d/ -f4)"
+
+for array in $arrays; do
+ MDBASE=/sys/block/$array/md
+
+ if [ ! -e $MDBASE/sync_action ]; then
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: skipping non-redundant array $array." >&2
+ continue
+ fi
+
+ cur_status="$(cat $MDBASE/sync_action)"
+
+ if [ $action = status ]; then
+ echo "$array: $cur_status"
+ continue
+ fi
+
+ if [ ! -w $MDBASE/sync_action ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: E: $MDBASE/sync_action not writeable." >&2
+ exit 4
+ fi
+
+ if [ "$(cat $MDBASE/array_state)" = 'read-auto' ]; then
+ [ $quiet -lt 1 ] && echo "$PROGNAME: W: array $array in auto-read-only state, skipping..." >&2
+ continue
+ fi
+
+ case "$action" in
+ idle)
+ echo $action > $MDBASE/sync_action
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: cancel request queued for array $array." >&2
+ ;;
+
+ check|repair)
+ if [ "$cur_status" != idle ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: W: array $array not idle, skipping..." >&2
+ continue
+ fi
+
+ # check if the array created recently and skip test if it is
+ created=$(mdadm --detail /dev/$array 2>/dev/null |
+ sed -n 's/.*Creation Time *://p' )
+ if [ -n "$created" ]; then
+ created=$(date +%s -d "$created" 2>/dev/null)
+ fi
+ if [ -n "$created" ]; then
+ now=$(date +%s)
+ if [ "$created" -lt "$now" -a \
+ "$created" -gt "$(($now - 14 * 24 * 60 * 60))" ]; then
+ [ $quiet -lt 2 ] && echo "$PROGNAME: I: array $array created recently, skipping..." >&2
+ continue
+ fi
+ fi
+
+ # queue request for the array. The kernel will make sure that these requests
+ # are properly queued so as to not kill one of the arrays.
+ echo $action > $MDBASE/sync_action
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: $action queued for array $array." >&2
+
+ case "$ionice" in
+ idle) ioarg='-c3'; renice=15;;
+ low) ioarg='-c2 -n7'; renice=5;;
+ high) ioarg='-c2 -n0'; renice=0;;
+ realtime) ioarg='-c1 -n4'; renice=-5;;
+ *) continue;;
+ esac
+
+ resync_pid= wait=5
+ while [ $wait -gt 0 ]; do
+ wait=$((wait - 1))
+ resync_pid=$(ps -ef | awk -v dev=$array 'BEGIN { pattern = "^\\[" dev "_resync]$" } $8 ~ pattern { print $2 }')
+ if [ -n "$resync_pid" ]; then
+ [ $quiet -lt 1 ] && echo "$PROGNAME: I: selecting $ionice I/O scheduling class and $renice niceness for resync of $array." >&2
+ ionice -p "$resync_pid" $ioarg 2>/dev/null || :
+ renice -n $renice -p "$resync_pid" 1>/dev/null 2>&1 || :
+ break
+ fi
+ sleep 1
+ done
+ ;;
+ esac
+
+done
+
+exit 0
diff --git a/debian/local/bin/mkconf b/debian/local/bin/mkconf
new file mode 100755
index 0000000..4dd09b1
--- /dev/null
+++ b/debian/local/bin/mkconf
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# mkconf -- outputs valid mdadm.conf contents for the local system
+#
+# Copyright © martin f. krafft <madduck@madduck.net>
+# distributed under the terms of the Artistic Licence 2.0
+#
+set -eu
+
+ME="${0##*/}"
+MDADM=/sbin/mdadm
+DEBIANCONFIG=/etc/default/mdadm
+CONFIG=/etc/mdadm/mdadm.conf
+
+# initialise config variables in case the environment leaks
+MAILADDR= DEVICE= HOMEHOST= PROGRAM=
+
+test -r $DEBIANCONFIG && . $DEBIANCONFIG
+
+if [ -n "${MDADM_MAILADDR__:-}" ]; then
+ # honour MAILADDR from the environment (from postinst)
+ MAILADDR="$MDADM_MAILADDR__"
+else
+ # preserve existing MAILADDR
+ MAILADDR="$(sed -ne 's/^MAILADDR //p' $CONFIG 2>/dev/null)" || :
+fi
+
+# save existing values as defaults
+if [ -r "$CONFIG" ]; then
+ DEVICE="$(sed -ne 's/^DEVICE //p' $CONFIG)"
+ HOMEHOST="$(sed -ne 's/^HOMEHOST //p' $CONFIG)"
+ PROGRAM="$(sed -ne 's/^PROGRAM //p' $CONFIG)"
+fi
+
+[ "${1:-}" = force-generate ] && rm -f $CONFIG
+case "${1:-}" in
+ generate|force-generate)
+ [ -n "${2:-}" ] && CONFIG=$2
+ # only barf if the config file specifies anything else than MAILADDR
+ if egrep -qv '^(MAILADDR.*|#.*|)$' $CONFIG 2>/dev/null; then
+ echo "E: $ME: $CONFIG already exists." >&2
+ exit 255
+ fi
+
+ mkdir --parent ${CONFIG%/*}
+ exec >$CONFIG
+ ;;
+esac
+
+cat <<_eof
+# mdadm.conf
+#
+# !NB! Run update-initramfs -u after updating this file.
+# !NB! This will ensure that initramfs has an uptodate copy.
+#
+# Please refer to mdadm.conf(5) for information about this file.
+#
+
+# by default (built-in), scan all partitions (/proc/partitions) and all
+# containers for MD superblocks. alternatively, specify devices to scan, using
+# wildcards if desired.
+#DEVICE ${DEVICE:-partitions containers}
+
+# automatically tag new arrays as belonging to the local system
+HOMEHOST ${HOMEHOST:-<system>}
+
+# instruct the monitoring daemon where to send mail alerts
+MAILADDR ${MAILADDR:-root}
+
+_eof
+
+if [ -n "${PROGRAM:-}" ]; then
+ cat <<-_eof
+ # program to run when mdadm monitor detects potentially interesting events
+ PROGRAM ${PROGRAM}
+
+ _eof
+fi
+
+error=0
+if [ ! -r /proc/mdstat ]; then
+ echo W: $ME: MD subsystem is not loaded, thus I cannot scan for arrays. >&2
+ error=1
+elif [ ! -r /proc/partitions ]; then
+ echo W: $ME: /proc/partitions cannot be read, thus I cannot scan for arrays. >&2
+ error=2
+else
+ echo "# definitions of existing MD arrays"
+ if ! $MDADM --examine --scan --config=partitions; then
+ error=$(($? + 128))
+ echo W: $ME: failed to scan for partitions. >&2
+ echo "### WARNING: scan failed."
+ else
+ echo
+ fi
+fi
+
+if [ -z "${SOURCE_DATE_EPOCH:-}" ]; then
+ echo "# This configuration was auto-generated on $(date -R) by mkconf"
+else
+ echo "# This configuration was auto-generated on $(date -R --utc -d@$SOURCE_DATE_EPOCH) by mkconf"
+fi
+
+exit $error