148 lines
4.5 KiB
Plaintext
148 lines
4.5 KiB
Plaintext
|
#!/bin/sh
|
||
|
|
||
|
# mdrun, (c) Eduard Bloch <blade@debian.org> 2003
|
||
|
|
||
|
# Usage:
|
||
|
# Without arguments: autodetect all RAID partitions and activate MDs
|
||
|
# Arguments: [ DEVDIR ] NUMBER UUID [ <NUMBER UUID> ... ]
|
||
|
# a number of number/uuid pairs, where NUMBER is the one from /dev/md/*
|
||
|
# Argument: LIST
|
||
|
# lists all raids in the syntax needed for the pairs (see above)
|
||
|
|
||
|
# IMPORTANT: create /dev/fs directory if you have devfs support in the kernel
|
||
|
# but do not want to mount it over /dev. Usage of /dev/fs directory will keep
|
||
|
# mdrun away from /dev.
|
||
|
|
||
|
# If the first argument is a directory, it will be used as a writeable
|
||
|
# temporary directory for device nodes. mdrun needs mknod to create them
|
||
|
# on-the-fly
|
||
|
|
||
|
# Environment:
|
||
|
# MORERAIDVOLUMES (list of strings) : additional raid disks to scan,
|
||
|
# eg. loop devices
|
||
|
|
||
|
if ! test -e /proc/partitions ; then
|
||
|
echo "/proc not mounted!"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
DEVDIR=/dev
|
||
|
|
||
|
if [ -d "$1" ] ; then
|
||
|
AUTOCREATE=true
|
||
|
DEVDIR="$1"
|
||
|
shift
|
||
|
fi
|
||
|
|
||
|
# For people that compile the kernel with devfs (means: different
|
||
|
# proc/partitions content), but without auto-mounting it
|
||
|
if ! uname -r | grep "^2.6" 1>/dev/null && [ -z "$AUTOCREATE" ] && grep " devfs" /proc/filesystems >/dev/null 2>&1 && ! grep "^devfs" /proc/mounts >/dev/null 2>&1 ; then
|
||
|
|
||
|
mkdir /dev/fs 2>/dev/null
|
||
|
# if we can do it - good, we will use it. Otherwise, use /dev even if it is ugly
|
||
|
|
||
|
# mount devfs for now to make the device names match, umount later
|
||
|
if [ -d /dev/fs ] ; then
|
||
|
DEVDIR=/dev/fs
|
||
|
fi
|
||
|
mount none $DEVDIR -tdevfs
|
||
|
UMNTDEVFS="umount $DEVDIR"
|
||
|
fi
|
||
|
|
||
|
# arr(array, index): return contents in array[index]; as with Bourne shell
|
||
|
# in general, there is no easy way to distinguish between index not
|
||
|
# existing and empty string assigned.
|
||
|
arr() { sa_i=`arr_index $2`; eval "echo \"\$$1_${sa_i}\""; unset sa_i; }
|
||
|
|
||
|
# seterr(array, index, value): assign the given value to array[index].
|
||
|
setarr() { sa_i=`arr_index $2`; eval "$1_${sa_i}=\"$3\""; unset sa_i; }
|
||
|
|
||
|
# arr_index(index): make sure the given index is valid for use.
|
||
|
arr_index() { echo $1 | sed -e 's/:/_/g' | sed 's;/;_;g'; }
|
||
|
|
||
|
|
||
|
BASE=$DEVDIR/md
|
||
|
export BASE
|
||
|
#devfs
|
||
|
test -d $BASE && BASE=$BASE/
|
||
|
|
||
|
next_free_md() {
|
||
|
for raidnr in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
|
||
|
if ! mdadm -D $BASE$raidnr >/dev/null 2>&1 ; then
|
||
|
echo $BASE$raidnr
|
||
|
return 0
|
||
|
fi
|
||
|
done
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
listpairs() {
|
||
|
for NUMBER in `cat /proc/mdstat | grep "^md. : active" | sed -e 's/^md\(.\) :.*/\1/'`; do
|
||
|
echo $NUMBER
|
||
|
mdadm -D ${BASE}$NUMBER 2>/dev/null |grep UUID | sed 's/.*: \(.*\)/\1/'
|
||
|
done
|
||
|
}
|
||
|
|
||
|
if [ "$1" = LIST ] ; then
|
||
|
echo `listpairs`
|
||
|
$UMNTDEVFS
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
DEVDIRESC=$(echo $DEVDIR | sed -e 's!/!\\/!g')
|
||
|
if [ "$AUTOCREATE" ] ; then
|
||
|
CREATECMD=$(sed -e "s/.*major.*//; s/.*\ \([:0-9:]\+\)\ \+\ \([:0-9:]\+\)\ \+\ [:0-9:]\+\ \+\([:a-z0-9\/:]\+\).*/mknod \3 b \1 \2 ; / ; s/\//_/g" < /proc/partitions)
|
||
|
export CREATECMD
|
||
|
export DEVDIR
|
||
|
# and we need array nodes, of course
|
||
|
(
|
||
|
cd $DEVDIR ;
|
||
|
eval $CREATECMD ;
|
||
|
for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ; do
|
||
|
mknod ${BASE}$x b 9 $x
|
||
|
done
|
||
|
)
|
||
|
PARTLIST=$(sed -e "s/.*major.*//; s/.*\ \([:0-9:]\+\)\ \+\ \([:0-9:]\+\)\ \+\ [:0-9:]\+\ \+\([:a-z0-9\/:]\+\).*/DEVDIR\3 /; s/\//_/g ; s/DEVDIR/$DEVDIRESC\//;" < /proc/partitions)
|
||
|
else
|
||
|
PARTLIST=$(sed -e "s/.*major.*//; s/^[:0-9 :]* \([:a-z:].[:a-z0-9\/:]*\).*/\1/; s/^\([:a-z:].*\)/$DEVDIRESC\/\1/g" < /proc/partitions)
|
||
|
fi
|
||
|
|
||
|
for SRC in $PARTLIST $MORERAIDVOLUMES ; do
|
||
|
SUM=$(mdadm -E $SRC 2>/dev/null | grep UUID | sed 's/.*: \(.*\)/\1/')
|
||
|
for x in $SUM; do
|
||
|
UUIDS="$UUIDS $SUM"
|
||
|
setarr MDS $SUM "`arr MDS $SUM` $SRC"
|
||
|
done
|
||
|
done
|
||
|
|
||
|
if [ "$#" -gt 1 ] ; then
|
||
|
NUMBER=${BASE}$1
|
||
|
MD=$2
|
||
|
shift ; shift
|
||
|
if [ "`arr MDS $MD`" != "started" ] ; then
|
||
|
mdadm -A $NUMBER -f `arr MDS $MD` && setarr MDS $MD "started"
|
||
|
# just to be sure
|
||
|
ln /dev/md/$NUMBER /dev/md$NUMBER 2>/dev/null
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# and process the rest, if it exists
|
||
|
# do not touch active arrays
|
||
|
#dropactive() {
|
||
|
for NUMBER in `cat /proc/mdstat | grep "^md. : active" | sed -e 's/^md\(.\) :.*/\1/'`; do
|
||
|
setarr MDS `mdadm -D ${BASE}$NUMBER 2>/dev/null |grep UUID | sed 's/.*: \(.*\)/\1/'` "started"
|
||
|
done
|
||
|
#}
|
||
|
|
||
|
|
||
|
for MD in $UUIDS; do
|
||
|
if [ "`arr MDS $MD`" != "started" ] ; then
|
||
|
NUMBER=`next_free_md`
|
||
|
mdadm -A $NUMBER -f `arr MDS $MD` && setarr MDS $MD "started"
|
||
|
# just to be sure
|
||
|
ln /dev/md/$NUMBER /dev/md$NUMBER 2>/dev/null
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
$UMNTDEVFS
|