[PATCH 1/1] rootfs: rework no-generate-initrd rootfs feature

13 views
Skip to first unread message

Christoph Steiger

unread,
Aug 20, 2025, 10:10:55 AMAug 20
to isar-...@googlegroups.com, felix.mo...@siemens.com, jan.k...@siemens.com, Christoph Steiger
Instead of using a negative feature replace it with a positive one:
generate-initrd. It can be confusing for the user why a initrd is
generated even though no additional rootfs features are enabled.

To keep default behavior the same add generate-initrd to the default
rootfs features, unless INITRD_IMAGE is provided.

Signed-off-by: Christoph Steiger <christop...@siemens.com>
---
RECIPE-API-CHANGELOG.md | 14 ++++++++++++++
meta/classes/image.bbclass | 2 --
meta/classes/rootfs.bbclass | 8 ++++----
.../sbuild-chroot/sbuild-chroot.inc | 2 +-
4 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/RECIPE-API-CHANGELOG.md b/RECIPE-API-CHANGELOG.md
index 8468717d..ef18a0ac 100644
--- a/RECIPE-API-CHANGELOG.md
+++ b/RECIPE-API-CHANGELOG.md
@@ -727,3 +727,17 @@ Changes in next

This was never documented and never had practical relevance. `oci-archive` is
the useful OCI image format that can be imported, e.g., by podman.
+
+### Rework `no-generate-initrd` rootfs feature
+
+This negative feature is being replaced with a positive one:
+`generate-initrd`. The default behavior remains unchanged, as `generate-initrd`
+is now a default rootfs feature. Disabling initrd creation can be done in the
+following way:
+```
+ROOTFS_FEATURE:remove = "generate-initrd"
+```
+instead of
+```
+ROOTFS_FEATURE += "no-generate-initrd"
+```
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index bd1b8552..f4b07816 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -67,8 +67,6 @@ inherit essential

ROOTFSDIR = "${IMAGE_ROOTFS}"
ROOTFS_FEATURES += "clean-package-cache clean-pycache generate-manifest export-dpkg-status clean-log-files clean-debconf-cache"
-# when using a custom initrd, do not generate one as part of the image rootfs
-ROOTFS_FEATURES += "${@ '' if d.getVar('INITRD_IMAGE') == '' else 'no-generate-initrd'}"
ROOTFS_PACKAGES += "${IMAGE_PREINSTALL} ${@isar_multiarch_packages('IMAGE_INSTALL', d)}"
ROOTFS_MANIFEST_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
ROOTFS_DPKGSTATUS_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
diff --git a/meta/classes/rootfs.bbclass b/meta/classes/rootfs.bbclass
index 7b7859b9..f5513277 100644
--- a/meta/classes/rootfs.bbclass
+++ b/meta/classes/rootfs.bbclass
@@ -14,8 +14,8 @@ ROOTFS_BASE_DISTRO ?= "${BASE_DISTRO}"
# 'generate-manifest' - generate a package manifest of the rootfs into ${ROOTFS_MANIFEST_DEPLOY_DIR}
# 'export-dpkg-status' - exports /var/lib/dpkg/status file to ${ROOTFS_DPKGSTATUS_DEPLOY_DIR}
# 'clean-log-files' - delete log files that are not owned by packages
-# 'no-generate-initrd' - do not generate debian default initrd
-ROOTFS_FEATURES ?= ""
+# 'generate-initrd' - generate debian default initrd
+ROOTFS_FEATURES ?= "${@ 'generate-initrd' if d.getVar('INITRD_IMAGE') == '' else ''}"

ROOTFS_APT_ARGS="install --yes -o Debug::pkgProblemResolver=yes"

@@ -258,7 +258,7 @@ rootfs_restore_initrd_tooling() {
sudo rm -rf "${ROOTFSDIR}${ROOTFS_STUBS_DIR}"
}

-ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'no-generate-initrd', 'rootfs_clear_initrd_symlinks', '', d)}"
+ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-initrd', '', 'rootfs_clear_initrd_symlinks', d)}"
rootfs_clear_initrd_symlinks() {
sudo rm -f ${ROOTFSDIR}/initrd.img
sudo rm -f ${ROOTFSDIR}/initrd.img.old
@@ -501,7 +501,7 @@ rootfs_generate_initramfs() {
}

python() {
- if 'no-generate-initrd' not in d.getVar('ROOTFS_FEATURES', True).split():
+ if 'generate-initrd' in d.getVar('ROOTFS_FEATURES', True).split():
bb.build.addtask('do_generate_initramfs', 'do_rootfs', 'do_rootfs_postprocess', d)
bb.build.addtask('do_generate_initramfs_setscene', None, None, d)
}
diff --git a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
index 98e427e5..ce35497f 100644
--- a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
+++ b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
@@ -55,7 +55,7 @@ SBUILD_CHROOT_PREINSTALL_COMMON = " \
SBUILD_CHROOT_DIR = "${WORKDIR}/rootfs"
ROOTFSDIR = "${SBUILD_CHROOT_DIR}"
ROOTFS_PACKAGES = "${SBUILD_CHROOT_PREINSTALL}"
-ROOTFS_FEATURES += "no-generate-initrd"
+ROOTFS_FEATURES:remove = "generate-initrd"

ROOTFS_POSTPROCESS_COMMAND:remove = "rootfs_cleanup_isar_apt"

--
2.39.5

Jan Kiszka

unread,
Aug 20, 2025, 12:25:33 PMAug 20
to Christoph Steiger, isar-...@googlegroups.com, felix.mo...@siemens.com
INITRD_IMAGE is initialized to an empty string in image.bbclass.
However, if rootfs.bbclass should be used in some recipe without
inhering image as well, getVar will deliver None, and comparing that to
a string will cause an ugly error. Probably better to do (d.getVar() or '').

Jan
Siemens AG, Foundational Technologies
Linux Expert Center

Jan Kiszka

unread,
Aug 20, 2025, 12:30:06 PMAug 20
to Christoph Steiger, isar-...@googlegroups.com, felix.mo...@siemens.com
...or just move the initialization of INITRD_IMAGE over - I just
realized that image inherits rootfs, so that will not break something else.

Jan

Christoph Steiger

unread,
Aug 21, 2025, 3:17:57 AMAug 21
to isar-...@googlegroups.com, felix.mo...@siemens.com, jan.k...@siemens.com, Christoph Steiger
Instead of using a negative feature replace it with a positive one:
generate-initrd. It can be confusing for the user why a initrd is
generated even though no additional rootfs features are enabled.

To keep default behavior the same add generate-initrd to the default
rootfs features, unless INITRD_IMAGE is provided.

Signed-off-by: Christoph Steiger <christop...@siemens.com>
---

Changes in v2:
- move initialisation of INITRD_IMAGE to rootfs

RECIPE-API-CHANGELOG.md | 14 ++++++++++++++
meta/classes/image.bbclass | 3 ---
meta/classes/rootfs.bbclass | 10 ++++++----
.../sbuild-chroot/sbuild-chroot.inc | 2 +-
4 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/RECIPE-API-CHANGELOG.md b/RECIPE-API-CHANGELOG.md
index 8468717d..ef18a0ac 100644
--- a/RECIPE-API-CHANGELOG.md
+++ b/RECIPE-API-CHANGELOG.md
@@ -727,3 +727,17 @@ Changes in next

This was never documented and never had practical relevance. `oci-archive` is
the useful OCI image format that can be imported, e.g., by podman.
+
+### Rework `no-generate-initrd` rootfs feature
+
+This negative feature is being replaced with a positive one:
+`generate-initrd`. The default behavior remains unchanged, as `generate-initrd`
+is now a default rootfs feature. Disabling initrd creation can be done in the
+following way:
+```
+ROOTFS_FEATURE:remove = "generate-initrd"
+```
+instead of
+```
+ROOTFS_FEATURE += "no-generate-initrd"
+```
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index bd1b8552..ca304e33 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -23,7 +23,6 @@ IMAGE_FULLNAME = "${PN}-${DISTRO}-${MACHINE}"

# These variables are used by wic and start_vm
KERNEL_IMAGE ?= "${IMAGE_FULLNAME}-${KERNEL_FILE}"
-INITRD_IMAGE ?= ""
INITRD_DEPLOY_FILE = "${@ d.getVar('INITRD_IMAGE') or '${IMAGE_FULLNAME}-initrd.img'}"

# This defines the deployed dtbs for reuse by imagers
@@ -67,8 +66,6 @@ inherit essential

ROOTFSDIR = "${IMAGE_ROOTFS}"
ROOTFS_FEATURES += "clean-package-cache clean-pycache generate-manifest export-dpkg-status clean-log-files clean-debconf-cache"
-# when using a custom initrd, do not generate one as part of the image rootfs
-ROOTFS_FEATURES += "${@ '' if d.getVar('INITRD_IMAGE') == '' else 'no-generate-initrd'}"
ROOTFS_PACKAGES += "${IMAGE_PREINSTALL} ${@isar_multiarch_packages('IMAGE_INSTALL', d)}"
ROOTFS_MANIFEST_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
ROOTFS_DPKGSTATUS_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
diff --git a/meta/classes/rootfs.bbclass b/meta/classes/rootfs.bbclass
index 7b7859b9..ac727249 100644
--- a/meta/classes/rootfs.bbclass
+++ b/meta/classes/rootfs.bbclass
@@ -8,14 +8,16 @@ ROOTFS_DISTRO ?= "${DISTRO}"
ROOTFS_PACKAGES ?= ""
ROOTFS_BASE_DISTRO ?= "${BASE_DISTRO}"

+INITRD_IMAGE ?= ""
+
# Features of the rootfs creation:
# available features are:
# 'clean-package-cache' - delete package cache from rootfs
# 'generate-manifest' - generate a package manifest of the rootfs into ${ROOTFS_MANIFEST_DEPLOY_DIR}
# 'export-dpkg-status' - exports /var/lib/dpkg/status file to ${ROOTFS_DPKGSTATUS_DEPLOY_DIR}
# 'clean-log-files' - delete log files that are not owned by packages
-# 'no-generate-initrd' - do not generate debian default initrd
-ROOTFS_FEATURES ?= ""
+# 'generate-initrd' - generate debian default initrd
+ROOTFS_FEATURES ?= "${@ 'generate-initrd' if d.getVar('INITRD_IMAGE') == '' else ''}"

ROOTFS_APT_ARGS="install --yes -o Debug::pkgProblemResolver=yes"

@@ -258,7 +260,7 @@ rootfs_restore_initrd_tooling() {
sudo rm -rf "${ROOTFSDIR}${ROOTFS_STUBS_DIR}"
}

-ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'no-generate-initrd', 'rootfs_clear_initrd_symlinks', '', d)}"
+ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-initrd', '', 'rootfs_clear_initrd_symlinks', d)}"
rootfs_clear_initrd_symlinks() {
sudo rm -f ${ROOTFSDIR}/initrd.img
sudo rm -f ${ROOTFSDIR}/initrd.img.old
@@ -501,7 +503,7 @@ rootfs_generate_initramfs() {
}

python() {
- if 'no-generate-initrd' not in d.getVar('ROOTFS_FEATURES', True).split():
+ if 'generate-initrd' in d.getVar('ROOTFS_FEATURES', True).split():
bb.build.addtask('do_generate_initramfs', 'do_rootfs', 'do_rootfs_postprocess', d)
bb.build.addtask('do_generate_initramfs_setscene', None, None, d)
}
diff --git a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
index 98e427e5..ce35497f 100644
--- a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
+++ b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc
@@ -55,7 +55,7 @@ SBUILD_CHROOT_PREINSTALL_COMMON = " \
SBUILD_CHROOT_DIR = "${WORKDIR}/rootfs"
ROOTFSDIR = "${SBUILD_CHROOT_DIR}"
ROOTFS_PACKAGES = "${SBUILD_CHROOT_PREINSTALL}"
-ROOTFS_FEATURES += "no-generate-initrd"
+ROOTFS_FEATURES:remove = "generate-initrd"

ROOTFS_POSTPROCESS_COMMAND:remove = "rootfs_cleanup_isar_apt"

--
2.39.5

Zhihang Wei

unread,
Oct 29, 2025, 11:40:02 AM (yesterday) Oct 29
to Christoph Steiger, isar-...@googlegroups.com, felix.mo...@siemens.com, jan.k...@siemens.com
Hello,
when testing the patch set on CI, the following test failed:
- citest.py:DevTest.test_dev_run_amd64_bookworm:  FAIL: Failed to boot
qemu machine

The qumu machine freezed after these log:
[    1.297629] IPI shorthand broadcast: enabled
[    1.298263] sched_clock: Marking stable (1253224661,
42713547)->(1298874476, -2936268)
[    1.300942] registered taskstats version 1
[    1.301376] Loading compiled-in X.509 certificates
[    1.350199] Loaded X.509 cert 'Build time autogenerated kernel key:
69f0a93457c7a5b34688fbc5c07f181934864335'
[    1.353656] zswap: loaded using pool lzo/zbud
[    1.355367] Key type .fscrypt registered
[    1.355604] Key type fscrypt-provisioning registered
[    1.363269] Key type encrypted registered
[    1.363535] AppArmor: AppArmor sha1 policy hashing enabled
[    1.364757] ima: No TPM chip found, activating TPM-bypass!
[    1.365096] ima: Allocated hash algorithm: sha256
[    1.366660] ima: No architecture policies found
[    1.367638] evm: Initialising EVM extended attributes:
[    1.367905] evm: security.selinux
[    1.368099] evm: security.SMACK64 (disabled)
[    1.368311] evm: security.SMACK64EXEC (disabled)
[    1.368524] evm: security.SMACK64TRANSMUTE (disabled)
[    1.370996] evm: security.SMACK64MMAP (disabled)
[    1.372496] evm: security.apparmor
[    1.373906] evm: security.ima
[    1.375307] evm: security.capability
[    1.376656] evm: HMAC attrs: 0x1
[    1.595233] clk: Disabling unused clocks
[    1.599988] Waiting for root device PARTLABEL=platform...
[    2.159239] tsc: Refined TSC clocksource calibration: 1999.909 MHz
[    2.163628] clocksource: tsc: mask: 0xffffffffffffffff max_cycles:
0x39a7b08d9f5, max_idle_ns: 881590595729 ns
[    2.167965] clocksource: Switched to clocksource tsc

You can redo the test on your machine using avocado:
1. Have a clean clone of isar, checkout to branch next and apply your
patches:
$ git clone -b next https://github.com/ilbers/isar.git
$ cd isar
$ git am /path-to/0001-my-contribution-to-isar.patch
2.Run kas shell, setup CI prerequisites (avocado, qemu) and cleanup:
$ ./kas/kas-container shell kas/isar.yaml --command \
    "rm -rf /work/build/conf && /work/scripts/ci_setup.sh"
3.Run the test to create the qemu image:
$ cd /work/testsuite
$ avocado run citest.py:DevTest.test_dev$
4. Run the failed test:
$ avocado run citest.py:DevTest.test_dev_run_amd64_bookworm

As the qemu machine won't be able to boot, the test will wait until timeout.
You can find the qemu machine boot log under /build/vmstart/.

Best regards,
Zhihang
Reply all
Reply to author
Forward
0 new messages