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$NA “不适用”、$DX“已禁用”和$NX“不可执行”。查看hook_exit_statuspm-functions 脚本中的函数

您甚至可以在自动恢复后重新安装它们;从这里我找到:

如果您想在挂起或休眠期间执行特定于您的设置的操作,那么您可以轻松地将自己的挂钩放入 /etc/pm/sleep.d 中。该目录中的钩子将在挂起期间按字母顺序调用(这就是它们的名称都以 2 位数字开头的原因,以使顺序明确),并在恢复期间按相反顺序调用。

因此,放入相同的脚本umountmount command应该可以工作(在挂起状态下,它在关闭网络之前执行,在恢复状态下,则在关闭网络之后执行)。

你的问题中的链接 具有启发性;我的解释是,如果 NetworkManager 在级别 00-50 的脚本运行之前关闭网络,那么这是一个错误 --- 至少如果连接被标记为系统连接(在网络设置 -> 选项 -> 身份 - > 可供其他用户使用)。

答案2

根据 @ensc 所说,您可以自己监听 D-Bus(系统会话)信号。界面的一般工作流程org.freedesktop.login1.Manager是:

  1. 禁止系统睡眠(也可能关闭)Inhibit(what, who, why, mode)
    • whatsleep或者shutdown:sleep
    • who:unmount_cifs或者无论你如何称呼你的脚本
    • whyunmounting cifs X before suspend ...或同等学历
    • modedelay抑制最大。 5 秒(默认)或block无限期阻止(我推荐第一个。如果您的脚本停止,您的笔记本将永远不会进入睡眠状态。)
    • 这将返回一个“持有”锁的文件描述符
  2. 现在你监听信号
    • PrepareForSleepTrue,当即将暂停或休眠以及False恢复和解冻时返回)
    • PrepareForShutdown,它True在即将关闭时返回,并且应该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

相关内容