Вопрос или проблема
Я знаю, что мой заголовок немного запутан, поэтому позвольте мне более подробно объяснить, что я здесь делаю. Я использую эфемерную корневую настройку на своем компьютере, что в основном означает, что мой /
монтируется как tmpfs
, и файлы, которые я хочу действительно использовать и сохранить между корнями, должны быть как-то связаны с этим /
монтированием. В основном у меня уже есть тривиально рабочее решение, которое связывает монтирование различных файлов с постоянного устройства на /sysroot
в initrd, которые затем сохраняются в фактической системе и могут использоваться как обычно.
Небольшая проблема, с которой я сталкиваюсь с этим подходом, заключается в том, что так как монтирование происходит внутри initrd, у меня нет много практического контроля над зависимостями systemd для созданного монтированного юнита. Я не могу объявить монтированный юнит в initrd, потому что его атрибуты не будут сохранены после switch_root
, и я не могу объявить другой монтированный юнит для моего связывающего монтирования, потому что тогда он будет перемонтирован сам на себя дважды (признаюсь, я не знаю, является ли это проблемой, но это не кажется «хорошим»).
Моя главная забота заключается в том, что я хочу объявить некоторую специальную последовательность для этих связывающих монтирований, чтобы они не были принудительно отключены слишком рано системой systemd при завершении работы системы (при достижении umount.target
). Основная причина этого заключается в том, что я сохраняю /var/log
как связывающее монтирование для сохранения журналов journalctl
, и когда umount.target
пытается отмонтировать связывающее монтирование в этом месте, это не удается. Я хочу каким-то образом убрать ConflictsWith=umount.target
, который прикреплен ко всем общим монтированным юнитам, чтобы не было необходимости отмонтировать так рано. В идеале я бы вообще не выполнял отмонтирование и просто позволил бы exitrd плавно завершить монтирование вместе с /
, что происходит автоматически.
Я не совсем уверен, как я могу это действительно сделать, особенно учитывая тот факт, что монтирования, происходящие в initrd, не сохраняют никакой информации, специфичной для systemd, которую я мог бы использовать. Эти монтирования также динамически генерируются через конфигурацию, поэтому жесткое кодирование их в /etc/fstab
с такими параметрами, как x-systemd.some-opt
, нецелесообразно.
На данный момент единственное, что я пробовал, это создание .mount
юнита в системе, который, как уже упоминалось ранее, “перемонтирует” монтированный юнит сверху, что приводит к двум обнаруженным монтированиям и, соответственно, требует двух операций unmount
на одном и том же месте монтирования. Снова, не знаю, является ли это действительно проблемой, но это не кажется особенно чистым, что меня беспокоит. Это перемонтирование происходило бы даже если бы я указал Options=remount,...
, что, по правде говоря, немного запутанно, но тоже не совсем понятно.
Ответ или решение
Объявление привязочного монтирования в initrd, управляемом systemd, и сохранение атрибутов systemd для монтирования в системе
Ваша задача по созданию эфемерной системы на основе tmpfs
с сохранением файлов через привязочные монтирования вызывает несколько сложных вопросов, связанных с функциональностью systemd в контексте инициализации системы. Рассмотрим ключевые аспекты вашей проблемы и предложим возможные решения.
Понимание контекста
Вы правильно заметили, что монтирование в initrd не сохраняет системные атрибуты, что создает ограничения. Это связано с тем, что systemd не может сохранить динамически созданные монтирования, так как они теряются при вызове switch_root
. В этом контексте важно задать правильные зависимости и порядок отключения монтирования, особенно когда речь идет о монтировании, связанного с системными логами.
Задачи и мета-теоретические проблемы
Вашей основной проблемой является необходимость избежать конфликта с umount.target
, когда происходит процесс завершения. Вы хотите настроить систему так, чтобы ваши специальные привязочные монтирования не удалялись на ранних стадиях отключения системы, что может привести к потере логов.
Возможные решения
-
Использование пользовательских единиц:
Создайте пользовательские unit-файлы для монтирования, которые будут включать указания на зависимости от других единиц (например,After=local-fs.target
) и эксплицитно указывайте, что эти монтирования следует сохранять до завершения системы. Это делается следующим образом:[Unit] Description=My Custom Bind Mount Requires=local-fs.target After=local-fs.target [Mount] What=/path/to/persistent/storage Where=/var/log Type=none Options=bind [Install] WantedBy=multi-user.target
-
Правила systemd для атрибутов:
Чтобы ваши предварительно объявленные привязочные монтирования не конфликтовали с системными событиями отключения, возможно, стоит добавить атрибуты к монтированию в initrd, чтобы указатьConflicts=
иBefore=
для управления последовательностью монтирования и размонтирования. -
Создание жесткой ссылки:
Если ваши mount-единицы создаются динамически и это становится проблемой, можно рассмотреть возможность создания жестких ссылок на ваши файловые системы для манипуляций с ними. Это возможно через сценарии активации, которые могут осуществлять изменения в том, как монтирования воспринимаются. -
Механизм удаления:
Обратите внимание на то, как systemd обрабатывает удаление монтирования. Правильная настройкаBefore=shutdown.target
и других целевых единиц позволяет указать systemd, что некоторые монтирования не должны быть отключены слишком рано. -
Изменение конфигурации initrd:
В некоторых случаях может потребоваться изменить поведение initrd через параметры ядра или параметры командной строки. Это может быть выполнено через прерывание процесса загрузки с помощьюrd.break
, где можно временно изменить поведение монтирования или добавить свое собственное монтирование.
Заключение
Обеспечение правильного управления привязочными монтированиями в системе с помощью управления через systemd требует взвешенного подхода к конфигурации и корректного задания зависимостей. Ваша основная цель — избежать конфликтов и обеспечить целостность ваших логов. Оптимизация systemd для ваших нужд подразумевает использование кастомизированных единиц, корректировку зависимостей и возможно, вмешательство на этапе инициализации системы.
Эти шаги позволят вам более эффективно управлять монтированием и обеспечивать сохранение необходимых данных в вашей эфемерной системе, обеспечивая при этом лучшую производительность и надежность.