# # Template -- for translation general intentions to exact initrd layout # Copyright (C) 2005 Erik van Konijnenburg, Marco Amadori # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # These templates define the translation from general intentions in the # plan to exact lists of files and script fragments to be included # on the initrd image. Templates are indexed by an action name, and include: # - files to be copied from current system to initrd; # often executables. # - directories to be created # - fragments to be appended to scripts on the image, # these are in a hash from script name to script content. # # Everything is processed by HTML::Template before being added to the # image: script fragments, but also file names and script names. # Leading spaces are dropped from template lines. # # If you want to implement busybox support, this is the place to do it. # # Obviously, the template names and the attributes used in the template # should match what is provided by the planner. # # TEMPLATE SET TEMPLATE prologue BEGIN # In principle, we don't want device files on the initrd # image: device numbers can change between kernels. # Instead, create device files at boot time based on info # in sysfs. However, /dev/null and /dev/console are needed # to mount sysfs. FILE "/dev/null" FILE "/dev/console" FILE "/bin/dash" FILE "/bin/cat" FILE "/bin/mkdir" FILE "/bin/mount" FILE "/bin/umount" FILE "/bin/mknod" FILE "/sbin/pivot_root" FILE "/usr/sbin/chroot" FILE "/bin/sleep" FILE "/bin/ls" FILE "/usr/bin/awk" FILE "/run_init" DIRECTORY "/mnt" DIRECTORY "/proc" DIRECTORY "/sys" DIRECTORY "/dev" DIRECTORY "/etc" DIRECTORY "/var" # # We can provide debugging opportunities in the # initramfs image; the question is when and how # to enable this. Consider two types of user: # - a developer, working on the template # - an end user, who has a boot problem with # an image that was generated automatically # after installing a new distribution kernel. # # The developer can simply add debugging code # to the template. # For the end user, adding an option to the kernel # command line is easier to enable debugging # than rebuilding the boot image with special # options or a modified configuration file. # # For this reason, we won't provide a template # parameter to control debugging, instead we # interpret a new kernel command line parameter: # ydebug. # SCRIPT "/init" BEGIN !#!/bin/dash !# !# Generator version: yaird . !# Kernel version: . !# !INIT_DEBUG= !if [ "$INIT_DEBUG" != "" ] !then ! set -x !fi ! !# !# Utility functions !# !mksymdev () { ! devfile="$1" ! sysfile="$2" ! cb="$3" ! devpair=$(/bin/cat "$sysfile") ! for delay in 1 2 4 8 16 ! do ! if [ "$devpair" = "" ] ! then ! echo "Waiting $delay seconds for $sysfile to show up" ! sleep $delay ! fi ! devpair=$(/bin/cat "$sysfile") ! done ! ! if [ "$devpair" = "" ] ! then ! echo "Device $sysfile seems to be down." ! if [ "$INIT_DEBUG" != "" ] ! then ! echo "Debugging opportunity, type ^D to continue." ! /bin/dash ! fi ! fi ! ! maj=${devpair%:*} ! min=${devpair#*:} ! /bin/mknod "$devfile" $cb $maj $min !} !mkcdev () { ! mksymdev "$1" "/sys/class/$2/dev" c !} !mkbdev () { ! mksymdev "$1" "/sys/block/$2/dev" b !} ! !switchroot () { ! if [ "$INIT_DEBUG" != "" ] ! then ! echo "Debugging opportunity, ^D to continue." ! /bin/dash ! fi ! ! echo "Switching root ..." ! /bin/umount -n /sys ! /bin/umount -n /proc ! ! echo "Waiting for rootfs ..." ! if [ -x /run_init ] ; then ! exec /run_init \ ! /mnt $init -- "$@" ! result=$? ! if [ "$result" -ne 0 ] ; then ! echo "run_init failed" ! sleep 15 ! fi ! else ! echo "run_init not found" ! sleep 15 ! fi !} ! !# !# Setting up mounts !# !/bin/mount -nt sysfs sysfs /sys !/bin/mount -nt proc proc /proc !# !# We don't set up a separate /dev file system, !# since rootfs is writable without problem. !# ! !# /dev/tty is needed for eg cryptsetup. !mkcdev /dev/tty tty/tty ! !# !# Command line processing !# init - first proc to start on next root !# root - to be done: how should it relate !# to file system selection? !# ro,rw - mount root read-only or read-write. !# This is like a mount -r; it overrules !# a -o rw. !# noresume, resume= - should we resume from a !# suspend-to-disk? The resume parameter !# is optional, but overrides automatic !# detection of the resume partition if present. !# noresume prevents us from attempting to resume. !# ide - options for module ide_core. !# need a way to append these to proper !# module. do a check on module name !# in insmod template? !# ip=, nfsaddrs=, nfsroot= - support NFS boot !# !ro=-r !ip= !nfsroot= !noresume= !resume= !resume2= !rootwait=0 !blkfsdelay=7 !init=/sbin/init !for i in $(cat /proc/cmdline) !do ! case "$i" in ! init=*) ! init=${i#init=} ! ;; ! ro) ! ro=-r ! ;; ! rw) ! ro= ! ;; ! ip=*|nfsaddrs=*) ! ip="$ip $i" ! ;; ! nfsroot=*) ! nfsroot="$i" ! ;; ! noresume) ! noresume=1 ! ;; ! resume=*) ! resume=${i#resume=} ! ;; ! resume2=*) ! resume=${i#resume=} ! ;; ! blkfsdelay=*) ! blkfsdelay=${i#blkfsdelay=} ! ;; ! rootfs=*) ! rootfs=${i#rootfs=} ! ;; ! rootwait) ! rootwait=1 ! ;; ! ydebug) ! INIT_DEBUG=yes ! ;; ! esac !done !if [ "$INIT_DEBUG" != "" ] !then ! set -x !fi END SCRIPT END TEMPLATE TEMPLATE insmod BEGIN FILE "" FILE "/sbin/insmod" # optionList may be undef # and already is suitably escaped. SCRIPT "/init" BEGIN !/sbin/insmod '' END SCRIPT END TEMPLATE TEMPLATE mkbdev BEGIN SCRIPT "/init" BEGIN !mkbdev '' '' !dyn_mkblkdev() { ! echo waiting $blkfsdelay for block devices ! sleep $blkfsdelay ! MKBLKDEV=done ! IFS= ! dash -c `awk '/^ [0-9]/ {print("/bin/mknod /dev/" $4 " b " $1 " " $2" ")}' /proc/partitions` > /dev/null 2>&1 ! #may be able to use these to wait for device partition scanning to complete ! #cat /sys/block/sda/device/device_blocked ! #cat /sys/block/sda/device/state ! unset IFS ! echo made special block devices !} !if [ -z "$MKBLKDEV" ] ; then ! dyn_mkblkdev !fi END SCRIPT END TEMPLATE TEMPLATE evms_activate BEGIN # # Note that evms_active will not do a single device, # but everything it encounters. # TREE "/lib/evms/" FILE "/sbin/evms_activate" FILE "/etc/evms.conf" SCRIPT "/init" BEGIN !# activate for !if [ ! -c /dev/evms ] !then ! /bin/mkdir /dev/evms !fi !/sbin/evms_activate END SCRIPT END TEMPLATE # # We cannot make mapper/control any earlier, # since dm-mod needs to be loaded to be able # to determine devno. # # Hmm. cf debian bug 335315. The config file is needed # on machines where an LVM volume is on an encrypted # partition. However, requiring this might get in # the way of machines that do not have a config file. # TEMPLATE vgchange BEGIN FILE "/etc/lvm/lvm.conf" # Older Debian releases needs this one #FILE "/lib/lvm-200/vgchange" FILE "/sbin/vgchange" SCRIPT "/init" BEGIN !if [ ! -c /dev/mapper/control ] !then ! /bin/mkdir /dev/mapper ! mkcdev /dev/mapper/control misc/device-mapper !fi !/sbin/vgchange -a y '' END SCRIPT END TEMPLATE # # NOTE: mdadm can operate without knowledge # of device numbers; it will assign an unused # one to the new device. Thus you could have # device name /dev/md/boot that is stable, # regardless of which other raid devices are # operational. However, debian installer # consistently uses device names like /dev/md0, # where the name depends on earlier minors # that happen to have been assigned. # To work around this problem, we forego # the --auto option, and mknod the device # before putting an md under it. Better hope # the major number is not going to change ... # TEMPLATE mdadm BEGIN FILE "/sbin/mdadm" SCRIPT "/init" BEGIN !mknod b ! ! mdadm -Ac partitions --run --uuid ! ! mdadm --assemble --run --uuid \ ! ! END SCRIPT END TEMPLATE # # cryptsetup arguments: # - target # - cipher # - keySize (always there, 0 for NULL crypto) # - hash (hashname or undef) # - src # - verify (yes or undef) # # A loop around 'cryptsetup --verify' can help detect # and correct typo's in the crypt password. # TEMPLATE cryptsetup BEGIN FILE "/sbin/cryptsetup" FILE "/bin/loadkeys" FILE "/bin/gzip" FILE "/etc/console/boottime.kmap.gz" FILE "/sbin/blkid" SCRIPT "/init" BEGIN !# loadkeys from the kbd package has problems !# uncompressing the keymap on-the-fly when !# run from initramfs, don't know why !if [ -e /etc/console/boottime.kmap.gz ] !then ! gzip -d /etc/console/boottime.kmap.gz !fi !if [ -e /etc/console/boottime.kmap ] !then ! loadkeys /etc/console/boottime.kmap !fi !DOCRYPT=1 !while [ "$DOCRYPT" != "0" ] !do ! /sbin/cryptsetup \ ! -c \ ! -s \ ! \ ! -h '' \ ! \ ! -y \ ! create '' \ ! '' ! DOCRYPT=$? ! while [ "$DOCRYPT" = "0" ] \ ! && [ -x /sbin/blkid ] \ ! && [ -z "`/sbin/blkid '/dev/mapper/'`" ] ! do ! echo 'Unable to identify the filesystem on volume .' ! echo 'Reenter, Ignore, Shell?' ! read a ! case "$a" in ! i|I) ! break ! ;; ! s|S) ! /bin/dash ! ;; ! r|R|*) ! /sbin/cryptsetup remove '' ! DOCRYPT=1 ! ;; ! esac ! done !done END SCRIPT END TEMPLATE # # cryptsetup arguments: # - target # - src # - verify (yes or undef) # # A loop around 'cryptsetup --verify' can help detect # and correct typo's in the crypt password. # TEMPLATE cryptsetup_luks BEGIN FILE "/sbin/cryptsetup" FILE "/bin/loadkeys" FILE "/bin/gzip" FILE "/etc/console/boottime.kmap.gz" FILE "/sbin/blkid" SCRIPT "/init" BEGIN !# loadkeys from the kbd package has problems !# uncompressing the keymap on-the-fly when !# run from initramfs, don't know why !if [ -e /etc/console/boottime.kmap.gz ] !then ! gzip -d /etc/console/boottime.kmap.gz !fi !if [ -e /etc/console/boottime.kmap ] !then ! loadkeys /etc/console/boottime.kmap !fi !DOCRYPT=1 !while [ "$DOCRYPT" != "0" ] !do ! /sbin/cryptsetup \ ! -y \ ! luksOpen '' \ ! '' ! DOCRYPT=$? ! while [ "$DOCRYPT" = "0" ] \ ! && [ -x /sbin/blkid ] \ ! && [ -z "`/sbin/blkid '/dev/mapper/'`" ] ! do ! echo 'Unable to identify the filesystem on volume .' ! echo 'Reenter, Ignore, Shell?' ! read a ! case "$a" in ! i|I) ! break ! ;; ! s|S) ! /bin/dash ! ;; ! r|R|*) ! /sbin/cryptsetup luksClose '' ! DOCRYPT=1 ! ;; ! esac ! done !done END SCRIPT END TEMPLATE # # Do a resume from swap, unless 'noresume' is on the command-line. # TEMPLATE resume BEGIN FILE "/usr/bin/awk" FILE "/lib/udev/vol_id" FILE "/usr/local/sbin/tuxoniceui_fbsplash" FILE "/usr/local/sbin/tuxoniceui_text" FILE "/usr/local/sbin/tuxoniceui_usplash" FILE "/etc/splash/suspend2/1024x768.cfg" FILE "/etc/splash/suspend2/Vera.ttf" FILE "/etc/splash/suspend2/VeraBd.ttf" FILE "/etc/splash/suspend2/images/silent-1024x768.png" SCRIPT "/init" BEGIN !if [ -z "$noresume" ] ; then ! TARGET=/sys/power/resume ! INIT_RESUME=/sys/power/resume ! echo looking for resume device $resume ! # for suspend2 (>= 2.2-rc8) ! if [ -w /sys/power/tuxonice/version ]; then ! mknod /dev/fb0 c 29 0 ! TARGET=/sys/power/tuxonice/resume ! INIT_RESUME=/sys/power/tuxonice/do_resume ! fi ! # for suspend2 (< 2.2-rc8) ! if [ -w /proc/software_suspend/do_resume ]; then ! INIT_RESUME=/proc/software_suspend/do_resume ! fi ! # for swsusp ! if [ -n "$resume" ] ; then ! #uuid to dev translation ! case "$resume" in ! swap:UUID=[0-9a-zA-Z-]*) ! uuid=${resume#swap:UUID=} ! for i in `/usr/bin/awk '{print $4}' /proc/partitions ` ; do ! #echo $i ! case `/lib/udev/vol_id --uuid /dev/$i 2> /dev/null` in ! *$uuid) ! SOURCE=/dev/$i ! echo found resume device at $SOURCE ! ;; ! esac ! done ! #no error condition handleing ! ;; ! [0-9]*:[0-9]*) ! SOURCE=$resume ! ;; ! *[a-z]*[0-9]) ! SOURCE=`cat /sys/block/*/${resume#/dev/}/dev` ! ;; ! esac ! #echo $SOURCE $TARGET $INIT_RESUME ! echo "$SOURCE" > $TARGET ! echo "$SOURCE" > $INIT_RESUME ! else ! echo > /sys/power/resume ! fi !fi END SCRIPT END TEMPLATE # # NOTE: honouring the kernel cmdline option ro,rw # is very nice, but... If you have an ext3 in a # file loopback-mounted from vfat, it's unlikely # that a remount rw of root will also make the # underlying vfat read-write. Underlying filesystems # should ignore the kernel ro/rw option; we # have an attribute isRoot that's defined iff # this is the real root. # # always -n, since we dont have writable /etc/mtab. # TEMPLATE mount BEGIN SCRIPT "/init" BEGIN !echo "looking for root device $rootfs" ! ! case "$rootfs" in ! UUID=[0-9a-zA-Z-]*) ! uuid=${rootfs#UUID=} ! if [ -n $uuid ] ; then ! echo "Using UUID $uuid" ! rootfs="-U $uuid" ! fi ! ;; ! esac ! ! mount_rootfs() { ! /bin/mount -n \ ! $ro \ ! -t \ ! \ ! $rootfs \ ! '' ! result=$? ! if [ $result -ne 0 ] ; then ! echo "failed result from mount was $result" ! fi ! return $result ! } ! if [ $rootwait -eq 1 ] ; then ! echo "Waiting for rootfs (rootwait)" ! mount_rootfs ! while [ $? -ne 0 ] ; do ! echo "Still Waiting for rootfs (rootwait)" ! sleep 3 ! dyn_mkblkdev ! mount_rootfs ! done ! else ! echo "Not waiting for rootfs" ! mount_rootfs ! fi END SCRIPT END TEMPLATE TEMPLATE nfsstart BEGIN FILE "/trynfs" SCRIPT "/init" BEGIN !if [ "$ip" != "" ] !then ! /trynfs $ip $nfsroot /mnt ! switchroot "$@" !fi END SCRIPT END TEMPLATE TEMPLATE postlude BEGIN SCRIPT "/init" BEGIN !switchroot "$@" END SCRIPT END TEMPLATE END TEMPLATE SET