みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject bitbake-hashservを使ってみる(TCP/IP編)

はじめに

前回unix domain socketでローカルPC上でsstate-cacheを共有した。

今回はリモートPCでsstate-cacheを共有してみる。

bitbake-hashservの実行

サーバのIPアドレス

リモートPCから接続するためにIPアドレスを決めておく必要がある。

今回は192.168.1.100とする。

サーバ側の設定

サーバとなる初回ビルドを行う環境についてはlocal.confにこのような設定があれば良い。

BB_HASHSERVE = "auto"
BB_SIGNATURE_HANDLER = "OEEquivHash"

このままbitbakeを実行して「hashserv.db」と「sstate-cache」が生成されれば必要なデータは揃う。 もちろん初回実行時なので数時間はかかる。

サーバ側環境の構築

実際にbitbake-hashservを動かす環境を作成してみる。

$ mkdir -p ~/yocto/rpi-kirkstone
$ cd ~/yocto/rpi-kirkstone
$ git clone git://git.yoctoproject.org/poky.git -b kirkstone
$ source poky/oe-init-build-env build-hashserv
$ bitbake-layers layerindex-fetch meta-raspberrypi

local.confに下記を追加する。

MACHINE = "raspberrypi4-64"

# setup for hashserv database
BB_SIGNATURE_HANDLER = "OEEquivHash"

# enable uart
ENABLE_UART = "1"

# systemd
INIT_MANAGER = "systemd"

これでbitbakeを実行する。

$  bitbake core-image-base

ここまでは前回と同じ。

SSTATE_DIRの公開

bitbake-hashservでリモートからの接続を受け付ける前に、SSTATE_DIRに保存されているssatete-cacheをリモートからアクセスできるようにする必要がある。

httpでアクセスできるようにpythonhttp.serverを使用する。

$ cd ~/yocto/rpi-kirkstone/build-hashserv/sstate-cache
$ python3 -m http.server 9000

bitbake-hashserv

別の端末でbitbake-hashservを起動する。

$ cd ~/yocto/rpi-kirkstone
$ source poky/oe-init-build-env build-hashserv
$ bitbake-hashserv -r -l debug -d ./cache/hashserv.db -b "0.0.0.0:8687"

bitbake-hashservへの接続

クライアント環境の構築

クライアントとなる別のPCでYoctoProjectの環境を作成する。

$ mkdir -p ~/yocto/rpi-kirkstone
$ cd ~/yocto/rpi-kirkstone
$ git clone git://git.yoctoproject.org/poky.git -b kirkstone
$ source poky/oe-init-build-env
$ bitbake-layers layerindex-fetch meta-raspberrypi

local.confの設定

local.confに下記の内容を追加する。

MACHINE = "raspberrypi4-64"

# setup for connecting to bitbake-hashserv
BB_SIGNATURE_HANDLER = "OEEquivHash"
BB_HASHSERVE = "192.168.1.100:8687"
SSTATE_MIRRORS = "file://.* http://192.168.1.100:9000/PATH"

# enable uart
ENABLE_UART = "1"

# systemd
INIT_MANAGER = "systemd"

bitbake-hashservへの接続

接続のための設定をlocal.confに行ったため、bitbakeを実行してみる。

$ time bitbake core-image-base
... (snip) ...
real    7m56.090s
user    0m15.131s
sys     0m2.858s

今回使用したクライアント用のPCはビルドPCのスペックからみるとコア数が1/4のノートPCなので、通信の遅延を考慮しても 約8分でbitbakeが完了するのはやはりすごい。

応用編 kasをつかう

リモートでsstate-cacheを共有する時に最大限に効果を得るためには下記のようなことをサーバ側と揃える必要がある。

  1. 使用するレイヤ
  2. レイヤのリビジョン
  3. bitbake-hashservへの接続情報

それらを手動で揃えるのもそこまで手間ではないがkasを使用するともっと確実に環境を整えることができる。

kasのインストール

kasはpipでインストールできる

$ pip3 install --user kas

設定ファイルの作成

kasはYAML形式の設定ファイルを使用してbitbake環境を整えてくれる。bblayers.confやlocal.confまで自動生成してくれるので、 YAMLファイルを共有しておけば確実に同じ環境を作成することができる。

この内容と適当な名前で保存する。今回はtest.yamlとする。

header:
  version: 14

machine: raspberrypi4-64
distro: poky
target:
  - core-image-base

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    path: poky
    refspec: 6cb27ba5379e0132d7ec46f1633c24855a3fa298
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

  meta-raspberry:
    url: https://git.yoctoproject.org/meta-raspberrypi
    path: poky/meta-raspberrypi
    refspec: 9dc6673d41044f1174551120ce63501421dbcd85

bblayers_conf_header:
  standard: |
    POKY_BBLAYERS_CONF_VERSION = "2"
    BBPATH = "${TOPDIR}"
    BBFILES ?= ""

local_conf_header:
  standard: |
    CONF_VERSION = "2"
    PACKAGE_CLASSES = "package_rpm"
    SDKMACHINE = "x86_64"
    USER_CLASSES ?= "buildstats"
    PATCHRESOLVE = "noop"
  debug-tweaks: |
    EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
  diskmon: |
    BB_DISKMON_DIRS ??= "\
      STOPTASKS,${TMPDIR},1G,100K \
      STOPTASKS,${DL_DIR},1G,100K \
      STOPTASKS,${SSTATE_DIR},1G,100K \
      STOPTASKS,/tmp,100M,100K \
      HALT,${TMPDIR},100M,1K \
      HALT,${DL_DIR},100M,1K \
      HALT,${SSTATE_DIR},100M,1K \
      HALT,/tmp,10M,1K"
  qemu_configuration: |
    PACKAGECONFIG:append:pn-qemu-system-native = " sdl"
  hashserv: |
    BB_SIGNATURE_HANDLER = "OEEquivHash"
    BB_HASHSERVE = "192.168.1.100:8687"
    SSTATE_MIRRORS = "file://.* http://192.168.1.100:9000/PATH"
  enable_uart: |
    ENABLE_UART = "1"
  systemd: |
    INIT_MANAGER = "systemd"

kasの実行

今回はビルド時間を計測したいので下記を実行して予めビルド環境を取得しておく。

$ kas checkout test.yaml

ビルドを実行する。書きを実行することでkasの中からbitbakeが呼び出される。

$ time kas build tests.yaml
... (snip) ...
real    7m39.846s
user    0m15.850s
sys     0m2.914s

手動で作成した環境のビルド時間とほぼ同じとなる。

「kas checkout」を実行せずに「kas build」を実行した場合でも自動的にcheckout相当の処理が実行される。 また、一度checkoutして環境を作成してしまえばkasを使用せずに通常通りbitbakeを使ってビルドすることもできる。

BSPによってはrepoツールで複数のレイヤを管理するケースもあるがrepoはリポジトリの管理しかしないため、 local.confやbblayers.confなどは自分で生成する必要がある。 サーバ設定などの反映は手動で行うか、自動化したければ自分でスクリプトなどを作成する必要がある。

まとめ

リモートで他のPCのsstate-cacheを共有する方法についてまとめた。 クライアント側の設定を解説する情報はわりとよく見かけるが、サーバ側の設定については見かけないので、調べるのに少し苦労した。 クライアント側でサーバの共通設定を共有するためにはkasは便利だが、それを使用しない場合でも共通設定だけsite.confに記述して共有する方法もある。

自前でsstate-cacheのサーバを構築できれば、社内などでYoctoProjectを使用する際の作業効率は劇的に向上するのではなかろうか。