casperブートは大変便利

Linuxの“casper”(キャスパー)という仕組みは使いようによっては大変便利だということが分かった。“casper”というとライブCD/DVDを実現したり、USBブートを実現するためにあると思いがちだが、通常のHDDからのブートにも使える。casperブートしている間に加えられた変更は、次回のブートで“無かったこと”にできる。

例えば“ちょっとソフトをインストールして試してみたい場合”とか“ルートファイルシステム(例えば /dev/sda1)のイメージダンプを取りたい場合”とかに使える。ソフトのお試しであれば、仮想マシンでスナップショットを取って後ででrevertする方法もあるが、仮想マシン環境を構築していない場合や、物理マシンで試したい場合もある。こういった時にcasperブートが便利だ。また、ルートファイルシステムのイメージダンプはライブDVDなどで立ち上げないと取れないが、casperブートを使えばライブDVDなどを用意しなくても実現できる。こんな便利な機能、今まで何で使わなかったのだろう。(実はcasperのソース(といってもシェルスクリプト)を眺めていたら、“おや、シンボリックリンクを1つ設定すれば通常のLinuxでもcasperの機能が使えるのでは?”と思い試したらBingo!だった。)

なお、casperのライブDVDやUSBメモリディスクレス・クライアントでの利用については“UbuntuでカスタムライブDVDを作る”や“UbuntuでカスタムライブUSBを作る”、“ライブUbuntuをネットワークブートする − ディスクレスサーバ構築”を参照のこと。

さて、casperブートの使うための準備は次の3コマンドでOK(いずれもroot権限で)。

# apt-get install casper
# mkdir /casper
# ln -s  ../  /casper/filesystem.dir

基本的な設定は以上で終わり。

casperブートを使うには、grub 1(Ubuntu 9.04まで)では、ブート時に[ESC]キーでgrubメニューから、[e]キーでbootオプションの編集に入り、ブートオプションの適当な場所(splashの後の最後でOK)に、

boot=casper

を書き込んで[Enter]、[b]キーでブートすればOK。(grubメニューで“=”が入力でいない場合は、“^”(“=”の右隣のキー)を押すと入力できる。)
Ubuntuの9.10から採用されたgrub 2では、BIOSのセルフテストが終了する前(=grubが起動する前)に[Shift]キーを押しっ放しにして、grubメニューを表示する。

[e]キーでbootオプションの編集に入り、ブートオプション(“linux”行)の適当な場所(splashの後の最後でOK)に boot=casperを追加し、

[Ctrl]-[x]でブートする。

後は普通に使える(後述するが環境によっては、ちょとした留意点やファイルの変更が必要)。apt-getコマンドでパッケージを追加することもできるし、ファイルの生成、変更、削除も可能だ。ただし、次回ブートした時には変更したものは全て無くなる(つまりcasperブートの前の状態に戻る)ので、もし、残したいデータがあればssh、もしくはNFSやsambaを使って他のマシンにコピーしておく。
NFSやsambaもcasper環境でインストールして“一時的に”利用することができる。

# apt-get install nfs-common
# apt-get install smbclient

また、他のディスクをマウントして使うこともでる。が、マウントしたファイルシステムはcasper環境の範囲外となるので、そこに加えられた変更はそのまま残るの注意が必要だ。

更にcasper環境ではルートファイルシステムパーティション本体は“read only”でマウントされているので、システム利用中も何の変更も加わらない。従って次のような操作も可能となる。(この例では /dev/sda1にルートファイルシステムがあり、それを/dev/sdb1のファイルシステムへダンプしている。)

root@ubuntu:~# mkdir /mnt/tmp
root@ubuntu:~# mount /dev/sdb1 /mnt/tmp
root@ubuntu:~# ls /mnt/tmp
root@ubuntu:~# mkdir /mnt/tmp/Backup
root@ubuntu:~# dd if=/dev/sda1 of=/mnt/tmp/Backup/sda1.img bs=1G
7+1 records in
7+1 records out
7583675904 bytes (7.6 GB) copied, 469.595 s, 16.1 MB/s
root@ubuntu:~# ls -l /mnt/tmp/Backup/sda1.img
-rw-r--r-- 1 root root 7583675904 2010-02-10 10:09 /mnt/tmp/Backup/sda1.img
root@ubuntu:~# fsck -f /mnt/tmp/Backup/sda1.img
fsck from util-linux-ng 2.16
e2fsck 1.41.9 (22-Aug-2009)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/mnt/tmp/Backup/sda1.img: 131968/463296 files (0.4% non-contiguous), 662732/1851483 blocks
root@ubuntu:~#

casper環境つかうためのTips

さて、ここで幾つか追加の留意点について触れておく。

なお、casper環境のカスタマイズに関しては、別途“HDDからのcasperブートの最適化”にも追記した。(一部、重複する部分もあるが。)

■ /homeディレクトリについて。
casper環境ではrootファイルシステム以外のファイルシステムをマウントしない(ようだ。全てのケースを見ているわけではないので。/bootや/var等については確認していない)。従って、/homeディレクトリがrootファイルシステムとは別のファイルシステムとして構成されている場合、casper環境ではマウントされないので、一般ユーザでログインしてもホームディレクトリが見つからない、ということになる。

/home以下もrootファイルシステム内のディレクトリとして使っている場合は問題ないが、別ファイルシステムとして構成している場合にcasper環境使うには、次のどちらかの方法を使う。

1:rootでログインして使う。Ubuntuの場合、rootではログインできないようにパスワードが潰されているので次のようにしてrootのパスワードを設定して、ログイン出来るようにする。

% sudo passwd

2:一旦、/homeのマウントを外し、/homeディレクトリの下にcasper用のダミーのホームディレクトリを作っておく。ただし、/homeのマウントを外すにはrootでログインするかLive DVDを使ってシステムを立ち上げる必要がある。(一般ユーザでログインしてsudoではumountできない。)

# umount /home
# ls /home
# mkhomedir_helper adsaria
# ls /home
adsaria
#

/homeの下のダミーのホームディレクトリは、他のファイルシステムがマウントされている通常の状態では見えなくなるので、通常の使用に関しては何の問題もない。

■ casper環境におけるユーザについて。
もともとcasperは(書込み不可の)ライブDVDや(書込みは可能だが、パフォーマンスが悪い)USBメモリ等を対象として作られたシステムだと思う(開発の経緯は知らないが)。用途とすればLinuxのインストールやシステム修復、もしくは“お試し”になろう。従って、Ubuntuのcasperでは“ubuntu(ユーザID 999)”というパスワードの無いユーザを生成し、自動ログインしてパスワード無しでsudoまで出来るようになっている。(Ubuntu以外のシステムでは知らないが、多分、似たようなもんだろう。)
これはcasperが起動する過程で“標準的に”行われる。上の方法でHDDにインストールされたLinuxでcasperブートしても同様だ。ただし、casperでは/etc/passwdにユーザIDが1000番以上の一般ユーザが存在する場合は“ubuntu”を作らない。インストール前のライブDVDの環境では一般ユーザは登録されていないので、これを基準としているらしい。確かにインストール後のシステムで勝手にセキュリティホールとなるユーザを作成されては困る。
従って、HDDからのcasperブートではubuntuではなく、既に登録されている一般ユーザとしてログインするのが正道となる。
しか〜し、強制的にcasperを作るようにも設定できる。casperの/usr/share/initramfs-tools/scripts/casper-bottom/10adduser というシェルスクリプトがあるが、その中の

log_begin_msg "$DESCRIPTION"

という行の直後に、

export OVERRIDE_SYSTEM_USER=true

という1行を追加する。なお、このファイルを修正した後は、次のコマンドを実行しなければならない。

# dpkg-reconfigure casper

■ ホスト名とIPアドレスについて
casperブートで立ち上げるとホスト名(システム名)が強制的に“ubuntu”になってしまう。IPアドレスも127.0.1.1が設定される。インストール前のライブDVDのシステムには正式なホスト名やIPアドレスがあるはずも無く、本来のcasperの使い方からすれば当たり前なのだが。しかし、既に稼働しているシステムでは(ホスト名はともかく)IPアドレスが変わってしまっては、他のマシンと通信ができなくなってしまい困ってしまう。casperブートの後に設定を変えて通信できるようにしても良いが、それもメンドクサイ。

そこで /usr/share/initramfs-tools/scripts/casper-bottom/18hostname というファイルを次の内容で置き換える。

2010/02/13 更新:上の内容には関係ないがネットワークブートの部分に不具合。/etc/resolv.confを消しただけで更新してなかった。
2010/02/15 更新:“23networking”でネットワーク設定を行うので、ここではホスト名関係の必要最小限の設定に限定した。

#! /bin/sh

# Written by Adsaria Mood, 2010/02/15
#    for casper boot from HDD or network

PREREQ=""
DESCRIPTION="Setting hostname..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

HOSTNAME=ubuntu
IPV4ADDR=127.0.1.1
DNSDOMAIN=localdomain

WRITEOUT=

if [ -e /root/etc/hosts ] ; then
    if [ -r /root/etc/hostname ]; then
        TEMP_STRING=$(cat /root/etc/hostname)
        [ "$TEMP_STRING" ] && HOSTNAME=$TEMP_STRING
    fi
else
    WRITEOUT=true
fi

# read from /netboot.config, rather than /tmp/net-*.config
CONFIG=/netboot.config
if [ -r "$CONFIG" ]; then
    NET_CONFIG=$(cat $CONFIG)

    TEMP_STRING=$(echo $NET_CONFIG | sed -ne 's/.* host : \([^ ]*\) .*/\1/p' )
    [ "$TEMP_STRING" ] && HOSTNAME=$TEMP_STRING

    TEMP_STRING=$(echo $NET_CONFIG | sed -ne 's/.* address: \([0-9.]*\) .*/\1/p' )
    [ "$TEMP_STRING" ] && IPV4ADDR=$TEMP_STRING

    # resolv.conf will be configured later, by "23networking".
    rm -f /root/etc/resolv.conf

    WRITEOUT=true
fi

if [ $WRITEOUT ] ; then
	echo "$HOSTNAME" > /root/etc/hostname
	cat > /root/etc/hosts <<EOF
127.0.0.1 localhost
$IPV4ADDR $HOSTNAME

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

EOF
fi

hostname "$HOSTNAME"

log_end_msg

もともとの 18hostnameは有無を言わさず /etc/hostnameと/etc/hostsを書き換えてしまうが、この18hostnameは既にhostsファイルが存在する(=インストール後)場合には、上書きせずに逆に現在の値をcasperに反映させる。ただし、casperブートがネットワークブートである場合(つまり、ディスクレスのシステムとしてブートしている場合)、DHCPサーバから取得したホスト名、IPアドレスドメイン名を使ってファイルを上書きする。

18hostnameを変更したら、次のコマンドでinitrdを更新する。

# dpkg-reconfigure casper

■ メモリに注意
casperを使っている間のHDDへの変更点はHDDではなくメモリ上のaufsというファイルシステムに保持されている。従って、HDDへの変更が多いとメモリを食い潰して動作しなくなる。あまりデータ量の多いソフトウェアをインストールする場合は注意が必要だ(ただ、最近のマシンは2G、4Gも当たり前になっているので、まぁ、大体のところは大丈夫だが)。仮想マシンでcasperを使う場合は、主記憶の大きさを多めに割り当てておく方がいいだろう。