PXE Gentooのdistccdログとsystemd sandboxを切り分ける

PXE Gentooのdistccdログとsystemd sandboxを切り分ける

目的

PXE boot した Gentoo client で distccd を systemd 管理するとき、root filesystem の overlay 状態と systemd sandbox の制限を分けて考える。

/var/log が overlayfs 上で書き込み可能でも、unit に ProtectSystem=strict があると、service process からは明示許可した path にしか書けない。

症状

distccd は起動しているが、journal に次のような log open failure が出る。

distccd: failed to open /var/log/distccd.log: Read-only file system

このとき、host 側で見ると //var/log は overlayfs 上にある。

/        overlayfs
/var/log overlayfs

したがって、すぐに「root overlay が read-only」と判断しない。

原因層

systemd unit が次のような sandbox を持つ場合がある。

ProtectSystem=strict
ReadWritePaths=/run/distcc

ProtectSystem=strict/usr/boot/etc などだけでなく、広い範囲を service から read-only に見せる。

この状態で distccd/var/log/distccd.log に書こうとすると、root filesystem 自体は writable でも、service sandbox により書けない。

対応

許可する path を最小化する。

ProtectSystem=strict
ReadWritePaths=/run/distcc /var/log/distccd.log

/var/log 全体を許可するより、必要な log file だけを許可する方が影響範囲を小さくできる。

PXE overlayでのログ扱い

tmpfs upper の root overlay では、/var/log/distccd.log は再起動で消える一時ログになる。

永続的に追いたい場合は、journald remote、syslog forwarding、または router / build host 側の log collection を使う。

確認コマンド

client 側:

findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS / /var/log
systemctl cat distccd --no-pager
systemctl show distccd -p ProtectSystem -p ReadWritePaths -p ExecStart --no-pager
journalctl -u distccd -b --no-pager

build root 側:

grep -nE 'FEATURES|DISTCC_HOSTS|MAKEOPTS|EMERGE_DEFAULT_OPTS' /etc/portage/make.conf
distcc --show-hosts

distcc host管理

PXE client や build root が増えると、DISTCC_HOSTS を手書きし続けるのはつらい。

Ansible などで管理する場合は、hostvars に次のような情報を持たせ、build root 側の make.conf/etc/distcc/hosts を同じ source から生成すると確認しやすい。

distcc:
  enabled: true
  slots: 4
  jobs: 4
  nice: 5

MAKEOPTS は 1 package 内の build 並列度、emerge --jobs は複数 package の同時 emerge 数を決める。distcc host があっても、preprocess、link、install は client / build root 側に残るため、I/O stall や memory pressure が出る場合は --jobs を下げる。

注意点

  • distcc-pump は package build 全体で使うと問題が出やすい。system-wide で安易に有効化しない。
  • gcc version / CHOST / cross compiler prefix は client と server で揃える。
  • root overlay の問題と systemd sandbox の問題を混ぜない。
  • ProtectSystem=strict は外さず、必要な writable path だけを追加する。