ExecStopが失敗した場合、Systemdの状態はアクティブのままです。

ExecStopが失敗した場合、Systemdの状態はアクティブのままです。

スクリプトにエラーが発生した場合、ExecStop=/usr/lib/pick/d3shutdown_custom pick0systemdはシャットダウンプロセスを中止して状態に戻ることを望みますactive

スクリプトがコード4(ユーザー権限不足)で終了すると、systemdはその状態に閉じ込められますdeactivating

これは私のシステムサービスファイルです

[Unit]
Description=D3 multivalue database
After=d3_sn.service rslm.service
Requires=rslm.service
Wants=d3_sn.service

[Service]
Type=forking
ExecStart=/usr/bin/d3 -n pick0 -s -a x
ExecStop=/usr/lib/pick/d3shutdown_custom pick0
TimeoutSec=0
RemainAfterExit=true
SuccessExitStatus=11

[Install]
WantedBy=multi-user.target

d3shutdown_customこれはスクリプトの一部です


log_error() {
    echo -e "Error: $1"
    echo "Aborting program ... "
    echo " "
}

if [ ! -f "$D3_PROPERTIES_FILE" ]; then log_error "File $D3_PROPERTIES_FILE not found."; exit 2; fi
source $D3_PROPERTIES_FILE
export PICKUSER
export PICKUPASS

if d3 -q | grep -q 'not running'; then
        exit 11
fi

D3TCL=$(/usr/bin/d3tcl 'listu')
if echo $D3TCL | grep -q 'Bad User or User Password'; then log_error "Bad password"; exit 4; fi

ベストアンサー1

ちょっとトリッキーなリクエストですね。あなたが何かをするときsystemctl stopしなければならないそして〜するいつも降りてください。失敗するかもしれませんが、systemd必ずしなければならないとしても結局は止まるでしょう。FinalKillSignal=(SIGKILL)〜の後TimeStopSec=(90s)

条件が失敗した場合、「終了」や「再開」などの操作は不可能であり、これらの操作は常に可能でなければなりません。

私はこれを達成するための最良の方法は次のとおりです。Conflicts=条件付きで衝突するデバイスを起動するデバイスとデバイスOnFailure=。これはあなたがsystemctl stop my-unit考えを変えなければならないことを意味しますsystemctl start maybe-kill-my-unit

これがシャットダウンがどのように機能するかです。私たちは他のユニット、私たちをブロックしませんsystemctl start shutdown.target

c.service人々が直接使用するのを防ぎ、使用をさらにsystemctl stop a.service強化することができます。RefuseManualStop=yes

a.service
[Unit]
Description=Long running service
RefuseManualStop=yes

[Service]
ExecStart=/bin/sleep 60
b.service
[Unit]
Description=Killer of the long running service
Conflicts=a

[Service]
Type=oneshot
ExecStart=/bin/true
c.service
[Unit]
Description=Conditional killer of the long runing service
OnFailure=b

[Service]
Type=oneshot
ExecStart=/usr/local/bin/myscript

以下は実際の例です(c失敗した場合)。

$ systemctl --user start a
$ systemctl --user start c 
Job for c.service failed because the control process exited with error code.

$ systemctl --user status a b c --lines 0
● a.service
     Loaded: loaded (.config/systemd/user/a.service; static)
     Active: inactive (dead) since Mon 2023-10-09 16:10:18 CEST; 3s ago

● b.service
     Loaded: loaded (.config/systemd/user/b.service; static)
     Active: inactive (dead) since Mon 2023-10-09 16:10:18 CEST; 3s ago

● c.service
     Loaded: loaded (.config/systemd/user/c.service; static)
     Active: failed (Result: exit-code) since Mon 2023-10-09 16:10:18 CEST; 3s ago

$ journalctl --user -u a -u b -u c --since "1 minute ago"
Oct 09 16:10:14: Long running service
Oct 09 16:10:18: Starting Conditional killer of the long runing service
Oct 09 16:10:18: c.service: Main process exited, code=exited, status=1/FAILURE
Oct 09 16:10:18: c.service: Triggering OnFailure= dependencies.
Oct 09 16:10:18: Starting Killer of the long running service...
Oct 09 16:10:18: Stopping Long running service...
Oct 09 16:10:18: Finished Killer of the long running service.

成功した例は次のとおりですc

$ systemctl --user start a
$ systemctl --user start c
$ systemctl --user status a b c --lines 0
● a.service
     Loaded: loaded (.config/systemd/user/a.service; static)
     Active: active (running) since Mon 2023-10-09 16:14:45 CEST; 9s ago

● b.service
     Loaded: loaded (.config/systemd/user/b.service; static)
     Active: inactive (dead)

● c.service
     Loaded: loaded (.config/systemd/user/c.service; static)
     Active: inactive (dead)

$ journalctl --user -u a -u b -u c --since "1 minute ago"
Oct 09 16:14:45: Started Long running service.
Oct 09 16:14:50: Starting Conditional killer of the long runing service...
Oct 09 16:14:50: Finished Conditional killer of the long runing service.

aこれが失敗すると、c例は停止します。スクリプトが反転した場合(c成功した場合は停止する必要があります)、再生できます。SuccessExitStatus=


最新バージョンのsystemdがある場合は、次のコマンドを使用してよりエレガントにすることができます。ExecCondition=結合するOnSuccess=。これにより、デバイスが故障したままになり、グローバル「ダウングレード」を汚染し、systemctl statusstderrにエラーメッセージを残すのを防ぎます。これを行うには、ExecCondition=スクリプトを実行してください。成功すればExecStart=成功OnSuccess=し、行動を促し、b.service人を殺しますa.serviceExecCondition=失敗するとExecStart=実行もOnSuccess=トリガーもされないため、生存が可能ですa.service

c.service
[Unit]
OnSuccess=b.service

[Service]
Type=oneshot
ExecCondition=/your-script
ExecStart=/bin/true

おすすめ記事