¿Systemd no parece respetar la dependencia After=?

¿Systemd no parece respetar la dependencia After=?

Tengo un servidor PostgreSQL ( postgresql.service) y un script de shell básico ( mobilizon-postgresql.serviceque se ejecuta para proporcionar algunas afirmaciones sobre la base de datos a un tercer servicio (Mobilizon).

Naturalmente, mobilizon-postgresql.serviceestá configurado con una After=dependencia para postgresql.service:

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

Aunque después de una reconfiguración del sistema (que no afectó estas dependencias), veo el siguiente comportamiento en los registros:

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

Entonces, mobilizon-postgresql.servicese iniciaantesel inicio 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.

Entonces, por supuesto, mobilizon.postgresqlno se puede configurar una conexión a la base de datos.

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.

Sólo más tarde postgresql.servicese informa que se ha iniciado por completo.

Este comportamiento va completamente en contra de mi comprensión de After=. De systemd.unit(5):

Si la unidad foo.service contiene la configuración Before=bar.service y ambas unidades se están iniciando, el inicio de bar.service se retrasa hasta que foo.service haya terminado de iniciarse.

¿Estoy teniendo suposiciones erróneas aquí?

La versión de Systemd es 251.12, la distribución es NixOS 22.11

Respuesta1

¿Qué quiere decir systemd con "terminado el inicio"? man systemd.unitdice

para las unidades de servicio, el inicio se considera completado a los efectos de Antes=/Después= cuando se han invocado todos sus comandos de inicio configurados y fallaron o informaron que el inicio fue exitoso.

Por lo tanto, debe buscar en el archivo de servicio postgresql para ver si está haciendo algo como bifurcar y poner su pid en un archivo, o usarlo sd_notify()en su código para indicar "listo". No es muy útil.

Lamentablemente, la forma más fácil de solucionar esto es hacer que el mobilizon-postgresql servicio espere a que exista el socket de dominio Unix, usando inotifywaito similar, o agregarlo Restart=on-failurey RestartSec=1volver a intentarlo hasta que tenga éxito.

La idea de Systemd de cómo deberían funcionar las cosas es que usted crea una unidad de socket y cada vez que alguien intenta abrir ese socket, inicia un programa. En este caso, al iniciar su script, que abre el socket, inicia postgresql.

Respuesta2

(Mostrar unidades completas sería útil, por cierto)

After=sin Wants=o Requires=no tiene el efecto que crees. Como man systemd.unitse describe (en Before=, After=):

Tenga en cuenta queesas configuraciones son independientes y ortogonales a las dependencias de requisitossegún lo configurado por Requires=, Wants=, Requisite=, o BindsTo=. Es un patrón común incluir un nombre de unidad en las opciones After=y Wants=, en cuyo caso la unidad enumerada se iniciará antes que la unidad configurada con estas opciones.

(Énfasis añadido por el cartel)

información relacionada