Author: Warren Crossing Date: To: submit CC: yaird-devel, tuxonice-users Subject: [TuxOnIce-users] Patch to support rootfs UUID and resume UUID using
vol_id from udev and mount -u
Kernel: Linux 2.6.26 (SMP w/2 CPU cores; PREEMPT)
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/bash
Versions of packages yaird depends on:
ii cpio 2.9-13 GNU cpio -- a program to
manage ar
ii dash 0.5.4-9 POSIX-compliant shell
ii libc6 2.7-11 GNU C Library: Shared libraries
ii libhtml-template-perl 2.9-1 HTML::Template : A module
for usin
ii libparse-recdescent-perl 1.95.1+dfsg-2 generates recursive-descent
parser
ii perl 5.10.0-10 Larry Wall's Practical
Extraction
yaird recommends no packages.
Versions of packages yaird suggests:
ii doc-base 0.7.21 utilities to manage online
documen
#
# 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 "<TMPL_VAR NAME=auxDir>/run_init"
#
# 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 <TMPL_VAR NAME=appVersion>.
!# Kernel version: <TMPL_VAR NAME=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 <TMPL_VAR NAME=auxDir>/run_init ] ; then
! exec <TMPL_VAR NAME=auxDir>/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 "<TMPL_VAR NAME=target>"
FILE "/sbin/insmod"
# optionList may be undef
# and already is suitably escaped.
SCRIPT "/init"
BEGIN
!/sbin/insmod '<TMPL_VAR NAME=target>' <TMPL_VAR NAME=optionList>
END SCRIPT
END TEMPLATE
TEMPLATE mkbdev
BEGIN
SCRIPT "/init"
BEGIN
!mkbdev '<TMPL_VAR NAME=target>' '<TMPL_VAR NAME=sysname>'
!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/<TMPL_VAR NAME=evmsVersion>"
FILE "/sbin/evms_activate"
FILE "/etc/evms.conf"
SCRIPT "/init"
BEGIN
!# activate for <TMPL_VAR NAME=target>
!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 '<TMPL_VAR NAME=target>'
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 <TMPL_VAR NAME=target> b <TMPL_VAR NAME=major> <TMPL_VAR
NAME=minor>
!<TMPL_IF NAME=supports_device_renaming>
! mdadm -Ac partitions <TMPL_VAR NAME=target> --run --uuid <TMPL_VAR
NAME=uuid>
!<TMPL_ELSE>
! mdadm --assemble <TMPL_VAR NAME=target> --run --uuid <TMPL_VAR
NAME=uuid> \
! <TMPL_LOOP NAME=components> <TMPL_VAR NAME=dev></TMPL_LOOP>
!</TMPL_IF>
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 <TMPL_VAR NAME=cipher> \
! -s <TMPL_VAR NAME=keySize> \
! <TMPL_IF NAME=hash> \
! -h '<TMPL_VAR NAME=hash>' \
! </TMPL_IF> \
! <TMPL_IF NAME=verify>-y </TMPL_IF> \
! create '<TMPL_VAR NAME=target>' \
! '<TMPL_VAR NAME=src>'
! DOCRYPT=$?
! while [ "$DOCRYPT" = "0" ] \
! && [ -x /sbin/blkid ] \
! && [ -z "`/sbin/blkid '/dev/mapper/<TMPL_VAR NAME=target>'`" ]
! do
! echo 'Unable to identify the filesystem on volume <TMPL_VAR
NAME=target>.'
! echo 'Reenter, Ignore, Shell?'
! read a
! case "$a" in
! i|I)
! break
! ;;
! s|S)
! /bin/dash
! ;;
! r|R|*)
! /sbin/cryptsetup remove '<TMPL_VAR NAME=target>'
! 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 \
! <TMPL_IF NAME=verify>-y </TMPL_IF> \
! luksOpen '<TMPL_VAR NAME=src>' \
! '<TMPL_VAR NAME=target>'
! DOCRYPT=$?
! while [ "$DOCRYPT" = "0" ] \
! && [ -x /sbin/blkid ] \
! && [ -z "`/sbin/blkid '/dev/mapper/<TMPL_VAR NAME=target>'`" ]
! do
! echo 'Unable to identify the filesystem on volume <TMPL_VAR
NAME=target>.'
! echo 'Reenter, Ignore, Shell?'
! read a
! case "$a" in
! i|I)
! break
! ;;
! s|S)
! /bin/dash
! ;;
! r|R|*)
! /sbin/cryptsetup luksClose '<TMPL_VAR NAME=target>'
! 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"
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
! 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 <TMPL_VAR NAME=devno> > /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 \
! <TMPL_IF NAME=isRoot>$ro</TMPL_IF> \
! -t <TMPL_VAR NAME=fsType> \
! <TMPL_VAR NAME=options> \
! $rootfs \
! '<TMPL_VAR NAME=target>'
! 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 "<TMPL_VAR NAME=auxDir>/trynfs"
SCRIPT "/init"
BEGIN
!if [ "$ip" != "" ]
!then
! <TMPL_VAR NAME=auxDir>/trynfs $ip $nfsroot /mnt
! switchroot "$@"
!fi
END SCRIPT
END TEMPLATE
TEMPLATE postlude
BEGIN
SCRIPT "/init"
BEGIN
!switchroot "$@"
END SCRIPT
END TEMPLATE
END TEMPLATE SET