NetworkManager:システムをスリープモードに切り替えるときにネットワークを無効にする

NetworkManager:システムをスリープモードに切り替えるときにネットワークを無効にする

ラップトップを一時停止すると、NetworkManagerワイヤレスネットワークが無効になります(からnm-manager.c:do_sleep_wake)。

ただし、短期間ではネットワークを引き続き使用できるようにしたいです(cifsインストールを削除しないと、リカバリ時にシステムが使用できなくなります)。

どうやって作れますか?NetworkManager いいえ自分のネットワークを無効にしますか?何秒間(または何かがトリガされるまで、またはロックが解除されるまで)待つことはできますか?

関連:pm-utils:ストップスクリプトにネットワークがありませんか?

デバッグログ:

Feb  8 10:03:23 zenbook NetworkManager[3606]: <debug> [1360314203.373226] [nm-manager.c:3391] upower_sleeping_cb(): Received UPower sleeping signal
Feb  8 10:03:23 zenbook NetworkManager[3606]: <info> sleep requested (sleeping: no  enabled: yes)
Feb  8 10:03:23 zenbook NetworkManager[3606]: <info> sleeping or disabling...
Feb  8 10:03:23 zenbook NetworkManager[3606]: <info> (wlan0): now unmanaged

編集:明確にするためにスクリプトを入力しても/etc/pm/sleep.d役に立ちません。スクリプトが実行されると、ネットワークはすでに無効になっているためです。

答え1

標準かどうかはわかりませんが、Ubuntuには中断前/再開後に/etc/pm/sleep.d実行されるスクリプトがあります/usr/lib/pm-utils/sleep.d。私のシステムでネットワークがダウンしているようです/usr/lib/pm-utils/sleep.d/60_wpa_supplicant

/etc/pm/sleep.d/10-umountたとえば、一時停止する前に共有をアンマウントするスクリプトを作成できます。これらのスクリプトの構造は次のとおりです。

#!/bin/sh
#
case "${1}" in
        suspend|hibernate)
                # your command to umount here 
                ;;
        resume|thaw)
                # (possibly) your command to mount here
                ;;
esac

スクリプトが通常のエラーを返すと一時停止が中断されるので、この点に注意してください(特に私のようにカバーを閉じてノートブックを離れて保管している場合...)。もっと複雑な内容を書いてくれたSamuel Peterのコメントありがとうございます。

定義された特別な値「該当なし」、「無効」、および「実行できません」の/usr/lib/pm-utils/pm-functionsいずれかを返すことで、停止を中断せずにエラーを返すことができます。 pm-functionsスクリプトで関数を表示する$NA$DX$NXhook_exit_status

自動回復後に再インストールすることもできます。ここ私が見つけたもの:

一時停止中または休止状態の間に設定に関連するタスクを実行するには、/etc/pm/sleep.dに独自のフックを簡単に配置できます。このディレクトリのフックは、一時停止中にアルファベット順に呼び出され(順序を明確にするために名前がすべて2桁の数字で始まる理由です)、再開中は逆の順序で呼び出されます。

したがって、同じスクリプトを入れると機能umountしますmount command(一時停止状態ではネットワークをシャットダウンする前に実行され、再開状態ではネットワークをシャットダウンした後に実行されます)。

これあなたの質問にリンク 私の解釈は、レベル00-50のスクリプトが実行される前にNetworkManagerがネットワークを終了した場合、これはバグであるということです。少なくとも接続がシステム接続としてマークされている場合(ネットワーク設定 - >オプション - > ID - >他のユーザーが利用可能)。

答え2

@enscによると、D-Bus(システムセッション)信号を直接聞くことができるという。インターフェイスの一般的なワークフローorg.freedesktop.login1.Managerは次のとおりです。

  1. システムの省電力モードを無効にする(終了する可能性があります)Inhibit(what, who, why, mode)
    • whatsleepまたはshutdown:sleep
    • whounmount_cifsまたはスクリプトを何と呼んでも構いません。
    • whyunmounting cifs X before suspend ...またはそれに対応するもの
    • modedelay最大抑制。 5秒(デフォルト)またはblock無期限のブロック(最初のものをお勧めします。スクリプトが停止すると、ラップトップは絶対スリープモードになりません。)
    • これにより、ロックを「保持」するファイル記述子が返されます。
  2. 今、あなたは信号を聞く
    • PrepareForSleepTrue、一時停止するか、休止状態に切り替え、False再起動して固定解除する場合に返します)
    • PrepareForShutdownTrueオフにしようとしたときFalseに返され、電源が再びオンになったときに返される必要があります(代わりにFalse返されたときにも返されるので、わかりませんので、ここではその部分をTrue無視しますFalse。おそらくすでにいくつかあります)。とにかく、システム起動時に一種の自動インストールスクリプトではありませんか?
  3. シグナルが処理されるとTrue(つまり、アンロードされた場合Inhibit(...))、ファイル記述子を閉じて(戻って)ロックを解除することができるため、システムは5秒間待つことなくできるだけ早くスリープモードに切り替えたり終了することができます(blockモードでも無制限)。
  4. False再インストール(ネットワークが最初に戻るまで待つこともあります)を介して信号(復元/解除)を処理し、新しいロックInhibit(...)(次のスリープまたはシャットダウンのため)を作成できます。

Python(2.7) では、次のようになります。

#!/usr/bin/env python
import os, atexit, dbus, gobject
from dbus.mainloop import glib

def login1ManagerDBusIface():
    system_bus = dbus.SystemBus()
    proxy = system_bus.get_object( 'org.freedesktop.login1',
                                  '/org/freedesktop/login1' )
    login1 = dbus.Interface( proxy, 'org.freedesktop.login1.Manager')
    return login1

def sleepShutdownInhibit():
    login1 = login1ManagerDBusIface()
    fd = login1.Inhibit( 'shutdown:sleep', 'unmount_cifs',
                         'Unmounting before suspend/shutdown ...',
                         'delay' )
    return fd

def take_lock():
    global FD
    FD = sleepShutdownInhibit()

def remove_lock():
    global FD
    if FD:
        os.close( FD.take() )
        FD = None

def signal_handler(boolean, member=None):
    if boolean:  ## going to suspend/hibernate or shutdown
        ## PLACE YOUR UNMOUNT STUFF HERE
        remove_lock()
    else:  ## resume/thaw
        if member == 'PrepareForSleep':
            ## PLACE YOUR MOUNT STUFF HERE
            take_lock()

if __name__ == '__main__':
    take_lock()
    atexit.register(remove_lock)
    login1 = login1ManagerDBusIface()
    for signal in ['PrepareForSleep', 'PrepareForShutdown']:
        login1.connect_to_signal(signal, signal_handler,
                                 member_keyword='member')
    glib.DBusGMainLoop(set_as_default=True)
    loop = gobject.MainLoop()
    loop.run()

存在するこの点私のPidginラッパーは、スリープやシャットダウン時にIMアカウントを切断するためにまったく同じ方法を使用していることがわかります。

公式freedesktopドキュメントも参照してください。阻害剤ロックそしてlogindDバスAPI

答え3

nm端末が終了する理由を確認してください。

dbus-monitor --system &
nmcli g logging level DEBUG
--> trigger suspend

(私の場合(Fedora 20)ように)systemd信号がトリガされると、dbus設定で信号伝達を拒否できます。

---- /etc/dbus-1/system.d/99-my-suspend.conf ---
<busconfig>
        <policy user="root">
                <deny receive_interface="org.freedesktop.login1.Manager"
                      receive_type="signal"
                      receive_member="PrepareForSleep"/>
        </policy>
</busconfig>

残念ながら、これらのルールは非常にきめ細かくなく、PrepareForSleep他のプロセスからの信号もブロックします。

答え4

サービスを中断する前に終了し、再開してからやり直してください。そう:

http://oleeekchoff.blogspot.ie/2012/05/restart-modulesservices-after.html

関連情報