はじめに
YoctoProjectではwicツールを使用することで、SDなどのストレージに直接書き込めるイメージを作成することができる。 wicイメージを作成する時点では書き込むストレージのサイズがわからないため、基本的には必要最低限のサイズでイメージは作成される様になっている。
データ領域などを多めに取りたい場合は、IMAGE_ROOTFS_EXTRA_SPACEなどの変数でファイルシステムの領域を確保することができるが、 その場合でも、実際に書き込むストレージのサイズはわからないため目一杯というのは難しい。
systemd-growfsを使用すると、初回システム起動時に指定したデバイスのファイルシステムをパーティションサイズいっぱいに拡張することができるが、パーティションサイズ自体は拡張されない。
そのため、ストレージ全体を使うためには少し工夫が必要となる。 meta-rauc-communityにその実装のヒントがあるため参考にしてみる。
環境構築
作業環境
$ mkdir -p ~/yocto/rpi-kirkstone $ cd ~/yocto/rpi-kirkstone
pokyの取得
$ git clone git://git.yoctoproject.org/poky.git -b kirkstone
環境変数の設定
$ source poky/oe-init-build-env
meta-raspberrypiの取得
$ bitbake-layers layerindex-fetch meta-raspberrypi
local.confを編集
MACHINE = "raspberrypi4-64" DL_DIR = "${TOPDIR}/../downloads" # systemd DISTRO_FEATURES:append = " systemd pam" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" # enable uart ENABLE_UART = "1"
レイヤを作成
meta-workを作成
$ bitbake-layers create-layer meta-work $ rm -rf ./meta-work/recipes-example $ mkdir -p ./meta-work/recipes-support/repart/files ./meta-work/wic $ bitbake-layers add-layer ./meta-work
レシピ作成
サービスファイル
systemdのサービスを作成するが、一部はbitbakeするまで内容が未確定なので、 変数にしておき、レシピを処理する過程で内容を確定させる。
そのためには次のようにsystemdのユニットそのものではなくテンプレートを作成する。
[Unit] Description=Service to resizing parition DefaultDependencies=no Before=local-fs.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/sbin/parted --script @repart-dev@ resizepart @repart-no@ 100% [Install] WantedBy=local-fs.target
[2023/1/28 追記]システムの2回目以降の起動時間を改良したバージョンをYoctoProject systemdでシステム起動時間計測で紹介している.
この内容をmeta-work/recipes-support/repart/files/repart.service.in
として保存する。
最後の.in
は慣例的にそのファイルがテンプレートであるということを示している。
つまり、.inがついているファイルに何らかの加工を加えることで、.inのないファイル(ここでは「repart.service」)が出来上がることを示している。
これの本体は下記の部分で、指定のパーティションストレージ目一杯に拡張する。
ExecStart=/usr/sbin/parted --script @repart-dev@ resizepart @repart-no@ 100%
repart.bb
meta-work/recipes-support/repart/repart.bb
を以下の内容で作成する。
SUMMARY = "resize partition for data" DESCRIPTION = "Recipe for resizin the partition and filesystem" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" REPART_DEV ??= "" REPART_NO ??= "" REPART_MOUNTPOINT ??= "" ALLOW_EMPTY:${PN} = "1" SRC_URI = "file://repart.service.in" RDEPENDS:${PN} = "parted" inherit systemd features_check REQUIRED_DISTRO_FEATURES = "systemd" S = "${WORKDIR}" do_compile() { if [ -z "${REPART_DEV}" ]; then bbfatal "REPART_DEV should be set." fi if [ -z "${REPART_NO}" ]; then bbfatal "REPART_NO should be set." fi sed -e "s#@repart-dev@#/dev/${REPART_DEV}#g; s#@repart-no@#${REPART_NO}#g" \ repart.service.in > repart.service } do_install() { if [ -n "${REPART_MOUNTPOINT}" ]; then install -d ${D}${REPART_MOUNTPOINT} fi install -d ${D}${systemd_unitdir}/system/ install -m 0644 ${S}/repart.service ${D}${systemd_system_unitdir} } SYSTEMD_SERVICE:${PN} = "repart.service" FILES:${PN} = "\ ${systemd_system_unitdir} \ ${REPART_MOUNTPOINT} \ "
下記の3つの変数は、必要に応じてlocal.conf
などで設定する。
REPART_DEV ??= "" REPART_NO ??= "" REPART_MOUNTPOINT ??= ""
do_compileタスクでは、先程のrepart.service.in
を処理し、repart.service
を作成する。
wksファイルを作成
meta-work/wic/sdimage-raspberrypi-growfs.wks.in
を下記の内容で作成し、/home
にx-systemd.growfsを指定することにより、システム起動時にパーティションジいっぱいに拡張されるようにする。
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4096 --size 20 part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 4096 part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --ondisk mmcblk0 --fstype=ext4 --label homefs --align 1024 --size 500 --fsoptions "x-systemd.growfs"
拡張子をwks
ではなくwks.in
とすることで、wksファイルの中でbitbakeの変数を使用することができる。
local.confの修正
local.confに下記を追加する。
IMAGE_INSTALL:append = " repart" REPART_DEV ?= "mmcblk0" REPART_NO ?= "3" #REPART_MOUNTPOINT ?= "" WKS_FILE = "sdimage-raspberrypi-growfs.wks.in"
今回は既存の/homeを拡張するためREPART_MOUNTPOINT
は指定しない。
動作確認
ビルド
$ bitbake core-image-base
動作確認
出来上がったイメージでラスベリーパイ4を起動する。
root@raspberrypi4-64:~# fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 3768 MB, 3951034368 bytes, 7716864 sectors 120576 cylinders, 4 heads, 16 sectors/track Units: sectors of 1 * 512 = 512 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/mmcblk0p1 * 64,0,1 1023,3,32 8192 152543 144352 70.4M c Win95 FAT32 (LBA) /dev/mmcblk0p2 1023,3,32 1023,3,32 155648 624229 468582 228M 83 Linux /dev/mmcblk0p3 1023,3,32 1023,7,32 624640 7716863 7092224 3463M 83 Linux
/dev/mmcblk0p3が3463Mになっていることがわかる。
下記mountの結果
root@raspberrypi4-64:~# mount | grep home /dev/mmcblk0p3 on /home type ext4 (rw,relatime,x-systemd.growfs)
次にdfの結果
root@raspberrypi4-64:~# df -h | grep home /dev/mmcblk0p3 3.4G 89.5M 3.2G 3% /home
/dev/mmcblk0p3がext4でフォーマットされ、3.4Gとして認識されている。また、/homeにマウントされていることが確認できる。
パーティションを追加
wksとlocal.confの修正
第4パーティションとして/data
を追加してみる。sdimage-raspberrypi-growfs.wks.inを下記のように修正する。
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4096 --size 20 part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 4096 part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --ondisk mmcblk0 --fstype=ext4 --label homefs --align 1024 --size=100M part /data --ondisk ${REPART_DEV} --fstype=ext4 --label data --align 4096 --size=1024 --fsoptions "x-systemd.growfs"
/data
は既存のルートファイルシステムには存在しないのでlocal.confでREPART_MOUNTPOINT
を設定する。
IMAGE_INSTALL:append = " repart" REPART_DEV ?= "mmcblk0" REPART_NO ?= "4" REPART_MOUNTPOINT ?= "/data"
動作確認
fdiskの結果
root@raspberrypi4-64:~# fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 3768 MB, 3951034368 bytes, 7716864 sectors 120576 cylinders, 4 heads, 16 sectors/track Units: sectors of 1 * 512 = 512 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/mmcblk0p1 * 64,0,1 1023,3,32 8192 152543 144352 70.4M c Win95 FAT32 (LBA) /dev/mmcblk0p2 1023,3,32 1023,3,32 155648 624229 468582 228M 83 Linux /dev/mmcblk0p3 1023,3,32 1023,3,32 624640 890879 266240 130M 83 Linux /dev/mmcblk0p4 1023,3,32 1023,7,32 892928 7716863 6823936 3332M 83 Linux
mountの結果
root@raspberrypi4-64:~# mount | grep mmc /dev/mmcblk0p2 on / type ext4 (rw,relatime) /dev/mmcblk0p3 on /home type ext4 (rw,relatime) /dev/mmcblk0p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,errors=remount-ro) /dev/mmcblk0p4 on /data type ext4 (rw,relatime,x-systemd.growfs)
まとめ
meta-rauc-communityの実装にヒントを得てrepart.bbを実装してみた。
指定したデバイスの最後のパーティションを指定することで、そのパーティションおよびファイルシステムがストレージの残り目一杯まで拡張されることを確認した。
もちろん途中のパーティションを指定しても拡張することはできない。