でびあんの initrd (5)

なんかログを追い掛けてみたらスクリプトを追い掛け始めたきっかけが微妙。
とりあえず init に戻って source scripts/functions な後から確認。

. /scripts/functions

# Export relevant variables
export break=
export init=/sbin/init
export quiet=n
export readonly=y
export rootmnt=/root
export debug=
export cryptopts=${CRYPTOPTS}
export ROOTDELAY=
export panic=

この後起動オプションで変数に色々設定なソレがあるんですが、デフォルトは上記になる模様。しかも export してるから panic した後も生きている、のかな?

# Parse command line options
for x in $(cat /proc/cmdline); do
	case $x in
	init=*)
		init=${x#init=}
		;;
	root=*)
		ROOT=${x#root=}
		case $ROOT in
		LABEL=*)
			ROOT="/dev/disk/by-label/${ROOT#LABEL=}"
			;;
		UUID=*)
			ROOT="/dev/disk/by-uuid/${ROOT#UUID=}"
			;;
		/dev/nfs)
			BOOT=nfs
			;;
		esac
		;;
	rootflags=*)
		ROOTFLAGS="-o ${x#rootflags=}"
		;;
	rootfstype=*)
		ROOTFSTYPE="${x#rootfstype=}"
		;;
	rootdelay=*)
		ROOTDELAY="${x#rootdelay=}"
		;;
	cryptopts=*)
		cryptopts="${x#cryptopts=}"
		;;
	nfsroot=*)
		NFSROOT="${x#nfsroot=}"
		;;
	ip=*)
		IPOPTS="${x#ip=}"
		;;
	boot=*)
		BOOT=${x#boot=}
		;;
	resume=*)
		RESUME="${x#resume=}"
		;;
	noresume)
		NORESUME=y
		;;
	panic=*)
		panic="${x#panic=}"
		;;
	quiet)
		quiet=y
		;;
	ro)
		readonly=y
		;;
	rw)
		readonly=n
		;;
	debug)
		debug=y
		exec >/tmp/initramfs.debug 2>&1
		set -x
		;;
	debug=*)
		debug=y
		set -x
		;;
	break=*)
		break=${x#break=}
		;;
	break)
		break=premount
		;;
	esac
done

指定可能なオプションはそのまんま、なんですがいくつかポイント高いナニを以下に控え。

  • root
    • root=LABEL=hoge なケースだと ROOT には /dev/disk/by-label/hoge になるんか
    • root=UUID=hoge なケースだた ROOT には /dev/disk/by-uuid/hoge
    • root=/dev/nfs だと ROOT には /dev/nfs がセットされて BOOT には nfs がナニ
  • debug
    • debug 単体指定だと debug の値は y になって以降の標準出力と標準エラーが /tmp/initramfs.debug にリダイレクトされる模様
  • break
    • break 単体指定だと premount で panic する模様

ちょっと試してみたい。んですがもう少し。

if [ -z "${NORESUME}" ]; then
	export resume=${RESUME}
fi

depmod -a
maybe_break top

NORESUME が優先な模様。あと depmod はよく分かってなかったのですが /lib/modules/`uname -a` 配下を読みこんで modules.dep (module の依存関係なリスト) を作成する模様。あと最後の maybe_break ですが scripts/functions にて定義されてて以下。

maybe_break()
{
	if [ x$1 = x${break} ]; then
		panic "Spawning shell within the initramfs"
	fi
}

例えば break=premount だった場合、maybe_break premount な呼び出しで panic します。panic の定義は scripts/functions にて以下。

panic()
{
	if [ -x /sbin/usplash_write ]; then
		/sbin/usplash_write "QUIT"
	fi
	# Disallow console access
	if [ "${panic}" = 0 ]; then
		reboot
	fi
	modprobe -q i8042
	modprobe -q atkbd
	echo $@
	PS1='(initramfs) ' /bin/sh -i </dev/console >/dev/console 2>&1
}

シェルが起動します。panic という変数に 0 がセットされてたら reboot する模様。ちょっと休憩してこのあたりの挙動を確認予定。

つづき

とりあえず起動オプションに break のみ追加で試験。/bin/sh 起動。export されている変数の値が確認できるかどうか。

/bin/sh: can't access tty; job control turned off
(initramfs) echo $break
premount
(initramfs) echo $init
/sbin/init
(initramfs) echo $quiet
n
(initramfs) echo $readonly
y
(initramfs) echo $rootmnt
/root
(initramfs) echo $debug

(initramfs) echo $cryptopts

(initramfs) echo $ROOTDELAY

(initramfs) echo $panic

(initramfs)

あと、debug 指定も確認要。reset して起動オプションに debug break 追加でナニ。/tmp/initramfs.debug がありますので、more で見てみたら止まらない。確認可能なケツのあたりが以下。

+ cat /conf/modules
+ read m
+ [ -z unix ]
+ printf %.1s unix
+ com=u
+ [ u = # ]
+ modprobe unix
+ read m
+ log_end_msg
+ [ -x /sbin/usplash_write ]
+ _log_msg done.\n
+ [ n = y ]
+ printf done.\n
done.
+ maybe_break premount
+ [ premount = premount ]
+ panic Spawning shell within the initramfs
+ [ -x /sbin/usplash_write ]
+ [ -n ]
+ modprobe i8042
+ modprobe atkbd
+ echo Spawning shell within the initramfs
Spawning shell within the initramfs
+ PS1=(initramfs) /bin/sh -i

たしかに処理経路をトレイスするには良いのですが、見れないんでは意味がないな。とりあえず一旦休憩。元気があれば続きに着手予定。
panic=0 なナニは未確認だな。