From 1793b582f6cf5bf5296a5ad50bb8d838a6e1e1d4 Mon Sep 17 00:00:00 2001 From: Justin Schneck Date: Tue, 25 Aug 2026 21:18:03 -0400 Subject: [PATCH 1/4] grow-var: resolve the whole disk with lsblk -d; refuse anything else `lsblk -no PKNAME ` also lists the partition's holders, and for a dm slave the dm child's row comes first - its PKNAME is the partition itself. On an encrypted /var this resolved "disk" to /dev/nvme0n1p16 and `sgdisk -e` then wrote a fresh GPT over the LUKS2 header (primary at 0, secondary at 16 KiB both destroyed; the mapping survived only because the key was already in the kernel). Observed on a Jetson Orin Nano on the first encrypted-/var boot; the plaintext path never hit it because there the var device is the partition and lsblk's first row is its own. Use -d (no dependents) and, before sgdisk touches anything, require the resolved device to be of TYPE disk. Claude-Session: https://claude.ai/code/session_01AqE5abpz1hSdeM9ZCRLLrf --- overlays/base/usr/bin/avocado-grow-var | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/overlays/base/usr/bin/avocado-grow-var b/overlays/base/usr/bin/avocado-grow-var index 15f810c..53a48fe 100755 --- a/overlays/base/usr/bin/avocado-grow-var +++ b/overlays/base/usr/bin/avocado-grow-var @@ -40,8 +40,17 @@ if [ -n "$dm_dev" ]; then : "${blk_dev:=$var_dev}" fi -disk=/dev/$(lsblk -no PKNAME "$blk_dev" | head -n 1) +# -d (no dependents): without it lsblk also lists the partition's holders, and +# for a dm slave the dm child's row comes first - its PKNAME is the partition +# itself, so "disk" resolved to /dev/nvme0n1p16 and `sgdisk -e` wrote a GPT +# over the LUKS2 header (observed on a Jetson Orin Nano with encrypted /var). +disk=/dev/$(lsblk -dno PKNAME "$blk_dev") part=$(printf '%s\n' "$blk_dev" | grep -oE '[0-9]+$') +# Never let sgdisk near anything that is not a whole disk holding a table. +if [ "$(lsblk -dno TYPE "$disk" 2>/dev/null)" != "disk" ]; then + echo "grow-var: $disk (parent of $blk_dev) is not a whole disk; refusing to touch it." >&2 + exit 1 +fi ptable=$(lsblk -dno PTTYPE "$disk") echo "grow-var: $var_dev (via $blk_dev) on $disk (partition $part, $ptable table)." From 78cf80438a608f179f589b0a3c796f666cf747c4 Mon Sep 17 00:00:00 2001 From: Justin Schneck Date: Wed, 26 Aug 2026 10:34:04 -0400 Subject: [PATCH 2/4] grow-var: read sector counts from sysfs, blockdev is not in the runtime The LUKS branch used blockdev --getsz, which util-linux-blockdev provides and the image does not ship: on a Jetson AGX Thor with encrypted /var the partition was extended and then the unit died with 'line 128: blockdev: command not found' (status 127) before the dm/partition size comparison. /sys/class/block//size is the same 512-byte sector count for both the partition and the dm-N node behind /dev/mapper/var. --- overlays/base/usr/bin/avocado-grow-var | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/overlays/base/usr/bin/avocado-grow-var b/overlays/base/usr/bin/avocado-grow-var index 53a48fe..2f4716d 100755 --- a/overlays/base/usr/bin/avocado-grow-var +++ b/overlays/base/usr/bin/avocado-grow-var @@ -124,9 +124,11 @@ if [ "$blk_dev" != "$var_dev" ]; then # resize cannot happen here. The initramfs (cryptsetup-var.sh) already # handles LUKS resize when it detects partition_sectors > dm_sectors on # the next boot — with the key still available at that point. + # Sizes from sysfs: blockdev(8) is not in the runtime image. + sectors() { cat "/sys/class/block/$(basename "$(readlink -f "$1")")/size"; } data_offset=$(dmsetup table "$dm_name" | awk '{print $8}') - expected_dm=$(( $(blockdev --getsz "$blk_dev") - data_offset )) - dm_sectors=$(blockdev --getsz "$var_dev") + expected_dm=$(( $(sectors "$blk_dev") - data_offset )) + dm_sectors=$(sectors "$var_dev") if [ "$dm_sectors" -lt "$expected_dm" ]; then echo "grow-var: LUKS container ($dm_sectors sectors) < partition ($expected_dm sectors)." echo "grow-var: partition extended — cryptsetup-var.sh will resize LUKS + btrfs on next boot." From ab9bce3da7fcd15b30358f48e6dc9b8ba7e380af Mon Sep 17 00:00:00 2001 From: Justin Schneck Date: Sat, 5 Sep 2026 08:11:16 -0400 Subject: [PATCH 3/4] ext: 0.2.0 so the fix supersedes what is in the feed The two commits above fix the runtime failure, but the extension still declared 0.1.0-r0 - the exact NEVR already published. Rebuilding at that version republishes the same package and a resolving device keeps whichever copy it already has: the broken one. 0.2.0 rather than a release bump: the payload changed, not just its packaging. grow-var no longer calls blockdev(8) and resolves the whole disk differently, so this is a new version of the thing being shipped. r0 restarts for it, as it does for any new upstream version. This is the same trap that just cost a day on avocado-img-bootfiles, where a correctly-built package sat in 2026/next unreachable because its version did not sort above the stale one. A content fix that does not move the version is not a release. Claude-Session: https://claude.ai/code/session_0126qmPTM1gce9r9CEh2vxbo --- avocado.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avocado.yaml b/avocado.yaml index dabf83b..2dacf95 100644 --- a/avocado.yaml +++ b/avocado.yaml @@ -2,7 +2,7 @@ supported_targets: '*' extensions: avocado-ext-dev: - version: 0.1.0 + version: 0.2.0 release: r0 summary: Avocado development tools description: Avocado development tools From 90c3534bad7f2e3d79d2d5cdc3a3571f18c7b13e Mon Sep 17 00:00:00 2001 From: Justin Schneck Date: Sat, 5 Sep 2026 08:18:02 -0400 Subject: [PATCH 4/4] ci: test against 2026 too, not just 2024 release.yml publishes to 2026/next and 2024/next; test.yml only built against 2024/next. A change that breaks against 2026 - the feed a 2026 project actually resolves - goes green on the PR and ships anyway. Mirror the release matrix so a PR builds against exactly the feeds its tag publishes into. Claude-Session: https://claude.ai/code/session_0126qmPTM1gce9r9CEh2vxbo --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4bbfa09..85397b2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,6 +12,7 @@ jobs: fail-fast: false matrix: include: + - { target: qemux86-64, distro-release: "2026", distro-channel: next } - { target: qemux86-64, distro-release: "2024", distro-channel: next } uses: avocado-linux/actions/.github/workflows/extension-test.yml@v1 with: