#analyzer
Debian Linux の OneCD(ライブDVD)化手順
Last-modified: 2014-12-23 (火) 03:50:25
初出 2007-8-2
最終更新 2009-03-29
開発時期 2007-8, 2009-3(squeeze, lenny対応)
このページの手順でUSBメモリ・ブートのルータなんかも作成できますが、その前に、
単なるUSBブートについての情報は→ こちら インストーラをUSBメモリ(ディスク)からブート可能にするなら→ こちら 久しぶりに新規にOneCD Linuxを作ってみました。今回の素材はDebian etch(2009-3にlenny,squeezeに対応)です。 本ページで作成するCD(DVD)は、元となるLinux環境をそのままCD(DVD)に焼いたバックアップ・ディスクとほぼ同じです。/sys,/proc,/tmpを省いていること、CDブートすること、特製のinitrd(イニシャルラムディスク)が追加されていることが単なるバックアップ・ディスクとの違いです。 ライブCD(DVD)として、元となるLinux環境と(早さを除いては)同様にアプリケーションを使用することも出来ますし、自力でブートして元となったDebian etch環境をレストアできるリカバリー・ディスクとして用いることも出来ます。 また、本ページ掲載のinitrd(イニシャルラムディスク)用パッチを用いれば、OneCD化やOneDVD化はもちろんですが、CF等のフラッシュメモリー系ディスクや、ごく普通のハードディスクをリードオンリーでマウントして運用する用途にも使用できます(※)。実は私の今回の製作目的はCFのリードオンリー運用です。→超格安CF-IDE変換アダプタの製作、CF-IDE変換アダプタの活用Tips ※: カーネルオプションのrootデバイスが/dev/?d?の場合は光学ドライブと見なし、/dev/?d??の場合は、パーティションテーブルを持つディスクと見なす仕様です。 特製のinitrdを作るためのパッチはaufs(etchではunionfs)を用いる版と用いない版の二種類を作成しました。aufs(unionfs)の説明は省略しますが、aufs(unionfs)を用いると見かけ上/以下どこにでも書き込みが可能となるのでデスクトップ用途としては優れていると思います。ただ私としてはルータやサーバ用途で長期連続稼動中にランダムなファイル名のファイルが大量に生成・消去された場合にはaufs(unionfs)を用いない方が安定感があるのではと思っています。用いる状態と用いない状態の切換はCF運用の場合、リモートからおこなえるので、今後ルータ兼簡易サーバとして運用しながら優劣を見極めたいと思っています。 通常はaufs(unionfs)を用いる版がおすすめです。aufs(unionfs)を用いない版も書き込みが必要な部分はラムディスクになっていて、基本的に全てのアプリケーションが普通に使用できます。しかしこちらの版はデスクトップ用途の場合、メモリ節約の為の小細工によってgnome、anthyの環境に特化してしまっています。使用する環境が大きく異なる場合は修正が必要です。こちらにも追加説明があります。 ライブCD(DVD)としての特徴を持っていますから、滅茶な使い方をしても再起動すれば初期状態に戻ります。またSATA-HDDやUSBブートにも対応しています。 (2007-12-27追記) パッチ中にコメントがないのは、出来るだけ「パッチの容量が小さいな」と言う印象を持ってもらいたいからです。これくらいの容量でコメントがない場合、わりと全てに目を通してくれる確率が高くなるような気がするからです。また、同じく容量を小さくするために、あまり至れり尽せりな内容にはしていません。例えば/bootをHDD上で元々別パーティションにしていた場合の扱いなんかは明らかに簡略化しています。
OneCD(ライブDVD)化、もしくはリードオンリー化の手順構築済みの Debian squeeze もしくは lenny もしくは etch 環境上で作業をおこないます。 1.追加パッケージのインストール# apt get install syslinux 今回もブートローダはgrubではなく、私がCDやDVDのブートではいつも使っているsyslinux(isolinux)を選びました。 # apt-get install aufs(unionfs)-modules-2.6.hoge-fuga ルータ用にbaseだけインストールした場合はmkisofsも入っていないのでインストールして下さい。 2.initrdの解凍作業ディレクトリをここでは仮に/boot/workとします。(以下も同じ) # cd /boot # cp -p initrd.img-2.6.hoge-fuga initrd.img-2.6.hoge-fuga.orig # mkdir work # cd work # gzip -dc ../initrd.img-2.6.hoge-fuga.orig | cpio -idmv 3.initrd内に追加ファイルをコピー元々etchのinitrd内には他のディストリと比べると驚くほど多くのコマンドが揃っています。 3-a) aufs(unionfs)を用いる場合# cd /boot/work/lib/modules/2.6.hoge-fuga/kernel/fs # cp -p /lib/modules/2.6.hoge-fuga/kernel/fs/exportfs/exportfs.ko . # squeeze, lennyの場合 # cp -p /lib/modules/2.6.hoge-fuga/extra/aufs/aufs.ko . # squeeze, lennyの場合 # cp -p /lib/modules/2.6.hoge-fuga/extra/unionfs/unionfs.ko . # etchの場合 3-b) aufs(unionfs)を用いない場合# cd /boot/work/bin # cp -p /usr/bin/stat . 4.initスクリプトにパッチを当てる4-a) aufs(unionfs)を用いる場合# cd /boot/work # patch -p0 < ../squeeze-initrd-init-onecd-aufs.patch # squeeze, lennyの場合 # patch -p0 < ../etch-initrd-init-onecd-unionfs.patch # etchの場合 ダウンロード --- init 2009-02-18 02:06:31.000000000 +0900 +++ init.new 2009-03-29 02:46:45.000000000 +0900 @@ -168,6 +168,9 @@ blacklist=*) blacklist=${x#blacklist=} ;; + ramdisk_size=*) + RAMDISKSIZE="${x#ramdisk_size=}" + ;; esac done @@ -197,8 +200,52 @@ log_begin_msg "Mounting root file system" . /scripts/${BOOT} parse_numeric ${ROOT} + +[ ! -n "${RAMDISKSIZE}" ] && RAMDISKSIZE=64M +mntpoint=DISK +diskmnt=${rootmnt}/${mntpoint} +echo "Mounting RAMDISK..." +mount -t tmpfs -o size=${RAMDISKSIZE} tmpfs ${rootmnt} +echo "Creating directories..." +mkdir ${diskmnt} +for i in boot initrd sys proc dev tmp; do +mkdir ${rootmnt}/${i} +done +chmod 1777 ${rootmnt}/tmp +echo > ${rootmnt}/fastboot + +echo "Mounting root disk..." +export rootmnt=${diskmnt} +if [ $(str=${ROOT##*/} && num=${str##*d} && echo ${#num}) -lt 2 ]; then +cdboot=1 +mount -o ro -t iso9660 ${ROOT} ${diskmnt} +else maybe_break mountroot mountroot +fi +export rootmnt=/root +mount --bind /dev ${rootmnt}/dev + +echo "Mounting aufs..." +mkdir ${rootmnt}/UNIONW ${rootmnt}/UNIONFS +chmod 1777 ${rootmnt}/UNIONW +modprobe -q aufs +mount -t aufs -o dirs=${rootmnt}/UNIONW=rw:${diskmnt}=ro unionfs ${rootmnt}/UNIONFS + +echo "Creating symbolic links..." +for i in bin sbin lib selinux srv usr opt var etc media mnt root home; do +ln -s UNIONFS/${i} ${rootmnt}/${i} +done + +if [ -n "${cdboot}" ]; then +cp -p ${rootmnt}/etc/fstab ${rootmnt}/etc/fstab.onecdbkup +grep -v "/boot"<${rootmnt}/etc/fstab.onecdbkup>${rootmnt}/etc/fstab +rm -rf ${rootmnt}/boot +ln -s UNIONFS/boot ${rootmnt}/boot +fi + +dmesg>${rootmnt}/var/log/dmesg + log_end_msg maybe_break bottom このsqueezeおよびlenny用のパッチのetch用からの実質的な違いは、etch用のものではunionfsと記述している個所をaufsと書き換えたことだけです。 4-b) aufs(unionfs)を用いない場合# cd /boot/work # patch -p0 < ../etch-initrd-init-onecd-normal.patch ダウンロード --- init 2009-02-18 02:06:31.000000000 +0900 +++ init.new 2009-03-29 11:28:38.000000000 +0900 @@ -168,6 +168,9 @@ blacklist=*) blacklist=${x#blacklist=} ;; + ramdisk_size=*) + RAMDISKSIZE="${x#ramdisk_size=}" + ;; esac done @@ -197,8 +200,110 @@ log_begin_msg "Mounting root file system" . /scripts/${BOOT} parse_numeric ${ROOT} + +dircp () +{ +SRCEDIR=$1 +DESTDIR=$2 +BASEDIR=`pwd` +mkdir -p "${DESTDIR}" +cd "${SRCEDIR}" +find . -type d|while read i +do + cd "${BASEDIR}" + cd "${SRCEDIR}" + DIRMODE=`stat -c %a "${i}"` + DIRUSER=`stat -c %u "${i}"` + DIRGROP=`stat -c %g "${i}"` + cd "${BASEDIR}" + cd "${DESTDIR}" + mkdir -p "${i}" + chmod $DIRMODE "${i}" + chown $DIRUSER "${i}" + chgrp $DIRGROP "${i}" +done +} +[ ! -n "${RAMDISKSIZE}" ] && RAMDISKSIZE=64M +mntpoint=DISK +diskmnt=${rootmnt}/${mntpoint} +echo "Mounting RAMDISK..." +mount -t tmpfs -o size=${RAMDISKSIZE} tmpfs ${rootmnt} +echo "Creating directories..." +mkdir ${diskmnt} +for i in boot initrd sys proc dev tmp; do +mkdir ${rootmnt}/${i} +done +chmod 1777 ${rootmnt}/tmp +echo > ${rootmnt}/fastboot + +echo "Mounting root disk..." +export rootmnt=${diskmnt} +if [ $(str=${ROOT##*/} && num=${str##*d} && echo ${#num}) -lt 2 ]; then +cdboot=1 +mount -o ro -t iso9660 ${ROOT} ${diskmnt} +else maybe_break mountroot mountroot +fi +export rootmnt=/root +mount --bind /dev ${rootmnt}/dev + +echo "Copying files, directories..." +for i in etc media mnt root home; do +cp -a ${diskmnt}/${i} ${rootmnt} +done +dircp ${diskmnt}/var ${rootmnt}/var + +echo "Creating symbolic links..." +for i in bin sbin lib selinux srv usr opt; do +ln -s ${mntpoint}/${i} ${rootmnt}/${i} +done + +echo "Adding /var/lib..." +rm -rf ${rootmnt}/var/lib +for i in ${diskmnt}/var/lib/*; do + case $i in + */gconf|*/dpkg|*/apt|*/aptitude|*/anthy) + ;; + *) + cp -a ${i} ${rootmnt}/var/lib + ;; + esac +done +for i in gconf dpkg apt anthy; do +if [ ! -e ${diskmnt}/var/lib/${i} ]; then continue; fi +ln -s ../../${mntpoint}/var/lib/${i} ${rootmnt}/var/lib/${i} +done + +echo "Adding /var/cache..." +rm -rf ${rootmnt}/var/cache +for i in ${diskmnt}/var/cache/*; do + case $i in + */apt|*/debconf|*/app-install|*/man) + ;; + *) + cp -a ${i} ${rootmnt}/var/cache + ;; + esac +done +for i in apt debconf app-install man; do +if [ ! -e ${diskmnt}/var/cache/${i} ]; then continue; fi +ln -s ../../${mntpoint}/var/cache/${i} ${rootmnt}/var/cache/${i} +done + +if [ -n "${cdboot}" ]; then +cp -p ${rootmnt}/etc/fstab ${rootmnt}/etc/fstab.onecdbkup +grep -v "/boot"<${rootmnt}/etc/fstab.onecdbkup>${rootmnt}/etc/fstab +rm -rf ${rootmnt}/boot +ln -s ${mntpoint}/boot ${rootmnt}/boot +fi + +echo "Copying crontabs..." +rm -rf ${rootmnt}/var/spool/cron/crontabs +cp -a ${diskmnt}/var/spool/cron/crontabs ${rootmnt}/var/spool/cron + +dmesg>${rootmnt}/var/log/dmesg + log_end_msg maybe_break bottom このsqueezeおよびlenny用のパッチのetch用からの実質的な違いは、etch用のものに/var/cacheと/var/spool/cron/crontabsのコピー部を追加したことだけです。
5.initrdの圧縮# cd /boot/work # find | cpio -H newc -o | gzip -9 > ../initrd.img-2.6.hoge-fuga # 元のファイル名 6.ハードディスクからのブートでCD、DVDブートの予行演習(動作確認)# cd /boot/grub menu.lstのデフォルトに指定されているセクションをコピーし、 title Debian GNU/Linux, kernel 2.6.hoge-fuga(original) root (hd0,○) kernel /vmlinuz-2.6.hoge-fuga root=/dev/hda○ ro initrd /initrd.img-2.6.hoge-fuga.orig savedefault みたいなセクションを追加しておきます。 ramdisk_size=192M のような指定を追加しておきます。指定しなければラムディスクサイズは64Mになります。 ハードディスクやCFからブートする場合、fstabに/bootを専用パーティションとしてマウントする記述があれば、それに従って/bootをマウントする仕様となっています。この場合、ルートデバイスをリードオンリーマウントした状態でもmenu.lst等の書き換えが可能です。 7.CDやDVDの作成7-a) isoファイル作成スクリプト の実行make-onecd-iso.sh ダウンロード #!/bin/sh -ex # make-onecd-iso.sh sysname=OneCDDebian outputpath=/iso-output mkdir -p ${outputpath} mkdir -p /isolinux cp -pf /vmlinuz /isolinux cp -pf /initrd.img /isolinux cp -pf /usr/lib/syslinux/isolinux.bin /isolinux cat>/isolinux/isolinux.cfg<<EOT default vmlinuz append initrd=initrd.img root=/dev/hdc vga=0x317 prompt 1 say Welcome to ${sysname} linux. say Select menu or override default boot option or wait 5 seconds. say eg.) boot: vmlinuz root=/dev/hdb ramdisk_size=192M say | say Default boot option: "vmlinuz root=/dev/hdc 0x317" say Default ramdisk size: 64M say | timeout 50 label hdc say hdc) Boot from /dev/hdc kernel vmlinuz append initrd=initrd.img root=/dev/hdc vga=0x317 label hda say hda) Boot from /dev/hda kernel vmlinuz append initrd=initrd.img root=/dev/hda vga=0x317 say | EOT mkisofs \ -V "${sysname}" \ -R \ -x ${outputpath} -x /sys -x /proc -x /tmp \ -b isolinux/isolinux.bin -o ${outputpath}/${sysname}.iso \ -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table / このスクリプトでは簡潔に記述する為にisolinuxのメニューにsayを使用しています。ほぼ言うまでもないことですが、メッセージファイルやグラフィカルメニューを使用するのが一般的です。必要であれば適宜変更して下さい。 7-b) オンザフライ焼きする場合make-onecd-on-the-fly.sh
ダウンロード #!/bin/sh -ex # make-onecd-on-the-fly.sh sysname=OneCDDebian mkdir -p /isolinux cp -pf /vmlinuz /isolinux cp -pf /initrd.img /isolinux cp -pf /usr/lib/syslinux/isolinux.bin /isolinux cat>/isolinux/isolinux.cfg<<EOT default vmlinuz append initrd=initrd.img root=/dev/hdc vga=0x317 prompt 1 say Welcome to ${sysname} linux. say Select menu or override default boot option or wait 5 seconds. say eg.) boot: vmlinuz root=/dev/hdb ramdisk_size=192M say | say Default boot option: "vmlinuz root=/dev/hdc 0x317" say Default ramdisk size: 64M say | timeout 50 label hdc say hdc) Boot from /dev/hdc kernel vmlinuz append initrd=initrd.img root=/dev/hdc vga=0x317 label hda say hda) Boot from /dev/hda kernel vmlinuz append initrd=initrd.img root=/dev/hda vga=0x317 say | EOT growisofs \ -V "${sysname}" \ -R \ -x /sys -x /proc -x /tmp \ -b isolinux/isolinux.bin \ -dvd-compat -Z /dev/dvd \ -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table / このスクリプトでは簡潔に記述する為にisolinuxのメニューにsayを使用しています。ほぼ言うまでもないことですが、メッセージファイルやグラフィカルメニューを使用するのが一般的です。必要であれば適宜変更して下さい。 ルータやサーバとして使用する場合の常套Tips
作成したディスクをリカバリー・ディスクとして用いる場合の注意点mkisofsコマンドに与えるオプションの影響で、以下の作業を付け加える必要があります。 # cd リカバリーしたroot # mkdir sys proc tmp # chmod 1777 tmp その後の状況(2008-8-31記述)私はnormalの方を常用しています。7月に9ヶ月ぶりに停止させ、普通に起動してapt-get dist-upgradeをおこないました。今後も特に変更予定はありません。 自作ルータを長期運用してきた私が得た教訓(2008-10-29記述)今までいくつかのOne CD LinuxやCFを使ったスピンドルレスなルータを長期間、常時稼動させてきました。それによって得た細かい教訓を挙げてみたいと思います。
※:電源にかかる負荷が低いので、劣化した電源でも障害が発生しにくいという意味で ご要望、ご意見、質問を下のフォームにどうぞ
|