web-dev-qa-db-ja.com

Systemd:別のユニットが本当に開始した後にユニットを開始する

私の特定のケースでは、すべてのglusterfsが完全に開始した後でremote-fsユニットを開始したいと思います。

私のsystemdファイル:

glusterfsターゲット:

node04:/usr/lib/systemd/system # cat glusterfsd.service 
[Unit]
Description=GlusterFS brick processes (stopping only)
After=network.target glusterd.service

[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
ExecStop=/bin/sh -c "/bin/killall --wait glusterfsd || /bin/true"
ExecReload=/bin/sh -c "/bin/killall -HUP glusterfsd || /bin/true"

[Install]
WantedBy=multi-user.target

remote-fsターゲット:

node04:/usr/lib/systemd/system # cat remote-fs.target 
[Unit]
Description=Remote File Systems
Documentation=man:systemd.special(7)
Requires=glusterfsd.service
After=glusterfsd.service remote-fs-pre.target
DefaultDependencies=no
Conflicts=shutdown.target

[Install]
WantedBy=multi-user.target

OK、すべてのGlusterデーモンが正常に起動し、NFS経由でGlusterファイルシステムをマウントしたいのですが、GlusterのNFS共有はglusterfs.serviceの開始直後ではなく数秒後に準備ができているため、通常remote-fsはマウントできませんRequiresおよびAfterディレクティブについても同様です。

ログを見てみましょう:

Apr 14 16:16:22 node04 systemd[1]: Started GlusterFS, a clustered file-system server.
Apr 14 16:16:22 node04 systemd[1]: Starting GlusterFS brick processes (stopping only)...
Apr 14 16:16:22 node04 systemd[1]: Starting Network is Online.
Apr 14 16:16:22 node04 systemd[1]: Reached target Network is Online.
Apr 14 16:16:22 node04 systemd[1]: Mounting /stor...

ここではすべてが正常です。リモートファイルシステム(/ stor)は、glusterfsの起動後にマウントされているようです。これは、ユニットファイルに従っているためです...しかし、次の行は次のとおりです。

//...skipped.....
Apr 14 16:16:22 node04 systemd[1]: Started GlusterFS brick processes (stopping only).

何? GlusterFSはこの瞬間のためだけに準備されました!そして、私たちは見る:

//...skipped.....
Apr 14 16:16:23 node04 mount[2960]: mount.nfs: mounting node04:/stor failed, reason given by server: No such file or directory
Apr 14 16:16:23 node04 systemd[1]: stor.mount mount process exited, code=exited status=32
Apr 14 16:16:23 node04 systemd[1]: Failed to mount /stor.
Apr 14 16:16:23 node04 systemd[1]: Dependency failed for Remote File Systems.
Apr 14 16:16:23 node04 systemd[1]: Unit stor.mount entered failed state.

SystemdがストレージをマウントしようとしたときにNFSサーバーの準備ができていなかったため、マウントが失敗しました。

Systemdブートプロセスの非決定的な性質により、このファイルシステムのブートへのマウント(10ブートのうち約1)が成功する場合があります。

Onbootマウントが失敗した場合、サーバーにログインして手動で/ storディレクトリをマウントできるため、GlusterのNFSサービスは正常に動作しているようです。

では、glusterfsdの後、つまりremote-fs行がログに表示された後にStarted GlusterFS brick processesを開始する方法は?

remote-fsは最後のターゲットの1つであると思われるため、remote-fsでは実際には必要とされていない別の「回避策」ターゲットの後に開始することはできません。

21
Sergey

次のコマンドでsystemdのブートシーケンスを分析できます。 SVG対応のWebブラウザーを使用して出力ファイルを表示します。

systemd-analyze plot > test.svg

そのプロットは、最後の起動のタイミング統計を提供し、問題に対するより明確な視点を提供します。

/etc/rc.localmountコマンドを追加して、NFSマウントの問題を解決しました。ただし、確信が持てません。glusterd統合で動作するので、簡単な修正を試してみる価値はあります。 systemdでrc.localを実行するには、次の条件を満たす必要があります。

# grep Condition /usr/lib/systemd/system/rc-local.service
ConditionFileIsExecutable=/etc/rc.d/rc.local
3
aesnak

他の人がすでに示唆したように;それが実際に「glusterfsd」への依存関係であるかどうかはわかりません。たとえば、「node4」を解決してNFS共有を正常にマウントするために成功する必要があるDNSルックアップなど、他の一般的な遅延ではありません。

ほとんどの設定ではローカル検証リゾルバーを使用しているため、この遅延が発生しました。DNSに依存する他のサービスが正常に開始する前に、このリゾルバーを使用できるようにする必要があります。

これに対する解決策は、基本的に、特定の依存関係の可用性が成功する(exit 0)か、試行がタイムアウトする(exit 1)まで、繰り返しテストする「ExecStartPre」スクリプトを用意することでした。

可能であれば、メインのsystemd libディレクトリ以外でカスタマイズしてください。パッケージファイルを変更すると、次のアップデートで上書きされる可能性があります。

1
user304238

たぶんいくつかの投票が役立つかもしれません。これはsystemdから独立しています。たとえば、mysqlで何か便利なことをする前に、ループでmysql -e ';'を使用します。

0
user97619

多分これをremote-fsターゲットに追加できます:

[Unit]
...
ConditionPathExists=/stor
0
Markus