当我暂停笔记本电脑时,NetworkManager
禁用无线网络(在 中nm-manager.c:do_sleep_wake
)。
但是,我希望仍然在很短的时间内使用网络(卸载cifs
安装,否则会使我的系统在恢复时无法使用)。
我怎样才能使NetworkManager
不是禁用我的网络?是否可以等待几秒钟(或直到触发某些内容;或释放锁)?
调试日志:
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_status
pm-functions 脚本中的函数
您甚至可以在自动恢复后重新安装它们;从这里我找到:
如果您想在挂起或休眠期间执行特定于您的设置的操作,那么您可以轻松地将自己的挂钩放入 /etc/pm/sleep.d 中。该目录中的钩子将在挂起期间按字母顺序调用(这就是它们的名称都以 2 位数字开头的原因,以使顺序明确),并在恢复期间按相反顺序调用。
因此,放入相同的脚本umount
和mount command
应该可以工作(在挂起状态下,它在关闭网络之前执行,在恢复状态下,则在关闭网络之后执行)。
这你的问题中的链接 具有启发性;我的解释是,如果 NetworkManager 在级别 00-50 的脚本运行之前关闭网络,那么这是一个错误 --- 至少如果连接被标记为系统连接(在网络设置 -> 选项 -> 身份 - > 可供其他用户使用)。
答案2
根据 @ensc 所说,您可以自己监听 D-Bus(系统会话)信号。界面的一般工作流程org.freedesktop.login1.Manager
是:
- 禁止系统睡眠(也可能关闭)
Inhibit(what, who, why, mode)
what
:sleep
或者shutdown:sleep
who
:unmount_cifs
或者无论你如何称呼你的脚本why
:unmounting cifs X before suspend ...
或同等学历mode
:delay
抑制最大。 5 秒(默认)或block
无限期阻止(我推荐第一个。如果您的脚本停止,您的笔记本将永远不会进入睡眠状态。)- 这将返回一个“持有”锁的文件描述符
- 现在你监听信号
PrepareForSleep
True
,当即将暂停或休眠以及False
恢复和解冻时返回)PrepareForShutdown
,它True
在即将关闭时返回,并且应该False
在重新打开电源时返回(相反,它也会False
在返回的同时返回,True
这对我来说毫无意义,所以我会忽略False
这里的部分;您可能已经有了某种自动安装脚本无论如何,在系统启动时,不是吗?)
- 一旦处理完
True
信号(即卸载),您就可以通过关闭文件描述符(由 返回Inhibit(...)
)来释放锁,以便机器可以尽快进入睡眠或关闭状态,而无需等待整个 5 秒(甚至在block
模式下无限期) - 您可以
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 文档抑制剂锁和logind
D总线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