Come posso fare in modo che i miei servizi utente aspettino che la rete sia online?


14

Ho scritto un paio di file di servizio utente di systemd che desidero abilitare agli utenti e che necessitano di una connessione di rete funzionante. Ho pensato che sarebbe stato facile come:

Wants=network-online.target
After=network-online.target

Tuttavia, i servizi sembrano iniziare troppo presto, e journalctlvedo:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

Poi ho cercato di più e provato

Wants=network.target
After=network.target

e lo ha fatto sudo systemctl enable systemd-networkd-wait-online.service.

Ora ho in journalctl:

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.

E ancora il servizio inizia troppo presto.

Quel messaggio dovrebbe essere lì? Come posso eseguire il debug del mio problema?


EDIT : il motivo è semplice e specificamente indicato nel Arch Wiki :

systemd --userviene eseguito come processo separato dal systemd --systemprocesso. Le unità utente non possono fare riferimento o dipendere dalle unità di sistema.

Questo post sul forum sembra suggerire una soluzione semplice: dovrei linkl'unità di sistema necessaria come utente, creando così un link simbolico disponibile sul percorso di ricerca dell'unità.

Dopo averlo fatto, non vedo alcun No such file or directorymessaggio, tuttavia, non riesco ancora a far funzionare effettivamente i servizi dopo che la rete è online. Ho provato di collegamento network.target, network-online.targete systemd-networkd-wait-online.service, impostando le mie unità a dipendere da ciascuno di loro, senza successo. Quando controllo lo stato dell'unità collegata in modalità utente, sono tutti alcuni morti, ad esempio:

$ systemctl --user status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.

Tuttavia, posso vedere network-online.targetattivo in modalità utente dopo averlo collegato:

$ systemctl --user status network-online.target
● network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.

Spero che tu abbia una risposta.

@Deleteme Grazie, penso di aver trovato la causa di questo (vedi aggiornamento), ma non come risolvere il problema.
Lev Levitsky,

Avete trovato tutti una soluzione a questo problema? Inoltre, noto che sottolinei che solo alcune unità collegate sono morte. Quali sono quelli che hanno funzionato e in cosa differiscono?
Sparhawk,

@Sparhawk purtroppo no. Come soluzione alternativa, utilizzo solo i timer impostati su alcuni secondi dopo l'avvio. La domanda ha un esempio: il target di rete online è attivo dopo il collegamento e il target di rete no.
Lev Levitsky,

Forse fraintendo, ma sto cercando qualcosa da licenziare ogni volta che la rete riprende, per controllare la mia e-mail dopo aver ripreso dalla sospensione. Ho pensato che questo sarebbe stato il modo di farlo. Vedo gli esempi ora. Pensavo intendessi attivare alcuni servizi personalizzati e altri no. Tuttavia, ora vedo che stai parlando delle versioni utente delle destinazioni di rete.
Sparhawk,

Risposte:


3

Poiché non è possibile dipendere da un servizio di sistema, l'unica soluzione è fornire un servizio utente che rilevi se la rete è online. (O rendi i tuoi servizi di sistema.) I dettagli per un servizio utente "detect-online" dipendono dalla tua definizione di "online". Potrebbe attendere un ping a 8.8.8.8, ad esempio. O affinché una risoluzione dei nomi DNS abbia esito positivo. Ad esempio, in una situazione simile con vpnc, aspetto un ping su un IP VPN per avere successo.

Quindi puoi fare in modo che i tuoi servizi utente dipendono dal (dopo =) il tuo servizio di rilevamento utenti online.

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done

Grazie, questo sembra abbastanza ragionevole e semplice. Ma se 10 utenti abilitano il mio servizio utente, ci saranno 10 istanze che eseguono il ping dello stesso server contemporaneamente, il che sembra un po 'ridondante. In pratica questo probabilmente non è in discussione, ma lo stavo chiedendo nella speranza di ottenere una singola "bandiera online" disponibile per tutti i servizi degli utenti. Tuttavia, non sono state ancora suggerite soluzioni migliori.
Lev Levitsky,

1

Consiglierei di provare qualcosa del genere:

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target

Seguito da:

# systemctl daemon-reload && systemctl enable foo.service

4
Ma questo è un servizio di sistema e sto cercando di impostare un servizio utente.
Lev Levitsky,
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.