<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/meta-virtualization.git/recipes-containers, branch master</title>
<subtitle>Mirror of git.yoctoproject.org/meta-virtualization</subtitle>
<id>https://git.enea.com/cgit/linux/meta-virtualization.git/atom?h=master</id>
<link rel='self' href='https://git.enea.com/cgit/linux/meta-virtualization.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/'/>
<updated>2026-06-15T14:12:26+00:00</updated>
<entry>
<title>lxc: pull in networking and templates via RRECOMMENDS</title>
<updated>2026-06-15T14:12:26+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-15T14:12:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=c595d3c9b714a1d15fe8e5dc1038f9372d68dbdb'/>
<id>urn:sha1:c595d3c9b714a1d15fe8e5dc1038f9372d68dbdb</id>
<content type='text'>
The lxc recipe ships three sub-packages: ${PN}, ${PN}-networking, and
${PN}-templates. ${PN} contains the lxc-* command-line binaries.
${PN}-networking owns lxc-net.service, /etc/default/lxc-net, the
dnsmasq drop-in for the lxcbr0 bridge, and the firewall plumbing.
${PN}-templates owns /usr/share/lxc/templates, the per-distro
container-creation scripts that lxc-create invokes via --template.

Installing only the main ${PN} package leaves a non-functional LXC.
There's no lxcbr0 bridge, so any container whose config references it
(every download-template default config does) fails to start with

  network.c: netdev_configure_server_veth: Failed to attach "vethXXX"
             to bridge "lxcbr0", bridge interface doesn't exist

and there are no template scripts, so lxc-create --template &lt;foo&gt;
has nothing to invoke. The user-facing toolchain is effectively broken
unless the integrator knows to add the sub-packages by hand.

Pull both sub-packages in through RRECOMMENDS so any image that
installs lxc gets a functional LXC by default, regardless of whether
the install path is packagegroup-lxc, IMAGE_INSTALL:append, or
CORE_IMAGE_EXTRA_INSTALL. Integrators who don't want them (custom
networking, hand-written templates) can drop either or both through
BAD_RECOMMENDATIONS.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>lxc: drop templates-actually-create-DOWNLOAD_TEMP-directory.patch</title>
<updated>2026-06-14T03:56:57+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-14T03:56:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=8599dba96a5ac81bdac269e95e8498b84def98ce'/>
<id>urn:sha1:8599dba96a5ac81bdac269e95e8498b84def98ce</id>
<content type='text'>
The local patch added in 2018 was meant to ensure DOWNLOAD_TEMP pointed
at a directory that actually existed by routing mktemp through the -p
option. Its else branch is reached precisely when DOWNLOAD_TEMP is unset
(the elif catches the set case), but the rewrite

    DOWNLOAD_TEMP="$(mktemp -p ${DOWNLOAD_TEMP} -d)"

substitutes an empty ${DOWNLOAD_TEMP} into the command line, leaving
the shell to parse mktemp -p -d as -d being the argument value for -p
rather than its own flag. mktemp then fails immediately with

    mktemp: failed to create file via template '-d/tmp.XXXXXXXXXX':
    No such file or directory

and lxc-create exits before doing any network work. Every invocation
of lxc-create --template download is broken.

Ferry Toth reported this on the meta-virt list 2026-06-13 (subject
"lxc: starting a container errors out"). His diagnosis is correct and
the fix he proposed — drop the patch — is the right one. The original
upstream line

    DOWNLOAD_TEMP="${DOWNLOAD_TEMP}$(mktemp -d)"

handles both cases correctly: with DOWNLOAD_TEMP set the elif branch
runs first, and with it unset the else branch reduces to just
DOWNLOAD_TEMP="$(mktemp -d)" which lets mktemp pick the default
TMPDIR / /tmp location and create the directory.

The original 2018 motivation ("DOWNLOAD_TEMP will not be pointing to
an actual directory") does not match how mktemp -d actually behaves
on modern systems — the directory IS created, and that's the whole
point of mktemp -d. The reported failure mode was likely a build-host
environment quirk specific to that 2018 setup rather than a general
bug worth carrying a layer-local patch for.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>vcontainer-tarball: unset OECORE_NATIVE_SYSROOT in CI</title>
<updated>2026-06-13T03:35:33+00:00</updated>
<author>
<name>Tim Orling</name>
<email>ticotimo@gmail.com</email>
</author>
<published>2026-06-12T20:11:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=5ebb6ee6c1db9d77e029a13f84c75216acdbeee6'/>
<id>urn:sha1:5ebb6ee6c1db9d77e029a13f84c75216acdbeee6</id>
<content type='text'>
Add 'unset OECORE_NATIVE_SYSROOT' to the end of environment-setup-ci
for the same reasons it needed to be in environment-setup-none.

This fixes issues seen on AutoBuilder workers which use buildtools-tarball
and also usage of oe-run-native (e.g. for skopeo-native or cosign-native).

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-tarball: track rootfs hash via explicit mcdepends</title>
<updated>2026-06-12T13:35:03+00:00</updated>
<author>
<name>Bruce Ashfield</name>
<email>bruce.ashfield@gmail.com</email>
</author>
<published>2026-06-12T03:12:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=6fc1aa83552713dc03933115890badebb297e4ae'/>
<id>urn:sha1:6fc1aa83552713dc03933115890badebb297e4ae</id>
<content type='text'>
vcontainer-tarball bundles vdkr and vpdmn rootfs images alongside
the helper scripts into a single-shot SDK tarball. Those rootfs
images live in the vruntime-x86-64 / vruntime-aarch64 multiconfigs
and are pulled into the tarball at do_populate_sdk time from
tmp-&lt;mc&gt;/deploy/images/&lt;machine&gt;/&lt;tool&gt;/&lt;arch&gt;/rootfs.img. For
sstate to behave correctly, the tarball task's hash must reflect
the actual rootfs content.

In practice it didn't. A rootfs content change — adding netavark
to the image, switching the runtime from iptables to nftables —
left consumers of the SDK with a stale runtime even though their
config asked for the new behaviour. Cleansstate of vcontainer-tarball
alone didn't help: the path through the cached intermediates was
serving the old image back.

The recipe was relying on the chain

  rootfs-image:do_build
    -&gt; initramfs-create:do_compile
    -&gt; initramfs-create:do_deploy
    -&gt; mcdepends -&gt; tarball:do_populate_sdk

to propagate the rootfs hash. The break is at do_deploy: it reads
its rootfs.img out of DEPLOY_DIR, which is a known sstate sharp edge.
do_deploy can sstate-hit on its own hash while the file it deploys
came from a stale prior run, after which the downstream tarball task
hash is computed against the stale content and also hits cache.

Add a direct mcdepends from do_populate_sdk to
{vdkr,vpdmn}-rootfs-image:do_image_complete for each enabled vruntime
multiconfig. The rootfs-image task's hash now feeds the tarball hash
directly, independent of the intermediate do_deploy step. If a rootfs
content change moves the rootfs-image hash, the tarball is forced to
rebuild. When the chain was already healthy this dep adds nothing
new and costs nothing.

Verified end-to-end:

  bitbake vcontainer-tarball -c cleansstate
  bitbake vcontainer-tarball
  sha256sum tmp/deploy/sdk/vcontainer-standalone.sh
  # -&gt; f8e75f947a506202d88a6eb196a3616f5088b11247207beab589e91fb6f2bba7

  echo 'IMAGE_INSTALL:append:pn-vpdmn-rootfs-image = " bash"' \
      &gt;&gt; conf/local.conf
  bitbake vcontainer-tarball
  sha256sum tmp/deploy/sdk/vcontainer-standalone.sh
  # -&gt; 1e89554500b2a4aaabc149a01f85fad2e78ba35796977469e7fcb1ecf15a856f

Hashes differ — the rootfs content change correctly invalidated the
tarball's sstate hash and produced a fresh build.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<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>incus: change service type from notify to simple</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-05T13:52:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=44bfc6144a8d4ebfc6e7fd02a667d69154a6b516'/>
<id>urn:sha1:44bfc6144a8d4ebfc6e7fd02a667d69154a6b516</id>
<content type='text'>
Incusd does not call sd_notify(READY=1) — the Go source has no
systemd notification support in the main daemon (only in incus-agent,
the guest-side component). With Type=notify, systemd waits indefinitely
for the ready notification and the service stays in 'activating' state
even though incusd is fully operational.

This was not caught before the v7 uprev because the previous build
was cached via sstate or the service was tested manually.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>incus: switch from iptables to nftables</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-05T13:10:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=edfc302dbd43e8ca834224a778f8ab2e7fc168f0'/>
<id>urn:sha1:edfc302dbd43e8ca834224a778f8ab2e7fc168f0</id>
<content type='text'>
Incus detects nftables at runtime and prefers it for firewall
management. Without the nft binary, incusd logs "nft missing" and
falls back to a degraded mode that can leave the service stuck in
activating state. The broader ecosystem has moved to nftables —
netavark already dropped iptables support entirely.

Signed-off-by: Bruce Ashfield &lt;bruce.ashfield@gmail.com&gt;
</content>
</entry>
<entry>
<title>k3s: fix pause image reference for containerd v2</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-05T03:56:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/linux/meta-virtualization.git/commit/?id=092f66d511ac303a73fb0853314d792dde69cd28'/>
<id>urn:sha1:092f66d511ac303a73fb0853314d792dde69cd28</id>
<content type='text'>
K3s's default pause image reference "rancher/mirrored-pause:3.6" is a
short name that containerd v1 auto-expanded to the fully qualified
"docker.io/rancher/mirrored-pause:3.6". The k3s v1.36 uprev moved to
containerd v2, which uses a new CRI plugin (io.containerd.cri.v1) with
a pinned_images config instead of the old sandbox_image. Containerd v2
no longer auto-expands short names when looking up pinned images,
causing every pod sandbox creation to fail with "image not found" even
though the image is present in the containerd image store under its
fully qualified name.

Pass --pause-image docker.io/rancher/mirrored-pause:3.6 in both the
server and agent systemd service files to use the fully qualified
reference that containerd v2 can resolve.

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