syslinuxの設定ファイルに関する工夫

Linuxを使ったネットワークブートで一般的に使うのはsyslinuxによる2次ローダとそれに続くOS本体のダウンロードだろう。syslinuxを呼び出すまでにはDHCPとtftpという仕組み(総括してPXEと呼んでいるが)を使っているが、これについての工夫は別に紹介するとして、まずはPXEで呼び出されたsyslinuxの設定ファイルの構成に関する工夫についてメモっておく。

ここではsyslinuxの中でもPXEブートに関する設定に絞っている。つまり標準で、/tftpboot/syslinux/pxelinux.cfgディレクトリの下のファイル構成が中心となる。

PXEブートにより各クライアントからの要求に対して、“その”クライアントに対する設定ファイルを用意することで、クライアント毎に違うブート設定を実現できる。クライアントの区別は、クライアントのMACアドレス、もしくはIPアドレスで行う。“01-xx-xx-xx-xx-xx-xx”というファイル名を用意することで“xx:xx:xx:xx:xx:xx”というMACアドレスのクライアントに対するブート設定を記述する(IPアドレスを使った方法もあるが説明を簡単にするためにここではMACアドレスによる指定だけに限定する)。等と言うことはマニュアルなどに書いてあるので(ここ)、一般には/tftpboot/syslinux/pxelinux.cfgディレクトリの下は、クライアントMACアドレスに対応するファイル名が多数できる。これを管理するのは結構手間がかかる。もっとも、クライアント個々で全く異なるカーネルやパラメータを使うことは無いので、雛形になるファイルを作り、そのファイルに個々のMACアドレスのファイルをシンボリックリンクすることになる。例えば、

root@ubuntu# cd /tftpboot/syslinux/pxelinux.cfg
root@ubuntu# ls -l
total 8
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root 23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root 53 2011-02-27 18:42 default.ubuntu1004xd32e
-rw-r--r-- 1 root root 53 2011-02-27 18:42 default.ubuntu1004xd64e

root@ubuntu# cat default.ubuntu1004xd32e
DEFAULT ubuntu1004xd32e

LABEL ubuntu1004xd32e
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

という感じでリンクを張ることで、クライアントによってブートするUbuntuを32bit版(i386)か64bit版(amd64)の指定できるようになる。(なお、以下のサンプルではsyslinuxの設定ファイル中で、syslinuxの予約語となっている単語(DEFUALT、LABEL、KERNEL等)は大文字にしてある。これらの予約語は大文字でも小文字でも関係ないので、私は予約語として認識し易くするために大文字を使っている。)

ただ、シンボリックリンクを使ってまとめたとしても雛形のファイル(シンボリック先のファイル、この例では“default.xxxxxx”)も種類がだんだん増えてきて管理が面倒になる。そこで、雛形ファイルを1つにまとめてしまうことを考えた。例えば次のうに“labels”というファイルを作り、そこに設定をまとめてしまう。

root@ubuntu# ls -l
total 12
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root  53 2011-02-27 19:01 default.ubuntu1004xd32e
-rw-r--r-- 1 root root  53 2011-02-27 19:02 default.ubuntu1004xd64e
-rw-r--r-- 1 root root 503 2011-02-27 18:59 labels

root@ubuntu# cat labels
LABEL ubuntu1004xd32e
	KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
	APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
	KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
	APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

と、しておく。このlabelsファイルにはLABELの項目だけが含まれ、DEFAULTの行はない。DEFAULTの指定は雛形ファイル(defaul.xxxxxx)で記述する。例えば次のようになる:

root@ubuntu# cat default.ubuntu1004xd32e
INCLUDE pxelinux.cfg/labels
DEFAULT ubuntu1004xd32e

雛形ファイルはlabelsファイルを読み込み、デフォルトを指定しているだけである。(この2行の順番は逆でも構わないが、誤ってlabelsファイルの方にDEFAULTの記述があっても、それを上書きするようにDEFAULT行はINCLUDE行の後にしている。)

この例では2つのエントリーしかないので、このように分けるメリットが余り感じられないが、もっと多様なブート設定が増えてきてもlabelsファイルだけを管理すれば良いので管理が楽になる。

私の環境で更に、クライアントのブート時にどのOSをブートするか指定できるようにメニューも出せるようにしているが、その場合は次の様に default.menuという雛形を作っている。

root@ubuntu# ls -l
total 16
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-00 -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-aa-bb-cc-dd-ee-ff -> default.ubuntu1004xd32e
lrwxrwxrwx 1 root root  12 2011-02-27 19:24 01-ab-cd-ef-12-34-56 -> default.menu
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-00 -> default.ubuntu1004xd64e
lrwxrwxrwx 1 root root  23 2011-02-27 18:44 01-ff-ee-dd-cc-bb-aa -> default.ubuntu1004xd64e
-rw-r--r-- 1 root root  45 2011-02-27 19:23 default.menu
-rw-r--r-- 1 root root  53 2011-02-27 19:01 default.ubuntu1004xd32e
-rw-r--r-- 1 root root  53 2011-02-27 19:02 default.ubuntu1004xd64e
-rw-r--r-- 1 root root 580 2011-02-27 19:33 labels

root@ubuntu# cat default.menu
INCLUDE pxelinux.cfg/labels
DEFAULT menu.c32

この様に設定しておくと“ab:cd:ef:12:34:56”というMACアドレスを持ったPCをPXEブートすると、画面に32bit版のUbuntuを起動するのかか64bit版のUbuntuを起動するのかメニューが表示される。その際に、“ubuntu1004xd32e”といった管理用のファイル名ではなく“Ubuntu 10.04 Desktop i386”というメッセージを出力するようにlabelsファイルでメニューラベルも指定しておく。

root@ubuntu# cat labels
LABEL ubuntu1004xd32e
        MENU LABEL Ubuntu 10.04 Desktop i386
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
        MENU LABEL Ubuntu 10.04 Desktop amd64
        KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

この様にLABEL記述だけを別ファイルに独立させることで、メニューを出す雛形も作れるし、(メニューを出さずに)特定のOSを即ブートする雛形も作れる。

以下は、実際に私の環境で使っている例である:

root@ubuntu# cat labels
LABEL mt86plus
        MENU LABEL Memory Test
        KERNEL mt86plus

################################################################################

LABEL gpxe
        MENU LABEL gPXE Boot
        KERNEL gpxe.0

################################################################################

LABEL ubuntu08044s32e-vmrc
        MENU LABEL VMware Remote Console
        KERNEL  /diskless/root/ubuntu08044s32e-vmrc/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu08044s32e-vmrc/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu08044s32e-vmrc netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd32e
        MENU LABEL Ubuntu 10.04 Desktop i386
        KERNEL  /diskless/root/ubuntu1004xd32e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd32e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd32e netboot=nfs quiet --

################################################################################

LABEL ubuntu1004xd64e
        MENU LABEL Ubuntu 10.04 Desktop amd64
        KERNEL  /diskless/root/ubuntu1004xd64e/vmlinuz
        APPEND  initrd=/diskless/root/ubuntu1004xd64e/initrd.img boot=casper nfsroot=192.168.1.1:/diskless/root/ubuntu1004xd64e netboot=nfs quiet --

################################################################################

LABEL ubuntu_32_-installer
        MENU LABEL Install Ubuntu i386
        KERNEL ubuntu-installer/i386/boot-screens/vesamenu.c32
        APPEND ubuntu-installer/i386/boot-screens/menu.cfg

################################################################################

LABEL ubuntu_64_-installer
        MENU LABEL Install Ubuntu amd64
        KERNEL ubuntu-installer/amd64/boot-screens/vesamenu.c32
        APPEND ubuntu-installer/amd64/boot-screens/menu.cfg

この様にlabelファイルを記述しておけば、先ほどのdefault.menuの雛形を使ったPCからPXEブートすると次のようなメニュー画面が表示される:

“Memory Test”はOSをブートするのではなくMemory Testプログラムを起動実行する。syslinuxに付属するmt86plus(旧memtest86+)を起動しているだけ。
“gPXE”を選択すると、gPXEを使って再ブートに入りiSCSIでのブートが可能となる。ここで、どのiSCSIディスクを使ってブートするのかメニュー化したかったのだが、現バージョン(1.0.1)のgPXEに対してパラメータを渡すことができないようなので、ここだけはマシン依存になってしまう(詳細はgPXEの設定の所で)。今のところはAndroidの開発環境をブートするのに使っている。
VMware Remote Desktop”はシンクライアントとしてPCを立ち上げて、サーバ上で動いている仮想マシンのリモートコンソールとして使う。捨てられずに置いてある昔のPCのための設定である。
Ubuntu 10.04 Desktop i386”、“Ubuntu 10.04 Desktop amd64”は(iSCSIを使わず)ディスクレス形態でUbuntuをブートする。ちょうどUbuntuのライブCDを起動したのと同じ状態をPXEでネットブートする形になる。この設定があると普段はWindowsを動かしているPCでも気軽にUbuntuを起動することができ、マシンの保守などのために利用する。Windowsマシンのバックアップ取る場合はLinuxをブートしてHDD(もしくはシステム・パーティション)を丸ごとイメージとしてバックアップするのに使う。また、HDDからブートできない!とかいう場合にも使う。
“Install Ubuntu i386”、“Install Ubuntu amd64”はUbuntuのインストールに使う。この様に設定しておけば、いちいちインストール用のDVDを焼かずにBIOSからPXEブートを選ぶだけでUbuntuのインストールが可能となる(ただGUI画面ではくCUI画面でのインストールになるが)。