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.