ログ日記

作業ログと日記とメモ

メモリ起動用initramfs作成の練習

busyboxをビルドする。

aptitude install build-essential devscripts
aptitude build-dep busybox-static
apt-get source busybox-static
cd busybox-1.14.2/
vi debian/config/static # CTTYHACKとSETSIDをyに
debuild -us -uc

ここまでやって、バイナリだけコピーすることにした。


インストールされているinitrdを利用する。

cd /tmp
mkdir myinitrd
cd myinitrd
cp /boot/initrd.img-2.6.32-3-amd64 initrd.img-2.6.32-3-amd64.gz
gunzip initrd.img-2.6.32-3-amd64.gz
cpio -i -d < initrd.img-2.6.32-3-amd64
rm initrd.img-2.6.32-3-amd64

cd bin
cp path_to_busybox/debian/build/build_static/busybox .
ln -s busybox setsid
ln -s busybox cttyhack
cd ..


vi scripts/ram

# RAM root mounting
mountroot()
{
        [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/ram-top"
        run_scripts /scripts/ram-top
        [ "$quiet" != "y" ] && log_end_msg

        # For DHCP
        #modprobe af_packet

        wait_for_udev 10

        configure_networking

        mount -t tmpfs none /root
        mkdir /root/root /root/dev /root/sys /root/proc

        sleep 5

        setsid cttyhack sh -c "rsync -avz --exclude-from=exclude.list 192.168.1.50:/ /root/"

        echo "" > /root/etc/fstab

        for foo in $(echo $IP|awk 'BEGIN{FS=":"}{print "MYIP="$1,"GW="$3,"MASK="$4,"HOST="$5,"DEVICE="$6}'); do eval $foo; done
        echo -e "auto lo\niface lo inet loopback\n\nallow-hotplug eth0\niface eth0 inet static\n\
\taddress $MYIP\n\tnetmask $MASK\n\tnetwork ${MYIP%.*}.0\n\tbroadcast 255.255.255.0\n\
\tgateway $GW\n\tdns-nameservers 192.168.1.1\n\tdns-search c-sat.co.jp" > /root/etc/network/interfaces

        echo $HOST > /root/etc/hostname
        echo "$MYIP $HOST.c-sat.co.jp $HOST" >> /root/etc/hosts
        echo "" > /root/etc/exports

        ifconfig lo 127.0.0.1

        [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/ram-bottom"
        run_scripts /scripts/ram-bottom
        [ "$quiet" != "y" ] && log_end_msg
}

ram-topやram-bottomはまだない。一応書いただけ。
シェルスクリプト素人なのでよくわからなかったが何とか動くところまではできた。



rsyncとかsshとかはstaticリンクのものやdropbearを入れればいいんだろうけど取り敢えずやっつけで。

cp /usr/bin/rsync bin/
cp /lib/libacl.so.1 /lib/libpopt.so.0 /lib/libattr.so.1 lib/


cp /usr/bin/ssh bin/
cp /usr/lib/libcrypto.so.0.9.8 /usr/lib/libz.so.1 /usr/lib/libgssapi_krb5.so.2 \
  /usr/lib/libkrb5.so.3 /usr/lib/libk5crypto.so.3 /usr/lib/libkrb5support.so.0 usr/lib/
cp /lib/libresolv.so.2 /lib/libcom_err.so.2 /lib/libkeyutils.so.1 /lib/libpthread.so.0 lib/

cp /lib/libnss_files.so.2 lib/

cp /usr/bin/setsid bin/


find . | cpio -o -H newc | gzip > ../initrd.img-2.6.32-3-amd64-ram.gz
cp ../initrd.img-2.6.32-3-amd64-ram.gz /srv/tftp/debian/squeeze/amd64/

この辺は mkinitramfs-tools に付いてくる /usr/share/initramfs-tools/hook-functions の copy_exec() 関数を使えばもっと楽かもしれない。



vi /srv/tftp/pxelinux.cfg/default

DISPLAY boot.txt

DEFAULT ram

LABEL boot
        kernel debian/squeeze/amd64/vmlinuz-2.6.32-3-amd64
        append vga=normal initrd=debian/squeeze/amd64/initrd.img-2.6.32-3-amd64-ram.gz --
LABEL ram
        kernel debian/squeeze/amd64/vmlinuz-2.6.32-3-amd64
        append vga=normal initrd=debian/squeeze/amd64/initrd.img-2.6.32-3-amd64-ram.gz boot=ram \
  ip=192.168.1.71:192.168.1.50:192.168.1.1:255.255.255.0:host:eth0 --
LABEL nfsroot
        kernel debian/squeeze/amd64/vmlinuz-2.6.32-3-amd64
        append vga=normal initrd=debian/squeeze/amd64/initrd.img-2.6.32-3-amd64  boot=nfs root=/dev/nfs \
  nfsroot=192.168.1.50:/srv/nfs ip=192.168.1.71:192.168.1.50:192.168.1.1:255.255.255.0:host:eth0 --
LABEL install
        kernel debian/squeeze/amd64/linux
        append vga=normal initrd=debian/squeeze/amd64/initrd.gz  --
LABEL rescue
        kernel debian/squeeze/amd64/linux
        append vga=normal initrd=debian/squeeze/amd64/initrd.gz  rescue/enable=true --

PROMPT 1
TIMEOUT 5


vi /srv/tftp/boot.txt

- Boot Menu -
=============

boot
ram
install
nfsroot
rescue

boot はエラーで止まるんだけど、そのままinitramfsに入れるのでデバッグ用。
ramは今回作った起動方法。
nfsrootは前回のやつ。テスト用。
installとrescueはネットワークインストールの解説にあったものをそのまま使った。





随分面倒な感じになってしまった。もっと簡単にできる方法がありそうだけど…。


今回は initramfs の中でrsyncを使うだけなのにかなり遠回りした。
最初はinitramfsの.ssh/に鍵を入れておいてテストしていたが、誰でもアクセスできる場所なのでパスワード入力に切り替えようとした。
それで /dev/tty が使えない問題(?)*1 があって、Debianbusyboxパッケージではコマンドが足りないのでコンパイルが必要になった。
それからinitramfsに元々付属しているスクリプトを調べたりで、やっとブートできるところまできたらこんな時間。
現状ではrsyncで/をミラーリングしているので、コピー元にソフトを色々入れたらメモリ起動側も同じだけソフトが入ってしまう問題がある。しかしミラーリング用のデータを別に用意するのも面倒な作業なのでしばらく様子見。
続きはまた今度。