NetworkManager:将系统发送到睡眠状态时禁用网络


11

当我挂起笔记本电脑时,请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执行并没有帮助,因为一旦执行脚本,网络已被禁用。


看一下电源管理选项,寻找能“在计算机暂停时禁用网络连接”的效果
Joseph R.

哪有这回事。我使用xmonad与侏儒3
C-奥托

您的意思是您要用xmonad替换GNOME Shell,但不进行其他更改?如果是这样,电源选项位于的“电源”窗格中gnome-control-center
奋斗

我知道。没有你说的那样。
C-Otto

您要问的Q有点XY问题,我去年提供给您的答案unix.stackexchange.com/questions/62157/…,通过创建与电源管理挂起/恢复相关的自定义作业挂钩是一种方法去这里 尝试将网络支撑得更长一点不是解决此问题的正确方法。
slm

Answers:


4

我不知道它是否是标准的,但是在Ubuntu中,有一些脚本在suspended中/etc/pm/sleep.d和in 之后的suspend /之后运行/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位数字开头,以使其顺序明确的原因),而在恢复期间则以相反的顺序被调用。

因此,将umount和放在相同的脚本中即可mount command(在挂起状态下,在关闭网络之前执行该脚本,然后在其上恢复)。

您问题中链接 正在显示;我的解释是,如果NetworkManager在运行级别为00-50的脚本之前关闭网络,那是一个bug ---至少如果将该连接标记为系统连接(在“网络设置”->“选项”->“身份”-“ >可供其他用户使用)。


+1 pm-utils应该在所有主流发行版中都可用,并且可能默认情况下已安装。
13年

1
请注意,您可以通过返回/ usr / lib / pm-utils / pm-functions中定义的特殊值之一来返回错误而不会中止挂起:$NA“不适用”,$DX“禁用”和$NX“不可执行” 。参见hook_exit_statuspm-functions脚本中的函数
Samuel Peter

注意:此问题的更多答案已提供给OP:unix.stackexchange.com/questions/62157/…我认为他正在寻找NetworkManager不存在的其他功能。
slm

正如我在提到的问题中已经说过的那样,脚本中没有任何网络(即10个上载)。一旦执行任何脚本,网络就已经关闭。
C-Otto

1
我将调查system connection财产。编辑:这已经是一个system connection
C-Otto

3

在@ensc所说的基础上,您可以改为监听自己的D-Bus(系统会话)信号。该org.freedesktop.login1.Manager界面的一般工作流程为:

  1. 禁止系统睡眠(也许也关闭) Inhibit(what, who, why, mode)
    • whatsleepshutdown:sleep
    • whounmount_cifs或任何您称呼的脚本
    • whyunmounting cifs X before suspend ...或等效
    • modedelay抑制最大。5s(默认)或block无限期阻塞(我建议使用第一个。如果脚本停滞,笔记本将永远不会进入睡眠状态。)
    • 这将返回一个“持有”锁的文件描述符
  2. 现在您收听信号
    • PrepareForSleep,它将True在即将暂停或休眠以及False恢复和解冻时返回)
    • PrepareForShutdown,它将True在即将关闭时返回,并应在重新False开机时返回(相反,它还会False在返回的同时返回True,这对我来说是没有意义的,因此在False这里我将忽略该部分;您可能已经有了某种自动安装脚本无论如何在系统启动时,对吗?
  3. 处理完True信号(即卸载)后,立即通过关闭文件描述符(由返回)释放锁定Inhibit(...),以便机器可以尽可能快地进入睡眠或关闭状态,而无需等待整个5s(甚至在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帐户的连接。

另请参见关于Inhibitor LockslogindD-Bus API的官方freedesktop文档。


我正在做类似的事情(对于unix.stackexchange.com/q/337853)。这听起来很有希望,但是可以肯定的是,它正在与NetworkManager进行相同的工作?如果我的与网络相关的脚本花费的时间比NetworkManager停止网络花费的时间长,该怎么办?
大卫,

尝试了一下(github.com/davidn/av),它似乎可以工作了!
戴维(David)

1

您可以尝试找出为什么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其他进程的信号。


0

尝试在挂起之前关闭服务,然后在恢复后重新启动。像那样:

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


你什么意思?我应该停止网络管理员服务吗?我不知道这将如何帮助。
C-Otto

欢迎参加Stack Exchange!请不要给出基本上是单个链接的答案。如果可能的话,您应该解释链接到的材料,否则,只要您将其归类,就可以进行复制和粘贴。再次欢迎您!
奋斗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.