Como posso acionar uma unidade do systemd na suspensão antes que a rede seja desligada?

4

(No teste Debian Stock, também conhecido como stretch aka 9, então eu tenho uma pilha regular do systemd + logind + NetworkManager + GNOME)

Eu tenho um script que quero executar na inicialização / desligamento e continuar / suspender. Esse script exige que a rede esteja presente quando for executada. Eu tentei isso com o seguinte script:

[Unit]
Description=Yamaha Reciever power
Requires=network-online.target
After=network-online.target
Before=sleep.target
Conflicts=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/av-up
ExecStop=/usr/local/bin/av-down
RemainAfterExit=yes

[Install]
WantedBy=graphical.target

Isso funciona corretamente na inicialização / desligamento, no entanto, durante a suspensão, ele é executado após a rede ser desligada e, portanto, falha.

Eu determinei que a razão para isso é como a suspensão continua sob o systemd:

  1. A suspensão é iniciada por um programa (por exemplo, systemctl suspend ) enviando uma chamada dbus para efetuar login.
  2. O Logind envia um sinal PrepareToShutdown dbus para qualquer pessoa que esteja ouvindo.
  3. O Logind envia uma chamada startUnit dbus para o systemd para executar a unidade suspend.target.

O NetworkManager escuta o PrepareToShutdown, portanto, remove a rede em (2), enquanto a minha unidade é acionada quando o systemd realmente inicia a suspensão em (3). O NetworkManager mantém um bloqueio "inibido" com o logind para garantir que ele encerre a rede antes (3). (Nota: parece loucura ter algo parecido com a ordem de controle do systemd de suspender / resumir, apenas para subvertê-lo com o logind fazendo coisas contornar isso)

Qual é o caminho certo para acionar um programa para ser executado em suspensão / retomada enquanto a rede ainda está em execução?

Devo usar scripts de pre-down do NetworkManager? Em caso afirmativo, como pará-lo a ser acionado se a rede ficar inativa, mas não suspendo

?

Existe uma maneira de conectar-se ao processo de suspensão antes?

Existe uma maneira de fazer o NetworkManager manter a rede por mais tempo?

NB: isso é diferente de Como escrever uma unidade Systemd que será disparada antes de a rede cair como eu estou falando de suspender / retomar.

    
por David 16.01.2017 / 21:19

2 respostas

1

Inspirado pelo link eu atualizei meus scripts de início / parada para um daemon completo e fiz com que ele ouvisse o PrepareToShutdown sinal. Esta é uma corrida contra o NetworkManager a cada partida / parada, mas parece funcionar de forma confiável no meu sistema.

Eu fiz o upload do meu código e da unidade systemd no link .

    
por 06.08.2017 / 20:31
1

De acordo com a documentação systemd-suspend , bem como o < a href="https://www.freedesktop.org/software/systemd/man/systemctl.html"> página man do systemctl systemctl suspend ativa o suspend.target .

systemctl list-dependencies suspend.target --after --all mostra que suspend.target chama systemctl-suspend.service , em seguida sleep.target . Isso significa que quando você chama systemctl suspend , a ordem de operações padrão é:

suspend.target
|-systemd-suspend.service
  |-sleep.target

Se você colocou Before=sleep.target , a sua ordem de operações é provável:

suspend.target
|-systemd-suspend.service
  |-[custom service]
    |-sleep.target

Portanto, o seu serviço é executado após systemd-suspend.service fazer a sua parte, o que provavelmente é o seu problema.

Você pode adicionar ao seu arquivo de serviço para obter os resultados corretos :

Before=systemd-suspend.service

Após chamar systemctl daemon-reload , você poderá usar systemctl list-dependencies suspend.target --after --all para ver seu serviço ser exibido entre suspend.target e systemd-suspend.service . Sua ordem final de operações deve ser:

suspend.target
|-[custom service]
  |-systemd-suspend.service
    |-sleep.target
    
por 25.01.2017 / 00:22