¿Cómo puede distinguir entre un bloqueo y un reinicio en RHEL7?

9

¿Hay alguna manera de determinar si un servidor RHEL7 se reinició a través de systemctl (o alias de reinicio / apagado) o si el servidor se bloqueó? Pre-sistemad esto fue bastante fácil de determinar last -x runlevel, pero con RHEL7 no está tan claro.

kwb
fuente

Respuestas:

3

Hay más de una forma de hacer esto, pero cubriré las 4 mejores que se me ocurran. (EDITAR: publiqué una versión limpia de esto como un artículo público en redhat.com. Consulte: Cómo distinguir entre un bloqueo y un reinicio elegante en RHEL 7 ).

(1) registros auditados

auditado es asombroso. Puede ver todos los diferentes eventos que registra marcando ausearch -m. A propósito del problema en cuestión, registra el apagado del sistema y el arranque del sistema, por lo que puede usar el comando ausearch -i -m system_boot,system_shutdown | tail -4. Si esto informa un SYSTEM_SHUTDOWN seguido de un SYSTEM_BOOT , todo está bien; sin embargo, si informa 2 líneas SYSTEM_BOOT seguidas, entonces claramente el sistema no se apagó correctamente, como en el siguiente ejemplo:

[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) último -x

Igual que el anterior, pero con el last -n2 -x shutdown rebootcomando simple . Ejemplo donde el sistema se bloqueó:

[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)    

O donde el sistema tuvo un reinicio 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) cree su propia unidad de servicio

Este es, en mi humilde opinión, el mejor enfoque porque puedes adaptarlo a lo que quieras. Hay un millón de formas de hacer esto. Aquí hay uno que acabo de inventar. Este próximo servicio solo se ejecuta en el apagado.

[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.

Luego, cuando se inicia el sistema, este próximo servicio solo se iniciará si existe el archivo creado por el servicio de apagado anterior.

[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.

Entonces, en cualquier momento, puedo verificar si el arranque anterior se realizó después de un apagado correcto haciendo systemctl is-active check_graceful, por ejemplo:

[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.

O aquí está después de un cierre sin gracia:

[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 la pena mencionar que si configura systemd-journaldpara mantener un diario persistente, puede usar journalctl -b -1 -npara mirar las últimas líneas (10 por defecto) del inicio anterior ( -b -2es el inicio anterior, etc.). Ejemplo donde el sistema se reinicia con gracia:

[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

Si obtiene una buena salida como esa, entonces claramente el sistema se apagó con gracia. Dicho esto, no es súper confiable en mi experiencia cuando suceden cosas malas (fallas del sistema). A veces la indexación se vuelve rara.

rsaw
fuente
7

Es curioso, anoche reinicié un sistema CentOS 7, así que tengo un buen registro de esto para mirar.

En el caso de un bloqueo, obviamente no se registra nada entre el momento del bloqueo y el reinicio del sistema.

En el caso de un reinicio, es bastante obvio, ya que obtiene un registro de (casi) todo lo que systemd está haciendo para apagar el sistema.

Una de esas entradas de registro que probablemente no verá en ninguna otra circunstancia que no sea apagar o pasar al modo de usuario único es:

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

Puede reiniciar su propio sistema para ver qué se registra realmente.

Michael Hampton
fuente
1
¿Creería usted que CentOS 7 registra esto y RHEL 7 no? Ese fue nuestro enfoque inicial basado en lo que vimos en los registros de CentOS (y Fedora). Cuando probamos en RHEL7, no dados.
kwb
1
@kwb Después de echar un vistazo a un sistema RHEL 7.2, sí, lo creo. De hecho, parece que muchas cosas que deberían registrarse no se registran. Todo lo que puedo decir es: ¿WTF?
Michael Hampton
No estoy seguro de qué están hablando. systemd en RHEL 7.0-7.2 genera los mensajes Stopping Multi-User Systemy Stopped target Multi-User System.
rsaw
@rsaw Somos conscientes de que los mensajes se generan. El problema es que no aparecen en el diario.
Michael Hampton
@MichaelHampton el diario no es persistente por defecto. Sólo se puede ver registros de su arranque actual a menos que usted mkdir /var/log/journalo explícitamente establece Storage=persistenten /etc/systemd/journald.conf. Publiqué una respuesta por separado.
rsaw
5

No me gusta especialmente la respuesta, pero es una respuesta que obtuvimos de RH. Lo estoy publicando aquí en caso de que ayude a alguien más.

Una forma posible es buscar rsyslogden /var/log/messages. Un cierre elegante habría tenido exiting on signal 15. Un choque no lo haría.

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

Dos startlíneas consecutivas pueden indicar un bloqueo. Y un startseguido de un exitpuede indicar un reinicio.

Desafortunadamente, también podría dar malos resultados si rsyslogd se cae o se reinicia fuera de un reinicio / bloqueo.

kwb
fuente
Mal juego Red Hat. Hay otros comportamientos que resultarán en eso, exiting on signal 15además de un reinicio. Una normal service rsyslog restarttambién da como resultado el mensaje de exiting on signal 15mensaje.
Stefan Lasiewski
Esta es una respuesta válida, pero como alguien que trabaja en el soporte técnico de Red Hat, no es con lo que hubiera ido. Mira mi respuesta.
rsaw
1

Esto parece funcionar constantemente por "el apagado ordenado" ( shutdown, reboot, systemctl), así como "accidentes" (apagado, reinicio, echo c > /proc/sysrq-trigger):

last -x | grep 'reboot\|shutdown'

Una rebootlínea seguida de una shutdownlínea indica un "apagado correcto". Dos rebootlíneas indican un "bloqueo".

kwb
fuente