fix(iso): let empty directories survive the squashfs layer split

bee_layer_classify only ever tracked regular files and symlinks
(`find ... -type f -o -type l`), so any directory that is empty at
build time — like /var/log/nvidia-dcgm, correctly created and chowned
by the datacenter-gpu-manager postinst — was silently dropped from
every layer's rsync --files-from list and never reached the built
ISO. This is why bbc6fb1's 78d1b9b follow-up (seeding a marker file
just for that one path) kept the directory alive: it was a targeted
workaround for a general gap in the classifier, not a fix of it.

Replace that workaround with the general mechanism: classify also
walks every directory, computes the subset that is empty all the way
down (no file or symlink anywhere in its subtree — a directory that
does hold files needs no entry, rsync already recreates it as an
implied parent), and assigns each one to a layer via the same
dpkg-ownership / injected-rule precedence used for files. Add an
injected rule routing /var/log/nvidia-dcgm to 20-nvidia-platform,
alongside the DCGM binaries that actually use it, instead of letting
it fall through to base by default.

bee_layer_build folds each layer's empty-dir list into the same
rsync --files-from call; recursion into a directory that is
by-construction empty copies nothing extra. Revert the 9000/9999 hook
changes from 78d1b9b now that they're redundant, and cover the new
path with test-squashfs-layers.sh (ruled, unruled, and nested-empty
directories, asserted present in the merged rootfs after a real
mksquashfs/unsquashfs round-trip).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 16:19:36 +03:00
co-authored by Claude Sonnet 5
parent 78d1b9b599
commit 9c5c29239c
4 changed files with 73 additions and 35 deletions
@@ -46,25 +46,6 @@ if [ "$GPU_VENDOR" = "nvidia" ]; then
systemctl enable nvidia-dcgm.service 2>/dev/null || true
systemctl enable nvidia-fabricmanager.service 2>/dev/null || true
systemctl enable bee-nvidia.service
# nvidia-dcgm.service runs `nv-hostengine --service-account nvidia-dcgm`,
# which drops privileges to that account for all file I/O and writes
# diagnostics to DCGM_HOME_DIR (/var/log/nvidia-dcgm, per the packaged
# unit's Environment=). The package's own postinst already creates and
# chowns this directory correctly — but it's empty at that point, and
# lib/squashfs-layers.sh's classifier only tracks regular files and
# symlinks (`find ... -type f -o -type l`), so an empty directory is
# silently dropped from every layer's rsync --files-from list and never
# reaches the built ISO at all. `dcgmi diag`'s deployment check then
# fails with DCGM_FR_FILE_CREATE_PERMISSIONS at boot because the
# directory doesn't exist, regardless of ownership. Re-create it and
# seed one real file so it rides along the classifier and rsync -a
# recreates the parent directory (with this ownership) as an implied
# parent.
if id nvidia-dcgm >/dev/null 2>&1; then
install -d -o nvidia-dcgm -g nvidia-dcgm -m 0755 /var/log/nvidia-dcgm
install -o nvidia-dcgm -g nvidia-dcgm -m 0644 /dev/null /var/log/nvidia-dcgm/.keep
fi
elif [ "$GPU_VENDOR" = "amd" ]; then
# ROCm symlinks (packages install to /opt/rocm-*/bin/)
for tool in rocm-smi rocm-bandwidth-test rvs; do