======================================================================== * mkinitrd ======================================================================== #!/bin/bash --norc # # mkinitrd # # Copyright 2005 Red Hat, Inc. # # Written by Erik Troan # # Contributors: # Elliot Lee # Miguel de Icaza # Christian 'Dr. Disk' Hechelmann # Michael K. Johnson # Pierre Habraken # Jakub Jelinek # Carlo Arenas Belon (carenas@chasqui.lared.net.pe> # Keith Owens # Bernhard Rosenkraenzer # Matt Wilson # Trond Eivind Glomsrød # Jeremy Katz # Preston Brown # Bill Nottingham # Guillaume Cottenceau # Peter Jones export MALLOC_PERTURB_=204 PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH export PATH . /etc/rc.d/init.d/functions LC_COLLATE=C export LC_COLLATE # Set the umask. For iscsi, the initrd can contain platintext # password (chap secret), so only allow read by owner. umask 077 VERSION=5.1.19.6 PROBE="yes" MODULES="" PREMODS="" DMDEVS="" NET_LIST="" CFG_DIR=${MKINITRD_CONFIG_DIR:-/etc/sysconfig/mkinitrd} cfgs="$CFG_DIR/*[^~]" for cfg in $cfgs ; do [ -x $cfg ] && . $cfg done CONFMODS="$MODULES" MODULES="" compress=1 allowmissing="" target="" kernel="" force="" verbose="" img_vers="" builtins="" modulefile=/etc/modules.conf withusb=1 if [ "$MULTIPATH" == "no" ]; then withmpath=0 else withmpath=1 fi rc=0 IMAGESIZE=8000 PRESCSIMODS="sd_mod" fstab="/etc/fstab" vg_list="" net_list="$NET_LIST" vecho() { NONL="" if [ "$1" == "-n" ]; then NONL="-n" shift fi [ -n "$verbose" ] && echo $NONL "$@" } error() { NONL="" if [ "$1" == "-n" ]; then NONL="-n" shift fi echo $NONL "$@" >&2 } usage () { if [ "$1" == "-n" ]; then cmd=echo else cmd=error fi $cmd "usage: `basename $0` [--version] [--help] [-v] [-f] [--preload ]" $cmd " [--force-ide-probe] [--force-scsi-probe | --omit-scsi-modules]" $cmd " [--image-version] [--force-raid-probe | --omit-raid-modules]" $cmd " [--with=] [--force-lvm-probe | --omit-lvm-modules]" $cmd " [--builtin=] [--omit-dmraid] [--net-dev=]" $cmd " [--fstab=] [--nocompress] " $cmd "" $cmd " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" if [ "$1" == "-n" ]; then exit 0 else exit 1 fi } moduledep() { vecho -n "Looking for deps of module $1" deps=$(modprobe --set-version $kernel --show-depends $1 2>/dev/null| awk '/^insmod / { print gensub(".*/","","g",$2) }' | while read foo ; do [ "${foo%%.ko}" != "$1" ] && echo -n "${foo%%.ko} " ; done) [ -n "$deps" ] && vecho ": $deps" || vecho } findone() { echo nash-find "$@" | /sbin/nash --force --quiet \ | /bin/awk '{ print $1; exit; }' } findall() { echo nash-find "$@" | /sbin/nash --force --quiet } dm_get_uuid() { echo nash-dm get_uuid "$1" | /sbin/nash --force --quiet } resolve_device_name() { echo nash-resolveDevice "$1" | /sbin/nash --forcequiet } findmodule() { skiperrors="" if [ $1 == "--skiperrors" ]; then skiperrors=--skiperrors shift fi local modName=$1 if [ "$modName" = "off" -o "$modName" = "null" ]; then return fi if [ "$modName" != "${modName##-}" ]; then skiperrors=--skiperrors modName="${modName##-}" fi case "$MODULES " in *"/$modName.ko "*) return ;; esac if echo $builtins | egrep -q '(^| )'$modName'( |$)' ; then vecho "module $modName assumed to be built in" return fi # special cases if [ "$modName" = "i2o_block" ]; then findmodule i2o_core findmodule -i2o_pci modName="i2o_block" elif [ "$modName" = "ppa" ]; then findmodule parport findmodule parport_pc modName="ppa" elif [ "$modName" = "sbp2" ]; then findmodule ieee1394 findmodule ohci1394 modName="sbp2" elif [ "$modName" = "gfs2" ]; then findmodule lock_nolock modName="gfs2" elif [ "$modName" = "nfs" ]; then findmodule sunrpc modName="nfs" elif [ "$modName" = "usb-storage" -o "$modName" = "ub" ]; then usbModName="$modName" fi if [ -n "$usbModName" \ -a "$modName" != "uhci-hcd" \ -a "$modName" != "ohci-hcd" \ -a "$modName" != "ehci-hcd" ]; then withusb=1 findmodule ehci-hcd findmodule ohci-hcd findmodule uhci-hcd usbModName="" fi moduledep $modName for i in $deps; do findmodule $i done for modExt in o.gz o ko ; do for modDir in /lib/modules/$kernel/updates /lib/modules/$kernel ; do if [ -d $modDir ]; then fmPath=$(findone $modDir -name $modName.$modExt) if [ -f "$fmPath" ]; then break 2 fi fi done done if [ ! -f $fmPath ]; then if [ -n "$skiperrors" ]; then return fi # ignore the absence of the scsi modules for n in $PRESCSIMODS; do if [ "$n" = "$modName" ]; then return; fi done; if [ -n "$allowmissing" ]; then error "WARNING: No module $modName found for kernel $kernel, continuing anyway" return fi error "No module $modName found for kernel $kernel, aborting." exit 1 fi # only need to add each module once MODULES="$MODULES $fmPath" # need to handle prescsimods here -- they need to go _after_ scsi_mod if [ "$modName" = "scsi_mod" ]; then for n in $PRESCSIMODS ; do findmodule $n done fi } finddmmods() { line=$(/sbin/dmsetup table "$1" 2>/dev/null) [ -z "$line" ] && return 1 type=$(echo "$line" | awk '{ print $3 }') [ -z "$type" ] && return 1 case "$type" in mirror) findmodule -dm-mirror ;; emc) findmodule -dm-emc findmodule -dm-round-robin ;; multipath) findmodule -dm-multipath findmodule -dm-round-robin ;; crypt) findmodule -dm-crypt ;; zero) findmodule -dm-zero ;; esac } inst() { if [ "$#" != "2" ];then echo "usage: inst " return fi vecho "$1 -> $2" cp $1 $2 } readlink() { echo nash-readlink "$1" | /sbin/nash --force --quiet } access() { echo nash-access "$@" | /sbin/nash --force --quiet } findstoragedriverinsys () { while [ ! -L device ]; do [ "$PWD" = "/sys" ] && return cd .. done cd $(readlink ./device) if is_iscsi $PWD; then handleiscsi "$PWD" return fi while [ ! -f modalias ]; do [ "$PWD" = "/sys/devices" ] && return cd .. done moduledep $(cat modalias) [ -z "$deps" -a -L driver/module ] && deps=$(basename $(readlink driver/module)) for driver in $deps ; do findmodule $driver done } findstoragedriver () { for device in $@ ; do case " $handleddevices " in *" $device "*) continue ;; *) handleddevices="$handleddevices $device" ;; esac if [[ "$device" =~ "md[0-9]+" ]]; then vecho "Found RAID component $device" handleraid "$device" continue fi vecho "Looking for driver for device $device" sysfs=$(findone -type d /sys/block -name $device) [ -z "$sysfs" ] && return pushd $sysfs >/dev/null 2>&1 findstoragedriverinsys popd >/dev/null 2>&1 done } findnetdriver() { for device in $@ ; do case " $handleddevices " in *" $device "*) continue ;; *) handleddevices="$handleddevices $device" ;; esac if [ -f /sys/class/net/$device/device/modalias ]; then modalias=$(cat /sys/class/net/$device/device/modalias) moduledep $modalias for driver in $deps ; do findmodule $driver done elif [ "$(basename $(readlink /sys/class/net/$device/device/bus) 2>/dev/null)" = "xen" ]; then findmodule xennet # FIXME: hack for xennet sucking else findmodule $(ethtool -i $device | awk '/^driver:/ { print $2 }') fi done } iscsi_get_rec_val() { # The open-iscsi 742 release changed to using flat files in # /var/lib/iscsi. result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = " | \ sed -e 's/.* = //') } iscsi_set_parameters() { path=$1 vecho setting iscsi parameters # Check once before getting explicit values, so we can output a decent # error message. if ! /sbin/iscsiadm -m session -r ${path} >/dev/null ; then echo Unable to find iscsi record for $path exit 1 fi nit_name=$(grep "^InitiatorName=" /etc/iscsi/initiatorname.iscsi | \ sed -e "s/^InitiatorName=//") iscsi_get_rec_val $path "node.name"; tgt_name=${result} iscsi_get_rec_val $path "node.tpgt"; tpgt=${result} iscsi_get_rec_val $path "node.conn\[0\].address"; tgt_ipaddr=${result} iscsi_get_rec_val $path "node.conn\[0\].port"; tgt_port=${result} # Note: we get chap secrets (passwords) in plaintext, and also store # them in the initrd. iscsi_get_rec_val $path "node.session.auth.username" chap=${result} if [ -n "${chap}" -a "${chap}" != "" ]; then chap="-u ${chap}" iscsi_get_rec_val $path "node.session.auth.password" chap_pw="-w ${result}" else chap="" fi iscsi_get_rec_val $path "node.session.auth.username_in" chap_in=${result} if [ -n "${chap_in}" -a "${chap_in}" != "" ]; then chap_in="-U ${chap_in}" iscsi_get_rec_val $path "node.session.auth.password_in" chap_in_pw="-W ${result}" else chap_in="" fi } emit_iscsi () { if [ -n "${iscsi_devs}" ]; then inst /sbin/iscsistart "$MNTIMAGE/bin/iscsistart" emit "echo Attaching to iSCSI storage" for dev in ${iscsi_devs}; do iscsi_set_parameters $dev # recid is not really used, just use 0 for it emit "/bin/iscsistart -t ${tgt_name} -i ${nit_name} \ -g ${tpgt} -a ${tgt_ipaddr} ${chap} ${chap_pw} \ ${chap_in} ${chap_in_pw}" done fi } is_iscsi() { path=$1 if echo $path | grep -q "/platform/host[0-9]*/session[0-9]*/target[0-9]*:[0-9]*:[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*"; then return 0 else return 1 fi } handleiscsi() { vecho "Found iscsi component $1" findmodule iscsi_tcp # We call iscsi_set_parameters once here to figure out what network to # use (it sets tgt_ipaddr), and once again to emit iscsi values, # not very efficient. iscsi_set_parameters $1 iscsi_devs="$iscsi_devs $1" netdev=$(/sbin/ip route get to $tgt_ipaddr | \ sed 's|.*dev \(.*\).*|\1|g' | awk '{ print $1; exit }') addnetdev $netdev } handleraid() { local start=0 if [ -n "$noraid" -o ! -f /proc/mdstat ]; then return 0 fi levels=$(awk "/^$1[ ]*:/ { print\$4 }" /proc/mdstat) devs=$(awk "/^$1[ ]*:/ { print gensub(\"[[0-9]*]\",\"\",\"g\",gensub(\"^md.*raid[0-9]*\",\"\",\"1\")) }" /proc/mdstat) for level in $levels ; do case $level in linear) findmodule linear start=1 ;; multipath) findmodule multipath start=1 ;; raid[01456] | raid10) findmodule $level start=1 ;; *) error "raid level $level (in /proc/mdstat) not recognized" ;; esac done findstoragedriver $devs if [ "$start" = 1 ]; then raiddevices="$raiddevices $1" fi return $start } handlelvordev() { local vg=`lvm.static lvs --ignorelockingfailure --noheadings -o vg_name $1 2>/dev/null` if [ -n "$vg" ]; then vg=`echo $vg` # strip whitespace case " $vg_list " in *" $vg "*) ;; *) vg_list="$vg_list $vg" for device in `lvm.static vgdisplay --ignorelockingfailure -v $vg 2>/dev/null | sed -n 's/PV Name//p'`; do findstoragedriver ${device##/dev/} done ;; esac else findstoragedriver ${1##/dev/} fi } handlenetdev() { local dev=$1 source /etc/sysconfig/network if [ ! -f /etc/sysconfig/network-scripts/ifcfg-$dev ]; then error "unable to find network device configuration for $dev" else source /etc/sysconfig/network-scripts/ifcfg-$dev fi if [ x"$BOOTPROTO" = x ]; then error "bootproto not specified for $dev, assuming DHCP" BOOTPROTO=dhcp fi [ -n "$IPADDR" ] && IPSTR="$IPSTR --ip $IPADDR" [ -n "$NETMASK" ] && IPSTR="$IPSTR --netmask $NETMASK" [ -n "$GATEWAY" ] && IPSTR="$IPSTR --gateway $GATEWAY" [ -n "$ETHTOOL_OPTS" ] && IPSTR="$IPSTR --ethtool \"$ETHTOOL_OPTS\"" [ -n "$MTU" ] && IPSTR="$IPSTR --mtu $MTU" if [ -n "$IPADDR" ]; then [ -z "$DOMAIN" ] && DOMAIN=$(awk '/^search / { print gensub("^search ","",1) }' /etc/resolv.conf) if [ -z "$DNS1" ]; then DNS1=$(awk '/^nameserver / { ORS="" ; if (x > 0) print "," ; printf "%s", $2 ; x = 1}' /etc/resolv.conf) fi fi [ -n "$DOMAIN" ] && IPSTR="$IPSTR --domain \"$DOMAIN\"" if [ -n "$DNS1" ]; then if [ -n "$DNS2" ]; then IPSTR="$IPSTR --dns $DNS1,$DNS2" else IPSTR="$IPSTR --dns $DNS1" fi fi network="network --device $dev --bootproto $BOOTPROTO $IPSTR" if [ "$BOOTPROTO" = "dhcp" ]; then dhclient_leases_cmd="cp /var/lib/dhclient/dhclient.leases /sysroot/dev/.dhclient-$dev.leases" mkdir -p $MNTIMAGE/var/lib/dhclient fi } addnetdev() { dev=$1 vecho "Adding network device $dev" findnetdriver $dev net_list="$net_list $netdev" } handlenfs() { remote=${1%%:*} remoteip=$(host $remote | awk '/ address / { print $4 }') # assume, if it didn't resolve, that it's an IP [ -z "$remoteip" ] && remoteip=$remote netdev=`/sbin/ip route get to $remoteip |sed 's|.*dev \(.*\).*|\1|g' |awk '{ print $1; exit }'` addnetdev $netdev } while [ $# -gt 0 ]; do case $1 in --fstab*) if [ "$1" != "${1##--fstab=}" ]; then fstab=${1##--fstab=} else fstab=$2 shift fi ;; --with-usb*) if [ "$1" != "${1##--with-usb=}" ]; then usbmodule=${1##--with-usb=} else usbmodule="usb-storage" fi basicmodules="$basicmodules $usbmodule" unset usbmodule ;; --without-usb) withusb=0 ;; --with*) if [ "$1" != "${1##--with=}" ]; then modname=${1##--with=} else modname=$2 shift fi basicmodules="$basicmodules $modname" ;; --builtin*) if [ "$1" != "${1##--builtin=}" ]; then modname=${1##--builtin=} else modname=$2 shift fi builtins="$builtins $modname" ;; --version) echo "mkinitrd: version $VERSION" exit 0 ;; -v) verbose=-v ;; --nocompress) compress="" ;; --ifneeded) # legacy ;; -f) force=1 ;; --preload*) if [ "$1" != "${1##--preload=}" ]; then modname=${1##--preload=} else modname=$2 shift fi PREMODS="$PREMODS $modname" ;; --force-scsi-probe) forcescsi=1 ;; --omit-scsi-modules) PRESCSIMODS="" noscsi=1 ;; --force-raid-probe) forceraid=1 ;; --omit-raid-modules) noraid=1 ;; --force-lvm-probe) forcelvm=1 ;; --omit-lvm-modules) nolvm=1 ;; --omit-dmraid) nodmraid=1 ;; --force-ide-probe) forceide=1 ;; --image-version) img_vers=yes ;; --allow-missing) allowmissing=yes ;; --net-dev*) if [ "$1" != "${1##--net-dev=}" ]; then net_list="$net_list ${1##--net-dev=}" else net_list="$net_list $2" shift fi ;; --noresume) noresume=1 ;; --rootdev*) if [ "$1" != "${1##--rootdev=}" ]; then rootdev="${1##--rootdev=}" else rootdev="$2" shift fi ;; --rootfs*) if [ "$1" != "${1##--rootfs=}" ]; then rootfs="${1##--rootfs=}" else rootfs="$2" shift fi ;; --rootopts*) if [ "$1" != "${1##--rootopts=}" ]; then rootopts="${1##--rootopts=}" else rootopts="$2" shift fi ;; --loopdev*) if [ "$1" != "${1##--loopdev=}" ]; then loopdev="${1##--loopdev=}" else loopdev="$2" shift fi ;; --loopfs*) if [ "$1" != "${1##--loopfs=}" ]; then loopfs="${1##--loopfs=}" else loopfs="$2" shift fi ;; --loopopts*) if [ "$1" != "${1##--loopopts=}" ]; then loopopts="${1##--loopopts=}" else loopopts="$2" shift fi ;; --looppath*) if [ "$1" != "${1##--looppath=}" ]; then looppath="${1##--looppath=}" else looppath="$2" shift fi ;; --help) usage -n ;; *) if [ -z "$target" ]; then target=$1 elif [ -z "$kernel" ]; then kernel=$1 else usage fi ;; esac shift done if [ -z "$target" -o -z "$kernel" ]; then usage fi if [ -n "$img_vers" ]; then target="$target-$kernel" fi if [ -z "$force" -a -f $target ]; then error "$target already exists." exit 1 fi if [ -n "$forcescsi" -a -n "$noscsi" ]; then error "Can't both force scsi probe and omit scsi modules" exit 1 fi if [ -n "$forceraid" -a -n "$noraid" ]; then error "Can't both force raid probe and omit raid modules" exit 1 fi if [ -n "$forcelvm" -a -n "$nolvm" ]; then error "Can't both force LVM probe and omit LVM modules" exit 1 fi if [ ! -d /lib/modules/$kernel ]; then error 'No modules available for kernel "'${kernel}'".' exit 1 fi if [ $UID != 0 ]; then error "mkinitrd must be run as root." exit 1 fi vecho "Creating initramfs" modulefile=/etc/modprobe.conf # find a temporary directory which doesn't use tmpfs if [ -z "$loopfs" ]; then TMPDIR="/tmp" else TMPDIR="" for t in /tmp /var/tmp /root ${PWD}; do if [ ! -d $t ]; then continue; fi if ! access -w $t ; then continue; fi fs=$(df -T $t 2>/dev/null | awk '{line=$1;} END {printf $2;}') if [ "$fs" != "tmpfs" ]; then TMPDIR=$t break fi done fi if [ -z "$TMPDIR" ]; then error "no temporary directory could be found." exit 1 fi if [ $TMPDIR = "/root" -o $TMPDIR = "${PWD}" ]; then error "WARNING: using $TMPDIR for temporary files" fi for n in $PREMODS; do findmodule $n done if [ -n "$withusb" ]; then findmodule uhci-hcd findmodule ohci-hcd findmodule ehci-hcd fi if [ "x$PROBE" == "xyes" ]; then [ -z "$rootfs" ] && rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' $fstab) [ -z "$rootopts" ] && rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' $fstab) [ -z "$rootopts" ] && rootopts="defaults" # in case the root filesystem is modular findmodule -${rootfs} [ -z "$rootdev" ] && rootdev=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $fstab) # check if it's nfsroot if [ "$rootfs" == "nfs" -a "x$net_list" == "x" ]; then handlenfs $rootdev # check if it's root by label elif [ "$rootdev" != "${rootdev##LABEL=}" -o \ "$rootdev" != "${rootdev##UUID=}" ]; then rootopts=$(echo $rootopts | sed -e 's/^r[ow],//' -e 's/,_netdev//' -e 's/_netdev//' -e 's/,r[ow],$//' -e 's/,r[ow],/,/' -e 's/^r[ow]$/defaults/' -e 's/$/,ro/') devname=$(resolve_device_name $rootdev) majmin=$(get_numeric_dev dec $devname) if [ -n "$majmin" ]; then dev=$(findall /sys/block -name dev | while read device ; do \ echo "$majmin" | cmp -s $device && echo $device ; done \ | sed -e 's,.*/\([^/]\+\)/dev,\1,' ) if [ -n "$dev" ]; then vecho "Found root device $dev for $rootdev" rootdev=$dev fi fi else rootopts=$(echo $rootopts | sed -e 's/^r[ow],//' -e 's/,_netdev//' -e 's/_netdev//' -e 's/,r[ow],$//' -e 's/,r[ow],/,/' -e 's/^r[ow]$/defaults/' -e 's/$/,ro/') fi [ "$rootfs" != "nfs" ] && handlelvordev $rootdev # find the first swap dev which would get used for swsusp swsuspdev=$(awk '/^[ \t]*[^#]/ { if ($3 == "swap") { print $1; exit }}' $fstab) if [ "$swsuspdev" = "${swsuspdev##LABEL=}" -o \ "$swsuspdev" = "${swsuspdev##UUID=}" ]; then handlelvordev $swsuspdev fi fi if [ -n "$forcescsi" -o -z "$noscsi" -a "x$PROBE" == "xyes" ]; then if [ ! -f $modulefile ]; then modulefile=/etc/conf.modules fi if [ -f $modulefile ]; then scsimodules=`grep "alias[[:space:]]\+scsi_hostadapter" $modulefile | grep -v '^[ ]*#' | LC_ALL=C sort -u | awk '{ print $3 }'` if [ -n "$scsimodules" ]; then for n in $scsimodules; do # for now allow scsi modules to come from anywhere. There are some # RAID controllers with drivers in block/ findmodule $n done fi fi fi # If we have ide devices and module ide, do the right thing ide=/proc/ide/ide* if [ -n "$forceide" -o -n "$ide" -a "x$PROBE" == "xyes" ]; then findmodule -ide-disk fi # If we have dasd devices, include the necessary modules (S/390) if [ "x$PROBE" == "xyes" -a -d /proc/dasd ]; then findmodule -dasd_mod findmodule -dasd_eckd_mod findmodule -dasd_fba_mod fi # Loopback root support # loopdev : device or nfs server:path file is on # looppath : filename # loopfs : filesystem of loopdev # loopots : options to mount loopfs if [ -n "${loopfs}" ] || [[ "$rootopts" =~ "loop" ]]; then # FIXME: probe this somehow? rootdev=/dev/loop0 [ -z "$rootopts" ] && rootopts="defaults" findmodule loop findmodule -${loopfs} if [ "$loopfs" == "nfs" -a "x$net_list" == "x" ]; then handlenfs $loopdev fi # FIXME: label support [ "$loopfs" != "nfs" ] && handlelvordev $loopdev fi # If we use LVM or dm-based raid, include dm-mod # XXX: dm not really supported yet. testdm="" [ -n "$vg_list" ] && testdm="yes" [ -n "$forceraid" -o -n "$forcelvm" ] && testdm="yes" [ -z "$nolvm" -o -z "$noraid" ] && testdm="yes" [ "x$PROBE" != "xyes" ] && testdm="" if [ -n "$testdm" -a -x /sbin/dmsetup -a -e /dev/mapper/control ]; then dmout=$(/sbin/dmsetup ls 2>/dev/null) if [ "$dmout" != "No devices found" -a "$dmout" != "" ]; then findmodule -dm-mod # DM requires all of these to be there in case someone used the # feature. broken. (#132001) findmodule -dm-mirror findmodule -dm-zero findmodule -dm-snapshot RAIDS=$(/sbin/dmraid -s -craidname 2>/dev/null | grep -vi "no raid disks") # I fucking hate shell. lineno=1 PREV="" LINE="" while :; do PREV="$LINE" LINE=$(/sbin/dmsetup table | head -$lineno | tail -1) if [ "$LINE" == "$PREV" ]; then break; fi eval $(echo $LINE | \ while read NAME START END TYPE TABLE ; do echo NAME=\"$(sed 's/:$//'<<< "$NAME")\" echo START=\"$START\" echo END=\"$END\" echo TYPE=\"$TYPE\" echo TABLE=\"$TABLE\" done) case "$TYPE" in multipath|emc) [ "$withmpath" == "0" ] && continue # ugggh. We could try to fish the module name out, but it # requires real parsing... # XXX also covered by #132001 for mod in $TABLE ; do DMMODS="$DMMODS $([[ "$mod" =~ "[[:alpha:]]" ]] && echo "$mod")" done DMDEVS="$DMDEVS $NAME" ;; *) for raid in $RAIDS ; do if [ "$raid" == "$NAME" ]; then dmname=$(resolve_dm_name $NAME) DMDEVS="$DMDEVS $dmname" RAIDS=$(sed 's/ $NAME //' <<< "$RAIDS") break fi done ;; esac lineno=$(($lineno + 1)) done for mod in $(tr ' ' '\n' <<< $DMMODS | sort -u) ; do findmodule -dm-$mod done DMDEVS=$(tr ' ' '\n' <<< $DMDEVS | sort -u) fi fi for n in $basicmodules; do findmodule $n done for n in $CONFMODS; do findmodule $n done finddmmods vecho "Using modules: $MODULES" MNTIMAGE=`mktemp -d ${TMPDIR}/initrd.XXXXXX` IMAGE=`mktemp ${TMPDIR}/initrd.img.XXXXXX` RCFILE=$MNTIMAGE/init cemit() { cat >> $RCFILE } emit() { NONL="" if [ "$1" == "-n" ]; then NONL="-n" shift fi echo $NONL "$@" >> $RCFILE } emitdm() { vecho "Adding dm map \"$1\"" UUID=$(dm_get_uuid "$1") if [ -n "$UUID" ]; then UUID="--uuid $UUID" fi emit dm create "$1" $UUID $(/sbin/dmsetup table "$1") } emitdms() { [ -z "$DMDEVS" ] && return 0 echo dm list $DMDEVS | nash --force --quiet | while read ACTION NAME ; do case $ACTION in rmparts) emit rmparts "$NAME" ;; create) emitdm "$NAME" ;; part) emit dm partadd "$NAME" ;; esac done } if [ -z "$MNTIMAGE" -o -z "$IMAGE" ]; then error "Error creating temporaries. Try again" exit 1 fi mkdir -p $MNTIMAGE mkdir -p $MNTIMAGE/lib mkdir -p $MNTIMAGE/bin mkdir -p $MNTIMAGE/etc mkdir -p $MNTIMAGE/dev mkdir -p $MNTIMAGE/proc mkdir -p $MNTIMAGE/sys mkdir -p $MNTIMAGE/sysroot ln -s bin $MNTIMAGE/sbin if [ -e /etc/fstab.sys ]; then inst /etc/fstab.sys "$MNTIMAGE/etc/fstab.sys" fi inst /sbin/nash "$MNTIMAGE/bin/nash" inst /sbin/insmod.static "$MNTIMAGE/bin/insmod" ln -s /sbin/nash $MNTIMAGE/sbin/modprobe for MODULE in $MODULES; do if [ -x /usr/bin/strip ]; then /usr/bin/strip -g $verbose $MODULE -o $MNTIMAGE/lib/$(basename $MODULE) else cp $verbose -a $MODULE $MNTIMAGE/lib fi done # mknod'ing the devices instead of copying them works both with and # without devfs... mkdir $MNTIMAGE/dev/mapper mknod $MNTIMAGE/dev/ram0 b 1 0 mknod $MNTIMAGE/dev/ram1 b 1 1 ln -sf ram1 $MNTIMAGE/dev/ram mknod $MNTIMAGE/dev/null c 1 3 mknod $MNTIMAGE/dev/zero c 1 5 mknod $MNTIMAGE/dev/systty c 4 0 if ! echo "$(uname -m)" | grep -q "s390"; then for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do mknod $MNTIMAGE/dev/tty$i c 4 $i done fi for i in 0 1 2 3 ; do mknod $MNTIMAGE/dev/ttyS$i c 4 $(($i + 64)) done mknod $MNTIMAGE/dev/tty c 5 0 mknod $MNTIMAGE/dev/console c 5 1 mknod $MNTIMAGE/dev/ptmx c 5 2 mknod $MNTIMAGE/dev/rtc c 10 135 if [ "$(uname -m)" == "ia64" ]; then mknod $MNTIMAGE/dev/efirtc c 10 136 fi # FIXME -- this can really go poorly with clvm or duplicate vg names. # nash should do lvm probing for us and write its own configs. if [ -n "$vg_list" ]; then inst /sbin/lvm.static "$MNTIMAGE/bin/lvm" if [ -f /etc/lvm/lvm.conf ]; then cp $verbose --parents /etc/lvm/lvm.conf $MNTIMAGE/ fi fi echo -n >| $RCFILE cemit << EOF #!/bin/nash mount -t proc /proc /proc setquiet echo Mounting proc filesystem echo Mounting sysfs filesystem mount -t sysfs /sys /sys echo Creating /dev mount -o mode=0755 -t tmpfs /dev /dev mkdir /dev/pts mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts mkdir /dev/shm mkdir /dev/mapper echo Creating initial device nodes mknod /dev/null c 1 3 mknod /dev/zero c 1 5 mknod /dev/systty c 4 0 mknod /dev/tty c 5 0 mknod /dev/console c 5 1 mknod /dev/ptmx c 5 2 mknod /dev/rtc c 10 135 EOF if [ "$(uname -m)" == "ia64" ]; then emit "mknod /dev/efirtc c 10 136" fi # XXX really we need to openvt too, in case someting changes the # color palette and then changes vts on fbcon before gettys start. # (yay, fbcon bugs!) if ! echo "$(uname -m)" | grep -q "s390"; then for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do emit "mknod /dev/tty$i c 4 $i" done fi for i in 0 1 2 3 ; do emit "mknod /dev/ttyS$i c 4 $(($i + 64))" done emit "echo Setting up hotplug." emit "hotplug" emit "echo Creating block device nodes." emit "mkblkdevs" usb_mounted="prep" scsi="" for MODULE in $MODULES; do text="" module=`echo $MODULE | sed -e "s|.*/||" -e "s/.k\?o$//"` fullmodule=`echo $MODULE | sed "s|.*/||"` options=`sed -n -e ':a' -e '/\\\\$/N; s/\\\\\n//; ta' -e "s/^options[ ][ ]*$module[ ][ ]*//p" $modulefile 2>/dev/null` if [ -n "$options" ]; then vecho "Adding module $module$text with options $options" else vecho "Adding module $module$text" fi # we mount usbfs before the first module *after* the HCDs if [ "$usb_mounted" == "prep" ]; then if [[ "$module" =~ ".hci[_-]hcd" ]]; then usb_mounted="no" fi elif [ "$usb_mounted" == "no" ]; then if [[ ! "$module" =~ ".hci[_-]hcd" ]]; then usb_mounted=yes emit "mount -t usbfs /proc/bus/usb /proc/bus/usb" fi fi emit "echo \"Loading $fullmodule module\"" emit "insmod /lib/$fullmodule $options" # Hack - we need a delay after loading usb-storage to give things # time to settle down before we start looking a block devices if [ "$module" = "usb-storage" -o "$module" = "ub" ]; then emit "echo Waiting for driver initialization." emit "stabilized /proc/bus/usb/devices" fi if [ "$module" = "sbp2" ]; then emit "echo Waiting for driver initialization." emit "stabilized /sys/bus/ieee1394/drivers/sbp2" fi if [ "$module" = "scsi_mod" ]; then scsi="yes" fi if [ "$module" = "zfcp" -a -f /etc/zfcp.conf ]; then emit "echo Waiting 2 seconds for driver initialization." emit "sleep 2" cat /etc/zfcp.conf | grep -v "^#" | tr "A-Z" "a-z" | while read DEVICE TWO THREE FOUR FIVE; do if [ -z "$FIVE" ]; then WWPN=$TWO FCPLUN=$THREE else WWPN=$THREE FCPLUN=$FIVE fi cemit < /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/port_add echo -n $FCPLUN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/unit_add echo -n 1 > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/online EOF done fi done unset usb_mounted if [ -n "$scsi" ]; then emit "echo Waiting for driver initialization." emit "stabilized --hash --interval 250 /proc/scsi/scsi" fi if [ -n "$vg_list" ]; then emit "echo Making device-mapper control node" emit "mkdmnod" fi if [ -n "$net_list" ]; then for netdev in $net_list; do emit "echo Bringing up $netdev" handlenetdev $netdev emit $network done fi emit_iscsi # HACK: module loading + device creation isn't necessarily synchronous... # this will make sure that we have all of our devices before trying # things like RAID or LVM emit "mkblkdevs" emitdms if [ -n "$raiddevices" ]; then for dev in $raiddevices; do cp -a /dev/${dev} $MNTIMAGE/dev emit "raidautorun /dev/${dev}" done fi if [ -n "$vg_list" ]; then emit "echo Scanning logical volumes" emit "lvm vgscan --ignorelockingfailure" emit "echo Activating logical volumes" emit "lvm vgchange -ay --ignorelockingfailure $vg_list" fi if [ -z "$noresume" -a -n "$swsuspdev" ]; then emit "resume $swsuspdev" fi if [ -n "$loopfs" ]; then emit "echo Mounting loop backing store." emit "mkdir /tmpmount" emit "mount -t $loopfs -o ${loopopts:-defaults} $loopdev /tmpmount" emit "echo Creating loop device." emit "losetup /dev/loop0 /tmpmount/$looppath" fi emit "echo Creating root device." # mkrootdev does "echo /dev/root /sysroot ext3 defaults,ro 0 0 >/etc/fstab" emit "mkrootdev -t $rootfs -o $rootopts $rootdev" rootdev=/dev/root emit "echo Mounting root filesystem." emit "mount /sysroot" if [ -n "$loopfs" ]; then emit "Cleaning up loop mount." emit "umount /tmpmount" fi emit "echo Setting up other filesystems." emit "setuproot" if [ -n "$dhclient_leases_cmd" ]; then emit "echo Copying DHCP lease" emit "$dhclient_leases_cmd" fi emit "echo Switching to new root and running init." emit "switchroot" chmod +x $RCFILE (cd $MNTIMAGE; findall . | cpio --quiet -c -o) >| $IMAGE || exit 1 if [ -n "$compress" ]; then gzip -9 < $IMAGE >| $target || rc=1 else cp -a $IMAGE $target || rc=1 fi rm -rf $MNTIMAGE $IMAGE if [ -n "$MNTPOINT" ]; then rm -rf $MNTPOINT ; fi exit $rc # vim:ts=8:sw=4:sts=4:et