slashbeast / better-initramfs

Small and reliable initramfs solution supporting (remote) rescue shell, lvm, dmcrypt luks, software raid, tuxonice, uswsusp and more.
BSD 3-Clause "New" or "Revised" License
318 stars 54 forks source link

/dev/console missing with embedded initramfs #55

Open jeandestouches opened 2 years ago

jeandestouches commented 2 years ago

Following my issue related to missing nodes when initramfs is embedded into kernel. I tried on my laptop, it is easier with a display. My laptop (like my headless system) uses LUKS with askpass to unlock drive as usual. Both are running kernel 5.10.74.

I added "sshd sshd_wait=10 sshd_port=43222 binit_net_if=eth0 binit_net_addr=192.168.1.14/24' to replicate what it is used on my headless system.

So, I tried with initramfs embedded into kernel and then, with initramfs passed to the bootloader. (grub) Both examples uses freshly built better-initramfs (with the commit that removed mknod calls) so dev/ is empty in sourceroot.

With initramfs embedded into kernel :

Enter passphrase for /dev/sda1: rescueshelll / # sh: k: not found
#(typing ls blindly)
rescueshell / # VERSION functions.sh [..] root sys
#(typing cat /init.log blindly)
Executed: 'mkdir -m 700 -p /newroot'
Executed: 'mkdir -m 700 -p /sbin'
Executed: 'mkdir -m 700 -p /proc'
Executed: 'mkdir -m 700 -p /sys'
Executed: 'mkdir -m 700 -p /etc'
Executed: 'mkdir -m 700 -p /var/log'
Executed: 'mkdir -m 700 -p /var/run'
Executed: 'mkdir -m 700 -p /run'
Executed: 'mkdir -m 700 -p /run/cryptsetup'
Executed: 'dodir /dev /newroot /sbin /proc /sys /etc /var/log /var/run /run /run/cryptsetup'
Executed: 'mknod /dev/console c 5 1'
Executed: 'mknod /dev/null c 1 3'
Executed: 'mknod /dev/tty c 5 0'
Executed: 'mknod /dev/urandom c 1 9'
Executed: 'mknod /dev/random c 1 8'
Executed: 'mknod /dev/zero c 1 5'
Executed: 'mount -t proc proc /proc'
Executed: 'mount -t sysfs sysfs /sys'
Executed: '/bin/busybox --install -s'
Executed: 'mount -t devtmpfs -o nosuid,relatime,size=10240k,mode=755 devtmpfs /dev'
Executed: 'ip link set up dev lo'
Executed: 'ip link set up dev eth0'
Executed: 'ip addr add 192.168.1.14/24 dev eth0'
Executed: 'mkdir /dev/pts'
Executed: 'mount -t devpts none /dev/pts'
Executed: 'mkdir -m 700 -p /etc/dropbear'
Executed: 'mkdir -m 700 -p /var/log'
Executed: 'mkdir -m 700 -p /var/run'
Executed: 'mkdir -m 700 -p /root/.ssh'
Executed: 'dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key'
Executed: 'dropbearkey -t ed25519 -f /etc/dropbear/dropbear_ed25519_host_key'
Executed: 'echo root:x:0:0:root:/root:/bin/sh'
Executed: 'cp /authorized_keys /root/.ssh/authorized_keys'
Executed: 'dropbear -s -p 192.168.1.14:43222'
Executed: 'lvm vgchange -a y'
Executed: 'echo -e #!/bin/sh\nexit 0'
Executed: 'chmod 755 /sbin/udevadm'

As you can see, 'mkdir -m 700 -p /dev' is missing and it tries to create nodes after (???)

Executed: 'mknod /dev/console c 5 1'
Executed: 'mknod /dev/null c 1 3'
Executed: 'mknod /dev/tty c 5 0'
Executed: 'mknod /dev/urandom c 1 9'
Executed: 'mknod /dev/random c 1 8'
Executed: 'mknod /dev/zero c 1 5'

If the initramfs is not embedded then it works fine :

Executed: 'mkdir -m 700 -p /dev'
Executed: 'mkdir -m 700 -p /newroot'
Executed: 'mkdir -m 700 -p /sbin'
Executed: 'mkdir -m 700 -p /proc'
Executed: 'mkdir -m 700 -p /sys'
Executed: 'mkdir -m 700 -p /etc'
Executed: 'mkdir -m 700 -p /var/log'
Executed: 'mkdir -m 700 -p /var/run'
Executed: 'mkdir -m 700 -p /run'
Executed: 'mkdir -m 700 -p /run/cryptsetup'
Executed: 'dodir /dev /newroot /sbin /proc /sys /etc /var/log /var/run /run /run/cryptsetup'
Executed: 'mount -t proc proc /proc'
Executed: 'mount -t sysfs sysfs /sys'
Executed: '/bin/busybox --install -s'
Executed: 'mount -t devtmpfs -o nosuid,relatime,size=10240k,mode=755 devtmpfs /dev'
Executed: 'ip link set up dev lo'
Executed: 'ip link set up dev eth0'
Executed: 'ip addr add 192.168.1.14/24 dev eth0'
Executed: 'mkdir /dev/pts'
Executed: 'mount -t devpts none /dev/pts'
Executed: 'mkdir -m 700 -p /etc/dropbear'
Executed: 'mkdir -m 700 -p /var/log'
Executed: 'mkdir -m 700 -p /var/run'
Executed: 'mkdir -m 700 -p /root/.ssh'
Executed: 'dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key'
Executed: 'dropbearkey -t ed25519 -f /etc/dropbear/dropbear_ed25519_host_key'
Executed: 'echo root:x:0:0:root:/root:/bin/sh'
Executed: 'cp /authorized_keys /root/.ssh/authorized_keys'
Executed: 'dropbear -s -p 192.168.1.14:43222'
Executed: 'lvm vgchange -a y'
Executed: 'echo -e #!/bin/sh\nexit 0'
Executed: 'chmod 755 /sbin/udevadm'

As you can see, "Executed: 'mkdir -m 700 -p /dev'' is present this time, and I can unlock the drive by typing my password on the laptop or connecting remotely via ssh, unlock & resume-boot works fine.

For now, I solved it using your "old" function to generate the nodes in /usr/src/better-initramfs/dev before building the kernel in the embedded scenario.

INIT='/usr/src/better-initramfs'

relaxed_mknod() {
if ! [ -e "${INIT}/dev/$1" ]; then
  mknod "${INIT}/dev/$1" "$2" "$3" "$4" || exit
fi
}

relaxed_mknod console c 5 1
relaxed_mknod null c 1 3
relaxed_mknod tty c 5 0
relaxed_mknod urandom c 1 9
relaxed_mknod random c 1 8
relaxed_mknod zero c 1 5

I guess, console would be enough here but whatever.

slashbeast commented 2 years ago

Now this is super bizarre. I will see what I can do to roll out a cpio archive with node. The gen_init_cpio from kernel sources would be best, but it requires to run on host. We could build it statically in sysroot, and currently crosscompilation is not supported so we can be sure that anything sysroot can run/build, can be executed on host.

Will ping you later today here with fixes to test.