como o systemd determina que o serviço está parado?

3

Nosso aplicativo usa um script init.d para iniciar e parar o aplicativo como um serviço. No CentOS 7, /sbin/init é um link simbólico para o systemd, portanto, posso iniciar meu aplicativo usando:

service myapp start

ou

systemctl start myapp

O problema que estou tendo é que executar stop no serviço usando service ou systemctl não parará meu aplicativo. A saída de systemctl status :

[root@nec04 ~]# systemctl status myapp
myapp.service - SYSV: Service script to start/stop my application
   Loaded: loaded (/etc/rc.d/init.d/myapp)
   Active: inactive (dead) since Mon 2015-10-05 15:17:41 CEST; 22h ago
  Process: 31850 ExecStop=/etc/rc.d/init.d/myapp stop (code=exited, status=0/SUCCESS)
  Process: 21054 ExecStart=/etc/rc.d/init.d/myapp start (code=exited, status=0/SUCCESS)

Usando o comando service :

[root@nec04 ~]# service myapp status
Local database at :3307 is started
Watchdog is running
Application is running

Por que systemctl acha que meu aplicativo não está sendo executado? Será que systemctl não está chamando a função stop porque acha que meu aplicativo já está parado?

    
por Wim Deblauwe 06.10.2015 / 14:27

2 respostas

1

Why does systemctl think my application is not running?

Porque, como diz Tom Hunt, não está sendo executado.

Could it be that systemctl is not calling the stop function because it thinks my application is already stopped?

Não. É muito claro que fez chamar a função de parada e executou como processo # 31850.

Existem duas possibilidades aqui, nenhuma das quais são problemas do sistema:

  • Em algum momento, você iniciou seus programas de serviço diretamente, não como um serviço systemd. Isso é o que ainda está funcionando. É claro que o sistema não saberá disso.
  • A funcionalidade status do seu script init.d está com defeito. Não seria o primeiro script init.d com defeito na história do mundo.

myapp.service - SYSV: Service script to start/stop my application

Esse "SYSV:" mostra que o script init.d é ruim. Ele nem tem o bloco de cabeçalho LSB.

Como diz Tom Hunt, escreva algumas unidades de serviço. Ou lembre-se da primeira regra para migração para o systemd e simplesmente aperte os que já foram escritos. Pela aparência, você realmente tem três serviços interdependentes, mas distintos, e deve estar escrevendo várias unidades de serviço com essas interdependências expressas. Se um deles é um servidor de banco de dados escutando na porta 3307, então a primeira regra quase certamente se aplica.

Leitura adicional

por 07.10.2015 / 12:27
3

Eu não sei sobre a saída service , nunca tendo realmente usado essa ferramenta, mas de acordo com systemctl , o aplicativo está realmente parado. Isso é o que a linha Active: inactive (dead) significa. ( Loaded significa apenas que o systemd tem o arquivo de unidade carregado na memória; isso deve ser verdadeiro o tempo todo, esteja o aplicativo em execução ou não).

Se ainda houver um processo em execução para o aplicativo, isso significa que a função de parada não está funcionando corretamente. No entanto, isso não deveria acontecer; uma vez systemctl pára alguma coisa, ele irá (após algum tempo limite) forçar a morte de todos os processos iniciados por aquela aplicação, usando cgroups. Então, a menos que seu processo seja executado como raiz e esteja intencionalmente saindo de seu cgroup (um comportamento extremamente patológico), o systemd deveria tê-lo matado. Não tenho certeza de como isso interage com a emulação sysVinit, no entanto.

Todo esse problema é complicado pelo fato de o systemd estar usando sua emulação sysVinit, usando o script de inicialização como um arquivo de unidade. Pode ser melhor reescrever como um arquivo unitário adequado, como descrito, e. aqui . Eu tenderia a recomendar o uso de Type=simple em vez de Type=dbus , já que é muito mais comum um programa ter um --no-daemon ou equivalente do que falar com dbus, e isso também é mais fácil de adicionar ao código tem controle sobre.

    
por 06.10.2015 / 19:14