Como você pode distinguir entre uma falha e uma reinicialização no RHEL7?

9

Existe uma maneira de determinar se um servidor RHEL7 foi reinicializado via systemctl (ou aliases de reinicialização / desligamento) ou se o servidor travou? Antes do sistema, isso era bastante fácil de determinar com last -x runlevel , mas com o RHEL7 não é tão claro.

    
por kwb 12.07.2016 / 22:35

4 respostas

3

Há mais de uma maneira de fazer isso, mas vou cobrir as 4 melhores que posso imaginar. (EDIT: Eu publiquei uma versão limpa deste como um artigo público sobre redhat.com. Veja: Como distinguir entre um acidente e uma reinicialização elegante no RHEL 7 .

(1) registros auditd

auditd é incrível. Você pode ver todos os diferentes eventos registrados, verificando ausearch -m . A propósito do problema em questão, ele registra o desligamento do sistema e a inicialização do sistema, para que você possa usar o comando ausearch -i -m system_boot,system_shutdown | tail -4 . Se isto reportar um SYSTEM_SHUTDOWN seguido por um SYSTEM_BOOT , tudo está bem; no entanto, se ele relata 2 linhas SYSTEM_BOOT em uma linha, é claro que o sistema não foi encerrado normalmente, como no exemplo a seguir:

[root@a72 ~]# ausearch -i -m system_boot,system_shutdown | tail -4
----
type=SYSTEM_BOOT msg=audit(09/20/2016 01:10:32.392:7) : pid=657 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg=' comm=systemd-update-utmp exe=/usr/lib/systemd/systemd-update-utmp hostname=? addr=? terminal=? res=success' 
----
type=SYSTEM_BOOT msg=audit(09/20/2016 01:11:41.134:7) : pid=656 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg=' comm=systemd-update-utmp exe=/usr/lib/systemd/systemd-update-utmp hostname=? addr=? terminal=? res=success' 

(2) last -x

O mesmo que acima, mas com o comando simples last -n2 -x shutdown reboot . Exemplo em que o sistema caiu:

[root@a72 ~]# last -n2 -x shutdown reboot
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:11 - 01:20  (00:08)    
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:10 - 01:20  (00:09)    

Ou onde o sistema teve uma reinicialização elegante:

[root@a72 ~]# last -n2 -x shutdown reboot
reboot   system boot  3.10.0-327.el7.x Tue Sep 20 01:21 - 01:21  (00:00)    
shutdown system down  3.10.0-327.el7.x Tue Sep 20 01:21 - 01:21  (00:00)    

(3) crie sua própria unidade de serviço

Esta é a melhor abordagem porque você pode adaptá-la ao que você quiser. Existem milhões de maneiras de fazer isso. Aqui está uma que acabei de inventar. Este próximo serviço só é executado no desligamento.

[root@a72 ~]# cat /etc/systemd/system/set_gracefulshutdown.service
[Unit]
Description=Set flag for graceful shutdown
DefaultDependencies=no
RefuseManualStart=true
Before=shutdown.target

[Service]
Type=oneshot
ExecStart=/bin/touch /root/graceful_shutdown

[Install]
WantedBy=shutdown.target
[root@a72 ~]# systemctl enable set_gracefulshutdown.service 
Created symlink from /etc/systemd/system/shutdown.target.wants/set_gracefulshutdown.service to /etc/systemd/system/set_gracefulshutdown.service.

Então, quando o sistema inicializar, este próximo serviço só será iniciado se o arquivo criado pelo serviço de desligamento acima existir.

[root@a72 ~]# cat /etc/systemd/system/check_graceful.service 
[Unit]
Description=Check if system booted after a graceful shutdown
ConditionPathExists=/root/graceful_shutdown
RefuseManualStart=true
RefuseManualStop=true

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/rm /root/graceful_shutdown

[Install]
WantedBy=multi-user.target
[root@a72 ~]# systemctl enable check_graceful
Created symlink from /etc/systemd/system/multi-user.target.wants/check_graceful.service to /etc/systemd/system/check_graceful.service.

Portanto, a qualquer momento, posso verificar se a inicialização anterior foi feita após um desligamento normal fazendo systemctl is-active check_graceful , por exemplo:

[root@a72 ~]# systemctl is-active check_graceful && echo YAY || echo OH NOES
active
YAY
[root@a72 ~]# systemctl status check_graceful
● check_graceful.service - Check if system booted after a graceful shutdown
   Loaded: loaded (/etc/systemd/system/check_graceful.service; enabled; vendor preset: disabled)
   Active: active (exited) since Tue 2016-09-20 01:10:32 EDT; 20s ago
  Process: 669 ExecStart=/bin/rm /root/graceful_shutdown (code=exited, status=0/SUCCESS)
 Main PID: 669 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/check_graceful.service

Sep 20 01:10:32 a72.example.com systemd[1]: Starting Check if system booted after a graceful shutdown...
Sep 20 01:10:32 a72.example.com systemd[1]: Started Check if system booted after a graceful shutdown.

Ou aqui está depois de um desligamento deselegante:

[root@a72 ~]# systemctl is-active check_graceful && echo YAY || echo OH NOES
inactive
OH NOES
[root@a72 ~]# systemctl status check_graceful
● check_graceful.service - Check if system booted after a graceful shutdown
   Loaded: loaded (/etc/systemd/system/check_graceful.service; enabled; vendor preset: disabled)
   Active: inactive (dead)
Condition: start condition failed at Tue 2016-09-20 01:11:41 EDT; 16s ago
           ConditionPathExists=/root/graceful_shutdown was not met

Sep 20 01:11:41 a72.example.com systemd[1]: Started Check if system booted after a graceful shutdown.

(4) journalctl

Vale a pena mencionar que, se você configurar systemd-journald para manter um diário persistente, poderá usar journalctl -b -1 -n para ver as últimas linhas (10 por padrão) da inicialização anterior ( -b -2 é a inicialização antes disso, etc). Exemplo onde o sistema reinicializou graciosamente:

[root@a72 ~]# mkdir /var/log/journal
[root@a72 ~]# systemctl -s SIGUSR1 kill systemd-journald
[root@a72 ~]# reboot
...
[root@a72 ~]# journalctl -b -1 -n
-- Logs begin at Tue 2016-09-20 01:01:15 EDT, end at Tue 2016-09-20 01:21:33 EDT. --
Sep 20 01:21:19 a72.example.com systemd[1]: Stopped Create Static Device Nodes in /dev.
Sep 20 01:21:19 a72.example.com systemd[1]: Stopping Create Static Device Nodes in /dev...
Sep 20 01:21:19 a72.example.com systemd[1]: Reached target Shutdown.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Shutdown.
Sep 20 01:21:19 a72.example.com systemd[1]: Reached target Final Step.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Final Step.
Sep 20 01:21:19 a72.example.com systemd[1]: Starting Reboot...
Sep 20 01:21:19 a72.example.com systemd[1]: Shutting down.
Sep 20 01:21:19 a72.example.com systemd-shutdown[1]: Sending SIGTERM to remaining processes...
Sep 20 01:21:19 a72.example.com systemd-journal[483]: Journal stopped

Se você obtiver um bom resultado como esse, então, claramente, o sistema foi encerrado normalmente. Dito isso, não é super confiável na minha experiência quando coisas ruins acontecem (falhas no sistema). Às vezes a indexação fica estranha.

    
por 20.09.2016 / 07:43
7

Engraçado, eu acabei de reiniciar o sistema CentOS 7 ontem à noite, então eu tenho um bom registro apenas para ver.

No caso de uma falha, obviamente nada é registrado entre a hora da falha e a reinicialização do sistema.

No caso de uma reinicialização, é bastante óbvio, já que você obtém um registro de (quase) tudo que o systemd está fazendo para desligar o sistema.

Uma dessas entradas de registro que você provavelmente não verá em nenhuma circunstância além de desligar ou ir para o modo de usuário único é:

Jul 13 01:27:55 yaungol systemd: Stopped target Multi-User System.

Você pode reinicializar seu próprio sistema para ver o que realmente é registrado.

    
por 13.07.2016 / 20:44
5

Eu particularmente não gosto da resposta, mas é uma resposta que recebemos da RH. Estou postando aqui caso ajude alguém.

Uma maneira possível é grep para rsyslogd in /var/log/messages . Um desligamento normal teria exiting on signal 15 . Um acidente não seria.

tac /var/log/messages | grep 'rsyslogd.*start\|rsyslogd.*exit'

Duas linhas start consecutivas podem indicar uma falha. E um start seguido por um exit pode indicar uma reinicialização.

Infelizmente, ele também pode gerar resultados ruins se o rsyslogd cair ou for reiniciado fora de uma reinicialização / falha.

    
por 13.07.2016 / 20:38
1

Isso parece funcionar consistentemente para "desligamentos normais" ( shutdown , reboot , systemctl ) e também "travamentos" (desligar, redefinir, echo c > /proc/sysrq-trigger ):

last -x | grep 'reboot\|shutdown'

Uma linha reboot seguida por uma linha shutdown indica um "desligamento normal". Dois reboot linhas indicam uma "falha".

    
por 21.07.2016 / 19:27