2015-08-25 14 views
9

Voglio generare processi figlio a esecuzione prolungata che sopravvivono quando il processo principale viene riavviato/muore. Questo funziona bene quando si esegue dal terminale:Impossibile disconnettere il processo figlio all'avvio del processo principale da systemd

$ cat exectest.go 
package main 

import (
     "log" 
     "os" 
     "os/exec" 
     "syscall" 
     "time" 
) 

func main() { 
     if len(os.Args) == 2 && os.Args[1] == "child" { 
       for { 
         time.Sleep(time.Second) 
       } 
     } else { 
       cmd := exec.Command(os.Args[0], "child") 
       cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} 
       log.Printf("child exited: %v", cmd.Run()) 
     } 
} 
$ go build 
$ ./exectest 
^Z 
[1]+ Stopped     ./exectest 
$ bg 
[1]+ ./exectest & 
$ ps -ef | grep exectest | grep -v grep | grep -v vim 
snowm  7914 5650 0 23:44 pts/7 00:00:00 ./exectest 
snowm  7916 7914 0 23:44 ?  00:00:00 ./exectest child 
$ kill -INT 7914 # kill parent process 
[1]+ Exit 2     ./exectest 
$ ps -ef | grep exectest | grep -v grep | grep -v vim 
snowm  7916  1 0 23:44 ?  00:00:00 ./exectest child 

Si noti che il processo figlio è ancora vivo dopo processo padre è stato ucciso. Tuttavia, se inizio il processo principale da systemd come questo ...

[[email protected] exectest]$ cat /etc/systemd/system/exectest.service 
[Unit] 
Description=ExecTest 

[Service]       
Type=simple 
ExecStart=/home/snowm/src/exectest/exectest 
User=snowm 

[Install] 
WantedBy=multi-user.target 
$ sudo systemctl enable exectest 
ln -s '/etc/systemd/system/exectest.service' '/etc/systemd/system/multi-user.target.wants/exectest.service' 
$ sudo systemctl start exectest 

... allora il bambino muore anche quando uccido il processo principale:

$ ps -ef | grep exectest | grep -v grep | grep -v vim 
snowm  8132  1 0 23:55 ?  00:00:00 /home/snowm/src/exectest/exectest 
snowm  8134 8132 0 23:55 ?  00:00:00 /home/snowm/src/exectest/exectest child 
$ kill -INT 8132 
$ ps -ef | grep exectest | grep -v grep | grep -v vim 
$ 

Come posso fare il bambino sopravvivere?

Versione go go go.4.4 linux/amd64 in versione CentOS Linux 7.1.1503 (Core).

+0

SystemD probabilmente uccide tutto nel gruppo di processi (o cgroup, non ho guardato l'installazione di systemd in un istante). Stai effettivamente cercando di emulare il comportamento daemon, o è solo per un esempio? – JimB

+0

@JimB: Il mio codice attuale genera processi figlio che eseguono ffmpeg. Fondamentalmente sto usando il modello sopra per emulare il comportamento demone, sì. –

+0

Perché non lasciare il genitore in esecuzione e lasciare che sia sistemato normalmente? Penso che potrebbe esserci un modo per generare il bambino e informare il sistema del nuovo processo, ma il primo sarebbe molto più facile. – JimB

risposta

13

soluzione è quella di aggiungere

KillMode=process 

al blocco del servizio. Il valore predefinito è control-group che significa che systemd pulisce qualsiasi processo figlio.

Da man systemd.kill

KillMode = Specifica come sono abbattuti i processi di questa unità. Uno dei gruppi di controllo , processo, misto, nessuno.

Se impostato al controllo-gruppo, tutti i processi rimanenti nel gruppo di controllo di questa unità verranno uccisi il blocco dell'unità (per i servizi: dopo l'arresto viene eseguito comando, come configurato con ExecStop =). Se impostato per elaborare, viene ucciso solo il processo principale stesso. Se impostato su mixed, il segnale SIGTERM (vedi sotto) viene inviato al processo principale mentre il successivo segnale SIGKILL (vedere di seguito) viene inviato a tutti i restanti processi del gruppo di controllo dell'unità . Se impostato su none, nessun processo viene ucciso. In questo caso , solo il comando di arresto verrà eseguito all'unità ferma, ma nessun processo verrà ucciso in caso contrario. I processi rimanenti vivi dopo l'arresto sono lasciati nel loro gruppo di controllo e il gruppo di controllo continua ad esistere dopo l'interruzione a meno che non sia vuoto.

+0

Ci sarebbe un modo per spostare invece il processo fuori dal gruppo? –