ネットワークがシャットダウンする前に一時停止したシステムデバイスを起動する方法は?

ネットワークがシャットダウンする前に一時停止したシステムデバイスを起動する方法は?

(別名Stock Debianテストで9に増えるため、通常のsystemd + logind + NetworkManager + GNOMEスタックがあります)

開始/終了、および再開/一時停止時に実行したいスクリプトのペアがあります。このスクリプトを実行するにはネットワークが必要です。次のスクリプトを使用してこれを実行しようとしています。

[Unit]
Description=Yamaha Reciever power
Requires=network-online.target
After=network-online.target
Before=sleep.target
Conflicts=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/av-up
ExecStop=/usr/local/bin/av-down
RemainAfterExit=yes

[Install]
WantedBy=graphical.target

起動/終了時には正常に動作しますが、一時停止中は実行されます。後ろにネットワークがダウンしてエラーが発生しました。

私は原因がsystemdで停止する方法だと判断しました。

  1. systemctl suspend停止は、ログインにdbus呼び出しを送信するプログラム(たとえば)によって開始されます。
  2. その後、Logindは聞いている人にprepareToShutdown dbus信号を送信します。
  3. その後、Logind は Systemd に StartUnit dbus 呼び出しを送信して suspens.target デバイスを実行します。

NetworkManager は prepareToShutdown を受信するので、(2) からネットワークが削除され、systemd が実際に(3) で中断し始めると、私のデバイスが起動します. NetworkManagerは、ログイン時に「禁止された」ロックを維持し、(3)以前にネットワークを終了します。 (注:systemdを使用して一時停止/再開コマンドのようなものを制御し、それをバイパスするためにログインでそれを破壊することは狂ったようです)

ネットワークの実行中に一時停止/再開時にプログラムを起動するための正しい方法は何ですか?

NetworkManager事前終了スクリプトを使用する必要がありますか?それでは、ネットワークがダウンしたときにトリガーされるのを防ぐにはどうすればよいですか?いいえ停止しますか?

プロセスを事前に中断する方法はありますか?

NetworkManagerにネットワークを長時間実行するように指示する方法はありますか?

注:これは次のように異なります。ネットワーク停止前にトリガーされるSystemdデバイスを作成する方法私が言ったように、一時停止/再開。

答え1

からインスピレーションを受けるhttps://unix.stackexchange.com/a/139664/160746起動/停止スクリプトをデーモン全体にアップグレードし、prepareToShutdownシグナルを受信するようにしました。 NetworkManagerを使用したすべてのスタート/ストップレースですが、私のシステムでは安定して動作しているようです。

私のコードとシステムデバイスを次にアップロードしました。https://github.com/davidn/av

答え2

~によるとシステム停止文書化とsystemctl のマニュアルページ systemctl suspend活性化suspend.target

systemctl list-dependencies suspend.target --after --all明示的にthenをsuspend.target呼び出します。つまり、電話するときsystemctl-suspend.servicesleep.targetsystemctl suspend基本作業順序は次のとおりです。

suspend.target
|-systemd-suspend.service
  |-sleep.target

Before=sleep.targetその時配置するとあなたの作業順序は次のとおりです。

suspend.target
|-systemd-suspend.service
  |-[custom service]
    |-sleep.target

サービスが実行中です。後ろに systemd-suspend.service仕事をしなさい。これがあなたの問題かもしれません。


サービスファイルに追加して取得できます。正しい結果:

Before=systemd-suspend.service

電話をかけると、その間にサービスが表示されることがわかりsystemctl daemon-reloadます。最終的な作業順序は次のとおりです。systemctl list-dependencies suspend.target --after --allsuspend.targetsystemd-suspend.service

suspend.target
|-[custom service]
  |-systemd-suspend.service
    |-sleep.target

答え3

作業ソリューションがあります。それは私にとって最高ではありませんが、他の人には最高ではありません。 /lib/systemd/system-sleep/tv_on_off に次の内容を入力します。

#!/bin/sh
# should be placed at 
# /lib/systemd/system-sleep

if [ "${1}" = "pre" ]; then
   # about to suspend no network here
   systemctl restart network-manager.service
   nm-online

   # code that requires network
   /usr/local/bin/av-down

elif [ "${1}" = "post" ]; then
   # about to resume 
   systemctl restart network-manager.service
   nm-online

   # code that requires network
   /usr/local/bin/av-up
fi

@Davidが述べたsystemdとdbusメソッドを試しました。 dbus メッセージ処理を使用しても、コードが実行される前にネットワークが終了します。または並列に。

答え4

によると返信するsystemd-develメーリングリストでネットワーク管理者を使用するときにsystemdを単独で使用することは不可能です。なぜなら、ネットワーク管理者はそれ自体が省電力信号を受信するからである。解決策は、直面する必要がある状況を次のように設定することです。

/etc/NetworkManager/dispatcher.d/pre-down.d/

これは、インターフェースが失敗するたびにスクリプトをトリガーすることに注意してください。私のコンピュータでは問題はありませんが、お使いのコンピュータではそうでない可能性があります。 D-Bus一時停止信号が発生しているかどうかを確認できますが、まだ見ていません。これに対するチケットがありますネットワーク管理者のgitlabトラッカー

関連情報