Can't use partitions of attached incus unix-block device

I’m testing Incus in a VM before I set it on baremetal (I hope my setup isn’t the culprit):

Virt Platform: JIT-enabled UTM on iOS

Host VM: Alpine Linux v3.23, with Linux virt (emulated)

Incus Pkgs: incus-feature-6.21.0-r2 incus-feature-client-6.21.0-r2

I’ve attached a 10M sized (virtual) disk through USB drive interface in UTM, in the host VM it appears as /dev/sda and I’ve partitioned using the host to have 1 4M partition, I then try to add the device to a privileged container (partprobing doesn’t work in unprivileged container) and run a few of commands:

On host:

alpine:~# ls -a /dev/sd*

/dev/sda /dev/sda1

alpine:~# incus create images:debian/13 c1 -c security.privileged=true

Creating c1

alpine:~# incus config device add c1 d1 unix-block source=/dev/sda

Device d1 added to c1

alpine:~# incus start c1

alpine:~# incus shell c1

On incus guest:

root@c1:~# ls -a /dev/sd*

/dev/sda

root@c1:~# partx -vd /dev/sda

partition: none, disk: /dev/sda, lower: 0, upper: 0
/dev/sda: partition #1 removed

root@c1:~# partx -va /dev/sda

partition: none, disk: /dev/sda, lower: 0, upper: 0
/dev/sda: partition table type 'dos' detected
range recount: max partno=1, lower=0, upper=0
/dev/sda: partition #1 added

root@c1:~# ls /dev/sd*

/dev/sda

I can see the partitions in lsblk but cannot find a way to use them. Would it be possible to access the partitions easily instead of just the attached unix-block device?

Maybe it’s a same issue Can `losetup` automatically expose the partitions of a loop device within a container?

My use case involves utilizing the Armbian build scripts to generate an SD card image for a development board. Additionally, this development board has its own dedicated build scripts.
Both sets of build scripts appear to rely on Unix block devices, and neither is able to automatically detect device partitions when executed within an Incus container.

However, both sets of scripts run successfully within a Docker container;

I’m curious—how exactly do Docker containers automatically detect these partitions?

Thank you for sharing, I’m not sure of the mechanisms, but I wrote a little hacky script for now to add or remove the a device and its partitions, it relies on the container having sfdisk with --json flag and jq installed (I picture it could be adjusted to work with more barebones utils but I didn’f have the time):

#!/bin/sh

set -e

_add() {
  echo "Doing $@..."
  incus config device add "$2" "$3" unix-block source="$3" || true
}
_del() {
  echo "Doing $@..."
  incus config device rm "$2" "$3" || true
}
_par() {
  while read -r dev; do "$4" "$1" "$2" "$dev"; done < <(
    incus exec "$2" -- bash -c "
      sfdisk -J "$3" | \
      jq -r '.partitiontable.partitions.[].node'
    "
  )
}
main() {
  if [ "$1" = 'add' ]; then
    _add "$@"
    _par "$@" _add
  elif [ "$1" = 'del' ]; then
    _par "$@" _del
    _del "$@"
  else
    echo "Usage: $0 (add|del) <instance> <device>"
    exit 1
  fi
}

main "$@"

Here’s how I use it:

alpine:~# incus exec c1 -- bash -c 'ls /dev/sd*'
ls: cannot access '/dev/sd*': No such file or directory

alpine:~# ./incdev.sh add c1 /dev/sda
Doing add c1 /dev/sda...
Device /dev/sda added to c1
Doing add c1 /dev/sda1...
Device /dev/sda1 added to c1
Doing add c1 /dev/sda2...
Device /dev/sda2 added to c1

alpine:~# incus exec c1 -- bash -c 'ls /dev/sd*'
/dev/sda  /dev/sda1  /dev/sda2

alpine:~# ./incdev.sh del c1 /dev/sda
Doing del c1 /dev/sda1...
Device /dev/sda1 removed from c1
Doing del c1 /dev/sda2...
Device /dev/sda2 removed from c1
Doing del c1 /dev/sda...
Device /dev/sda removed from c1

alpine:~# incus exec c1 -- bash -c 'ls /dev/sd*'
ls: cannot access '/dev/sd*': No such file or directory

alpine:~# ./incdev.sh
Usage: ./incdev.sh (add|del) <instance> <device>