Вопрос или проблема
Я сталкиваюсь с странной проблемой с journald
на пользовательской встроенной системе Linux, построенной с использованием Yocto.
На только что подготовленной и загруженной системе журнал работает нормально:
- использование
--list-boots
показывает только одну (0) запись journalctl -n 5 -b
показывает последние 5 записей
Однако после вводе команды reboot
и повторного входа в систему текущая загрузка становится как-то невидимой:
--list-boots
по-прежнему показывает только одну записьjournalctl -b
выводит-- Нет записей --
- инспекция файла
system.journal
с использованиемjournalctl --file
показывает, что последние записи в нем относятся к предыдущему выключению (то есть ничего после перезагрузки), те же записи показываются при вызове простоjournalctl
без-b
Всё вышеупомянутое исправляется после вызова --rotate
– создается новый файл в каталоге journal/
, -b
начинает показывать логи для текущей загрузки, список загрузок показывает ещё одну запись, как и ожидалось. Это кажется мне так, как если бы файл system.journal
был недоступен для journald
для записи после перезагрузки, и вращение как-то это исправляет.
Интересно, что это происходит только с командой reboot
(“мягкая” перезагрузка). Отключение питания устройства и повторное его включение (с или без вызова poweroff
сначала, и даже с использованием reboot
с отключением питания сразу после перезапуска системы), после загрузки системы journald
работает, как и ожидалось, и новая загрузка корректно распознается.
Некоторая дополнительная информация:
- Логи хранятся на отдельном разделе SD карты, который монтируется с помощью
fstab
, и на который/var/log
является символьной ссылкой:
lrwxrwxrwx 1 root root 6 Mar 9 2018 /var/log -> /log
- Размонтирование указанного раздела не удается во время последовательности перезагрузки/выключения:
[FAILED] Failed unmounting /log
(Я полагаю, что это может быть решающим для решения проблемы, хотя не уверен как) - Версия Yocto
scarthgap
, systemd255.4
- Система работает полностью с SD карты, корневой раздел монтирован RW, и initramfs не используется
Я был бы благодарен за предложения по решению или дальнейшей отладке этого, и дополнительно (даже если это не связано с основной проблемой) о том, как решить проблему размонтирования раздела логов (возможно, существует способ задержать размонтирование до того, как journald
остановился?).
Спасибо
Я отвечу на собственный вопрос:
Единственное необходимое исправление было добавить точку монтирования логов в RequiresMountsFor
в файле юнита службы systemd-journal-flush
:
RequiresMountsFor=/var/log/journal /log
В yocto это потребовало внесения изменений в рецепт systemd
для изменения в units/systemd-journal-flush.service
.
После этого изменения новая загрузка корректно распознается каждый раз, и больше нет сбоев размонтирования во время выключения.
Ответ или решение
Теория
Проблемы с systemd-journald
могут возникать по нескольким причинам, и в данном случае ключевыми факторами являются работа с нестандартными конфигурациями, такими как использование Yocto и хранение журналов на отдельном разделе SD-карты.
Изначально journald
предназначен для сбора и хранения логов различных системных процессов и предоставляет множество опций для их управления и поиска. Он ожидает, что журналы будут храниться в определённом месте, обычно это /var/log/journal
, но в случае нестандартных конфигураций (например, использование символических ссылок или хранение на других носителях) могут возникнуть проблемы с доступностью журналов.
Основное предположение заключается в том, что после мягкой перезагрузки (reboot
) система сталкивается с проблемами доступа к месту хранения журналов до тех пор, пока вручную не будет выполнено вращение журналов (journalctl --rotate
). Это указывает на то, что монтирование носителя, на котором хранятся журналы, либо запаздывает, либо вовсе не осуществляется должным образом, что и приводит к отсутствию записей текущего сеанса после перезагрузки.
Пример
Рассмотрим пример конкретного поведения системы. После первоначальной загрузки всё функционирует корректно:
- Команда
--list-boots
показывает только одну запись (текущую загрузку). - Команда
journalctl -n 5 -b
отображает последние пять записей логов текущей загрузки.
Однако, после выполнения reboot
, система показывает:
--list-boots
также показывает только одну запись.journalctl -b
не отображает записей для текущей загрузки.- Рассмотрение содержания файла
system.journal
показывает записи лишь до предыдущего выключения.
Проблема решается после принудительного вращения:
- Новая запись в каталоге журналов создаётся, и команда
-b
теперь отображает логи для текущей загрузки. - Список загрузок теперь увеличивается на одну запись.
Применение
Чтобы решить проблему и устранить из отказов размонтирования, был внесён ряд изменений в конфигурацию systemd. Основной шаг заключался в добавлении требуемых точек монтирования в свойство RequiresMountsFor
юнита systemd-journal-flush
. Теперь он явно включает раздел для хранения журналов:
RequiresMountsFor=/var/log/journal /log
В рамках Yocto это требовало изменений в рецепте сборки systemd
, где выполнялась модификация файла units/systemd-journal-flush.service
.
Объяснение этой проблемы заключается в том, что systemd
может не всегда автоматически и своевременно определять необходимость монтирования связанных точек до тех пор, пока не будет запущен journald
, что и вызывало задержки или отсутствие доступа к файлам логов. Настройка юнита через RequiresMountsFor
позволяет гарантировать, что все необходимые точки монтирования будут доступны до момента запуска служб, зависящих от них.
Заключение
Таким образом, для устранения подобных неполадок в системах, работающих на нестандартных конфигурациях, важно уделить внимание корректному управлению монтированием и обеспечению доступности всех необходимых ресурсов до запуска системных служб. Это может требовать тонкой настройки, особенно в средах с ограниченными ресурсами, таких как встроенные системы, построенные с использованием Yocto, где надлежащая конфигурация становится определяющим фактором для стабильной работы.