NetworkManager: rede desativada ao enviar o sistema para dormir

11

Quando eu suspendo meu notebook, NetworkManager desativa a rede sem fio (em nm-manager.c:do_sleep_wake ).

No entanto, eu adoraria continuar a usar a rede por um tempo muito curto (para desmontar cifs montagens, que de outro modo deixariam meu sistema inutilizável quando retomar).

Como posso fazer com que NetworkManager não desative minha rede? É possível esperar alguns segundos (ou até que algo seja disparado ou um bloqueio seja liberado)?

Relacionados: pm-utils: sem rede suspender scripts?

log de depuração:

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

EDIT: Para deixar claro, ter scripts em /etc/pm/sleep.d não ajuda, pois a rede já está desativada assim que um script é executado.

    
por C-Otto 08.02.2013 / 09:54

4 respostas

4

Eu não sei se é padrão, mas no Ubuntu existem scripts que são executados antes da suspensão / após o reinício em /etc/pm/sleep.d e em /usr/lib/pm-utils/sleep.d . No meu sistema parece que a rede está desligada por /usr/lib/pm-utils/sleep.d/60_wpa_supplicant .

Você pode escrever um script, por exemplo /etc/pm/sleep.d/10-umount , para desmontar seus compartilhamentos antes de suspendê-lo. A estrutura desses scripts é assim:

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

Observe que, se o script retornar um erro genérico, a suspensão será abortada, então cuide disso (especialmente se você, como eu, usar para fechar a tampa e armazenar o laptop fora ...). Para escrever coisas mais complexas, obrigado a Samuel Peter pelo seu comentário:

you can return an error without aborting the suspend by returning one of the special values defined in /usr/lib/pm-utils/pm-functions : $NA is "not applicable", $DX is "disabled", and $NX is "not executable". See the hook_exit_status function in the pm-functions script

Você pode até mesmo montá-los depois de continuar automaticamente. de aqui descobri que:

If you want to do something specific to your setup during suspend or hibernate, then you can easily put your own hook into /etc/pm/sleep.d. The hooks in this directory will be called in alphabetic order during suspend (that is the reason their names all start with 2 digits, to make the ordering explicit) and in the reverse order during resume.

Portanto, colocando o mesmo script, o umount e mount command devem funcionar (na suspensão, ele é executado antes de desligar a rede e retomar depois disso).

O link da sua pergunta é revelador; é minha interpretação que se o NetworkManager desligar a rede antes dos scripts no nível 00-50 serem executados, é um erro --- pelo menos se a conexão estiver marcada como uma conexão do sistema (em Configurações de Rede - > Opções - > Identidade - > Disponibilizar para outro usuário).

    
por 26.11.2013 / 18:18
3

Com base no que o @ensc disse, você poderia ouvir o sinal do D-Bus (sessão do sistema). O fluxo de trabalho geral com a interface org.freedesktop.login1.Manager seria:

  1. inibe a suspensão do sistema (talvez também o desligamento) com Inhibit(what, who, why, mode)
    • what : sleep ou shutdown:sleep
    • who : unmount_cifs ou o que você chamar de seu script
    • why : unmounting cifs X before suspend ... ou equivalente
    • mode : delay para inibir no máximo. de 5s (padrão) ou block para bloquear indefinidamente (eu recomendaria o primeiro. Se o seu script parar, seu notebook nunca irá dormir).
    • isso retorna um descritor de arquivo que 'mantém' o bloqueio
  2. agora você ouve o (s) sinal (es)
    • PrepareForSleep , que retorna True quando estiver prestes a suspender ou hibernar e False ao retomar e descongelar)
    • PrepareForShutdown , que retorna True quando prestes a desligar e deve retornar False ao ligar novamente (em vez disso, ele também retorna False ao mesmo tempo em que retorna True , o que não faz sentido para mim, apenas ignore a parte False aqui; você provavelmente já tem algum tipo de script de automontagem no início do sistema, não é?)
  3. assim que você terminar de manipular o sinal True (ou seja, desmontar), libere o bloqueio fechando o descritor de arquivo (retornado por Inhibit(...) ), para que a máquina entre adormecida ou desligue rapidamente possível sem esperar pelos 5s inteiros (ou mesmo indefinidamente quando no modo block )
  4. você pode manipular o sinal False (resume / descongelar) remontando (talvez primeiro esperando a rede voltar) e, em seguida, criar um novo bloqueio com Inhibit(...) (para o próximo repouso ou desligamento)

No Python (2.7), isso pode parecer:

#!/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()

Em esta Gist , você encontrará meu wrapper em torno do Pidgin para desconectar as contas de MI durante o sono e o desligamento, usando exatamente a mesma abordagem.

Veja também a documentação oficial do freedesktop em Inhibitor Locks e o logind API do D-Bus .

    
por 28.06.2014 / 16:13
1

Você pode tentar descobrir por que nm está desligando os dispositivos:

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

Quando (como no meu caso (Fedora 20)), systemd está acionando o sinal, você pode negar sua entrega na configuração do 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>

Infelizmente, essas regras não são muito refinadas e também bloqueiam o sinal PrepareForSleep para outros processos.

    
por 28.12.2013 / 16:43
0

Tente encerrar o serviço antes de suspendê-lo e reiniciá-lo após o reinício. Assim:

link

    
por 26.11.2013 / 00:43