Ответы:
Есть несколько способов сделать это, но я расскажу о 4 лучших из них, которые я могу придумать. (РЕДАКТИРОВАТЬ: я опубликовал исправленную версию этого как общедоступную статью на redhat.com. См .: Как различить сбой и постепенную перезагрузку в RHEL 7. )
AuditD удивительно. Вы можете увидеть все различные события, которые он регистрирует, проверив ausearch -m
. Что касается рассматриваемой проблемы, он регистрирует завершение работы системы и загрузку системы, поэтому вы можете использовать команду ausearch -i -m system_boot,system_shutdown | tail -4
. Если это сообщает о SYSTEM_SHUTDOWN, за которым следует SYSTEM_BOOT , все в порядке; однако, если он сообщает о 2 строках SYSTEM_BOOT подряд, то очевидно, что система не завершилась корректно , как в следующем примере:
[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'
То же, что и выше, но с помощью простой last -n2 -x shutdown reboot
команды. Пример сбоя системы:
[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)
Или там, где система имела изящную перезагрузку:
[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)
Это ИМХО лучший подход, потому что вы можете адаптировать его к тому, что вы хотите. Есть миллион способов сделать это. Вот тот, который я только что сделал. Эта следующая служба работает только при выключении.
[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.
Затем при загрузке системы эта следующая служба будет запускаться только в том случае, если существует файл, созданный вышеуказанной службой завершения работы.
[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.
Поэтому в любой момент времени я могу проверить, была ли выполнена предыдущая загрузка после корректного завершения работы systemctl is-active check_graceful
, например:
[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.
Или вот после неуместного отключения:
[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.
Стоит отметить, что если вы сконфигурируете systemd-journald
вести постоянный журнал, вы можете использовать его journalctl -b -1 -n
для просмотра нескольких последних (по умолчанию 10) строк предыдущей загрузки ( -b -2
есть ли загрузка до этого и т. Д.). Пример, где система перезагрузилась изящно:
[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
Если вы получаете хороший вывод, как этот, то ясно, что система была корректно завершена. Тем не менее, это не супер надежно в моем опыте, когда происходят плохие вещи (сбои системы). Иногда индексация становится странной.
Забавно, я просто случайно перезагрузил систему CentOS 7 прошлой ночью, и поэтому у меня есть хороший журнал, на который можно посмотреть.
В случае сбоя, очевидно, ничего не регистрируется между моментом сбоя и перезагрузкой системы.
В случае перезагрузки это довольно очевидно, поскольку вы получаете журнал (почти) всего, что systemd делает для выключения системы.
Одна из таких записей в журнале, которую вы вряд ли увидите при любых обстоятельствах, кроме выключения или перехода в однопользовательский режим:
Jul 13 01:27:55 yaungol systemd: Stopped target Multi-User System.
Вы можете перезагрузить свою собственную систему, чтобы увидеть, что на самом деле регистрируется.
Stopping Multi-User System
и Stopped target Multi-User System
сообщений.
mkdir /var/log/journal
или явно не установлены Storage=persistent
в /etc/systemd/journald.conf
. Я разместил отдельный ответ.
Мне не очень нравится ответ, но это ответ, который мы получили от RH. Я публикую это здесь на случай, если это поможет кому-то еще.
Одним из возможных способов является вычленить информацию rsyslogd
в /var/log/messages
. Изящное отключение будет иметь exiting on signal 15
. А крушения не будет.
tac /var/log/messages | grep 'rsyslogd.*start\|rsyslogd.*exit'
Две последовательные start
строки могут указывать на сбой. И start
после exit
может указывать на перезагрузку.
К сожалению, это может также дать плохие результаты, если rsyslogd выходит из строя или перезапускается после перезагрузки / сбоя.
exiting on signal 15
кроме перезагрузки. Нормаль service rsyslog restart
также приводит к exiting on signal 15
сообщению.
Это похоже на работу последовательно для «изящных остановов» ( shutdown
, reboot
, systemctl
), а также «авария» (отключение питания, сброс, echo c > /proc/sysrq-trigger
):
last -x | grep 'reboot\|shutdown'
reboot
Линии следует shutdown
линии указывает на «завершение» изящный. Две reboot
строки указывают на «сбой».