diff --git a/build/meta-bsp/classes/bsp.bbclass b/build/meta-bsp/classes/bsp.bbclass index 8b7c57a51..0e5638bef 100644 --- a/build/meta-bsp/classes/bsp.bbclass +++ b/build/meta-bsp/classes/bsp.bbclass @@ -166,7 +166,10 @@ inherit filesystem # `deploy.sh ` without a prior build still pulls them through sstate). do_deploy_boot_chain[nostamp] = "1" -do_deploy_boot_chain[depends] = "uboot:do_build" +# filesystem:do_fs_check because a chain may write its first stage into the +# raw area of the card (bsp_virt64.inc, IB_FIRST_STAGE_FROM_CARD): on a fresh +# tree the storage image must exist before, not be created by do_deploy after. +do_deploy_boot_chain[depends] = "uboot:do_build filesystem:do_fs_check" python () { extra = [] diff --git a/build/meta-filesystem/classes/fs_arm_common.bbclass b/build/meta-filesystem/classes/fs_arm_common.bbclass index 30ddea85c..ff2eb7c24 100644 --- a/build/meta-filesystem/classes/fs_arm_common.bbclass +++ b/build/meta-filesystem/classes/fs_arm_common.bbclass @@ -27,6 +27,7 @@ IB_PARTITION_LAYOUT ?= "${@'ab' if d.getVar('IB_ZEPHYR_BOOT_APP') else 'rootfs'} def __platform_init_storage(d): import os import subprocess + import time IB_STORAGE_MODE = d.getVar('IB_STORAGE_MODE') IB_ROOTFS_SIZE = d.getVar('IB_ROOTFS_SIZE') @@ -128,14 +129,26 @@ def __platform_init_storage(d): print("Waiting ...") - # TODO: use ionotify(7) - # Give a chance to the real SD-card to be sync'd - time.sleep(2) - if devname[-1].isdigit(): devname += "p" - utils_sudo(["mkfs.fat", "-F32", "-a", "-v", "-n", "boot", f"/dev/{devname}1"]) + # Wait for the partition nodes rather than a fixed delay. They are created + # asynchronously by the host's udev, and inside the build container + # (dbuild.sh bind-mounts the host /dev) that regularly takes longer than + # the 2 s this used to sleep: mkfs then ran on a node that did not exist + # yet, failed, and the card was left with an unformatted p1 that only + # showed up as a failed mount in the next deploy. + parts = ("1", "2", "3") if layout == "ab" else ("1", "2") + for _ in range(100): + if all(os.path.exists(f"/dev/{devname}{n}") for n in parts): + break + time.sleep(0.2) + else: + bb.fatal(f"/dev/{devname}{{{','.join(parts)}}} did not appear after " + "partitioning /dev/" + devname.rstrip("p")) + + utils_sudo(["mkfs.fat", "-F32", "-a", "-v", "-n", "boot", f"/dev/{devname}1"], + check=True) if layout == "ab": # p2 and p3 are raw slots. A filesystem on them would be a filesystem @@ -146,7 +159,7 @@ def __platform_init_storage(d): utils_sudo(["dd", "if=/dev/zero", f"of=/dev/{devname}{part}", "bs=1M", "count=1", "conv=fsync"]) else: - utils_sudo(["mkfs.ext4", "-L", "rootfs1", f"/dev/{devname}2"]) + utils_sudo(["mkfs.ext4", "-L", "rootfs1", f"/dev/{devname}2"], check=True) if IB_STORAGE_MODE == "soft": utils_sudo(["losetup", "-D"]) diff --git a/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb b/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb index dfbede236..77a39b530 100644 --- a/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb +++ b/build/meta-usr/recipes-usr/linux/usr-linux_1.0.bb @@ -74,8 +74,20 @@ python do_deploy() { d.setVar('ROOTFS_FILENAME', 'rootfs') __do_rootfs_mount(d) - utils_sudo(["rsync", "-a", "--keep-dirlinks", - deploy_src + "/", f"{IB_ROOTFS_PATH}/fs/"], check=True) + + # A failed copy must not leave the extracted, root-owned tree behind, + # as the p2 path below makes sure of for its mount. But not through a + # plain finally: __do_rootfs_umount re-packs the tree INTO rootfs.cpio, + # and a half-copied user space must not end up there. On failure the + # tree is dropped and rootfs.cpio stays as it was; the next deploy + # starts over from it. + try: + utils_sudo(["rsync", "-a", "--keep-dirlinks", + deploy_src + "/", f"{IB_ROOTFS_PATH}/fs/"], check=True) + except Exception: + utils_sudo(["rm", "-rf", os.path.join(d.getVar('WORKDIR'), "fs")]) + raise + __do_rootfs_umount(d) bb.plain("usr deployed into rootfs.cpio (IB_RAMFS_SOURCE = rootfs)") @@ -146,10 +158,14 @@ do_install_apps () { usr_do_install_file_root "${IB_TARGET}/src/modules/*.ko" } -do_clean:append () { +# usr.bbclass defines do_clean in Python, and a shell :append is pasted +# verbatim into that Python function, so `-c clean` died on a SyntaxError. +# The shell stays shell, in its own function, called from a Python append. +usr_linux_clean () { - # Clean the modules - if [ -d ${IB_TARGET}/src/modules ]; then + # Clean the modules — only when there is a kernel tree to clean them + # against; before the first linux build there is nothing to clean. + if [ -d ${IB_TARGET}/src/modules ] && [ -d ${IB_LINUX_PATH} ]; then make -C ${IB_LINUX_PATH} M=${IB_TARGET}/src/modules clean fi @@ -166,3 +182,7 @@ do_clean:append () { # Clean the user space apps rm -rf ${IB_TARGET}/build } + +python do_clean:append () { + bb.build.exec_func('usr_linux_clean', d) +} diff --git a/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend b/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend index fc61b713f..f518015c1 100644 --- a/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend +++ b/build/meta-usr/recipes-usr/lvgl/usr-linux_1.0.bbappend @@ -60,7 +60,10 @@ do_install_apps:append () { fi } -do_clean:append () { +# usr.bbclass defines do_clean in Python, and a shell :append is pasted +# verbatim into that Python function, so `-c clean` died on a SyntaxError. +# The shell stays shell, in its own function, called from a Python append. +usr_linux_clean_lvgl () { if echo ":${OVERRIDES}:" | grep -q ":lvgl"; then @@ -76,3 +79,7 @@ do_clean:append () { rm -rf ${WORKDIR}/git fi } + +python do_clean:append () { + bb.build.exec_func('usr_linux_clean_lvgl', d) +} diff --git a/scripts/dbuild.sh b/scripts/dbuild.sh index 1c4292ff3..29f58cc30 100755 --- a/scripts/dbuild.sh +++ b/scripts/dbuild.sh @@ -119,6 +119,16 @@ fi set -- -e IB_TREE="$IB_ROOT" -e IB_CWD="$cwd" "$@" +# Forward the per-invocation knobs env.sh lets through to bitbake +# (BB_ENV_PASSTHROUGH_ADDITIONS) when they are set on the host. Without it +# `IB_FORCE_ATTACH=1 dbuild.sh build.sh ` — what the attach guard +# itself advises — never reached the container, and the guard kept refusing. + +for _v in IB_FORCE_ATTACH IB_PARTITION_LAYOUT; do + eval "_val=\${$_v:-}" + [ -n "$_val" ] && set -- -e "$_v=$_val" "$@" +done + # Hardware deployment: make any IB_HTTP_DEPLOY_PATH feed directory # visible at its own path so `deploy.sh` can publish into it from inside # (IB_STORAGE_MODE=http). This serves the verdin-imx8mp TEZI flow; on the