Systemd não-determinismo no início do boot do squashfs

1

Versão curta

Ao inicializar exatamente o mesmo sistema repetidamente, algumas vezes as mensagens de inicialização começam com

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

enquanto em outras ocasiões eles começam com

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

e falta várias mensagens de inicialização de serviços mais tarde, em comparação com o primeiro caso. Como posso encontrar a causa disso?

Versão longa

Eu tenho uma configuração não padrão aqui, já que estou criando uma configuração de quiosque.

Criação do sistema de arquivos raiz

Eu não executei um instalador completo do Ubuntu, mas comecei com debootstrap --variant=minbase … vivid , adicionando alguns pacotes e customizando coisas em um chroot. Esse chroot é então usado para criar um squashfs que serve como o sistema de arquivos raiz da minha configuração.

Montagem do initramfs

Esse squashfs somente leitura está contido em um arquivo em algum sistema de arquivos host, que pode ser vfat ou ext4 ou qualquer outro. Ele é montado pelo initramfs. Para conseguir isso eu tenho um arquivo em /etc/initramfs-tools/conf.d/ que define LOOP para o caminho do squashfs no sistema de arquivos raiz e também define LOOPFSTYPE=squashfs . O squashfs contém um diretório vazio chamado /host , que faz com que o /usr/share/initramfs-tools/scripts/local to mount -o move do sistema de arquivos do host para esse diretório. Portanto, quando o initramfs passar o controle para o systemd, terei / e /host montado e pronto para uso.

fstab

Meu /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

Então, eu tenho uma entrada para / , mas ela está marcada com noauto , já que o initramfs já cuidou disso, certo? No entanto, as opções listadas ali aparentemente são aplicadas em algum momento, o que eu notei enquanto acidentalmente tinha nosuid lá. Eu não tenho uma entrada para /host , pois não sei o dispositivo que eu teria que usar para isso. O initramfs pode trabalhar com esse dispositivo a partir da configuração do carregador de boot, mas eu não gostaria de incluir qualquer id de sistema de arquivos ou algo assim nos squashfs, já que os mesmos squashfs devem ser utilizáveis de diferentes sistemas de arquivos host.

Inicializando

Atualmente, estou apenas inicializando essa configuração no qemu. E estou usando sua opção -snapshot , com um sistema de arquivos que minha conta de usuário não pode modificar. Portanto, tenho certeza de que não há nenhuma mudança na imagem do sistema de arquivos subjacente, e qualquer diferença de comportamento deve, portanto, ser a consequência de algum não-determinismo, provavelmente algum tipo de condição de corrida. Minha chamada do qemu atualmente é mais ou menos assim:

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

Então eu vou pegar uma tela que eventualmente mostrará uma GUI, mas também receberei mensagens de boot impressas no terminal onde iniciei o qemu, que o kernel guest verá como um console serial. São essas mensagens para o console que me preocupam.

Aparentemente, o initramfs faz o trabalho bem, e depois o controle das mãos no systemd. O Systemd, por sua vez, exibirá uma saudação, definirá o nome do host e, aparentemente, seguirá um dos dois caminhos possíveis.

O primeiro caminho causa as mensagens de montagem para / e /host . Começando com uma mensagem [ OK ] Reached target Swap. , muitas das etapas de inicialização serão iniciadas por uma linha de mensagem iniciando em [ OK ] com o OK impresso em verde. Posteriormente, provavelmente em resposta a Starting Journal Service , as mensagens dmesg -like timestamped desaparecerão, presumivelmente redirecionadas para algum daemon de registro, e somente aquelas [ OK ] mensagens permanecem.

O segundo caminho não menciona remontar / e /host antecipadamente. Em vez disso, escreve Unit host.mount is bound to inactive unit dev-sda1.device. Stopping, too. . O dev-sda1.device corresponde ao argumento do kernel root=/dev/sda1 ; mudar isso para algum ID do sistema de arquivos altera a mensagem de erro de acordo. Nunca há linhas coloridas neste processo de inicialização. As linhas correspondentes simplesmente parecem estar ausentes, mesmo se o log de linhas com registro de data e hora iniciar e concluir muitas das mesmas etapas. A ordem dessas etapas é diferente. O que significa que, uma vez iniciado o serviço de diário, não vejo mais nenhuma mensagem.

Até agora, não sei dizer quais outras diferenças reais esses diferentes bootups causam no sistema em execução. Mas eu não gosto de comportamento não-determinístico que eu não entendo.

Depuração

Em uma tentativa de depurar esta situação, adicionei systemd.log_target=console systemd.log_level=debug à linha de comando do kernel. Um efeito indesejado disso foi que a execução do initramfs imprimia um milhão de linhas aparentemente durante o processamento do evento do udev. A parte relevante do log parece ser a seguinte. Se eu obtiver o% green co_de% likes, ele lê

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

e se eu não obtiver essas linhas, ele lê

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

Não tenho certeza se isso é de alguma utilidade.

    
por MvG 04.05.2015 / 13:03

0 respostas