go-debos / debos

Debian OS builder
Apache License 2.0
536 stars 138 forks source link

udev not functional within container #160

Open elboulangero opened 5 years ago

elboulangero commented 5 years ago

I need to run this command as part of a recipe: lsblk -nlp -o NAME,PARTTYPE. In order to query the parttype, lsblk relies on udev.

However, udev is not really functional within a systemd-nspawn container. Which is kind of expected, according to this discussion: https://lists.freedesktop.org/archives/systemd-devel/2013-July/012347.html

As a consequence, lsblk cannot display the parttype if it's run from within a container (ie. debos run action with chroot: true).

I found a workaround though: I can add --bind /run/udev to the systemd-nspawn command, which is enough to at least query udev, and get lsblk to work as I expect.

Could we add that to debos systemd-nspawn call? Or does that sound silly?


Here's a quick recipe to illustrate this issue:

{{- $suite := or .suite "stretch" -}}

architecture: amd64

actions:
  - action: debootstrap
    suite: {{ $suite }}
    components: [ main ]

  - action: apt
    packages: [ gdisk, util-linux ]

  - action: image-partition
    imagename: {{ $suite }}.img
    imagesize: 2GB
    partitiontype: gpt
    partitions:
      - name: efi
        fs: fat32
        start: 0%
        end: 128MB
        flags: [ esp ]
      - name: root
        fs: ext4
        start: 128MB
        end: 100%
    mountpoints:
      - mountpoint: /
        partition: root
      - mountpoint: /efi
        partition: efi

  # Set GPT UID for each partition, see:
  # <https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/>
  # - EFI system partitions    c12a7328-f81f-11d2-ba4b-00a0c93ec93b
  # - Root partitions (x86-64) 4f68bce3-e8cd-4db1-96e7-fbcaf984b709

  - action: run
    description: "Setting partition GUIDs"
    chroot: false
    command: |
      sfdisk --part-type "$IMAGE" 1 c12a7328-f81f-11d2-ba4b-00a0c93ec93b >/dev/null 2>&1
      sfdisk --part-type "$IMAGE" 2 4f68bce3-e8cd-4db1-96e7-fbcaf984b709 >/dev/null 2>&1
      partprobe "$IMAGE"

  - action: run
    description: "Run lsblk, chroot=false"
    chroot: false
    command: lsblk -nlp -o NAME,PARTTYPE

  - action: run
    description: "Run lsblk, chroot=true"
    chroot: true
    command: lsblk -nlp -o NAME,PARTTYPE

And here's the relevant part of debos output:

==== Run lsblk, chroot=false ====
lsblk -nlp -o NAME,PARTTYPE | /dev/fd0  
lsblk -nlp -o NAME,PARTTYPE | /dev/sr0  
lsblk -nlp -o NAME,PARTTYPE | /dev/vda  
lsblk -nlp -o NAME,PARTTYPE | /dev/vda1 c12a7328-f81f-11d2-ba4b-00a0c93ec93b
lsblk -nlp -o NAME,PARTTYPE | /dev/vda2 4f68bce3-e8cd-4db1-96e7-fbcaf984b709
==== Run lsblk, chroot=true ====
lsblk -nlp -o NAME,PARTTYPE | /dev/fd0  
lsblk -nlp -o NAME,PARTTYPE | /dev/sr0  
lsblk -nlp -o NAME,PARTTYPE | /dev/vda  
lsblk -nlp -o NAME,PARTTYPE | /dev/vda1 
lsblk -nlp -o NAME,PARTTYPE | /dev/vda2 

And some more debug lines that you can easily reproduce from the debos debug shell:

  1. systemd-nspawn as it's run by debos: lsblk can't display the parttype.
# systemd-nspawn -D /scratch/root --bind /dev/vda --bind /dev/vda1 --bind /dev/vda2
# lsblk -nlp -o NAME,PARTTYPE /dev/vda1
/dev/vda1
# strace lsblk -nlp -o NAME,PARTTYPE /dev/vda1
...
open("/run/udev/data/b254:1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
...
  1. Adding --bind /run/udev solves the issue.
# systemd-nspawn -D /scratch/root --bind /dev/vda --bind /dev/vda1 --bind /dev/vda2 --bind /run/udev
# lsblk -nlp -o NAME,PARTTYPE /dev/vda1
/dev/vda1 c12a7328-f81f-11d2-ba4b-00a0c93ec93b
elboulangero commented 5 years ago

Another symptom of that is grub-mkconfig being super slow with lines like:

Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.19.0-1-amd64
Found initrd image: /boot/initrd.img-4.19.0-1-amd64
  WARNING: Device /dev/vda not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda1 not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda2 not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda3 not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda4 not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda5 not initialized in udev database even after waiting 10000000 microseconds.
  WARNING: Device /dev/vda6 not initialized in udev database even after waiting 10000000 microseconds.
elboulangero commented 4 years ago

FWIW, comparing with what other tools do, arch-chroot bind-mounts /run: https://git.archlinux.org/arch-install-scripts.git/tree/common#n80