Системный недетерминизм в начале загрузки из squashfs

Укороченная версия

При повторной загрузке одной и той же системы иногда сообщения о загрузке начинаются с

[  ...] systemd[1]: Set hostname to <liab>.
[  ...] systemd[1]: Mounted /.
[  ...] systemd[1]: Mounted /host.
[  ...] systemd[1]: Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.

в то время как в другое время они начинают с

[  ...] systemd[1]: Set hostname to <liab>.
[  ...] systemd[1]: Unit host.mount is bound to inactive unit dev-sda1.device. Stopping, too.
[  ...] systemd[1]: Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.

и не хватает нескольких сообщений запуска службы позже, по сравнению с первым случаем. Как я могу найти причину этого?

Длинная версия

У меня здесь очень нестандартные настройки, так как я строю настройки киоска.

Создание корневой файловой системы

Я не запустил полный установщик Ubuntu, но начну с debootstrap --variant=minbase … vivid, добавив несколько пакетов и настроив вещи в chroot. Затем этот chroot используется для создания squashfs, который служит корневой файловой системой моей установки.

Монтирование из initramfs

Этот squashfs только для чтения содержится в файле в некоторой файловой системе хоста, который может быть vfat или ext4 или любым другим. Он монтируется initramfs. Для этого у меня есть файл в /etc/initramfs-tools/conf.d/ который устанавливает LOOP к пути squashfs в корневой файловой системе, а также устанавливает LOOPFSTYPE=squashfs, Squashfs содержит пустой каталог с именем /host что вызывает /usr/share/initramfs-tools/scripts/local в mount -o move файловая система хоста в этот каталог. Поэтому, когда руки initramfs перейдут к systemd, у меня будет / а также /host смонтирован и готов к использованию.

Fstab

мой /etc/fstab читает

# <fs>          <mountpoint>    <type>          <opts>                                          <dump/pass>
/dev/loop0      /               squashfs        nodev,noauto,ro                                 0 0
/host/boot      /boot           auto            bind,ro                                         0 0
none            /run            tmpfs           noexec,nodev,nosuid                             0 0
none            /tmp            tmpfs           noexec,nodev,nosuid                             0 0
none            /var/tmp        tmpfs           noexec,nodev,nosuid                             0 0
none            /var/log        tmpfs           noexec,nodev,nosuid,size=5%                     0 0
none            /home/liab      tmpfs           nodev,nosuid,uid=liab,gid=liab,mode=0770        0 0

Итак, у меня есть запись для / но это отмечено noauto так как об этом уже позаботились initramfs, верно? Тем не менее, перечисленные там опции, по-видимому, применяются в какой-то момент, что я заметил, когда случайно nosuid там. У меня нет записи для /host так как я не знаю устройство, которое мне пришлось бы использовать для этого. Initramfs может обработать это устройство из конфигурации загрузчика, но я бы не хотел включать какой-либо идентификатор файловой системы или что-то подобное в squashfs, поскольку одни и те же squashfs должны использоваться из разных файловых систем хоста.

Загрузка

В настоящее время я загружаю эту настройку только в qemu. И я использую ее -snapshot вариант, с файловой системой моя учетная запись не может изменить. Таким образом, я уверен, что нет никакого изменения в основном образе файловой системы, и поэтому любое различие в поведении должно быть следствием некоторого недетерминизма, наиболее вероятно некоторого условия гонки. Мой вызов QEMU в настоящее время выглядит примерно так:

qemu-system-x86_64 \
-serial stdio \
-kernel …/boot/vmlinuz-3.19.0-15-generic \
-append 'console=ttyS0 root=/dev/sda1' \
-initrd …/initrd.img-3.19.0-15-generic \
-snapshot -hda …/hdimg

Таким образом, я получу экран, который в конечном итоге покажет графический интерфейс, но я также получу сообщения загрузки, напечатанные на терминал, где я запустил qemu, который гостевое ядро ​​увидит как последовательную консоль. Меня тревожат те сообщения на консоль.

По-видимому, initramfs отлично справляется со своей задачей, а затем передает управление systemd. Systemd, в свою очередь, отобразит приветствие, задаст имя хоста, а затем, очевидно, выберет один из двух возможных путей.

Первый путь вызывает сообщения монтирования для / а также /host, Начиная с сообщения [ OK ] Reached target Swap. многие шаги загрузки будут изменены строкой сообщения, начинающейся с [ OK ] с ОК, напечатанным зеленым цветом. Позже, вероятно, в ответ на Starting Journal Service, dmesg сообщения, подобные меткам времени, исчезают, по-видимому, перенаправляются на некоторый демон ведения журнала, и только те [ OK ] сообщения остаются.

Второй путь не упоминает перемонтирование / а также /host на ранней стадии. Вместо этого пишет Unit host.mount is bound to inactive unit dev-sda1.device. Stopping, too., dev-sda1.device там соответствует root=/dev/sda1 аргумент ядра; изменение этого идентификатора файловой системы соответственно изменяет сообщение об ошибке. В этом процессе загрузки никогда не бывает цветных линий. Кажется, что соответствующие строки просто отсутствуют вообще, даже если строки с метками времени регистрируют начало и завершение многих из тех же шагов. Порядок этих шагов отличается. Это означает, что после запуска службы журнала я больше не вижу никаких сообщений.

До сих пор я не могу сказать, какие другие реальные различия эти разные загрузки вызывают для работающей системы. Но мне не нравится недетерминированное поведение, которое я не понимаю.

отладка

В попытке отладить эту ситуацию я добавил systemd.log_target=console systemd.log_level=debug в командной строке ядра. Одним из нежелательных последствий этого было то, что при выполнении initramfs было напечатано миллион строк, очевидно, во время обработки события udev. Соответствующая часть журнала выглядит следующим образом. Если я получу зеленый OK нравится, это читает

Using notification socket /run/systemd/notify
Successfully created private D-Bus server.
dev-loop0.device changed dead -> tentative
dev-sda1.device changed dead -> tentative
Trying to enqueue job host.mount/start/fail
Installed new job host.mount/start as 1
Installed new job -.slice/start as 4
Installed new job system.slice/start as 3
Installed new job dev-sda1.device/start as 5
Installed new job -.mount/start as 2
Enqueued job host.mount/start as 1
host.mount changed dead -> mounted
Job host.mount/start finished, result=done
-.mount changed dead -> mounted
Job -.mount/start finished, result=done
Activating default unit: default.target
Failed to load configuration for all.target: No such file or directory
Failed to load configuration for bluetooth.service: No such file or directory
Failed to load configuration for hal.service: No such file or directory
Failed to load configuration for kbd.service: No such file or directory
Failed to load configuration for console-screen.service: No such file or directory
Failed to load configuration for plymouth-quit-wait.service: No such file or directory
Failed to load configuration for plymouth-quit.service: No such file or directory
Failed to load configuration for display-manager.service: No such file or directory
Trying to enqueue job graphical.target/start/isolate
Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.
Job dev-sda1.device/start finished, result=canceled
Installed new job syslog.socket/start as 90

и если я не получаю эти строки, он вместо этого читает

Using notification socket /run/systemd/notify
Successfully created private D-Bus server.
host.mount changed dead -> mounted
Unit host.mount is bound to inactive unit dev-sda1.device. Stopping, too.
Trying to enqueue job host.mount/stop/fail
Installed new job host.mount/stop as 1
Enqueued job host.mount/stop as 1
-.mount changed dead -> mounted
dev-loop0.device changed dead -> tentative
dev-sda1.device changed dead -> tentative
Activating default unit: default.target
Failed to load configuration for bluetooth.service: No such file or directory
Failed to load configuration for hal.service: No such file or directory
Failed to load configuration for kbd.service: No such file or directory
Failed to load configuration for console-screen.service: No such file or directory
Failed to load configuration for all.target: No such file or directory
Failed to load configuration for plymouth-quit-wait.service: No such file or directory
Failed to load configuration for plymouth-quit.service: No such file or directory
Failed to load configuration for display-manager.service: No such file or directory
Trying to enqueue job graphical.target/start/isolate
Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.
Job host.mount/stop finished, result=canceled
Startup finished in 13.247s (kernel) + 2.322s (userspace) = 15.569s.
Installed new job systemd-modules-load.service/start as 48

Не уверен, что это полезно.

0 ответов

Другие вопросы по тегам