Il 24 ottobre 2026 Type=simple non è Type=notify. La pagina systemd.service, letta oggi, usa Type= per dire quando il manager considera finito l’avvio. Non è Restart= e non è una probe. Non ho avviato un’unità e non ho aperto oggi la pagina di sd_notify(3): la cito solo perché questa man page la nomina.
In breve: i valori elencati sono simple, exec, forking, oneshot, dbus, notify, notify-reload e idle. simple è il default se c’è ExecStart= e non ci sono né Type= né BusName=, e se non si usano le credenziali. Il manager la considera avviata subito dopo fork(), prima di execve(). notify è simile a exec, ma aspetta un messaggio READY=1.
simple parte prima del binario
Con simple il manager considera l’unità avviata appena il processo principale è stato creato con fork(), prima che siano configurati gli attributi di processo e prima che il processo nuovo chiami execve() sul binario. La stessa voce dice che di solito Type=exec è la scelta migliore, e più sotto raccomanda exec per i servizi lunghi proprio perché gli errori di preparazione — binario assente, User= inesistente — vengono tracciati.
systemctl start su un servizio simple può riportare successo anche se il binario non parte. Su exec riporta fallimento in quegli stessi casi: il manager non procede prima che fork() e execve() siano riusciti. exec è anche il tipo implicito se si usano le credenziali (LoadCredential=, rinviato a systemd.exec, che oggi non ho riletto).
C’è un’eccezione che la pagina non nasconde. User= e Group= possono innescare chiamate NSS lente. simple è l’unico tipo in cui il manager non aspetta il completamento di quelle operazioni di setup. A volte, scrive la pagina, conviene proprio per non far dipendere la transazione da quelle attese. Non è una smentita del consiglio su exec: sono due frasi diverse, sullo stesso documento.
Chi aspetta cosa
| Type= | Quando l’unità è considerata avviata |
|---|---|
| simple | Subito dopo fork(), prima di execve(). Default se c’è ExecStart= e mancano Type= e BusName=, senza credenziali. |
| exec | Dopo che il binario è stato eseguito. systemctl start fallisce se il binario non parte. |
| notify | Come exec, poi un READY=1 via sd_notify(3) o chiamata equivalente. Le unità successive partono dopo quel messaggio. |
| notify-reload | Come notify, ma il reload manda SIGHUP (o ReloadSignal=) e aspetta RELOADING=1 con MONOTONIC_USEC=, poi un altro READY=1. |
| idle | Come simple, ma l’esecuzione slitta finché i job attivi sono smistati. Tetto di 5 secondi, poi il programma parte comunque. Non è uno strumento di ordinamento. |
| forking | Quando il processo padre esce. La pagina ne sconsiglia l’uso: meglio notify, notify-reload o dbus. |
oneshot e dbus sono altri due valori, non li appiattisco su questa tabella. oneshot è il default se mancano sia Type= sia ExecStart=. dbus è il default se c’è BusName=, e l’unità è su quando quel nome sul bus è stato preso.
READY=1 non è un Restart=
NotifyAccess= regola chi può scrivere sul socket di notifica: none (default), main, exec o all. Se si usa Type=notify o Type=notify-reload e NotifyAccess= manca o vale none, la pagina dice che viene forzato a main. Non è una scelta che resta none in silenzio.
Con notify-reload, al primo READY=1 systemd controlla che il processo principale abbia un handler per il segnale di reload, di default SIGHUP, sia via sigaction(2) sia via segnali bloccati e signalfd(2). Se il handler non c’è, l’avvio viene interrotto. Subito prima del reload, se il handler non c’è più, la pagina dice che systemd scrive un avviso ma il segnale parte lo stesso. Il handler va installato prima del primo READY=1.
Tutto questo non dice se il processo, una volta morto, va rilanciato. Quello è Restart=, già trattato, e non è il campo Type=. Una probe che chiede «sei pronto?» a un server HTTP è un altro meccanismo ancora.
Errori da evitare
Leggere un
systemctl startriuscito, susimple, come prova che il binario esista. La man page dice il contrario.Mettere
Type=notifysu un programma che non chiamasd_notify(). Le unità successive restano in attesa diREADY=1.Usare
notify-reloade mandareREADY=1prima di installare il handler diSIGHUP. L’avvio, in quel caso, viene interrotto.Trattare
idlecome unAfter=. La pagina lo limita all’output in console e gli dà un tetto di 5 secondi.Confondere
Type=conRestart=on-failure. Il primo decide quando l’avvio è finito. Il secondo decide se ripartire.
In sintesi
Il 24 ottobre 2026 la man page systemd.service fa partire Type=simple dopo fork() e prima di execve(), e fa aspettare a Type=notify un READY=1. exec sta in mezzo: aspetta il binario, non la notifica dell’applicazione. NotifyAccess=none, se manca su un tipo notify, viene forzato a main. Non ho eseguito un’unità e non ho riletto sd_notify(3).
Foto di copertina: Dave Winer, utente a un terminale Unix all’Università del Wisconsin, Madison, circa 1978, Wikimedia Commons, CC BY-SA 2.0. È un terminale del 1978, non un file di unità e non un READY=1.


