RaspbianのOSイメージのパーティションを分割した
動機
公式で配布されているRaspbian OSイメージはbootとrootfsのパーティションのみで構成されていて、 Raspberry PIに入れて起動するとrootfsが自動でSDカード全体まで拡張される。
そのまま常時稼働で運用していると、OSのログやtmpやswapの利用でSDカードへの書き込みがチクチク行われて、 NANDフラッシュの書き込み上限を迎えてある日ディスクが壊れることになる。
NANDフラッシュはSLC、MLC、TLCで書き込み上限が異なるので、なるべく上限の多いタイプを選ぶべきだけど、 それでも上限があることには変わりないし、工業用のSLCのSDカードとか結構高価。
なのでなるべくディスクへの書き込みは最小限にしたい。
また、電源ぶち切りとか停電とか考えると、そもそもrootfsはReadOnlyにしたい。
ただし、ReadOnlyにすると設定ファイルの書き換えみたいな最低限の書き込みや変更ができなくなってしまうので、 書き込みができる領域が別にほしいということになる。
というわけで、公式のRaspbian OSイメージをカスタマイズして、bootとrootfsの他にもう一つパーティションを追加する手順をまとめた。
作業環境とRaspbian OSイメージのバージョン
作業環境は今回もLinux PC。
Raspbianのイメージは(もう新しいの出てるけど)2018-11-13-raspbian-stretch-lite.img
を利用した。
カスタマイズ手順
作業は次のように行った。
カスタマイズ用のOSイメージを作ってパーティションの状況確認
まずカスタマイズ用に公式イメージのコピーを作成した。
$ cp 2018-11-13-raspbian-stretch-lite.img 2018-11-13-raspbian-stretch-lite-custom.img
次にfdiskで現在のイメージのパーティション状況を確認した。
$ fdisk -l 2018-11-13-raspbian-stretch-lite-custom.img Disk 2018-11-13-raspbian-stretch-lite-custom.img: 1.8 GiB, 1866465280 bytes, 3645440 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ee80803 デバイス 起動 Start 最後から セクタ Size Id タイプ 2018-11-13-raspbian-stretch-lite-custom.img1 8192 98045 89854 43.9M c W95 FAT32 (LBA) 2018-11-13-raspbian-stretch-lite-custom.img2 98304 3645439 3547136 1.7G 83 Linux
デバイス2018-11-13-raspbian-stretch-lite-custom.img1
がbootパーティションで、
2018-11-13-raspbian-stretch-lite-custom.img2
がrootfsパーティションに当たる。
OSイメージのファイルサイズを増やす
パーティションを追加できるようにするために、まずtruncateを使ってOSイメージのファイルサイズを増やす。
$ truncate -s 4GiB 2018-11-13-raspbian-stretch-lite-custom.img
とりあえず4GBまで増やした。
改めてfdiskでイメージの状況を確認する。
$ fdisk -l 2018-11-13-raspbian-stretch-lite-custom.img Disk 2018-11-13-raspbian-stretch-lite-custom.img: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ee80803 デバイス 起動 Start 最後から セクタ Size Id タイプ 2018-11-13-raspbian-stretch-lite-custom.img1 8192 98045 89854 43.9M c W95 FAT32 (LBA) 2018-11-13-raspbian-stretch-lite-custom.img2 98304 3645439 3547136 1.7G 83 Linux
イメージのサイズが1.8GBから4GBまで増えたことが確認できる。
rootfsのパーティションサイズを変更
次にrootfsのパーティションサイズを拡張する。
fdiskの対話モードでカスタムイメージを開いて、dコマンドで一度rootfsのパーティションを削除し、nコマンドで改めて作りなおす。
この時新たに作るパーティションのFirst sectorはもともとの値(今回であれば98304)を指定する。
Last sectorは今回はrootfsを3GB固定にするので+3G
を指定した。
$ fdisk 2018-11-13-raspbian-stretch-lite-custom.img Welcome to fdisk (util-linux 2.27.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. コマンド (m でヘルプ): d パーティション番号 (1,2, default 2): 2 Partition 2 has been deleted. コマンド (m でヘルプ): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p パーティション番号 (2-4, default 2): 2 First sector (2048-8388607, default 2048): 98304 Last sector, +sectors or +size{K,M,G,T,P} (98304-8388607, default 8388607): +3G Created a new partition 2 of type 'Linux' and of size 3 GiB.
作りなおしたrootfsパーティションをpコマンドで確認すると次のようになる。
コマンド (m でヘルプ): p Disk 2018-11-13-raspbian-stretch-lite-custom.img: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ee80803 デバイス 起動 Start 最後から セクタ Size Id タイプ 2018-11-13-raspbian-stretch-lite-custom.img1 8192 98045 89854 43.9M c W95 FAT32 (LBA) 2018-11-13-raspbian-stretch-lite-custom.img2 98304 6389759 6291456 3G 83 Linux
書き込み用領域のパーティションを追加
次に書き込み領域にする予定のパーティションをnコマンドで追加する。
First sectorは2018-11-13-raspbian-stretch-lite-custom.img2
の最後のセクタ + 1の値(今回であれば6389760)とし、
Last sectorは指定せずにイメージファイルのサイズいっぱいまでを使う。
コマンド (m でヘルプ): n Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): p パーティション番号 (3,4, default 3): 3 First sector (2048-8388607, default 2048): 6389760 Last sector, +sectors or +size{K,M,G,T,P} (6389760-8388607, default 8388607): Created a new partition 3 of type 'Linux' and of size 976 MiB.
追加したパーティションをpコマンドで確認する。
コマンド (m でヘルプ): p Disk 2018-11-13-raspbian-stretch-lite-custom.img: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ee80803 デバイス 起動 Start 最後から セクタ Size Id タイプ 2018-11-13-raspbian-stretch-lite-custom.img1 8192 98045 89854 43.9M c W95 FAT32 (LBA) 2018-11-13-raspbian-stretch-lite-custom.img2 98304 6389759 6291456 3G 83 Linux 2018-11-13-raspbian-stretch-lite-custom.img3 6389760 8388607 1998848 976M 83 Linux
wコマンドでパーティションの変更を反映してfdiskの対話モードを抜ける。
コマンド (m でヘルプ): w The partition table has been altered. Syncing disks.
書き込み用領域のフォーマットとラベル付け
追加したパーティションはまだフォーマットしていないので、フォーマットするためにイメージをLinux PCでマウントできるようにする。 これにはkpartxを利用してイメージファイル内のパーティションをデバイスにマッピングする。
$ sudo kpartx -av 2018-11-13-raspbian-stretch-lite-custom.img add map loop0p1 (253:0): 0 89854 linear 7:0 8192 add map loop0p2 (253:1): 0 6291456 linear 7:0 98304 add map loop0p3 (253:2): 0 1998848 linear 7:0 6389760
各パーティションは/dev/mapper
下にマッピングされる。
$ ls /dev/mapper control loop0p1 loop0p2 loop0p3
/dev/mapper/loop0p1
がboot、/dev/mapper/loop0p2
がrootfs、/dev/mapper/loop0p3
が今回追加したパーティションに当たる。
/dev/mapper/loop0p3
をEXT4でフォーマットする。
$ sudo mkfs -t ext4 /dev/mapper/loop0p3 mke2fs 1.42.13 (17-May-2015) Discarding device blocks: done Creating filesystem with 249856 4k blocks and 62464 inodes Filesystem UUID: 828efd40-40d9-42f9-85f7-5d39b1154840 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done
わかりやすいようにパーティションにラベルをつける。
$ sudo e2label /dev/mapper/loop0p3 extrafs
ラベルがついたか確認。
$ sudo e2label /dev/mapper/loop0p3 extrafs
rootfsの自動リサイズを無効化・書き込み用領域のマウントを設定
bootとrootfsのファイルに手を加えるために、それぞれのマウントポイントを作成する。
$ mkdir boot $ mkdir rootfs
bootをマウントする。
$ sudo mount /dev/mapper/loop0p1 boot
rootfsをマウントする。
$ sudo mount /dev/mapper/loop0p2 rootfs
boot/cmdline.txt
を編集し、末尾のinit=/usr/lib/raspi-config/init_resize.sh
を削除して、初回起動時のrootfsの自動拡張を無効にする。
$ sudo vi boot/cmdline.txt`
編集後のboot/cmdline.txt`は次のようになる。
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=7ee80803-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet
rootfs/etc/fstab
を編集し、extrafsパーティションが起動時にマウントされるように設定する。
末尾に/dev/mmcblk0p3 /extra ext4 defaults,noatime 0 1
を追加する。
$ sudo vi rootfs/etc/fstab
編集後のrootfs/etc/fstab
は次のようになる。
proc /proc proc defaults 0 0 PARTUUID=7ee80803-01 /boot vfat defaults 0 2 PARTUUID=7ee80803-02 / ext4 defaults,noatime 0 1 /dev/mmcblk0p3 /extra ext4 defaults,noatime 0 1
他のパーティションがPARTUUID指定なのでちょっと歪だけどとりあえずこれで行く。
rootfs内にextrafs用のマウントポイントを追加しておく。
$ sudo mkdir rootfs/extra
bootとrootfsをアンマウントする。
$ sudo umount boot $ sudo umount rootfs
$ sudo kpartx -d 2018-11-13-raspbian-stretch-lite-custom.img
カスタムイメージの動作確認
出来上がったカスタムイメージをSDカードに書き込む。
$ sudo dd if=2018-11-13-raspbian-stretch-lite-custom.img of=/dev/mmcblk0 bs=1M 4096+0 レコード入力 4096+0 レコード出力 4294967296 bytes (4.3 GB, 4.0 GiB) copied, 776.849 s, 5.5 MB/s
書き込み完了したSDカードをRaspberry PIに入れて起動する。
起動したRaspbianにログインし、fdiskでパーティションの状況を確認する。
$ sudo fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 7.4 GiB, 7969177600 bytes, 15564800 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x7ee80803 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 8192 98045 89854 43.9M c W95 FAT32 (LBA) /dev/mmcblk0p2 98304 6389759 6291456 3G 83 Linux /dev/mmcblk0p3 6389760 8388607 1998848 976M 83 Linux
mountの状況を確認する。
$ mount /dev/mmcblk0p2 on / type ext4 (rw,noatime,data=ordered) devtmpfs on /dev type devtmpfs (rw,relatime,size=217616k,nr_inodes=54404,mode=755) sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime) proc on /proc type proc (rw,relatime) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000) tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755) tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k) tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755) cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) sunrpc on /run/rpc_pipefs type rpc_pipefs (rw,relatime) debugfs on /sys/kernel/debug type debugfs (rw,relatime) systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct) mqueue on /dev/mqueue type mqueue (rw,relatime) configfs on /sys/kernel/config type configfs (rw,relatime) /dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro) /dev/mmcblk0p3 on /extra type ext4 (rw,noatime,data=ordered) tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=44384k,mode=700,uid=1000,gid=1000)
/dev/mmcblk0p3 on /extra type ext4 (rw,noatime,data=ordered)
となっていれば/extra
に追加したパーティションがマウントされていることが確認できる。
まとめ
とりあえず分割までできた。
この作業をいちいち手でやるのが面倒になったので、作成用スクリプト作った。
$ sudo ./create-extra-partition <path to>/YYYY-MM-DD-raspbian-stretch-lite.img
みたいな感じで作成できる。