Existe de fato uma condição de corrida com unidades systemd especificando “After = suspend.target”

5

Em Relatório de bugs do Debian sobre como iniciar o anacron no currículo , há a alegação de que esse trecho (simplificado para brevidade) pode ser acionado durante a suspensão, em vez de ser retomado, devido à maneira como as dependências do systemd funcionam. Não consigo entender a condição de corrida indicada lá usando a documentação do systemd e os arquivos da unidade enviados com o systemd.

[Unit]
Description=Do something at resume
After=suspend.target

[Service]
ExecStart=/bin/do-something

[Install]
WantedBy=suspend.target

O autor desta postagem continua citando systemd-suspend.service , que contém as seguintes declarações (novamente reduzidas às declarações relevantes)

[Unit]
After=sleep.target
Requires=sleep.target

seguido pela reivindicação de que duas unidades diferentes, ambas ordenando após sleep.target , são executadas em paralelo e, portanto, não há ordenação entre essas duas unidades. Eu concordo perfeitamente com esse ponto, mas não há duas unidades, dependendo de sleep.target , como eu a entendo. A declaração em systemd-suspend.service garante que sleep.target seja completamente iniciado antes de entrar no modo de suspensão, portanto, todas as unidades que são dependentes de sleep.target são iniciadas. Mas, olhando para suspend.target (o alvo do arquivo de unidade original realmente depende), eu encontro as seguintes declarações:

[Unit]
BindsTo=systemd-suspend.service
After=systemd-suspend.service

Eu entendo este arquivo como declarando que suspend.target é iniciado com sucesso somente depois que systemd-suspend.service é iniciado com sucesso. Agora, olhando em systemd-suspend.service novamente, encontro as seguintes declarações nesse arquivo:

[Service]
Type=oneshot
Exec=/lib/systemd/systemd-sleep suspend

Pelo que entendo os serviços one-shot, eles não entram no estado "iniciado" até que o comando Exec seja concluído. Então, qualquer coisa pedindo After este serviço não pode começar até systemd-sleep terminar. Finalmente, dando uma olhada no systemd-sleep, ele contém a escrita mágica de alguma string para /sys/power/state , que bloqueia até que o sistema seja retomado. Isso deve garantir que tudo que deseja ser iniciado após systemd-suspend.service não seja realmente iniciado antes do currículo.

A razão pela qual afirmo que escrever para /sys/power/state blocks é que essa escrita é manipulada por a função de armazenamento sysfs para esse arquivo , que chama pm_suspend para modos não-hibernados, que por sua vez chama enter_state (diretamente antes de pm_suspend no mesmo arquivo de origem) que obviamente não retorna antes de continuar.

    
por Michael Karcher 04.01.2017 / 12:40

1 resposta

1

Você está certo; post # 124 está errado.

Há um problema que as pessoas às vezes gravam unidades WantedBy=sleep.target After=sleep.target . Isso iniciará a unidade antes de dormir e não esperará que eles terminem antes de ir dormir, o que certamente não é o que eles estavam tentando fazer. É possível que isso seja o que o pôster estava pensando.

Autoridade: Eu escrevi independentemente uma unidade como esta para executar o hdparm no currículo, com base em uma análise semelhante. Funciona bem, assim como a resposta em postar # 129 diz. Minha unidade funciona corretamente todas as vezes. Eu sei, porque se eu correr sem , eu posso ouvir os cliques do meu disco rígido. Mais cedo, eu consegui identificar um bug no udev que fez com que minha solução anterior não fosse confiável, apenas porque percebi ouvir os cliques.

    
por 26.07.2017 / 15:51

Tags