O Systemd parece não respeitar a dependência After=?

O Systemd parece não respeitar a dependência After=?

Eu tenho um servidor PostgreSQL ( postgresql.service) e um script shell básico ( mobilizon-postgresql.serviceque é executado para fornecer algumas asserções no banco de dados para um terceiro serviço (Mobilizon).

Então, naturalmente, mobilizon-postgresql.serviceestá configurado com uma After=dependência para postgresql.service:

# systemctl show mobilizon-postgresql.service | grep After=
After=basic.target system.slice systemd-journald.socket sysinit.target postgresql.service

Embora após uma reconfiguração do sistema (que não afetou essas dependências), estou vendo o seguinte comportamento nos logs:

1677672119.103035 myserver systemd[1]: Starting Mobilizon PostgreSQL setup...
...
1677672119.153192 myserver systemd[1]: Starting PostgreSQL Server...

Então, mobilizon-postgresql.serviceé iniciadoantesa inicialização de postgresql.service.

1677672119.279742 myserver mobilizon-postgresql-start[329444]: psql: error: could not connect to server: No such file or directory
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         Is the server running locally and accepting
1677672119.279742 myserver mobilizon-postgresql-start[329444]:         connections on Unix domain socket "/run/postgresql/.s.PGSQL.543>
1677672119.283558 myserver systemd[1]: mobilizon-postgresql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
1677672119.283707 myserver systemd[1]: mobilizon-postgresql.service: Failed with result 'exit-code'.
1677672119.289678 myserver systemd[1]: Failed to start Mobilizon PostgreSQL setup.

Então, é claro, mobilizon.postgresqlnão é possível configurar uma conexão com o banco de dados.

1677672119.503881 myserver postgres[329458]: [329458] LOG:  starting PostgreSQL 13.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11>
1677672119.512541 myserver postgres[329458]: [329458] LOG:  listening on IPv4 address "0.0.0.0", port 5432
1677672119.512863 myserver postgres[329458]: [329458] LOG:  listening on IPv6 address "::", port 5432
1677672119.519498 myserver postgres[329458]: [329458] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
...
1677672119.871989 myserver systemd[1]: Started PostgreSQL Server.

Somente mais tarde postgresql.serviceé relatado que o programa foi totalmente iniciado.

Esse comportamento vai completamente contra a minha compreensão do After=. De systemd.unit(5):

Se a unidade foo.service contiver a configuração Before=bar.service e ambas as unidades estiverem sendo iniciadas, a inicialização de bar.service será atrasada até que foo.service termine de inicializar.

Estou tendo suposições erradas aqui?

A versão do Systemd é 251.12, a distribuição é NixOS 22.11

Responder1

O que o systemd quer dizer com "inicialização concluída"? man systemd.unitdiz

para unidades de serviço, a inicialização é considerada concluída para o propósito de Antes=/Depois= quando todos os seus comandos de inicialização configurados foram chamados e falharam ou relataram sucesso na inicialização.

Então você precisa olhar no arquivo de serviço do postgresql para ver se ele está fazendo algo como bifurcar e colocar seu pid em um arquivo, ou usar sd_notify()em seu código para sinalizar "pronto". Não é muito útil.

Infelizmente, a maneira mais fácil de contornar isso é fazer o mobilizon-postgresql serviço aguardar a existência do soquete de domínio Unix, usando inotifywaitou similar, ou adicionar Restart=on-failuree RestartSec=1tentar novamente até obter sucesso.

A ideia do Systemd de como as coisas deveriam funcionar é que você crie uma unidade de soquete e, sempre que alguém tentar abrir esse soquete, você inicia um programa. Neste caso, ao iniciar o seu script, que abre o soquete, ele inicia o postgresql.

Responder2

(Mostrar unidades completas seria útil, aliás)

After=sem Wants=ou Requires=não tem o efeito que você pensa. Como man systemd.unitdescreve (em Before=, After=):

Observe queessas configurações são independentes e ortogonais às dependências de requisitosconforme configurado por Requires=, Wants=, Requisite=, ou BindsTo=. É um padrão comum incluir um nome de unidade nas opções After=e Wants=; nesse caso, a unidade listada será iniciada antes da unidade configurada com essas opções.

(Ênfase adicionada pelo pôster)

informação relacionada