In sstate.bbclass, sstate_package() sets SSTATE_CURRTASK from
the sstate task being packaged, then runs every function listed
in SSTATECREATEFUNCS. This happens independent of the context the sstate
task is scoped to for all tasks in a single recipe.
While this pattern is not problematic in isar itself (we only have one
SSTATECREATEFUNC per recipe), it becomes problematic when downstream
users define further manual sstate tasks. In this case, the sstate tasks
are executed in the wrong context, leading to races and failures in all
colors.
We fix this by guarding each manually defined sstate func to only run in
its intended context.
meta/classes-recipe/dpkg-base.bbclass | 4 ++++
meta/classes-recipe/rootfs.bbclass | 4 ++++
meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/meta/classes-recipe/dpkg-base.bbclass b/meta/classes-recipe/dpkg-base.bbclass
index f7a12302..85c37a5a 100644
--- a/meta/classes-recipe/dpkg-base.bbclass
+++ b/meta/classes-recipe/dpkg-base.bbclass
@@ -184,6 +184,8 @@ SSTATECREATEFUNCS += "dpkg_build_sstate_prepare"
SSTATEPOSTINSTFUNCS += "dpkg_build_sstate_finalize"
dpkg_build_sstate_prepare() {
+ [ "${SSTATE_CURRTASK}" = "dpkg_build" ] || return 0
+
# this runs in SSTATE_BUILDDIR, which will be deleted automatically
if [ -n "$(find ${WORKDIR} -maxdepth 1 -name '*.deb' -print -quit)" ]; then
cp -f ${WORKDIR}/*.deb -t .
@@ -191,6 +193,8 @@ dpkg_build_sstate_prepare() {
}
dpkg_build_sstate_finalize() {
+ [ "${SSTATE_CURRTASK}" = "dpkg_build" ] || return 0
+
# this runs in SSTATE_INSTDIR
if [ -n "$(find . -maxdepth 1 -name '*.deb' -print -quit)" ]; then
mv -f ./*.deb -t ${WORKDIR}/
diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass
index 8a4aad16..936f56fe 100644
--- a/meta/classes-recipe/rootfs.bbclass
+++ b/meta/classes-recipe/rootfs.bbclass
@@ -691,6 +691,8 @@ SSTATE_TAR_ATTR_FLAGS ?= "--xattrs --xattrs-include='*'"
# the rootfs is owned by root, so we need some sudoing to pack and unpack
rootfs_install_sstate_prepare() {
+ [ "${SSTATE_CURRTASK}" = "rootfs_install" ] || return 0
+
# this runs in SSTATE_BUILDDIR, which will be deleted automatically
# tar --one-file-system will cross bind-mounts to the same filesystem,
# so we use some mount magic to prevent that
@@ -705,6 +707,8 @@ rootfs_install_sstate_prepare() {
rootfs_install_sstate_prepare[lockfiles] = "${REPO_ISAR_DIR}/isar.lock"
rootfs_install_sstate_finalize() {
+ [ "${SSTATE_CURRTASK}" = "rootfs_install" ] || return 0
+
# this runs in SSTATE_INSTDIR
# - after building the rootfs, the tar won't be there, but we also don't need to unpack
# - after restoring from cache, there will be a tar which we unpack and then delete
diff --git a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
index e746f469..98f6c090 100644
--- a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
+++ b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc
@@ -264,12 +264,16 @@ SSTATECREATEFUNCS += "bootstrap_sstate_prepare"
SSTATEPOSTINSTFUNCS += "bootstrap_sstate_finalize"
bootstrap_sstate_prepare() {
+ [ "${SSTATE_CURRTASK}" = "bootstrap" ] || return 0
+
# this runs in SSTATE_BUILDDIR, which will be deleted automatically
sudo cp -a "${WORKDIR}/rootfs.tar.zst" ./bootstrap.tar.zst
sudo chown $(id -u):$(id -g) bootstrap.tar.zst
}
bootstrap_sstate_finalize() {
+ [ "${SSTATE_CURRTASK}" = "bootstrap" ] || return 0
+
# this runs in SSTATE_INSTDIR
# we should restore symlinks after using tar
if [ -f bootstrap.tar.zst ]; then
--
2.53.0