私が望むもの

私が望むもの

私が望むもの

一時停止/終了する前に停止し、再開後に再起動したいシステムサービスがあります。

システムの詳細

システムの詳細は次のとおりです。

$ lsb_release -dc
Description:    Ubuntu 20.04.1 LTS
Codename:   focal

$ systemd --version
systemd 245 (245.4-4ubuntu3.3)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid

私が今まで持っていること

一時停止と再開の両方のPythonプロセスをmyservice-resume.service開始および停止する2つのサービスがあります。myservice-suspend.servicePythonスクリプトは、RGBライトを制御するSDKサーバーでコマンドを実行します。 onがパラメータとして渡された場合(ExecStartと同様)、ループの一部としてコマンドを実行し続けるには、プロセスをバックグラウンドで実行する必要があります。プロセスがSIGINT信号を捕捉すると、照明は消え、正常に終了します。この設定では、myservice-suspens.serviceが中断される前に実行され、競合のために停止しますmyservice-resume.service

myservice-resume.service

[Unit]
Description=Start myservice-resume.service after suspend and shutdown

[Service]
Type=simple
ExecStart=/path/to/python3 /path/to/script.py on

myservice-suspend.service
[Unit]
Description=Stop myservice-resume.service before suspend and shutdown
Before=suspend.target shutdown.target
Conflicts=myservice-resume.service

[Service]
Type=oneshot
ExecStart=/bin/true

[Install]
WantedBy=suspend.target shutdown.target

この設定では、を使用してサービス(および照明)を開始し、を使用してsystemctl start myservice-resume.service照明を正常に終了するsystemctl start myservice-suspend.servicesystemctl stop myservice-resume.service、を使用してシステムの停止を実行しますsystemctl suspendmyservice-resume.serviceシステムの再起動時に最初のサービスが自動的に再起動したいと思います。 [Unit]セクションと[Install]セクションにいくつかの巧妙なAfter / Before / WantedByターゲットを追加することが含まれると思いますが、それを設定する適切な方法はわかりません。

研究/私が試したこと

関連投稿(Systemd:サスペンド前のサービスの停止、リカバリ後の再起動)は、サービスが実行されるように構成できることを意味します。後ろにAfter=suspend.targetユニットセクションに追加して一時停止から再開しますmyservice-resume.service。これを試しましたが、systemctlログには、回復時にデバイスが再起動されないことが示されています。

この投稿(一時停止/再開のためのシステム単位ファイルの作成)ソリューションを提案し、After / WantedByの目的を明確にするために、OPをsystemdのマニュアルページとして指定しましたが、そこでも解決策が見つかりませんでした。

答え1

最後に、次の例では、または必要After=性を確認できます。Before=アーキテクチャLinux(いつものように、これは特別な助けの源です。)これらのリンクに基づいて一時停止と再開時にコマンドを実行するための2つのソリューションがあります。

mysyssuspend1つの方法は、などの2つの単位を使用することですmysysresume。次の例では、dateコマンドがアクティブになるタイミングを確認できるように、syslogのコマンドのみを実行します。

/etc/systemd/system/mysyssuspend.service

[Unit]
Before=suspend.target
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/date +'mysyssuspend start %%H:%%M:%%S'
[Install]
WantedBy=suspend.target

/etc/systemd/system/mysysresume.service

[Unit]
After=suspend.target
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/date +'mysysresume start %%H:%%M:%%S'
[Install]
WantedBy=suspend.target

通常どおりにユニットファイルを作成した後、およびを実行しますsystemctl daemon-reloadsystemctl enable mysyssuspend mysysresume

最初のユニットはBefore一時停止の対象に依存し、コンピュータが一時停止状態になると実行されます。 2番目のユニットにもAfter依存関係があり、回復時に実行されます。

別のアプローチは、すべてのコマンドを1つのユニットに入れることです。 /etc/systemd/system/mysuspendresume.service

[Unit]
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
StandardOutput=syslog
RemainAfterExit=yes
ExecStart=/bin/date +'mysuspendresume start %%H:%%M:%%S'
ExecStop=/bin/date +'mysuspendresume stop %%H:%%M:%%S'
[Install]
WantedBy=sleep.target

これはStopWhenUnneeded=yes、アクティブなサービスが不要な場合にサービスが停止するように機能します。睡眠目標もあるので、StopWhenUnneeded完了するとExecStopユニットが実行されます。これは、完了後もRemainAfterExit私たちのユニットがまだアクティブと見なされるようにするために必要です。ExecStart

systemdバージョン237を使用してUbuntu 18.04.5で両方の方法をテストしましたが、うまく動作しているようです。


あなたの要件を上記の作業メカニズムに統合しようとするよりも、スタンドアロンデバイスを停止/起動するためにこれらのいずれかを使用する方が実用的かもしれません。たとえば、2番目の方法を使用してmylongrunサービスを追加します。

/etc/systemd/system/mysuspendresume.service

[Unit]
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
StandardOutput=syslog
RemainAfterExit=yes
ExecStart=-/bin/date +'my1 %%H:%%M:%%S' ; /bin/systemctl stop mylongrun ; /bin/date +'my2 %%H:%%M:%%S'
ExecStop=-/bin/date +'my3 %%H:%%M:%%S' ; /bin/systemctl start mylongrun ; /bin/date +'my4 %%H:%%M:%%S'
[Install]
WantedBy=sleep.target

/etc/systemd/system/mylongrun.service

[Unit]
Description=Long Run
[Service]
Type=simple
StandardOutput=syslog
ExecStart=/bin/bash -c 'date +"my11 %%H:%%M:%%S"; while sleep 2; do date +"my12 %%H:%%M:%%S"; done'
ExecStop=/bin/bash -c 'date +"my13 %%H:%%M:%%S"; sleep 10; date +"my14 %%H:%%M:%%S"'
[Install]
WantedBy=multi-user.target

ふたを起動して閉じてmylongrunそれをテストすると、次のJournalctlエントリが作成されます。

09:29:19 bash[3626]: my12 09:29:19
09:29:21 bash[3626]: my12 09:29:21
09:29:22 systemd-logind[803]: Lid closed.
09:29:22 systemd-logind[803]: Suspending...
09:29:22 date[3709]: my1 09:29:22
09:29:22 systemd[1]: Stopping Long Run...
09:29:22 bash[3715]: my13 09:29:22
09:29:23 bash[3626]: my12 09:29:23
09:29:25 bash[3626]: my12 09:29:25
09:29:27 bash[3626]: my12 09:29:27
09:29:29 bash[3626]: my12 09:29:29
09:29:31 bash[3626]: my12 09:29:31
09:29:32 bash[3715]: my14 09:29:32
09:29:32 systemd[1]: Stopped Long Run.
09:29:32 date[3729]: my2 09:29:32
09:29:32 systemd[1]: Reached target Sleep.
09:29:33 systemd[1]: Starting Suspend...

長期実行停止コマンド(sleep 10)が正しく完了したことを確認できます。回復すると、長期実行コマンドが再開されます。

09:35:12 systemd[1]: Stopped target Sleep.
09:35:12 systemd[1]: mysuspendresume.service: Unit not needed anymore. Stopping.
09:35:12 systemd[1]: Reached target Suspend.
09:35:12 date[3813]: my3 09:35:12
09:35:12 systemd[1]: Started Long Run.
09:35:12 date[3817]: my4 09:35:12
09:35:12 bash[3816]: my11 09:35:12
09:35:14 bash[3816]: my12 09:35:14
09:35:16 bash[3816]: my12 09:35:16
09:35:18 bash[3816]: my12 09:35:18

関連情報