[PATCH 0/2] Fix issue around missing initrd on partial rebuilds

1 view
Skip to first unread message

Felix Moessbauer

unread,
9:34 AM (8 hours ago) 9:34 AM
to isar-...@googlegroups.com, quirin.g...@siemens.com, Felix Moessbauer
When working with a in-tree initrd, the generation of the initrd has the
side effect of placing the initrd in /boot as well (in addition to the
deployment to the deploy dir). This part is currently skipped in case
the initrd is taken from the sstate cache, leading to reproducibility
issues of non-wic images (e.g. a rootfs tarball).

While this is just a reproducibility issue on wic images (as the initrd
is anyways replaced by the one from the deploy dir), it is a bug that
breaks booting on non-wic images.

Best regards,
Felix

Felix Moessbauer (2):
rootfs: make DEPLOYDIR available to all rootfs
fix(rootfs): generate in-tree initrd as part of image install

meta/classes-recipe/image.bbclass | 3 +--
meta/classes-recipe/initramfs.bbclass | 39 ++++++++++++++++++++++++++-
meta/classes-recipe/rootfs.bbclass | 35 +++++-------------------
3 files changed, 46 insertions(+), 31 deletions(-)

--
2.53.0

Felix Moessbauer

unread,
9:34 AM (8 hours ago) 9:34 AM
to isar-...@googlegroups.com, quirin.g...@siemens.com, Felix Moessbauer
When working with a in-tree initrd, the generation of the initrd has the
side effect of placing the initrd in /boot as well (in addition to the
deployment to the deploy dir). This part is currently skipped in case
the initrd is taken from the sstate cache, leading to reproducibility
issues of non-wic images (e.g. a rootfs tarball).

This issue remained unnoticed, as all image types that go through wic
anyways replace the /boot part with the artifacts from the deploy dir.

We now run the initrd generator as part of the rootfs_install in case an
in-tree initrd is used. If an out-of-tree initrd is used, the current
logic is kept, as the rootfs from the initrd generation is not used.

Fixes: b0913306 ("Delay creation of initrd until end of rootfs ...")
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta/classes-recipe/image.bbclass | 2 +-
meta/classes-recipe/initramfs.bbclass | 38 +++++++++++++++++++++++++++
meta/classes-recipe/rootfs.bbclass | 33 ++++-------------------
3 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/meta/classes-recipe/image.bbclass b/meta/classes-recipe/image.bbclass
index 4194dda4..03127ded 100644
--- a/meta/classes-recipe/image.bbclass
+++ b/meta/classes-recipe/image.bbclass
@@ -488,7 +488,7 @@ EOSUDO
-exec touch '{}' -h -d@${SOURCE_DATE_EPOCH} ';'
}
do_rootfs_finalize[network] = "${TASK_USE_SUDO}"
-addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess do_generate_initramfs
+addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess

ROOTFS_QA_FIND_ARGS ?= ""

diff --git a/meta/classes-recipe/initramfs.bbclass b/meta/classes-recipe/initramfs.bbclass
index e0a5f5ab..bfe530c4 100644
--- a/meta/classes-recipe/initramfs.bbclass
+++ b/meta/classes-recipe/initramfs.bbclass
@@ -44,4 +44,42 @@ python do_validate_rootfs_packages () {
bb.error(f"{pkg} is incompatible with the selected generator '{initrd_generator}'")
}
addtask do_validate_rootfs_packages before do_rootfs_install
+
+SSTATETASKS += "do_generate_initramfs"
+do_generate_initramfs[cleandirs] += "${DEPLOYDIR}"
+do_generate_initramfs[network] = "${TASK_USE_SUDO}"
+do_generate_initramfs[sstate-inputdirs] = "${DEPLOYDIR}"
+do_generate_initramfs[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
+python do_generate_initramfs() {
+ bb.build.exec_func('rootfs_do_mounts', d)
+ bb.build.exec_func('rootfs_do_qemu', d)
+
+ progress_reporter = bb.progress.ProgressHandler(d)
+ d.rootfs_progress = progress_reporter
+
+ try:
+ bb.build.exec_func('rootfs_generate_initramfs', d)
+ bb.build.exec_func('rootfs_purge_initramfs', d)
+ finally:
+ bb.build.exec_func('rootfs_do_umounts', d)
+}
+
+python do_generate_initramfs_setscene () {
+ sstate_setscene(d)
+}
+
+# When generating an external initrd, remove it from the rootfs to ensure
+# identical artifacts when using the sstate cache. The remaining rootfs
+# is not used for booting.
+rootfs_purge_initramfs[weight] = "1"
+rootfs_purge_initramfs() {
+ sudo find ${ROOTFSDIR}/boot -name "initrd.img-*" -delete
+}
+
+# If an external initrd shall be used, run it as a task
+# instead of as part of the rootfs install.
+addtask do_generate_initramfs before do_rootfs_postprocess after do_rootfs_install
+addtask do_generate_initramfs_setscene
+ROOTFS_INSTALL_COMMAND:remove = "rootfs_generate_initramfs"
+
inherit rootfs
diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass
index aaacd1e6..f46df2bc 100644
--- a/meta/classes-recipe/rootfs.bbclass
+++ b/meta/classes-recipe/rootfs.bbclass
@@ -424,6 +424,9 @@ rootfs_clear_initrd_symlinks() {
}

do_rootfs_install[root_cleandirs] = "${ROOTFSDIR}"
+do_rootfs_install[cleandirs] += "${DEPLOYDIR}"
+do_rootfs_install[sstate-inputdirs] = "${DEPLOYDIR}"
+do_rootfs_install[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
do_rootfs_install[vardeps] += "${ROOTFS_CONFIGURE_COMMAND} ${ROOTFS_INSTALL_COMMAND} ${ROOTFS_VARDEPS}"
do_rootfs_install[vardepsexclude] += "IMAGE_ROOTFS"
do_rootfs_install[depends] = "bootstrap-${@'target' if d.getVar('ROOTFS_ARCH') == d.getVar('DISTRO_ARCH') else 'host'}:do_build"
@@ -630,28 +633,8 @@ python do_rootfs_postprocess() {
}
addtask rootfs_postprocess before do_rootfs after do_unpack

-SSTATETASKS += "do_generate_initramfs"
-do_generate_initramfs[network] = "${TASK_USE_SUDO}"
-do_generate_initramfs[cleandirs] += "${DEPLOYDIR}"
-do_generate_initramfs[sstate-inputdirs] = "${DEPLOYDIR}"
-do_generate_initramfs[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
-python do_generate_initramfs() {
- bb.build.exec_func('rootfs_do_mounts', d)
- bb.build.exec_func('rootfs_do_qemu', d)
-
- progress_reporter = bb.progress.ProgressHandler(d)
- d.rootfs_progress = progress_reporter
-
- try:
- bb.build.exec_func('rootfs_generate_initramfs', d)
- finally:
- bb.build.exec_func('rootfs_do_umounts', d)
-}
-
-python do_generate_initramfs_setscene () {
- sstate_setscene(d)
-}
-
+ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-initrd', 'rootfs_generate_initramfs', '', d)}"
+rootfs_generate_initramfs[weight] = "1000"
rootfs_generate_initramfs[progress] = "custom:rootfs_progress.InitrdProgressHandler"
rootfs_generate_initramfs() {
if [ -n "$(sudo find '${ROOTFSDIR}/boot' -type f -name 'vmlinu[xz]*')" ]; then
@@ -671,12 +654,6 @@ rootfs_generate_initramfs() {
fi
}

-python() {
- 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)
-}
-
python do_rootfs() {
"""Virtual task"""
pass
--
2.53.0

Felix Moessbauer

unread,
9:34 AM (8 hours ago) 9:34 AM
to isar-...@googlegroups.com, quirin.g...@siemens.com, Felix Moessbauer
This variable contains a WORKDIR specific deploy dir that shall be used
when deploying via the sstate cache. To be able to use this from all
rootfs tasks, we move this variable to the rootfs class.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta/classes-recipe/image.bbclass | 1 -
meta/classes-recipe/initramfs.bbclass | 1 -
meta/classes-recipe/rootfs.bbclass | 2 ++
3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/meta/classes-recipe/image.bbclass b/meta/classes-recipe/image.bbclass
index a44c6de4..4194dda4 100644
--- a/meta/classes-recipe/image.bbclass
+++ b/meta/classes-recipe/image.bbclass
@@ -3,7 +3,6 @@

# Make workdir and stamps machine-specific without changing common PN target
WORKDIR = "${TMPDIR}/work/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/${PV}-${PR}"
-DEPLOYDIR = "${WORKDIR}/deploy"
STAMP = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/${PV}-${PR}"
STAMPCLEAN = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/*-*"

diff --git a/meta/classes-recipe/initramfs.bbclass b/meta/classes-recipe/initramfs.bbclass
index 1b3133d7..e0a5f5ab 100644
--- a/meta/classes-recipe/initramfs.bbclass
+++ b/meta/classes-recipe/initramfs.bbclass
@@ -2,7 +2,6 @@

# Make workdir and stamps machine-specific without changing common PN target
WORKDIR = "${TMPDIR}/work/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/${PV}-${PR}"
-DEPLOYDIR = "${WORKDIR}/deploy"
STAMP = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/${PV}-${PR}"
STAMPCLEAN = "${STAMPS_DIR}/${DISTRO}-${DISTRO_ARCH}/${PN}-${MACHINE}/*-*"

diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass
index 312b7904..aaacd1e6 100644
--- a/meta/classes-recipe/rootfs.bbclass
+++ b/meta/classes-recipe/rootfs.bbclass
@@ -8,6 +8,8 @@ inherit sbom
ROOTFS_ARCH ?= "${DISTRO_ARCH}"
ROOTFS_DISTRO ?= "${DISTRO}"

+DEPLOYDIR = "${WORKDIR}/deploy"
+
# This variable is intended to be set if dracut is
# the default initramfs generator and it is not
# possible to derive the value in another way
--
2.53.0

Quirin Gylstorff

unread,
10:32 AM (7 hours ago) 10:32 AM
to Felix Moessbauer, isar-...@googlegroups.com


On 7/14/26 3:34 PM, Felix Moessbauer wrote:
> When working with a in-tree initrd, the generation of the initrd has the
> side effect of placing the initrd in /boot as well (in addition to the
> deployment to the deploy dir). This part is currently skipped in case
> the initrd is taken from the sstate cache, leading to reproducibility
> issues of non-wic images (e.g. a rootfs tarball).
>
> While this is just a reproducibility issue on wic images (as the initrd
> is anyways replaced by the one from the deploy dir), it is a bug that
> breaks booting on non-wic images.
>
> Best regards,
> Felix
>

Looks good to me. ACK
Quirin
Reply all
Reply to author
Forward
0 new messages