Eu tenho um serviço SysVinit muito simples em /etc/rc.d
:
#!/bin/bash
PIDFILE="/var/run/test.pid"
status() {
if [ -f "$PIDFILE" ]; then
echo 'Service running'
return 1
fi
return 0
}
start() {
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")"; then
echo 'Service already running'
return 1
fi
echo 'Starting...'
test & echo $! > "$PIDFILE"
return 0
}
stop() {
if [ ! -f "$PIDFILE" ] || ! kill -0 "$(cat "$PIDFILE")"; then
echo 'Service not running'
return 1
fi
echo 'Stopping...'
kill -15 "$(cat "$PIDFILE")" && rm -f "$PIDFILE"
return 0
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
Quando o sistema inicia, ele inicia o serviço.
Mas quando o sistema para, ele nunca chama o comando stop. A única razão pela qual consigo pensar é que o sistema pensa que o serviço não está em execução ou não foi iniciado corretamente.
Mas quais são os requisitos para isso?
- Você precisa retornar um código de saída especial para o comando start?
- Preciso criar um arquivo em
/var/lock/subsys
para sinalizar que está ativo? - Mais alguma coisa que possa fazer com que o sistema pense que o serviço não foi iniciado?
Parece que a Synology mudou do SysVinit clássico para
upstart
o DSM 6 ou mais, e depois parasystemd
o DSM 7. Ambos os sistemas init fornecem compatibilidade com versões anteriores para scripts de início/parada clássicos no estilo SysVinit, mas há algumas peculiaridades das quais você deve estar ciente.Se você tiver o DSM 7.0 ou mais recente, depois de instalar o script, provavelmente deverá executar
systemctl daemon-reload
, portantosystemd-sysv-generator
, deverá criar automaticamente um.service
arquivo para ele (talvez em/run/systemd
). Em seguida, você pode iniciar seu script comsystemctl start <script name>
- e, na verdade, deve fazer exatamente isso, em vez de apenas executar o script manualmente.systemd
estará ciente da necessidade de executar<your script> stop
o trabalho apenas se tiver realmente executado o trabalho inicial correspondente.Isso ocorre porque
systemd
irá configurar cada serviço como um grupo de controle separado de processos à medida que os inicia (e o administrador que executa o script de início manualmente não faz isso).Isso é algo completamente invisível para os próprios serviços (a menos que eles o procurem especificamente), e qualquer processo filho dos serviços herdará essa participação no grupo de controle. Se um grupo de controle não tiver mais processos nele, ele deixará de existir automaticamente.
Ao desligar,
systemd
ele apenas passará pelos grupos de controle existentes e executará o comando de parada para qualquer grupo de controle não padrão que encontrar. Quaisquer serviços iniciados sem usosystemctl start
farão parte do grupo de controle "sessão interativa do administrador" em vez do grupo de controle "serviço X" e serão basicamente eliminados sem executar o script de parada correspondente.Se você precisar de recursos como uma reinicialização automática para o seu serviço se ele morrer por algum motivo, considere usar o método de configuração "nativo" apropriado para o sistema init aplicável:
/etc/init/*
arquivos para Upstart na série Synology DSM 6.x/etc/systemd/system/*.service
arquivos para systemd na série Synology DSM 7.x e mais recente. Esses sistemas init têm recursos integrados de reinicialização automática que você pode usar com apenas um pouco de configuração, em vez de ter que escrever um script wrapper para observar o processo do serviço por conta própria.Guia do desenvolvedor para Synology DSM 7
Guia do desenvolvedor para Synology DSM 6
Notas possivelmente úteis sobre a configuração de serviços para DSM 6 e 7