In systemd, qual è la differenza tra After = e Richiede =?


55

Sto creando un file systemd .service e ho bisogno di aiuto per capire la differenza tra Requires=e After=. La pagina man dice che Requires="Configura le dipendenze dei requisiti su altre unità". e After="Configura le dipendenze di ordinamento tra le unità." Qual è la differenza?

Risposte:


45

After=configura l'ordine di servizio (esegui X solo dopo Y), mentre Requires=le dipendenze dello stato. Se non specifichi un ordine, un servizio dipendente da un altro verrebbe avviato contemporaneamente a quello da cui dipende. Inoltre, il modo in cui lo capisco (anche se non riesco a provarlo ora e non trovo un riferimento), After=è un "accoppiamento lento" e un servizio con una tale dichiarazione continuerebbe a funzionare se quello indicato nella After=riga non è non è iniziato affatto, mentre Require=impedirebbe che inizi se il requisito non è soddisfatto.

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

richiede =

Configura le dipendenze dei requisiti da altre unità. Se questa unità viene attivata, verranno attivate anche le unità elencate qui. Se una delle altre unità viene disattivata o la sua attivazione non riesce, questa unità verrà disattivata. Questa opzione può essere specificata più di una volta oppure è possibile specificare più unità separate da spazio in un'opzione, nel qual caso verranno create le dipendenze dei requisiti per tutti i nomi elencati. Si noti che le dipendenze dei requisiti non influenzano l'ordine in cui i servizi vengono avviati o arrestati. Questo deve essere configurato in modo indipendente con le opzioni After = o Before =. Se un'unità foo.service richiede un'unità bar.service come configurato con Require = e nessun ordine è configurato con After = o Before =, allora entrambe le unità verranno avviate simultaneamente e senza alcun ritardo tra di loro se foo.service è attivato. Spesso,

e

Prima =, Dopo =

Un elenco separato da spazi di nomi di unità. Configura le dipendenze degli ordini tra le unità. Se un'unità foo.service contiene un'impostazione Prima = bar.service ed entrambe le unità vengono avviate, l'avvio di bar.service viene ritardato fino all'avvio di foo.service. Si noti che questa impostazione è indipendente e ortogonale alle dipendenze dei requisiti come configurato da Richiede =. È un modello comune includere un nome di unità nell'opzione Dopo = e Richiede =, nel qual caso l'unità elencata verrà avviata prima dell'unità configurata con queste opzioni. Questa opzione può essere specificata più di una volta, nel qual caso vengono create le dipendenze per l'ordinamento di tutti i nomi elencati. After = è l'inverso di Before =, ovvero mentre After = assicura che l'unità configurata venga avviata dopo che l'unità elencata ha terminato l'avvio, Before = assicura il contrario, ovvero che l'unità configurata è completamente avviata prima dell'avvio dell'unità elencata. Si noti che quando due unità con una dipendenza di ordinamento tra loro vengono spente, viene applicato l'inverso dell'ordine di avvio. cioè se un'unità è configurata con After = su un'altra unità, la prima viene arrestata prima della seconda se entrambe vengono spente. Dato due unità con qualsiasi dipendenza di ordinamento tra loro, se un'unità viene spenta e l'altra viene avviata, l'arresto viene ordinato prima dell'avvio. Non importa se la dipendenza dell'ordine è Dopo = o Prima =. Inoltre, non importa quale dei due sia spento, purché uno sia spento e l'altro sia avviato. Lo spegnimento viene ordinato prima dell'avvio in tutti i casi. Se due unità non hanno dipendenze di ordinamento tra loro, vengono spente o avviate contemporaneamente,


7
Che cos'è una dipendenza se non una dichiarazione d'ordine? (seriamente ... non capisco la differenza)
TomOnTime

Vedi la mia modifica. La mia comprensione: After=Xsignificherebbe "Fallo dopo X se X è fatto", mentre Require=Xsignificherebbe "non farlo affatto se non puoi fare X".
Sven

La Before=sezione della pagina man sembra confermare questo. 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 Il modo in cui ho capito che, l'ordinamento non essere eseguita se bar.servicenon viene avviato in ogni caso e foo.serviceavrebbe cominciato normalmente.
Sven

10

Una delle maggiori differenze è

  • After controlla solo se l'unità è già attivata e non attiva esplicitamente le unità specificate.
  • Le unità elencate in Requiresvengono attivate insieme all'unità. Se una delle unità richieste non si avvia, l'unità non viene attivata.

Considera che ho un file unitario test-app.service,

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

Ecco cosa accadrà quando viene eseguita questa affermazione,

  • Aftercontrolla se network-online.target.
  • se network-online.targetnon avviato, attenderà.
  • test-appinizia solo dopo che network-online.targetè attivo

Se Requiresinvece avessi ,

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

Ecco cosa accadrà quando viene eseguita questa affermazione,

  • network-online.targete test-appvengono attivati ​​insieme
  • se network-online.targetnon si avvia test-appnon verrà attivato.

2

systemd è un gestore del lavoro. La pagina man non è molto precisa su come funzionano le cose.

Quando si avvia, ciò che fa systemd è creare una transazione comprendente lavori per il lavoro di ancoraggio (ovvero avviare un lavoro per default.target). Ciò che fanno tutte queste dipendenze e relazioni è definire come e quali lavori verranno attivati. L'ordinamento definisce quali lavori dovranno attendere tutti gli altri lavori. L'unità default.target è quindi al centro di tutto ciò, motivo per cui quando si abilitano le unità si usa una dipendenza inversa che attraverso l'abilitazione di systemctl crea un collegamento simbolico del filesystem che indica che un sistema di dipendenza diretta può seguire (anche perché è necessario un link simbolico nel filesystem nel primo posto). Simile è quando si avvia manualmente un'unità, quindi quell'unità è ancora e la transazione viene calcolata.

Non andando troppo nei dettagli, spiegherò cosa richiede = e dopo =.

Richiede = farà sì che systemd avvii un lavoro di avvio per l'unità richiesta quando viene attivato un lavoro di avvio (esplicitamente o attraverso una dipendenza: non c'è distinzione internamente). Ha anche la proprietà di avviare un processo di arresto su di te quando questa unità viene arrestata (nota: arrestata, non andare in giù da sola) o riavviata. Ciò significa che se una dipendenza / systemctl provoca l'arresto / riavvio, si arresterà / riavvierà anche. Tuttavia, se si riduce da solo, non ti fermerai, poiché non c'era lavoro e il cambiamento di stato è avvenuto senza il coinvolgimento di systemd. È qui che dovresti usare BindsTo = (simile alle unità del dispositivo, che possono diventare inattive senza il coinvolgimento di systemd, per ovvi motivi).

Ora, l'uso di After = è raccomandato in quanto richiede = da solo è spinto per quello che fa: annullare il requisito se il processo di avvio ha esito negativo. Questa cancellazione tuttavia funziona solo per lavori, cioè se l'altra unità non definisce l'ordinamento, systemd si innesca entrambi in parallelo e se il suo lavoro di avvio termina prima che il lavoro di avvio fallisca, non verrà annullato (non può essere annullato, in effetti) . L'uso di After = indica che l'altro lavoro continua ad attendere fino al termine del lavoro di avvio dell'unità richiesta e, a seconda del risultato, se fallito, il lavoro di avvio in attesa dell'unità viene annullato con il risultato del lavoro JOB_DEPENDENCY (perché si utilizza il giallo [DEPEND] all'avvio per tali casi). Quindi, questo effetto di invalidazione non è deterministico senza l'uso di After =.

Questo è il motivo per cui usare Wants = senza After = va bene se non vuoi aspettare l'avvio dell'altra unità: poiché non c'è invalidazione lì, quindi non c'è gara. In tal caso, non è altro che un meccanismo di sincronizzazione.

Inoltre, puoi anche abilitare entrambi all'avvio e non richiederci l'un l'altro e definire solo l'ordinamento, in quel caso, quando entrambi vengono estratti come parte della stessa transazione, verranno ordinati (o se il lavoro per l'altro viene attivato mentre il lavoro per l'unità che vuole eseguire dopo è in esecuzione, prima aspetterà che finisca, attraverso le transazioni).

Ora, se non c'è lavoro, l'ordinazione non ha alcun effetto per detta unità. Tuttavia, di solito c'è un lavoro, come conseguenza dell'uso di dipendenze come Richiede = e Vuole =, o entrambi vengono richiamati alla volta e definiscono un ordine, nel qual caso attendono i lavori di un'altra unità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.