En systemd, ¿cuál es la diferencia entre After = y Requiere =?

55

Estoy creando un archivo systemd .service y necesito ayuda para comprender la diferencia entre Requires=y After=. La página de manual dice que Requires="Configura las dependencias de requisitos en otras unidades". y After="Configura las dependencias de pedido entre unidades". ¿Cual es la diferencia?

TomOnTime
fuente

Respuestas:

45

After=configura el orden de servicio (hacer X solo después de Y), mientras que Requires=depende del estado. Si no especifica un pedido, un servicio que depende de otro se iniciará al mismo tiempo que el que depende. Además, la forma en que lo entiendo (aunque no puedo probar eso ahora y no encuentro una referencia), After=es un "acoplamiento flojo", y un servicio con tal declaración aún se ejecutaría si el nombre en la After=línea no es No comenzó en absoluto, mientras Require=que evitaría su inicio si no se cumple el requisito.

Citando https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Requiere =

Configura las dependencias de requisitos en otras unidades. Si esta unidad se activa, las unidades enumeradas aquí también se activarán. Si una de las otras unidades se desactiva o su activación falla, esta unidad se desactivará. Esta opción se puede especificar más de una vez o se pueden especificar varias unidades separadas por espacios en una opción, en cuyo caso se crearán dependencias de requisitos para todos los nombres enumerados. Tenga en cuenta que las dependencias de requisitos no influyen en el orden en que se inician o detienen los servicios. Esto tiene que configurarse independientemente con las opciones After = o Before =. Si una unidad foo.service requiere una unidad bar.service configurada con Requiere = y no se configura ningún pedido con After = o Before =, ambas unidades se iniciarán simultáneamente y sin demora entre ellas si foo.service está activado. A menudo,

y

Antes =, Después =

Una lista de nombres de unidades separadas por espacios. Configura las dependencias de pedido entre unidades. Si una unidad foo.service contiene una configuración Before = bar.service y ambas unidades se están iniciando, el inicio de bar.service se retrasa hasta que foo.service se inicia. Tenga en cuenta que esta configuración es independiente y ortogonal a las dependencias de requisitos configuradas por Requiere =. Es un patrón común incluir un nombre de unidad en las opciones After = y Requiere =, en cuyo caso la unidad que se muestra se iniciará antes que la unidad que está configurada con estas opciones. Esta opción se puede especificar más de una vez, en cuyo caso se crean dependencias de pedido para todos los nombres listados. After = es el inverso de Before =, es decir, After = asegura que la unidad configurada se inicia después de que la unidad listada termine de iniciarse, Before = asegura lo contrario, es decir que la unidad configurada se ha iniciado completamente antes de que se inicie la unidad enumerada. Tenga en cuenta que cuando dos unidades con una dependencia de ordenamiento entre ellas se apagan, se aplica el inverso del orden de inicio. es decir, si una unidad está configurada con After = en otra unidad, la primera se detiene antes que la segunda si ambas se apagan. Dadas dos unidades con cualquier dependencia de ordenamiento entre ellas, si una unidad se apaga y la otra se inicia, el apagado se ordena antes del inicio. No importa si la dependencia de pedidos es After = o Before =. Tampoco importa cuál de los dos esté apagado, siempre que uno esté apagado y el otro esté encendido. El apagado se ordena antes del inicio en todos los casos. Si dos unidades no tienen dependencias de orden entre ellas, se apagan o se inician simultáneamente,

Sven
fuente
77
¿Qué es una dependencia sino una declaración de orden? (en serio ... no entiendo la diferencia)
TomOnTime
Mira mi edición. Mi entendimiento: After=Xsignificaría "Haz esto después de X si X está hecho", mientras Require=Xque significaría "no hagas esto si no puedes hacer X".
Sven
La Before=sección de la página del manual parece confirmar esto. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up Según tengo entendido, el pedido no se aplicaría si bar.serviceno se inicia de todos modos y foo.servicecomenzaría normalmente.
Sven
10

Una de las principales diferencias es,

  • After solo comprueba si la unidad ya está activada y no activa explícitamente las unidades especificadas.
  • Las unidades enumeradas en Requiresse activan junto con la unidad. Si alguna de las unidades requeridas no se inicia, la unidad no se activa.

Considere que tengo un archivo unitario test-app.service,

[Unit]
Description=test app
After=network-online.target

Esto es lo que sucederá cuando se ejecute esta declaración,

  • Aftercomprueba si network-online.target.
  • si network-online.targetno se inicia, esperará.
  • test-appcomienza solo después de que network-online.targetestá activo

Si tuviera en su Requireslugar,

[Unit]
Description=test app
Requires=network-online.target

Esto es lo que sucederá cuando se ejecute esta declaración,

  • network-online.targety test-appse activan juntos
  • si network-online.targetno se inicia test-app, no se activará.
Sufiyan Ghori
fuente
2

systemd es un gerente de trabajo. La página del manual no es muy precisa sobre cómo funcionan las cosas.

Cuando inicia, lo que hace systemd es crear una transacción que comprende trabajos para el trabajo de anclaje (es decir, iniciar el trabajo para default.target). Lo que hacen todas estas dependencias y relaciones es definir cómo y qué trabajos se activarán. Ordenar define qué trabajo (s) esperará cualquier otro trabajo. La unidad default.target, por lo tanto, está en el centro de todo esto, razón por la cual cuando habilita las unidades, utiliza una dependencia inversa que a través de systemctl enable crea un enlace simbólico del sistema de archivos que denota una dependencia directa que systemd puede seguir (también por qué necesita enlaces simbólicos del sistema de archivos en el primer lugar). Similar es cuando inicia manualmente alguna unidad, luego esa unidad es ancla, y la transacción se calcula con ella.

Sin entrar en demasiados detalles, explicaré lo que Requiere = y Después =.

Requiere = hará que systemd active un trabajo de inicio para la unidad requerida cuando se active un trabajo de inicio (explícitamente, o mediante una dependencia: no hay distinción interna). También tiene la propiedad de activar un trabajo de detención cuando esta unidad se detiene (nota: se detuvo, no baja por sí sola) o se reinicia. Esto significa que si alguna dependencia / systemctl hace que se detenga / reinicie, también se detendrá / reiniciará. Sin embargo, si cae solo, no se detendrá, ya que no había trabajo y el cambio de estado se produjo sin la participación del sistema. Ahí es donde usaría BindsTo = (similar a las unidades de dispositivo, que pueden pasar a inactivo sin la participación del sistema, por razones obvias).

Ahora, se recomienda el uso de After = ya que Requiere = solo es rápido para lo que hace: cancele el requerido si falla el trabajo de inicio. Sin embargo, esta cancelación solo funciona en trabajos wrt, es decir, si la otra unidad no define el orden, systemd se dispara en paralelo, y si su trabajo de inicio finaliza antes de que su trabajo de inicio falle, no se cancelará (de hecho, no se puede cancelar) . El uso de After = significa que otro trabajo sigue esperando hasta que finalice el trabajo de inicio de la unidad requerida y, dependiendo del resultado, si falla, el trabajo de inicio de espera de su unidad se cancela con el resultado del trabajo JOB_DEPENDENCY (por qué usa amarillo [DEPEND]) en el arranque para tales casos). Por lo tanto, este efecto de invalidación es indeterminado sin el uso de After =.

Esta es la razón por la que usar Desea = sin Después = está bien si no desea esperar el inicio de la otra unidad: como no hay invalidación allí, entonces no hay carrera. En ese caso, no es más que un mecanismo de sincronización.

Además, también puede habilitar ambos al inicio, y no requerirse entre sí, y solo definir el orden, en ese caso, cuando ambos se extraen como parte de la misma transacción, se ordenarán (o si se activa el trabajo para el otro) mientras se ejecuta el trabajo para la unidad que quiere ejecutar después, primero esperará a que termine, en todas las transacciones).

Ahora, si no hay trabajo, el pedido no tiene efecto para dicha unidad. Sin embargo, generalmente hay un trabajo, como consecuencia del uso de dependencias como Requiere = y Deseos =, o ambos son detenidos a la vez y definen algún orden, en cuyo caso esperan en el trabajo de la otra unidad.

Jonathan Kowalski
fuente