File mkinitrd-setup.sh of Package mdadm.2874
#!/bin/bash
#
#%stage: softraid
#
# blockdev is supposed to contain real devices (/dev/X) for root, resume, journal, dumb and swap
# In case it does not, convert the MD RAID devices into real devices, updating blockdev at the end.
mdblockdev=
# Full mdadm.conf generated by mdadm.
# Contains all created MD RAIDs used by root, resume, journal, dump and swap.
mdadm_conf=
# List to keep track of already seen MD containers.
cont_list=
# List to keep track of already seen MD RAID devices.
md_devs=
# Collected MD RAID devices used by root, resume, journal, dump and swap.
root_md=
declare -A md_conf
# SYNOPSIS
# convertMDs <space separated list of device nodes ("/dev/...")>
#
# DESCRIPTION
# Because a MD RAID might have been constructed using other MD RAID devices, we need to be able
# walk through the entire MD RAID definition chain, in order to be able to convert all MD RAID
# devices to their real devices.
# This is done by recursive calling this function with a list of device nodes that might need to
# to converted to real devices, if not already being a such.
#
# RETURNS
# Updated global variables as defined above.
#
function convertMDs()
{
local bd
for bd in $@ ; do
local is_part_dev=false
bd=`readlink --canonicalize $bd`
case $bd in
/dev/md[_0-9]*p[0-9]* )
# Partitionable MD RAID -- Drop the partitioning, only need the MD RAID itself.
bd=${bd%p[0-9]*}
is_part_dev=true
;;
/dev/md[0-9_]*)
;;
# All other kinds of real devices -- Collect the device and continue with next
*)
mdblockdev="$mdblockdev $bd"
continue
;;
esac
# Check if this device has already been added (possible for partitionable).
local 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
local dup_found=false
for dup in $md_devs; do
if [ x"$dup" = x"$md_dev" ]; then
dup_found=true
break
fi
done
if $dup_found; then
if ! $is_part_dev; then
echo "setup-md.sh: $md_dev found multiple times" >&2
fi
continue
fi
local mdconf=$(mdadm -Db "$bd")
# If device has not been configured, assume it is a real device and continue with next.
if test -z "$mdconf"; then
mdblockdev="$mdblockdev $bd"
continue
fi
# Fetch the devices from which this MD RAID has been constructed.
md_tmpblockdev=$(mdadm -Dbv $bd | sed -n "1D;s/,/ /g;s/^ *devices=//p")
# Convert any used MD RAID devices in the current MD RAID device to real devices.
convertMDs $md_tmpblockdev
# Collect the current MD RAID for late dup checking.
md_devs="$md_devs $md_dev"
# Handle container definitions correctly, if any.
container=$(echo "$mdconf" | sed -rn 's/.* container=([^ ]*) .*/\1/p')
for cnt in $cont_list; do
if [ x"$container" = x"$cnt" ]; then
container=
break
fi
done
case "$container" in
"")
;;
/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 "setup-md.sh: Unrecognized container for $md_dev: $container" >&2
;;
esac
# If /etc/mdadm.conf contains a different name for this array, use that instead.
md_uuid=`echo $mdconf | sed -n -e 's/.* UUID=\([0-9a-f:]*\).*/\1/p'`
if [ -f /etc/mdadm.conf -a -n "$md_uuid" ]; then
md_devname=`sed -n -e 's,^ARRAY */dev/\([^ ]*\) .*[Uu][Uu][Ii][Dd]='$md_uuid'.*,\1,p' /etc/mdadm.conf`
if [ -n "$md_devname" ]; then
mdconf=`echo $mdconf | sed -e 's,^ARRAY /dev/\([^ ]*\),ARRAY /dev/'$md_devname','`
fi
fi
# Collect used MD RAID device for "/etc/mdadm.conf" configuration to be used in "initrd".
md_conf["$md_dev"]="$mdconf"
root_md=1
done
}
convertMDs $blockdev
# Update "blockdev" with the actual used real devices, in case any MD RAID devices have been used.
blockdev="$mdblockdev"
# If MD RAID device(s) has/have been used, construct a "/etc/mdadm.conf" for the "initrd" file system.
if [ -n "$root_md" ] ; then
need_mdadm=1
echo "AUTO -all" > $tmp_mnt/etc/mdadm.conf
for md in $md_devs; do
echo -e "${md_conf["$md"]}" >> $tmp_mnt/etc/mdadm.conf
done
fi
# If "need_mdadm" has been defined (here or elsewhere), create needed udev rules in the "initrd" file system.
if [ "x$need_mdadm" = "x1" ] ; then
for rule in \
63-md-raid-arrays.rules \
64-md-raid-assembly.rules; do
if [ -f /usr/lib/udev/rules.d/$rule ]; then
cp /usr/lib/udev/rules.d/$rule $tmp_mnt/usr/lib/udev/rules.d
elif [ -f /lib/udev/rules.d/$rule ]; then
cp /lib/udev/rules.d/$rule $tmp_mnt/lib/udev/rules.d
fi
done
fi
save_var need_mdadm