本稿は前稿の CentOS版だ。要件定義はおよそ同じだが、LiveBootの実現方法の違いにより、構築手順は大きく異なる。
要件定義
- 対象機は x86_64(amd64)とする。
- VGAデバイスは物理的に搭載されていない。GUIも使用しない。よって起動する CentOSはコンソールベースとする。
- BIOSコンソールリダイレクト機能は対象機材でサポートされているものとする。
- シリアルコンソールは baud=115.2kで接続する。1
- 成果物は ISOイメージとし、CD-R/DVD-Rに焼いて USB-ODDブート(USB光学ドライブ起動)できるものとする。通常は、再起動毎にあらゆる設定や痕跡は完全に忘却される。
- 他の Linuxマシンを必要とすることなく、一般的な Windowsマシンから既成の USBインストーラを用いて、USBフラッシュドライブに変換できるものとする。この際 persistent領域を設定できなければならない。
- yum一式を備えている。追加したパッケージや設定は、persistent有効時は維持される。
- 既定のログインユーザ名は liveuser とし、パスワードも無しとする。ゆえにパスワード無しで sudoできるものとする。(一般的な LiveBootの流儀)
- 既定のネットワーク設定・接続はオフとする。
- これらのパスワードやネットワーク設定は persistent有効時には自由に設定変更して永続化することができ、再起動しても設定内容が失われてはならない。
以後は CentOS-7-x86_64-LiveCD-1503.iso をベースにして話を進める。32bit版や CentOS-6でも同様の手順で構築できる。2
Ubuntuでは最終的な rootfsを作るのにオンメモリ(2GiB程度)で作業できたが、CentOS用の rootfsを作成するには作業領域が足りないため、起動用 USBメモリの他に Ext4でフォーマットできるフラッシュドライブや HDDを別途用意しなければならない。なお最終的に出来上がるブータブルイメージは CD-Rに充分格納できるサイズ(640MiB以下)になる。
なお製作時のリファレンス機材には Riava RS670A を使用した。3
シリアルコンソール対応のインストーラUSBメモリを作る
まずヘッドレス環境で使用できる CentOSインストーラを LiveCD ISOイメージから作成する。Windows上でこれを行うには Fedora LiveUSB Creator4を使用する。
次に起動メニューを書き換える。LiveUSB Creatorが作成したベースファイルからの相違点はシリアルコンソール設定の追加が主だ。
#serial 0 115200
#console 0
default vesamenu.c32
timeout 100
menu background
menu autoboot Starting CentOS Linux 7 in # second{,s}. Press any key to interrupt.
menu clear
menu title CentOS Linux 7
menu vshift 4
menu rows 12
menu margin 8
menu helpmsgrow 15
menu tabmsgrow 13
menu tabmsg Press Tab for full configuration options on menu items.
menu separator
menu separator
label linux0
menu label ^Start CentOS Linux 7 Live
kernel vmlinuz0
append initrd=initrd0.img root=live:CDLABEL=LIVE rootfstype=vfat ro rd.live.image quiet rd.luks=0 rd.md=0 rd.dm=0 console=tty0 console=ttyS0,115200n8
menu default
menu separator
menu begin ^Troubleshooting
menu title Troubleshooting
label check0
menu label ^Test this media & start CentOS Linux 7 Live
kernel vmlinuz0
append initrd=initrd0.img root=live:CDLABEL=LIVE rootfstype=vfat ro rd.live.image quiet rd.luks=0 rd.md=0 rd.dm=0 rd.live.check console=tty0 console=ttyS0,115200n8
menu separator
label local
menu label Boot from ^local drive
localboot 0xffff
menu separator
label returntomain
menu label Return to ^main menu.
menu exit
menu end
このフラッシュドライブで、Troubleshootingサブメニュー内の Test this media & start CentOS Linux 7 Live を選んで起動しよう。しばらく待っているとログインプロンプトが出現する。ここからは root[ENTER]
で rootシェルに入ることが出来る。
rootfsを作成する
この時点で NetworkManager は起動しているので DHCPでのIP取得は既に済んでいるだろう。作業に必要なパッケージを yumで追加する。
LANG=C
yum install -y squashfs-tools
作業用の追加ドライブを接続してパーテションをフォーマットし、/mnt
にマウントしてそこに移動する。ここでは /dev/sdb1
とする。
mkfs.ext4 /dev/sdb1
mount /dev/sdb1 /mnt
cd /mnt
起動時のフラッシュドライブは /run/initramfs/live
に ReadOnlyでマウントされているので、これを rwオプションでリマウントして書き換え可能にする。
mount -o rw,remount /run/initramfs/live
cd /run/initramfs/live
現在起動している rootfsの実体は /run/initramfs/live/LiveOS/squashfs.img
だ。このファイルを差し替えるのが最終目的だが、これは LiveOS/ext3fs.img
という loopbackファイルを squashfsで圧縮した構造になっている。そこでこれを以下のようにして再現する。rootfs容量はここでは8GiBとするが、適宜任意のサイズに変えても良い。
mkdir -p squashfs-root/LiveOS
truncate -s $((2**33)) squashfs-root/LiveOS/ext3fs.img
mkfs.ext4 -L _CentOS-7-livecd squashfs-root/LiveOS/ext3fs.img
このファイルを loopbackマウントして /mnt/chrootでアクセスできるようにする。
mkdir /mnt/chroot
mount -o loop squashfs-root/LiveOS/ext3fs.img /mnt/chroot/
後は yumのグループインストールコマンド一発で、任意の新しい rootfs環境が構築できる。
yum --installroot=/mnt/chroot --releasever=7 -y groupinstall Core
releaseverオプションに指定する CentOSのバージョンは、/etc/os-release
ファイルを参照すると良い。
rootfsの環境設定
まず各システム領域を chroot内に bindマウントする。そしてダミーの /etc/fstab
(中身は空でも良い)を作成しておく。
mount -o bind /dev/ chroot/dev/
mount -o bind /proc/ chroot/proc/
mount -o bind /tmp/ chroot/tmp/
mount -o bind /run/ chroot/run/
touch chroot/etc/fstab
initramfsの構築設定ファイルを追加する。これは LiveBoot可能な initramfsを作成するのに必須の設定だ。
hostonly="no"
add_dracutmodules+="dmsquash-live"
compress="xz"
現在起動している LiveCDシステムの、livesysサービスファイルを chroot内にコピーしてサービス登録する。このサービスは初回起動時に liveuserアカウントの作成や rootパスワードの削除処理を行うようになっている。5
cp -p /etc/init.d/livesys* chroot/etc/init.d/
chroot chroot/ chkconfig --add livesys
chroot chroot/ chkconfig --add livesys-late
タイムゾーンとロケール情報を設定し、NetworkManagerが初回起動時は起動しないように修正する。
ln -sf ../usr/share/zoneinfo/Asia/Tokyo chroot/etc/localtime
echo "LANG=en_US.utf8" > chroot/etc/locale.conf
chroot chroot /usr/bin/systemctl disable NetworkManager
Linux kernelモジュールの組み込み
kernelと、その他の追加パッケージをインストールする。
yum --installroot=/mnt/chroot -y install kernel squashfs-tools dump isomd5sum epel-release
kernelと作成された initramfsを、フラッシュドライブに移動する。rescue関係のファイルは必要ないので削除する。
rm -f chroot/boot/*rescue*
mv chroot/boot/vmlinuz-* /run/initramfs/live/syslinux/vmlinuz0.new
mv chroot/boot/initramfs-* /run/initramfs/live/syslinux/initrd0.img.new
最後にクリーンアップを行ってアンマウントする。rootfsの umount後は fsckで損傷がないかチェックする。
yum --installroot=/mnt/chroot clean all
find chroot/var/log -type f -exec /bin/truncate -s0 {} \;
umount chroot/proc/
umount chroot/dev/
umount chroot/run/
umount chroot/tmp/
du -sh chroot/
720M chroot/
umount chroot/
fsck.ext4 squashfs-root/LiveOS/ext3fs.img
squashfs.img ファイルの作成
こうして出来た rootfsを mksquashfsで圧縮すれば、LiveBoot可能な新しいシステムファイルになる。ただし Ext4フォーマットした loopbackファイルをそのまま圧縮するため、インストール過程で生じた削除ファイルの痕跡などもそのまま残っていて圧縮率が低下してしまう。
mksquashfs squashfs-root squashfs.img.new
ls -lh squashfs.img.new
-rw-r--r--. 1 root root 474M Jun 24 08:21 squashfs.img.new
これを可能な限り取り除いて圧縮するには、dump/restoreコマンドを経由してファイルシステムを完全に作り直すとよい。ただし dumpコマンドはブロックデバイスしか扱えないので、losetupコマンドを用いて /dev/loopX に loopbackファイルをバインドして指定する。手順は面倒だが、比較するとその効果は絶大だ。
mv squashfs.img.new squashfs.img.nev
yum install -y dump
loopdev=$(losetup -f)
losetup $loopdev squashfs-root/LiveOS/ext3fs.img
dump -0z9 -f rootdump $loopdev
losetup -d $loopdev
ls -lh rootdump
-rw-r--r--. 1 root root 277M Jun 24 08:30 rootdump
rm -f squashfs-root/LiveOS/ext3fs.img
truncate -s $((2**33)) squashfs-root/LiveOS/ext3fs.img
mkfs.ext4 -L _CentOS-7-livecd squashfs-root/LiveOS/ext3fs.img
mount -o loop squashfs-root/LiveOS/ext3fs.img chroot
(cd chroot/; restore -r -f ../rootdump)
rm -fr chroot/lost+found restoresymtable
umount chroot
fsck.ext4 squashfs-root/LiveOS/ext3fs.img
mksquashfs squashfs-root squashfs.img.new
ls -lh squashfs.img.ne?
-rw-r--r--. 1 root root 474M Jun 24 08:21 squashfs.img.nev
-rw-r--r--. 1 root root 250M Jun 24 08:38 squashfs.img.new
cp squashfs.img.new /run/initramfs/live/LiveOS/
新 rootfsでの起動テスト
こうして作成した rootfsファイルをブートUSBメモリにコピーして shutdownし、Windows(あるいは他のLinux機)で以下の起動用ファイルを差し替える。
- vmlinuz0.new を syslinux/vmlinuz0 へ
- initrd0.img.new を syslinux/initrd0.img へ
- squashfs.img.new を LiveOS/squashfs.img へ
syslinux/syslinux.cfg は前述のそのままでよいが、今度の起動は通常の Start CentOS Linuxラベルを選択する。ログイン・プロンプトは rootで直接、あるいは liveuser(いずれもパスワード無し)でシェルに入れる。liveuserアカウントは sudoで rootアカウントになれる。
NetworkManagerは停止状態なので、ネットワークに接続するには dhclientで Link Upするか、nmcli/nmtuiでインタフェース設定を行って NetworkManagerを起動する。
sudo -s
systemctl enable NetworkManager
systemctl start NetworkManager
nmcli connection modify enp2s0 ipv4.method manual ipv4.addresses 192.168.240.101/24 ipv4.gateway 192.168.240.1 ipv4.dns 8.8.8.8
systemctl restart network.service
# cat /etc/sysconfig/network-scripts/ifcfg-enp2s0
ISOイメージを作成する
元の ISOの squashfs.img等を差し替えた、新しいISOイメージを作成する。まず作業に必要なパッケージをインストールし、作業領域に ISO内のファイルを展開して ReadOnlyを外す。
mount /dev/sdb1 /mnt
cd /mnt
# install mkisofs tools
yum install -y mkisofs isomd5sum
# mount image: CentOS-7-x86_64-LiveCD-1503.iso
mkdir loop
mount /dev/cdrom loop
# copy iso files and modify attributes
cp -rf loop files
chmod -R +w files/
umount loop
フラッシュドライブから先に作成した新しいシステムファイルをコピーする。このときフラッシュドライブ上では /syslinux
に vmlinuz0と initrd0.img ファイルが置かれているが、ISOイメージでは /isolinux
ディレクトリになる。6
# copy kernel and filesystem
cp -f /run/initramfs/live/syslinux/vmlinuz0 files/isolinux/
cp -f /run/initramfs/live/syslinux/initrd0.img files/isolinux/
cp -f /run/initramfs/live/LiveOS/squashfs.img files/LiveOS/
files/isolinux/isolinux.cfg をシリアルコンソール対応に修正する。最初のシリアルポート設定は BIOSコンソールリダイレクトの有無による。また先に作成した rootfsは SELinuxをサポートするように構築してはいないので、これを無効にする。isolinux/mt86plus
については標準では存在しないが、これについては別稿を参照されたい。
#serial 0 115200
#console 0
default vesamenu.c32
timeout 100
menu background
menu autoboot Starting CentOS Linux 7 in # second{,s}. Press any key to interrupt.
menu clear
menu title CentOS Linux 7
menu vshift 4
menu rows 12
menu margin 8
#menu hidden
menu helpmsgrow 15
menu tabmsgrow 13
menu tabmsg Press Tab for full configuration options on menu items.
menu separator
menu separator
label linux0
menu label ^Start CentOS Linux 7 Live
kernel vmlinuz0
append initrd=initrd0.img root=live:CDLABEL=CentOS7-liveboot rootfstype=auto ro rd.live.image quiet rd.luks=0 rd.md=0 rd.dm=0 selinux=0 console=tty0 console=ttyS0,115200n8
menu default
menu separator
menu begin ^Troubleshooting
menu title Troubleshooting
label check0
menu label ^Test this media & start CentOS Linux 7 1503 Live
kernel vmlinuz0
append initrd=initrd0.img root=live:CDLABEL=CentOS7-liveboot rootfstype=auto ro rd.live.image quiet rd.luks=0 rd.md=0 rd.dm=0 rd.live.check selinux=0 console=tty0 console=ttyS0,115200n8
label memtest
menu label Test ^memory
kernel mt86plus
append console=ttyS0,115200n8
menu separator
label local
menu label Boot from ^local drive
localboot 0xffff
menu separator
label returntomain
menu label Return to ^main menu.
menu exit
mkisofsコマンドで ISOイメージを作成する。ここではもっともシンプルなオプション構成として GRUB(gfxboot)や EFI対応、Macintosh対応は行ってはいない。注意が必要なのは -Vオプションに渡すCDラベルで、これは kernel起動オプションに記述したのと同じものでなければならない。またこのラベルは最大16文字なのでこれを超えないようにしよう。
find ./files -print | xargs touch -m {} \;
LANG=C mkisofs -r -J -l \
-V CentOS7-liveboot \
-cache-inodes \
-b isolinux/isolinux.bin \n
-c isolinux/boot.cat \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-o CentOS7-liveboot.iso \
./files
こうして出来た ISOイメージに、それ自体の改竄検出 MD5チェックサムを implantisomd5コマンドで埋め込む。Ubuntuではファイル単位で MD5をチェックしていたが、CentOSではメディアそのものをチェックする。従ってフラッシュドライブではこの仕組は動かない。一方で CD-R等に焼いた際に Write Errorが有っても、メディアの完全性を確認することが出来る。7
LANG=C implantisomd5 CentOS7-liveboot.iso
改竄チェックは checkisomd5コマンドで行える。引数には調べたい ISOファイルか、メディアを挿れた ODDのデバイスファイルを指定すればよい。なお implantisomd5と checkisomd5コマンドは、isomd5sumパッケージに含まれている。8
checkisomd5 CentOS7-liveboot.iso
checkisomd5 /dev/cdrom
CD-RW/DVD-RWに ISOイメージを焼く
光学メディアへのライティングは、Ubuntuとおなじく wodimコマンドで行える。
yum install -y wodim
# erase CD/DVD-RW media
wodim dev=/dev/sr0 blank=fast
# writing image
wodim -sao -eject dev=/dev/sr0 CentOS7-liveboot.iso
# check image
checkisomd5 /dev/sr0
こうして作成した光学メディアで ODDブートが正常に行えたら、Test this media & start CentOSラベルで起動してみよう。検査が正常に終了するとログイン・プロンプトに進み、失敗した場合は System Haltするはずだ。9
persistentモードを設定する
前述の ISOイメージ/光学メディアで ODDブートが正常に行えたなら、次はその ISOイメージを Live USB Creatorでもって、今度は persistent領域を設定したフラッシュドライブを作成しよう。
persistentモードは kernelオプションの rd.live.overlay=LABEL=LIVE
によって有効になる。initramfsは指定された LABELを blkidコマンドで探し、これを /run/initramfs/live/
にマウントする。persistent領域ファイルは LiveOS
ディレクトリ内の overlay-${LABEL}-${UUID}
というファイル名で探して、Device Mapperによって snapshotとして /
に結合される。これ自体は初期状態では(ファイルシステムではないので)単なる Zero Fillファイルである。
blkid -L LIVE
/dev/sda1
blkid /dev/sda1
/dev/sda1: LABEL="LIVE" UUID="0621-6D9B" TYPE="vfat"
ls -l /run/initramfs/live/LiveOS/
total 1299100
-rwxr-xr-x 1 root root 20480 Jun 26 05:26 osmin.img
-rwxr-xr-x 1 root root 1068498944 Jun 30 12:32 overlay-LIVE-0621-6D9B
-rwxr-xr-x 1 root root 261758976 Jun 30 08:26 squashfs.img
Ubuntuと異なり、Device Mapperを使用しているためもあって実際にあとどの程度データが書き込めるか(保存できるか)は dfコマンドでは判断することができない。dmsetupコマンドの statusサブコマンドで、live-rwボリュームの snapshot消費ブロック数(512byte単位)を知ることはできるから、これを利用するしかない。
dmsetup status live-rw
0 16777216 snapshot 14960/2086912 72
echo | awk '{print 14960/2086912}'
0.00716849
また Ubuntuの場合は、persistentファイルは overlayfsで重ねられた独立したファイルシステムであったから、非起動状態のフラッシュドライブから persistent領域内のファイルを抜き出すことは容易だったが、CentOSではこれは容易なことではない。
(現在起動しているのとは別の)フラッシュドライブ内の persistent領域にアクセスするには、以下のようにする。
## 作業領域の準備
cd /mnt
mkdir media squash rootfs
## フラッシュドライブを作業領域にマウントし、その中の squashfs.imgをマウントする
mount /dev/sdc1 media
mount -o loop media/LiveOS/squashfs.img squash
## ext3fs.img(readonly)と overlayファイルに loopbackデバイスを割り当てる
## 空きデバイス名は losetup -fで得られる
losetup -f
/dev/loop6
losetup /dev/loop6 squash/LiveOS/ext3fs.img -r
losetup /dev/loop7 edia/LiveOS/overlay-LIVE-0621-6D9B
## ふたつのデバイスを束ねて rootfsを再生する
blockdev -q --getsz /dev/loop6
16777216
dmsetup create live-rootfs --table "0 16777216 snapshot /dev/loop6 /dev/loop7 P 8"
dmsetup status live-rootfs
0 16777216 snapshot 17312/2086912 80
## あとはfsckしたり・・・
fsck -f -y /dev/mapper/live-rootfs
## dumpしたり・・・
## (squashfs.img作成以後分だけを抜き出すのに /etc/dumpdatesを利用する例)
echo "/dev/mapper/live-rootfs 0 $(LANG=C \
date +"%a %b %d %X %z" \
-r media/syslinux/ldlinux.sys)" >> /etc/dumpdates
dump -u1z9 /dev/mapper/live-rootfs -f rootfsdump
## mountしたり・・・
mount /dev/mapper/live-rootfs rootfs
ls -a rootfs/home/liveuser
## 作業を終えたら後始末してフラッシュドライブを切り離す
umount rootfs
dmsetup remove live-rootfs
losetup -d /dev/loop6
losetup -d /dev/loop7
umount squash
umount media
rmdir media squash rootfs
/homeや swapパーテションを設定する
/etc/init.d/livesys
を覗いてみると解る10が、フラッシュドライブの /LiveOS
ディレクトリに、home.img
ファイルがあれば /home
に、swap.imgファイルが有れば swap
に、それぞれ自動的にマウントするようになっている。これらのボリュームファイルは以下のようにセットアップする。
## persistentオフの場合はフラッシュドライブを rwリマウントする
mount -o rw,remount /run/initramfs/live
## 保存領域へcd
cd /run/initramfs/live/LiveOS
## home.img ボリュームの作成(サイズは適宜)
truncate -s $((2**31)) home.img
mkfs.ext4 -L "home-vol" home.img
## swap.img ボリュームの作成(サイズは適宜)
truncate -s $((2**31)) swap.img
mkswap -L "swap-vol" swap.img
## あとは特に設定変更もなく再起動するだけ
sync;sync;sync
reboot
## homeボリュームの有無は losetupで確認できる
## 容量は dfコマンドで把握可能
losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 0 1 /osmin.img (deleted)
/dev/loop1 0 0 0 1 /osmin
/dev/loop2 0 0 0 1 /run/initramfs/live/LiveOS/squashfs.img
/dev/loop3 0 0 0 1 /LiveOS/ext3fs.img
/dev/loop4 0 0 0 0 /LiveOS/overlay-LIVE-748B-70C6
/dev/loop5 0 0 0 0 /run/initramfs/live/LiveOS/home.img
## swapは freeコマンドで容量が確認できる
free
total used free shared buff/cache available
Mem: 8162140 178452 7610852 16720 372836 7767880
Swap: 262136 0 262136
ダウンロード
CentOS7-liveboot-20150703.iso 313MiB (md5sum)
USBシリアル変換は FTDI系を前提にしている。PL2303系(特にノーブランドのコピー品)は baud=115.2kではFIFOバッファが足りずに通信不具合が多発してトラブルのもとになる。 ↩
Riava RS670A 基本スペックは Intel Gigabit NICx6を持つ Intel/Atom C2758 でメモリ8GiB。基本OSは CentOSまたはUbuntu。SSD内蔵だがこれはここでは使用しない(壊さない)。なおフロントパネルのシリアルコンソールポート(COM0)はCisco互換配線(Yost Serial Device Wiring Standard)になっている。 ↩
persistentモードで初期化済フラグファイルが書けるようになると、これらの初期化処理はスキップされるようになる。 ↩
Fedora LiveUSB Creatorが、ISOイメージ中の /isolinux を /syslinux へコンバートしている。 ↩
Ubuntuでは USBメモリでも一応改竄チェックが可能だが、ISOイメージ中のブートセクタといった非ファイル領域に生じたライティングエラーを検出できない。 ↩
Dracutは、isomd5sumパッケージがインストール済なら initramfsを作成する際にこれを組み込む。initramfsに組み込まれていない場合、rd.live.checkオプションによるメディア検査は正しく実行できない。 ↩
Test this media & start CentOSは光学メディア起動時は chkisomd5が走り、検査に成功しなければログイン・プロンプトに達しないが、USBメモリ起動時はメディア自体が検査不能なので、そのまま進んでログイン・プロンプトに達することができる。 ↩
物理パーテションを /homeにしたり、暗号化したりする起動オプションもある。 ↩