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
openSUSE Build Service is sponsored by