読み取り専用/ファイルシステムでsystemd-timesyncを使用する

読み取り専用/ファイルシステムでsystemd-timesyncを使用する

読み取り専用ファイルシステムでRaspberry Piを設定しようとしています。デフォルトのイメージはDebian Buster lite Raspbianイメージです。
次の簡単な修正が必要な場合は、ほとんどの操作が機能します。

mv /etc/resolv.conf /var/run/resolv.conf && ln -s /var/run/resolv.conf /etc/resolv.conf

DHCPなどのサービスに類似

しかし、サービスが欲しいが、systemd-timesyncのような動作を拒否します。

私がしたことと起こったことは次のとおりです。 systemd-timesyncユーザーsystemd-timesync:systemd-timesyncが所有する/run/systemd-timesyncディレクトリを作成し、/var/lib/systemd/timesync -> /run/systemd -timesyncシンボリックリンクを作成しました。

root@raspberrypi:/var/lib/systemd # ls -l /var/lib/systemd/timesync
lrwxrwxrwx 1 root root 21 Dec 25 14:48 /var/lib/systemd/timesync -> /run/systemd-timesync

root@raspberrypi:/var/lib/systemd # ls -l /run/systemd-timesync/
total 0
-rw-r--r-- 1 systemd-timesync systemd-timesync 0 Dec 25 15:02 clock

システム単位ファイルの関連部分:

...
[Service]
User=systemd-timesync
AmbientCapabilities=CAP_SYS_TIME
CapabilityBoundingSet=CAP_SYS_TIME
WorkingDirectory=/run/systemd-timesync
Environment=SYSTEMD_LOG_LEVEL=debug
ExecStartPre=/bin/pwd
ExecStart=!!/lib/systemd/systemd-timesyncd
...
RuntimeDirectory=systemd/timesync
StateDirectory=systemd/timesync
...

現在の作業ディレクトリのみをログに出力するExecStartPre = / bin / pwdを追加しました。

systemd-timesyncを起動して/を読み取り専用としてマウントすると、次のことが起こります。

root@raspberrypi:/var/lib/systemd # systemctl stop systemd-timesyncd.service && systemctl daemon-reload && systemctl start systemd-timesyncd.service
Job for systemd-timesyncd.service failed because of unavailable resources or another system error.
See "systemctl status systemd-timesyncd.service" and "journalctl -xe" for details.

Journalctl 出力

Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Trying to enqueue job systemd-timesyncd.service/stop/replace
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Installed new job systemd-timesyncd.service/stop as 1214
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Enqueued job systemd-timesyncd.service/stop as 1214
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Job 1214 systemd-timesyncd.service/stop finished, result=done
Dec 25 15:34:10 raspberrypi systemd[1]: /lib/systemd/system/systemd-timesyncd.service:36: Failed to parse system call, ignoring: io_pgetevents
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Changed dead -> failed
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Trying to enqueue job systemd-timesyncd.service/start/replace
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Installed new job systemd-timesyncd.service/start as 1215
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Enqueued job systemd-timesyncd.service/start as 1215
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/VBoxService succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/chronyd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/openntpd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/ntpd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionVirtualization=!container succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionCapability=CAP_SYS_TIME succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Failed to run 'start-pre' task: Read-only file system
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Failed with result 'resources'.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Job 1215 systemd-timesyncd.service/start finished, result=failed
Dec 25 15:34:11 raspberrypi systemd[1]: Failed to start Network Time Synchronization.

明らかに、読み取り専用ファイルシステムのため、ExecStartPreの/bin/pwdが失敗しました。私はこれを理解しておらず、それを修正する方法がわかりません。 ExecStartPreを削除すると、ExecStartコマンドでも同じことが起こります。

しかし、私がこれをするとき、

mount -o remount,rw /

その後

root@raspberrypi:/var/lib/systemd # systemctl stop systemd-timesyncd.service && systemctl daemon-reload && systemctl start systemd-timesyncd.service

ログへのpwd出力​​を含むすべてがうまく機能します。

同じように始めたとき

root@raspberrypi:/var/lib/systemd # /lib/systemd/systemd-timesyncd
Synchronized to time server for the first time 84.199.86.247:123 (0.debian.pool.ntp.org).

すべてが正常です。

これまでの私の結論は、systemdがExecStartPreまたはExecStartからコマンドを起動するためにどこかに書き込みアクセス権が必要であることです。

Raspberryに時間設定を更新させる元の目標を達成する方法についてのアイデアはありますか?

注:これは、ユニットファイルのStateDirectory行とRuntimeDirectory行に関連している可能性があります。

答え1

これはDietPiの問題を解決しました。

  • /runはtmpfsとしてマウントされます。

  • /var/lib の下に StateDirectory へのソフトリンクを作成します。

    ln -s /run /var/lib/run

  • 無効PrivateTmp

    #PrivateTmp=yes

  • StateDirectoryをtmpfsに変更します。

    StateDirectory=run/timesync

RuntimeDirectory は /run に対して絶対的であり、すでに tmpfs なので、変更する必要はありません。

答え2

長い修正の最後に、[Unit]セクションで次の2行をコメントアウトするだけで十分であることがわかりました。

#CapabilityBoundingSet=CAP_SYS_TIME
#PrivateTmp=yes

読み取り専用/ファイルシステムで正しく機能するには、コメントアウトが必要な唯一の2行があることがわかりました。

これらの行のいずれかのコメントを外すと、読み取り専用ファイルシステムでsystemd-timesyncが機能しなくなる理由を理解できません。私はPrivateTmp = yesがプロセス用にプライベート/ tmpにマウントされたプライベートtmpfsを生成すると予想しましたが、明らかにそうではありません。もしそうなら、systemdのバグかもしれません。

答え3

overlayfs読み取り専用(ただし、偽の書き込み可能)/ファイルシステムの使用を検討する必要があります。これにより、特定のシステムサービスが失敗するのを防ぎます。

raspi-config>のスクリプトを使用してこれを行うことができます。4 Performance OptionsP3 Overlay File System

FSは読み取り専用ですが、書き込みは可能です(終了または再起動するとすべての変更が失われます)。

あなたは読むことができますラスピ構成詳細はスクリプトです。

答え4

ただ設定がStateDirectory=私にとって効果的です。システムファイルを編集する代わりに、次のような数行を追加できます/etc/systemd/system/systemd-timesyncd.service.d/local-allow-readonly.conf

[Service]
StateDirectory=

ディレクトリ/ファイルパスはハードコーディングされています。時間同期化プログラムUser=systemd-timesyncしたがって、systemd-timesyncdがディレクトリ自体を作成できないことを除いて、あまり変わりません。だから、

  • systemd-timesyncが最初に実行される前に(たとえば、初期設定スクリプトで)この操作を実行すると、ディレクトリ(およびクロックファイル)は生成されません。
  • ディレクトリの作成後にこれを行うと、ファイルシステムが読み取り/書き込みでマウントされている間に時計ファイルを更新できます。

(エラーがどこで発生するのか気になったらchmodを試してくださいモードが目的のモードに設定されていても、EROFSは失敗します。PrivateTmpとは関係がないようですCapabilityBoundingSet。 )

関連情報