<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/meta-virtualization.git/recipes-containers/vcontainer/files/vrunner.sh, branch master-next</title>
<subtitle>Mirror of git.yoctoproject.org/meta-virtualization</subtitle>
<id>https://git.enea.com/cgit/linux/meta-virtualization.git/atom?h=master-next</id>
<link rel='self' href='https://git.enea.com/cgit/linux/meta-virtualization.git/atom?h=master-next'/>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/'/>
<updated>2026-06-12T02:58:55+00:00</updated>
<entry>
<title>vrunner: warn on shutdown-escalation that state disk may be corrupted</title>
<updated>2026-06-12T02:58:55+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-08T18:33:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=5bd3f928dad9f423a74793cad6a6bda212a12bde'/>
<id>urn:sha1:5bd3f928dad9f423a74793cad6a6bda212a12bde</id>
<content type='text'>
When the guest doesn't exit within the daemon_stop() poll window, the
graceful_shutdown() didn't complete and the state disk's ext4 journal
may have unflushed writes from this session. Any subsequent escalation
(QMP quit, SIGTERM, SIGKILL) leaves the disk image at risk of corruption:
layer files end up with correct inode metadata but partially-unwritten
data extents, surfacing on the next session as

  Error: reading blob sha256:&lt;hash&gt;: EOF
  Error: reading blob sha256:&lt;hash&gt;: file integrity checksum failed
         for "&lt;file&gt;"

These errors are silent today — the operator hits them later in another
session with no way to correlate back to the original cause. Emit a
WARN as soon as the poll window expires, naming the symptom and pointing
at the remediation (`memres restart --clean`) so the next session starts
from a known-good state instead of inheriting a corrupted image.

This is purely diagnostic — no behavior change to the shutdown sequence
itself. The escalation paths (QMP quit, SIGTERM, SIGKILL) still run
unchanged.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vrunner: use QMP quit before SIGTERM in daemon_stop escalation</title>
<updated>2026-06-12T02:58:55+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-08T18:32:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=f989375e12f60b2e9627dddb01ecfa1f11ff7fa3'/>
<id>urn:sha1:f989375e12f60b2e9627dddb01ecfa1f11ff7fa3</id>
<content type='text'>
When the SHUTDOWN-via-virtio-serial poll window expires and the QEMU
process is still alive, send a QMP quit before SIGTERMing. Functionally
near-equivalent to SIGTERM at the process level (both converge on
qemu_system_killed() and a block-layer flush) but goes through QEMU's
monitor interface, which is the same mechanism hv_idle_shutdown() already
uses for idle-timeout shutdowns. Unifying the two escalation paths
makes the code easier to reason about — one channel for "ask QEMU to
exit cleanly," one fallback for "the monitor isn't responding."

QMP quit is NOT a replacement for the virtio-serial ===SHUTDOWN===
command: it stops QEMU without giving the guest a chance to run its
own graceful_shutdown() (which is what cleanly unmounts the state
disk). It's only an improvement over SIGTERM as the *fallback* when
the guest hasn't responded to the SHUTDOWN command within the poll
window. The full architectural fix — QMP system_powerdown driving an
ACPI handler in the guest that calls graceful_shutdown() — needs
guest-side acpid wiring and is tracked separately.

SIGTERM and SIGKILL remain as further fallbacks for cases where QMP
itself is unresponsive (e.g. older configs without a QMP socket, or
QEMU hung in a state where the monitor stops servicing commands).

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vrunner: poll for clean VM exit before SIGTERM in daemon_stop</title>
<updated>2026-06-12T02:58:55+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-08T18:26:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=23da02f0189cc046def58a43117b50d7918e62e1'/>
<id>urn:sha1:23da02f0189cc046def58a43117b50d7918e62e1</id>
<content type='text'>
The daemon_stop() flow sent ===SHUTDOWN=== over virtio-serial and then
slept exactly 2 seconds before unconditionally SIGTERMing QEMU. The
guest's graceful_shutdown(), which is what the SHUTDOWN command
ultimately triggers, does:

  sync
  umount /var/lib/containers/storage   (ext4 journal commit)
  sync
  blockdev --flushbufs (per disk)
  sync
  sleep 2
  reboot -f

Under load this routinely takes 5-30 seconds — the ext4 journal commit
on the state disk after a vimport that just wrote tens of MB of layer
blobs is the slow step. A fixed 2-second wait followed by SIGTERM kills
the guest mid-umount and leaves the state disk's journal half-committed:
layer files have correct inode metadata but partially-unwritten data
extents.

The next memres session remounts that disk and reads the apparently-OK
files. Tar-split reassembly during podman save / podman push then hits
the unwritten extents and produces:

  Error: reading blob sha256:&lt;hash&gt;: EOF
  Error: reading blob sha256:&lt;hash&gt;: file integrity checksum failed
         for "&lt;file&gt;"

Reported via yocto-patches as a workaround in run-push-containers
(`&lt;runtime&gt; image rm --all` before push) on the autobuilder. The
"first push works, subsequent fail" pattern in that report comes from
the first push hitting a clean session and subsequent pushes inheriting
the corrupted state disk from the prior SIGTERM-truncated shutdown.

Replace the fixed sleep with a poll loop that watches for the QEMU
process to exit, up to 60 seconds (120 * 0.5s). 60s is generous enough
to cover heavy ext4 journal commits; short enough that a truly hung
guest doesn't block the caller indefinitely. The existing SIGTERM and
SIGKILL escalation paths remain as fallbacks for the genuinely-stuck
case.

Reproducer: vimport an OCI image as testimg:latest, save it, memres
restart, re-vimport, save again. Without this fix the second save
fails 100% of the time on the same blob digest with EOF or CRC error.
With this fix six consecutive vimport+save cycles across three restart
rounds complete cleanly.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vcontainer: add --config / VDKR_CONFIG for docker/podman auth credentials</title>
<updated>2026-04-29T20:15:49+00:00</updated>
<author>
<name>Tim Orling</name>
<email>tim.orling@konsulko.com</email>
</author>
<published>2026-04-16T20:30:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=4ba5825ee16fcded87f4d555b4ed7a7615dc67ac'/>
<id>urn:sha1:4ba5825ee16fcded87f4d555b4ed7a7615dc67ac</id>
<content type='text'>
Add a VDKR_CONFIG / VPDMN_CONFIG env var and a matching --config &lt;path&gt;
CLI flag that passes an existing docker config.json / podman auth.json
into the QEMU-hosted container runtime so pulls from private registries
work without having to retype --registry-user / --registry-pass on every
command.

Security posture (defence in depth):
- Host-side pre-flight validation in vrunner.sh (validate_auth_config):
  reject symlinks, non-regular files, missing / unreadable files, files
  smaller than 2 bytes (minimum "{}") or larger than 1 MiB, and any
  permissions other than 0400 / 0600 / 0200. WARN if not owned by the
  invoking user.
- Stage the file into a dedicated per-invocation directory under
  $TEMP_DIR at mode 0400 inside a 0700 parent; auto-cleanup rides the
  existing EXIT/INT/TERM trap.
- Expose the staged file over a *separate* read-only virtio-9p tag
  ("${TOOL_NAME}_auth") so credentials cannot leak into the general
  /mnt/share input/output directory or into storage.tar outputs.
- Only a boolean flag ("${CMDLINE_PREFIX}_auth=1") is appended to the
  kernel cmdline - never the path, the env var name, or the contents.
- Guest mounts /mnt/auth ro,nosuid,nodev,noexec, copies to the runtime's
  canonical path, then unmounts immediately so neither the runtime nor
  user workloads keep a reference to the host staging directory.

vrunner.sh:
- Initialise AUTH_CONFIG from $VDKR_CONFIG / $VPDMN_CONFIG
- Parse --config &lt;path&gt; (overrides the env vars)
- Add validate_auth_config() and setup_auth_share() with the rules above
- Call setup_auth_share in both the daemon start path and the
  non-daemon / batch-import path

vcontainer-init-common.sh:
- Default RUNTIME_AUTH="0" and parse ${VCONTAINER_RUNTIME_PREFIX}_auth=*
  from the kernel cmdline
- Define mount_auth_share() / unmount_auth_share() using the per-runtime
  "${VCONTAINER_RUNTIME_NAME}_auth" 9p tag, mounted at /mnt/auth with
  ro,nosuid,nodev,noexec

vdkr-init.sh:
- install_auth_config() copies /mnt/auth/config.json to
  /root/.docker/config.json (mode 0600; parent dir 0700)
- Called after install_registry_ca in main flow so --config takes
  precedence over --registry-user / --registry-pass; logs a NOTE when
  both mechanisms are supplied
- Unmounts /mnt/auth after copy

vpdmn-init.sh:
- install_auth_config() copies to /run/containers/0/auth.json (the
  rootful podman canonical path) and exports REGISTRY_AUTH_FILE so the
  creds are picked up regardless of podman's search order
- Mode 0600 on the file, 0700 on the containing directory
- Unmounts /mnt/auth after copy

vcontainer-common.sh:
- Honour $VDKR_CONFIG / $VPDMN_CONFIG, parse --config, and forward
  AUTH_CONFIG to vrunner.sh via --config in build_runner_args
- Document the flag and env vars in show_usage

README.md:
- New "Passing an existing docker/podman auth file (--config)" section
  with examples for both runtimes, a table of target paths, and the
  full security model

AI-Generated: Claude Cowork Opus 4.7
Signed-off-by: Tim Orling &lt;tim.orling@konsulko.com&gt;
Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vcontainer: detach background-process stdio from memres start caller</title>
<updated>2026-04-22T20:17:55+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-04-22T20:17:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=891c00db7ba647d0b68a929ca1ad15b0ba9dc5a1'/>
<id>urn:sha1:891c00db7ba647d0b68a929ca1ad15b0ba9dc5a1</id>
<content type='text'>
The memres start operation spawns long-running background processes
(host-side idle watchdog and Xen domain monitor) that persist beyond
the vrunner.sh script. These processes inherited file descriptors
0/1/2 from the parent shell without redirection.

When invoked through a harness capturing output via pipes—such as
pytest's subprocess.run(..., capture_output=True)—the inherited pipe
write-ends kept the caller's read/communicate() operations blocked
until memres stop executed, potentially for up to 30 minutes
(IDLE_TIMEOUT default).

The fix fully detaches stdio from three background spawners:
- vrunner.sh: Watchdog subshell now redirects stdin from /dev/null,
  stdout/stderr to /dev/null, and uses disown
- vrunner-backend-qemu.sh: Adds stdin redirection from /dev/null
  to existing log file redirections
- vrunner-backend-xen.sh: Applies same detachment plus disown for
  daemon mode; redirects stdin for ephemeral-mode console reader

From: Tim Orling &lt;tim.orling@konsulko.com&gt;
Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vruntime, vrunner, conftest: fix multiconfig and batch import issues</title>
<updated>2026-04-06T23:48:37+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-04-05T02:10:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=4b0789cbb615c29ad7a0d072ab88b5fa81099605'/>
<id>urn:sha1:4b0789cbb615c29ad7a0d072ab88b5fa81099605</id>
<content type='text'>
vruntime.conf:
- Reset all VIRTUAL-RUNTIME_container_* variables to prevent
  CONTAINER_PROFILE selections from leaking into vruntime multiconfigs
  (e.g., podman profile pulling netavark into vruntime builds)
- Disable ptest for glib-2.0 — its -ptest RDEPENDS chain
  (python3-dbusmock -&gt; python3-pygobject -&gt; cairo -&gt; fontconfig)
  pulls the entire graphics stack which is masked in vruntime
- OE-core commit 159148f4de2 replaced DISTRO_FEATURES_BACKFILL_CONSIDERED
  with DISTRO_FEATURES_OPTED_OUT. The old variable no longer has any
  effect, which meant ptest, gobject-introspection-data, wayland, and
  other features were no longer being blocked in vruntime builds. This
  caused glib-2.0's ptest RDEPENDS to pull in the cairo → fontconfig →
  freetype graphics stack, which is masked by the vruntime BBMASK.
- Set PREFERRED_PROVIDER_virtual/runc with strong assignment to
  ensure the unified runc recipe is used

vrunner.sh:
- Fix batch import exit code handling: wrap import chain in subshell
  and make the images listing best-effort. The previous '&amp;&amp; podman
  images' caused false failures when podman images couldn't initialize
  its network backend. Using 'exit' was also wrong as the command runs
  inside PID 1 init's eval — exit kills init causing kernel panic.

vpdmn-rootfs-image.bb:
- Switch from netavark to CNI networking — netavark's dependency chain
  (nmap -&gt; libpcap -&gt; bluez5 -&gt; python3-pygobject -&gt; cairo) cannot be
  built under the vruntime BBMASK environment
- Add nsswitch.conf override (files-only backend) to prevent
  libnss_systemd segfaults — the vruntime VM uses busybox init with
  no systemd running, but libnss_systemd.so is pulled in as a
  dependency and segfaults on NSS resolution

vdkr-rootfs-image.bb:
- Document skopeo requirement for batch import

conftest.py:
- Add --k3s-timeout option and k3s/multinode markers for upcoming
  K3s test suite

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vcontainer: fix daemon mode missing shared directory for 9p</title>
<updated>2026-02-26T01:05:01+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-02-24T14:24:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=90d6712b3bead6fc6def7050787b5c4b2ce03260'/>
<id>urn:sha1:90d6712b3bead6fc6def7050787b5c4b2ce03260</id>
<content type='text'>
DAEMON_SHARE_DIR was referenced in the CA certificate copy and idle
watchdog paths but never assigned, causing 'cp: cannot create regular
file /ca.crt: Permission denied' when starting the daemon.

Create the share directory under DAEMON_SOCKET_DIR and register it
as a 9p mount, matching the path expected by daemon_run().

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vxn: add Docker/Podman integration and CLI frontends</title>
<updated>2026-02-26T01:05:01+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-02-19T01:53:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=035e0daebeb53880ea2a6bd0f0e31785f3ec9e55'/>
<id>urn:sha1:035e0daebeb53880ea2a6bd0f0e31785f3ec9e55</id>
<content type='text'>
Add vdkr/vpdmn as Dom0 target packages with Xen auto-detection,
native Docker/Podman config sub-packages, and OCI runtime fixes
for Docker compatibility (JSON logging, root.path, kill --all,
monitor PID lifecycle).

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vxn: add per-container DomU lifecycle and memres persistent DomU</title>
<updated>2026-02-26T01:05:01+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-02-17T13:27:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=fa4b171a436559787cfcebd4046a1354a1f5cacf'/>
<id>urn:sha1:fa4b171a436559787cfcebd4046a1354a1f5cacf</id>
<content type='text'>
Per-container DomU lifecycle:
- run -d: per-container DomU with daemon loop and PTY-based IPC
- ps: show Running vs Exited(code) via ===STATUS=== PTY query
- exec/stop/rm: send commands to per-container DomU
- logs: retrieve entrypoint output from running DomU
- Entrypoint death detection with configurable grace period
- Graceful error messages for ~25 unsupported commands
- Command quoting fix: word-count+cut preserves internal spaces

Memres (persistent DomU for fast container dispatch):
- vxn memres start/stop/status/list for persistent DomU management
- vxn run auto-dispatches to memres via xl block-attach + RUN_CONTAINER
- Guest daemon loop handles ===RUN_CONTAINER===: mount hot-plugged
  xvdb, extract OCI rootfs, chroot exec entrypoint, unmount, report
- Falls back to ephemeral mode when memres is occupied (PING timeout)
- Xen-specific memres list shows xl domains and orphan detection

Tested: vxn memres start + vxn run --rm alpine echo hello +
vxn run --rm hello-world both produce correct output.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vxn: fix non-interactive mode for clean container output</title>
<updated>2026-02-26T01:05:01+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-02-15T20:25:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=464503218652139d412b42ff0f00d2be2e89a698'/>
<id>urn:sha1:464503218652139d412b42ff0f00d2be2e89a698</id>
<content type='text'>
Fix several issues preventing non-interactive mode (vxn --no-daemon run)
from showing clean container output:

- Fix console capture: check DAEMON_MODE instead of DAEMON_SOCKET in Xen
  backend so ephemeral runs use xl console capture instead of the daemon
  socat bridge (DAEMON_SOCKET is always set, DAEMON_MODE is only "start"
  for actual daemon launches)
- Fix race condition: add post-loop marker detection after VM exits,
  with 2s delay for xl console to flush its buffer
- Add stdbuf -oL to xl console for line-buffered output
- Suppress mke2fs stdout (was only redirecting stderr)
- Suppress kernel console messages during VM lifecycle in non-verbose mode
- Fix grep -P (Perl regex) for BusyBox compatibility in exit code parsing
- Preserve temp directory on failure for debugging
- Fix hardcoded "QEMU" in error messages to "VM"

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
</feed>
