From patchwork Mon Sep 7 06:36:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97444 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5AD46C79FAA for ; Mon, 7 Sep 2026 06:37:39 +0000 (UTC) Received: from mta-65-226.siemens.flowmailer.net (mta-65-226.siemens.flowmailer.net [185.136.65.226]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28901.1788763051702658989 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=arDGBqxM; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.226, mailfrom: fm-1329275-202609070637287fcfb80fe800020732-d2wgja@rts-flowmailer.siemens.com) Received: by mta-65-226.siemens.flowmailer.net with ESMTPSA id 202609070637287fcfb80fe800020732 for ; Mon, 07 Sep 2026 08:37:28 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=2p7gAouxJn7TOWyp36zRSZg68tD3dgL3mff1NdheCuM=; b=arDGBqxMK7tnpyTb4XPhQ+VLGXZpOqT4jw/UXEDoTKxcTIjn2nRr3801DH5uObiuunK4MC u7EAsPu9JVQo6MrJayFvEGqquaZOmsi6EcmujTPYMOp/mBqs4qpRK1sLpaofXBs6RnuT6kp9 EIBXYitSAoWjMTuhzODJ33JlhtPUtjvRGCPMc0VRunJFd9CfWMaEIKKBMIJQ+Dt/eb2qZz8n 2KwSdJCokvgXCT0WY+T/MLs66kLO2jBrVDwkWcJUAhggCxvD4Ij9JRwJwka+ZJC1OEW9g8DY psFohU5edbmw3SqOTMYNBN1RXgLbHkiUL8KlOhw0589vyWMwc0X5etXQ==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 1/9] devtool: ide-sdk: fix GDB loading stale libs instead of recipe's own build Date: Mon, 7 Sep 2026 08:36:07 +0200 Message-ID: <20260907063720.56742-2-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245235 From: Adrian Freihofer Setting GDB's sysroot to the recipe's D (image/) directory is often not enough: D only contains "usr/lib", but the target reports merged-usr paths like "/lib/libfoo.so.0", so the sysroot lookup fails and GDB falls back to solib-search-path, resolving the library from the full image's rootfs-dbg/rootfs instead. Recipes that install libraries outside the standard libdir hit this on every rebuild, silently debugging with stale symbols from the last full image build. Confirmed against gdb-17.2 gdb/solib.c (solib_find_1()) by capturing the GDB MI trace of an attach session and cross-checking against that code. Fix: add RecipeModified._find_elf_dirs(), which walks D and returns every directory containing an ELF file, and prepend those directories to additionalSOLibSearchPath, ahead of the rootfs-dbg/rootfs entries, in every generated launch config. Since with usrmerge in DISTRO_FEATURES (the default) base_libdir and libdir resolve to the same path, this can introduce literal duplicates in the list; dedupe with list(dict.fromkeys(...)) instead of a set, since the order of the list is essential: it defines GDB's solib-search-path priority. Also extend the launch.json oe-selftest assertions to check that the first additionalSOLibSearchPath entry is the recipe's own image (D) directory, not rootfs-dbg. Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/devtool.py | 5 ++ scripts/lib/devtool/ide_sdk.py | 62 +++++++++++++++++-------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 3e0eb7948f..de59feadb8 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3591,6 +3591,11 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): so_paths = config.get("additionalSOLibSearchPath", []) self.assertIn("/.debug", so_paths, f"Configuration '{config['name']}' should include debug symbol paths") self.assertIn("/rootfs-dbg/", so_paths, f"Configuration '{config['name']}' should include rootfs-dbg paths") + # The recipe's own D/usr/lib must come first, so GDB's solib-search-path basename fallback + # prefers freshly rebuilt libraries over a stale rootfs-dbg/rootfs copy from the last full image build. + first_so_path = so_paths.split(":", 1)[0] + self.assertIn("/image/", first_so_path, f"Configuration '{config['name']}' first SO lib search path should be the recipe's own image dir: {first_so_path}") + self.assertNotIn("rootfs-dbg", first_so_path, f"Configuration '{config['name']}' first SO lib search path should not be rootfs-dbg: {first_so_path}") # Verify source file mappings source_map = config.get("sourceFileMap", {}) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 9225546c5e..6558137134 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -827,27 +827,50 @@ class RecipeModified: return True return False + @staticmethod + def _find_elf_dirs(root): + """Return every directory under root that contains an ELF file""" + elf_dirs = [] + for dirpath, _dirnames, filenames in os.walk(root): + for filename in filenames: + file_path = os.path.join(dirpath, filename) + if os.path.islink(file_path): + continue + try: + with open(file_path, 'rb') as elf_file: + is_elf = elf_file.read(4) == b'\x7fELF' + except OSError: + continue + if is_elf: + elf_dirs.append(dirpath) + break + return elf_dirs + def solib_search_path(self, image): - """Search for debug symbols in the rootfs and rootfs-dbg + """Search for debug symbols - The debug symbols of shared libraries which are provided by other packages - are grabbed from the -dbg packages in the rootfs-dbg. + This recipe's own D is searched (for ELF files, wherever they are + installed), so that this recipe's freshly rebuilt libraries take + precedence over any stale copy from the last full image build. + "set sysroot D" alone cannot achieve this: GDB's sysroot (tested with + GDB 17.2) only matches "/lib" paths, but D usually only contains + "usr/lib" (no top-level "lib" symlink), so it falls back to + solib-search-path's basename matching instead. This also covers + libraries not installed into the standard libdirs. - But most cross debugging tools like gdb, perf, and systemtap need to find - executable/library first and through it debuglink note find corresponding - symbols file. Therefore the library paths from the rootfs are added as well. - - Note: For the devtool modified recipe compiled from the IDE, the debug - symbols are taken from the unstripped binaries in the image folder. - Also, devtool deploy-target takes the files from the image folder. - debug symbols in the image folder refer to the corresponding source files - with absolute paths of the build machine. Debug symbols found in the - rootfs-dbg are relocated and contain paths which refer to the source files - installed on the target device e.g. /usr/src/... + D is listed first, ahead of rootfs-dbg/rootfs. For every other + library, i.e. one provided by another package, debug symbols are + grabbed from the -dbg packages in rootfs-dbg. gdb, perf, and + systemtap need to find the executable/library itself first, and + through its debuglink find the symbols file, so the plain rootfs + paths are added too. """ base_libdir = self.base_libdir.lstrip('/') libdir = self.libdir.lstrip('/') - so_paths = [ + # dedupe (e.g. base_libdir = libdir) while keeping the order (using dict instead of set) + so_paths = dict.fromkeys([ + # This recipe's own rebuilt libraries/plugins, ahead of rootfs-dbg/rootfs. + *self._find_elf_dirs(self.d), # debug symbols for package_debug_split_style: debug-with-srcpkg or .debug os.path.join(image.rootfs_dbg, base_libdir, ".debug"), os.path.join(image.rootfs_dbg, libdir, ".debug"), @@ -858,13 +881,12 @@ class RecipeModified: # With image-combined-dbg.bbclass the binaries are copied into rootfs-dbg os.path.join(image.rootfs_dbg, base_libdir), os.path.join(image.rootfs_dbg, libdir), - # Without image-combined-dbg.bbclass the binaries are only in rootfs. - # Note: Stepping into source files located in rootfs-dbg does not - # work without image-combined-dbg.bbclass yet. + # Without image-combined-dbg.bbclass the binaries are only in rootfs + # (stepping into rootfs-dbg sources needs image-combined-dbg.bbclass) os.path.join(image.rootfs, base_libdir), os.path.join(image.rootfs, libdir) - ] - return so_paths + ]) + return list(so_paths) def solib_search_path_str(self, image): """Return a : separated list of paths usable by GDB's set solib-search-path""" From patchwork Mon Sep 7 06:36:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 670A8C79FAC for ; Mon, 7 Sep 2026 06:37:39 +0000 (UTC) Received: from mta-64-226.siemens.flowmailer.net (mta-64-226.siemens.flowmailer.net [185.136.64.226]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.28581.1788763051699422547 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=ZABRC37e; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.226, mailfrom: fm-1329275-202609070637285e4972813a000207fc-bsjciu@rts-flowmailer.siemens.com) Received: by mta-64-226.siemens.flowmailer.net with ESMTPSA id 202609070637285e4972813a000207fc for ; Mon, 07 Sep 2026 08:37:28 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=L+DU88ooyFegsMFg3AqRJfeJ7zuMLrTe0TE2Xma5dEw=; b=ZABRC37eXWLX3B6P0z4YvcgJsaf3iCQnsJUKDqHphNSYIBj0b2VBfzAeTc9dYwe6CNB6R/ KPtJMESrzBTvnMb+sVyMffp9NXDcWn2wQWqQo0zoo+R5+C5Z3hUNcRVeazWgiUCsHvhvfFRP D8fMdBv9Szjl1+kF72S9MA9TRReKvC3iuw4HcuCVRNONQbRjEwsSKqsQtdv31GvJt6IGjPqT dNt2Xjnwx2qoNHvOMZl7W0rEpohB8ghEv6K+KX//4GnFmtSTN/qEmJVO5SRz9Se5CrnaKLTe yTKvtmwvUU/SXpvE2HmCvYjvflgoFCH9Bo0FM7+U/XrTEpEA/cYiXPFw==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 2/9] oe-selftest: devtool ide-sdk: do not guess the slirp SSH port Date: Mon, 7 Sep 2026 08:36:08 +0200 Message-ID: <20260907063720.56742-3-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245230 From: Adrian Freihofer Falling back to a hardcoded 2222 hides the case where runqemu did not report an ip:port pair: the test would then keep running against a port that nothing listens on and fail somewhere further down. Assert the port instead, so the failure points at its actual cause. Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/devtool.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index de59feadb8..3a407a5162 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3991,7 +3991,8 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): with runqemu(testimage, runqemuparams="nographic slirp") as qemu: slirp_host = qemu.ip - slirp_port = qemu.port or '2222' + self.assertIsNotNone(qemu.port, 'No SSH port for the slirp target') + slirp_port = qemu.port # Re-run ide-sdk with the actual slirp address; image is already built. bitbake_sdk_cmd = ( From patchwork Mon Sep 7 06:36:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43A6AC79F9E for ; Mon, 7 Sep 2026 06:37:38 +0000 (UTC) Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28902.1788763051702694510 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=VaHBoIHR; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.228, mailfrom: fm-1329275-202609070637280c45b4247300020788-zggiks@rts-flowmailer.siemens.com) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 202609070637280c45b4247300020788 for ; Mon, 07 Sep 2026 08:37:28 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=6AlUM29nFpKNoSOB76K+XEvJKIZL8ujuRTWdSXT4bjQ=; b=VaHBoIHRv3TLkh7g3lBj9RmM3eWbuxaPRZaf2g0IIadZM/np5nsUDejbV/OYQtcgexiX+9 v/nWbIM8n010bjBMCIaUdcFhSwwSkDjywo+qr4nuS4bHiRvQmGLM+QGSGD+8NWEafrygGFxt vFaj/LSXTIptQ6fLVexEFJc5Mw+psQvIGayFn9v9lIoOIp4NGWQLtPgZTYeaWcHGxlpfcom5 DIuKWUbRRCKQsHV/er1TPJ2j+cb9T569mLhwlQrpf57/AGR6gFPt95TSASNOwaucyro2/ke0 Us+Plf4EoaZQ7yvN673rJ0xVIc4gEpC/fAhbXh1CKkDhSL6hxEWWc8Og==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 3/9] devtool: ide-sdk: pre-select attach process with processFilter Date: Mon, 7 Sep 2026 08:36:09 +0200 Message-ID: <20260907063720.56742-4-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245237 From: Adrian Freihofer The ATTACH launch config now uses the extended-remote protocol, which makes cppdbg show a picker listing every process running on the target. In modified-recipe mode the binary to attach to is already known, so the picker is only extra clicking, and on a busy target it can make finding the right process among unrelated ones tedious. Set "processFilter" to a regex matching the deployed binary's path so cppdbg pre-selects it instead of showing the full process list. This is a recent cpptools feature; until it ships in a released cpptools, cppdbg silently ignores it and falls back to showing the full unfiltered process list. Require cpptools version that supports processFilter https://github.com/microsoft/vscode-cpptools/pull/14684 Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/devtool.py | 1 + scripts/lib/devtool/ide_plugins/ide_code.py | 1 + 2 files changed, 2 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 3a407a5162..a4b7a83094 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3569,6 +3569,7 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): # from the process instead of killing it. self.assertTrue(config.get("useExtendedRemote"), f"Configuration '{config['name']}' should use useExtendedRemote") self.assertNotIn("cwd", config, f"Configuration '{config['name']}' should not set cwd in attach mode") + self.assertTrue(config.get("processFilter"), f"Configuration '{config['name']}' should use processFilter") else: self.fail(f"Configuration '{config['name']}' has unexpected request type: {config['request']}") diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py index 937c63a4a5..6effbac654 100644 --- a/scripts/lib/devtool/ide_plugins/ide_code.py +++ b/scripts/lib/devtool/ide_plugins/ide_code.py @@ -387,6 +387,7 @@ class IdeVSCode(IdeBase): # this configuration is generated. Stopping the session detaches # from the process instead of killing it. launch_config["useExtendedRemote"] = True + launch_config["processFilter"] = "(^| )%s( |$)" % cross_debug_config.binary.binary_path else: # cwd, environment and externalConsole configure the process the # debugger starts, they are not part of the attach schema. From patchwork Mon Sep 7 06:36:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3061C79FAE for ; Mon, 7 Sep 2026 06:37:39 +0000 (UTC) Received: from mta-65-227.siemens.flowmailer.net (mta-65-227.siemens.flowmailer.net [185.136.65.227]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.28580.1788763051699160064 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=HVWdLYzl; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.227, mailfrom: fm-1329275-20260907063728a77935ffbf00020714-2jnn53@rts-flowmailer.siemens.com) Received: by mta-65-227.siemens.flowmailer.net with ESMTPSA id 20260907063728a77935ffbf00020714 for ; Mon, 07 Sep 2026 08:37:28 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=pS11joJ71i5fICEMrki89ZNucs3an6B+OJrT7MzQYDM=; b=HVWdLYzlpbz/1Y4IpMTSm5RUUY/c15DQcymOlZiYnLUiAOpL0btp75dL5RHb0gsk/DFPg4 I6XHCScAG766+QqsAURyHs3YSRAd6iWPG55KmEuWC+jvQK8BzJ1hYF4DpBHpZqUZ8KIS2Rkq zPdaKvnsRn1Wjww4956fvSIuMX2PShk6eTfct1Y+8p5MGvDwXrd/9lqEr9MaMv2jNvyBRofm EaUuX5j5YQnFVcbxJqpRREf6Or+jdpb5yRvbiRoI0NFCCdP6gqOksWlceUfZ6W1gkr//MyD4 9bzwPV2F2Lt73lv6pGbJurF0LahafRixzeosrh1K7X21tVbt1l74oCxw==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 4/9] oe-selftest: tinfoil: test prepared task runner Date: Mon, 7 Sep 2026 08:36:10 +0200 Message-ID: <20260907063720.56742-5-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245228 From: Adrian Freihofer Add shell and Python marker tasks to pseudo-pyc-test, with and without fakeroot. Build the tasks normally to prepare their dependencies, remove their markers, then rerun them through Tinfoil's run_prepared_task() API. This verifies that a prepared task can be rerun through BitBake's worker path without resolving its dependencies, including shell and Python task execution within and outside a pseudo session as needed by devtool ide-sdk. Signed-off-by: Adrian Freihofer --- .../pseudo-pyc-test/pseudo-pyc-test.bb | 45 ++++++++++++++ meta/lib/oeqa/selftest/cases/tinfoil.py | 60 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/meta-selftest/recipes-test/pseudo-pyc-test/pseudo-pyc-test.bb b/meta-selftest/recipes-test/pseudo-pyc-test/pseudo-pyc-test.bb index 12dc91a8f3..f6b31b63cd 100644 --- a/meta-selftest/recipes-test/pseudo-pyc-test/pseudo-pyc-test.bb +++ b/meta-selftest/recipes-test/pseudo-pyc-test/pseudo-pyc-test.bb @@ -13,3 +13,48 @@ python do_install() { import pseudo_pyc_test2 print(pseudo_pyc_test2.STRING) } + +TINFOIL_TEST_MARKER_DIR = "${TMPDIR}/tinfoil-prepared-task" +TINFOIL_TEST_MARKER_VALUE ?= "" + +write_tinfoil_shell_marker() { + mkdir -p ${TINFOIL_TEST_MARKER_DIR} + printf '%s%s' "$1" "${TINFOIL_TEST_MARKER_VALUE}" > ${TINFOIL_TEST_MARKER_DIR}/"$1" +} + +do_tinfoil_dep() { + write_tinfoil_shell_marker dep +} +addtask tinfoil_dep + +do_tinfoil_shell() { + write_tinfoil_shell_marker shell +} +addtask tinfoil_shell after do_tinfoil_dep + +do_tinfoil_shell_fakeroot() { + write_tinfoil_shell_marker shell-fakeroot +} +do_tinfoil_shell_fakeroot[fakeroot] = "1" +do_tinfoil_shell_fakeroot[depends] += "virtual/fakeroot-native:do_populate_sysroot" +addtask tinfoil_shell_fakeroot after do_tinfoil_dep + +def write_tinfoil_marker(d, name): + import os + + marker_dir = d.getVar('TINFOIL_TEST_MARKER_DIR') + os.makedirs(marker_dir, exist_ok=True) + with open(os.path.join(marker_dir, name), 'w') as marker: + marker.write(name + d.getVar('TINFOIL_TEST_MARKER_VALUE')) + +python do_tinfoil_python() { + write_tinfoil_marker(d, 'python') +} +addtask tinfoil_python after do_tinfoil_dep + +python do_tinfoil_python_fakeroot() { + write_tinfoil_marker(d, 'python-fakeroot') +} +do_tinfoil_python_fakeroot[fakeroot] = "1" +do_tinfoil_python_fakeroot[depends] += "virtual/fakeroot-native:do_populate_sysroot" +addtask tinfoil_python_fakeroot after do_tinfoil_dep diff --git a/meta/lib/oeqa/selftest/cases/tinfoil.py b/meta/lib/oeqa/selftest/cases/tinfoil.py index 21c8686b2a..d8009eddfe 100644 --- a/meta/lib/oeqa/selftest/cases/tinfoil.py +++ b/meta/lib/oeqa/selftest/cases/tinfoil.py @@ -6,11 +6,14 @@ import os import re +import shutil import time import logging +import uuid import bb.tinfoil from oeqa.selftest.case import OESelftestTestCase +from oeqa.utils.commands import bitbake class TinfoilTests(OESelftestTestCase): """ Basic tests for the tinfoil API """ @@ -77,6 +80,63 @@ class TinfoilTests(OESelftestTestCase): localdata.setVar('PN', 'hello') self.assertEqual('hello', localdata.getVar('BPN')) + def test_run_prepared_task(self): + """Verify run_prepared_task() runs only the requested task, not its + dependency. + + pseudo-pyc-test's do_tinfoil_* tasks depend on do_tinfoil_dep; both + write a marker file containing the task name plus the current value + of TINFOIL_TEST_MARKER_VALUE. A normal bitbake build is expected to + update both the dependency's and the requested tasks' markers to a + new value. Calling run_prepared_task() with another new value must + update only the requested tasks' markers, leaving do_tinfoil_dep's + marker at the value written by the earlier bitbake build. + """ + marker_dir = os.path.join( + self.builddir, 'tmp', 'tinfoil-prepared-task') + shutil.rmtree(marker_dir, ignore_errors=True) + self.track_for_cleanup(marker_dir) + + tasks = ('shell', 'shell_fakeroot', 'python', 'python_fakeroot') + + # Use a fresh, random value each run so the tasks' signatures change + # and bitbake can't skip them as "up to date" from a previous run. + value1 = uuid.uuid4().hex + bitbake(' '.join('pseudo-pyc-test:do_tinfoil_%s' % task + for task in tasks), + postconfig='TINFOIL_TEST_MARKER_VALUE = "%s"\n' % value1) + + # do_tinfoil_dep is a dependency of all the tasks above, so a normal + # bitbake build is expected to have run it too, with the same value. + with open(os.path.join(marker_dir, 'dep')) as marker: + self.assertEqual(marker.read(), 'dep' + value1) + for task in tasks: + marker_name = task.replace('_', '-') + with open(os.path.join(marker_dir, marker_name)) as marker: + self.assertEqual(marker.read(), marker_name + value1) + + with bb.tinfoil.Tinfoil() as tinfoil: + tinfoil.prepare(config_only=False, quiet=2) + # A distinct value per call proves each run_prepared_task() + # invocation re-reads the variable rather than reusing a value + # cached from an earlier call in this loop. + values2 = {task: uuid.uuid4().hex for task in tasks} + for task in tasks: + tinfoil.run_command('setVariable', 'TINFOIL_TEST_MARKER_VALUE', values2[task]) + tinfoil.run_prepared_task( + 'pseudo-pyc-test', 'do_tinfoil_%s' % task) + + # The requested tasks must have re-run and picked up their own value + for task in tasks: + marker_name = task.replace('_', '-') + with open(os.path.join(marker_dir, marker_name)) as marker: + self.assertEqual(marker.read(), marker_name + values2[task]) + + # ...but run_prepared_task() must not have run do_tinfoil_dep, so its + # marker should still hold the value written by the earlier bitbake build + with open(os.path.join(marker_dir, 'dep')) as marker: + self.assertEqual(marker.read(), 'dep' + value1) + # The config_data API to parse_recipe_file is used by: # layerindex-web layerindex/update_layer.py def test_parse_recipe_custom_data(self): From patchwork Mon Sep 7 06:36:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 30DBDC79FA9 for ; Mon, 7 Sep 2026 06:37:39 +0000 (UTC) Received: from mta-65-228.siemens.flowmailer.net (mta-65-228.siemens.flowmailer.net [185.136.65.228]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.28579.1788763051698837091 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=EGfCPOkv; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.228, mailfrom: fm-1329275-2026090706372831830838b1000207c0-kakku0@rts-flowmailer.siemens.com) Received: by mta-65-228.siemens.flowmailer.net with ESMTPSA id 2026090706372831830838b1000207c0 for ; Mon, 07 Sep 2026 08:37:28 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=NuTHXMVx56kgah/008ySd9suXzyg1Tg8cD9ZNzEJ8lA=; b=EGfCPOkv0f/HI2JgurbrhHL/fdwothPJglCFPzVCgZzPiysOwvipDUHy48YiFk8rM+e681 vZK/mUvxLoMLSYKMmQ+vzCjAhZRRSdM5kLQ6QF0VhecjvhPjrCBkI30x/XMZX5GMYeeurb7L IXyT//z49ptRLGH6hKALL0iPxB/nl4SWe88hILktW+tee5fgy7QThgQGdyEU0BXElCGnzi37 Y3XPoNdY/wIT+1gPM02JaZIDlZdGJxXJkNQZMjLbNSglytB1uW9TaJJzcJAUJU7tER4q7CW+ 4PXk3Ev0qqITj9U3pGIt6qhAQ73uxADIuD89rSeyR4eTYOxl6RttYDvw==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 5/9] devtool: ide-sdk: run do_install through BitBake Date: Mon, 7 Sep 2026 08:36:11 +0200 Message-ID: <20260907063720.56742-6-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245229 From: Adrian Freihofer Generate a Python install-task runner for the IDE SDK environment. It prepares Tinfoil normally, then invokes run_prepared_task() to rerun do_install through BitBake's worker path before deploying the result. The IDE owns configure, compile, and unit-test steps in the modified source tree. At deployment time, resolving task dependencies could rerun those steps, discard the IDE's build results, and add unnecessary delay. The prepared-task runner therefore executes only do_install after BitBake has prepared its prerequisites. This supports shell and Python task bodies and lets BitBake establish the fakeroot environment when the task requires pseudo. Signed-off-by: Adrian Freihofer --- scripts/lib/devtool/ide_sdk.py | 42 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 6558137134..0b76aa448b 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -1421,26 +1421,32 @@ class RecipeModified: self.fakerootcmd, self.fakerootenv)) return self.write_script(cmd_lines, 'deploy_target') + def gen_install_task_script(self): + """Generate a script which runs do_install through BitBake.""" + cmd_lines = ['#!%s' % sys.executable] + if self.cmd_compile: + cmd_lines += ['import subprocess', + 'subprocess.run(%s, cwd=%r, shell=True, check=True)' % + (repr(self.cmd_compile), self.real_srctree)] + cmd_lines += ['import os', + 'import sys', + 'sys.path.insert(0, %r)' % os.path.realpath( + os.path.join(self.bitbakepath, '..', 'lib')), + 'import bb.tinfoil', + 'os.chdir(%r)' % self.topdir, + 'tinfoil = bb.tinfoil.Tinfoil()', + 'try:', + ' tinfoil.prepare(config_only=False, quiet=2)', + ' tinfoil.run_prepared_task(%r, "do_install")' % self.pn, + 'finally:', + ' tinfoil.shutdown()'] + return self.write_script(cmd_lines, 'bb_run_do_install') + def gen_install_deploy_script(self, args): """Generate a script which does install and deploy""" - cmd_lines = ['#!/bin/sh'] - - # Save the original command-line args before 'set' overwrites $@ - cmd_lines.append('_args="$@"') - # . oe-init-build-env $BUILDDIR $BITBAKEDIR - # Using 'set' to pass the build directory to oe-init-build-env in sh syntax - cmd_lines.append('cd "%s" || { echo "cd %s failed"; exit 1; }' % ( - self.oe_init_dir, self.oe_init_dir)) - cmd_lines.append('set %s %s' % (self.topdir, self.bitbakepath.rstrip('/bin'))) - cmd_lines.append('. "%s" || { echo ". %s %s failed"; exit 1; }' % ( - self.oe_init_build_env, self.oe_init_build_env, self.topdir)) - - # bitbake -c install - cmd_lines.append( - 'bitbake %s -c install --force || { echo "bitbake %s -c install --force failed"; exit 1; }' % (self.bpn, self.bpn)) - - # Self contained devtool deploy-target - use saved args, not $@ (overwritten by 'set') - cmd_lines.append(self.gen_deploy_target_script(args) + ' $_args') + cmd_lines = ['#!/bin/sh -e'] + cmd_lines.append(self.gen_install_task_script()) + cmd_lines.append(self.gen_deploy_target_script(args) + ' "$@"') return self.write_script(cmd_lines, 'install_and_deploy') From patchwork Mon Sep 7 06:36:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AF16C79FA0 for ; Mon, 7 Sep 2026 06:37:38 +0000 (UTC) Received: from mta-64-227.siemens.flowmailer.net (mta-64-227.siemens.flowmailer.net [185.136.64.227]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28905.1788763051781260538 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=IoW6eLs/; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.227, mailfrom: fm-1329275-202609070637285c096d5f3000020788-fyfaik@rts-flowmailer.siemens.com) Received: by mta-64-227.siemens.flowmailer.net with ESMTPSA id 202609070637285c096d5f3000020788 for ; Mon, 07 Sep 2026 08:37:29 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=5aBTMJCbJTqe33Z4Hf1g1etper4QEr6My+8fwQ3yZRs=; b=IoW6eLs/9xr46GUJHduUfLl1WpsZ8PR4zXtscoKEdw+bpN8wRe73Rr0Ufi1n8Zk9bC1eYf LRf1y7jOYt/Uaf7xTtzEc+5DLE3DSgbHfPLD45poJdQpkL18TVkk5G05lPsgcsFv555Njo/d vm4nVgiH5h4kRng5VQFxnEiAE4aKmBWUTUCg0rtOLGY164DIAMtmNVlaMGV1nl2EEaWXytfE UM+OBABVgnGLL7eo4MPR6xF60N3/4HRAmlAoeDZGsqr5KTswcAZUP1mRlamUHdm1EW2pTvEB eTGZEv4iQ1QfUqN5ghArtlA9vRoVlzERxdSHPy5kevvz3AgqrZ3aYwxQ==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 6/9] oe-selftest: devtool ide-sdk: test install task Date: Mon, 7 Sep 2026 08:36:12 +0200 Message-ID: <20260907063720.56742-7-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245234 From: Adrian Freihofer Verify that the ide-sdk setup generates the do_install task script and that the script runs successfully. This covers the prepared-task runner used by the IDE deployment workflow without requiring Qemu. Replace the ad-hoc dependsOn handling in _verify_launch_config() with a new helper that mirrors VS Code's task dependency resolution and execution order. This ensures that the selftest runs the same sequence of tasks as VS Code would, including compile and install/deploy prerequisites, before starting the debug server. This also aligns the gdb and lldb selftest paths to avoid behavior drift and improve test reliability. Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/devtool.py | 86 ++++++++++++++++++++----- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index a4b7a83094..cf7b97fdda 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3043,7 +3043,7 @@ class DevtoolIdeSdkTests(DevtoolBase): """Verify the scripts referred by the tasks.json file are fine. This function does not depend on Qemu. Therefore it verifies the scripts - exists and the delete step works as expected. But it does not try to + exists and the install step works as expected. But it does not try to deploy to Qemu. """ recipe_id, recipe_id_pretty = self._get_recipe_ids(recipe_name) @@ -3061,6 +3061,11 @@ class DevtoolIdeSdkTests(DevtoolBase): i_and_d_script_path = os.path.join( self._workspace_scripts_dir(recipe_name), i_and_d_script) self.assertExists(i_and_d_script_path) + install_script = 'bb_run_do_install_' + recipe_id + install_script_path = os.path.join( + self._workspace_scripts_dir(recipe_name), install_script) + self.assertExists(install_script_path) + runCmd(install_script_path, cwd=tempdir, output_log=self._cmd_logger) deploy_script_path = os.path.join( self._workspace_scripts_dir(recipe_name), 'deploy_target_' + recipe_id) @@ -3295,6 +3300,60 @@ class DevtoolIdeSdkTests(DevtoolBase): self.assertEqual(actual_group, group, msg="%s not owned by group %s: got %s" % (conf_file, group, actual_group)) + def _run_vscode_task_with_dependencies(self, tempdir, task_label, run_main_task=True): + """Run a VS Code shell task and its dependsOn chain. + + The helper mirrors VS Code task dependency ordering for selftests, so + preLaunchTask prerequisites (e.g. compile and do_install/deploy tasks) + run before the debug server task. + """ + tasks_path = os.path.join(tempdir, '.vscode', 'tasks.json') + self.assertExists(tasks_path, 'tasks.json not found at %s' % tasks_path) + + with open(tasks_path) as tasks_j: + tasks_d = json.load(tasks_j) + + task_by_label = { + task.get('label'): task + for task in tasks_d.get('tasks', []) + if task.get('label') + } + self.assertIn(task_label, task_by_label, + "Task '%s' not found in tasks.json" % task_label) + + ran = set() + + def run_task(label, execute_task): + if label in ran: + return + + task = task_by_label[label] + deps = task.get('dependsOn', []) + if isinstance(deps, str): + deps = [deps] + + for dep in deps: + self.assertIn(dep, task_by_label, + "DependsOn task '%s' not found in tasks.json" % dep) + run_task(dep, True) + + if execute_task: + command = task.get('command') + if command: + args = task.get('args', []) + if not isinstance(args, list): + args = [args] + task_cmd = [command] + [str(arg) for arg in args] + + task_cwd = task.get('options', {}).get('cwd', tempdir) + if isinstance(task_cwd, str): + task_cwd = task_cwd.replace('${workspaceFolder}', tempdir) + runCmd(task_cmd, cwd=task_cwd, output_log=self._cmd_logger) + + ran.add(label) + + run_task(task_label, run_main_task) + class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): @@ -3786,21 +3845,10 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): (task for task in tasks if task["label"] == prelaunch_task_name), None) self.assertIsNotNone(prelaunch_task, f"PreLaunchTask '{prelaunch_task_name}' not found in tasks.json") - # Find the dependsOn task if exists (install and deploy-target) - if "dependsOn" in prelaunch_task: - depends_task_names = prelaunch_task["dependsOn"] - for depends_task_name in depends_task_names: - depends_task = next( - (task for task in tasks if task["label"] == depends_task_name), None) - self.assertIsNotNone(depends_task, f"DependsOn task '{depends_task_name}' not found in tasks.json") - # For simplicity, we assume the dependsOn task is a prerequisite and does not affect the main command - self.logger.debug(f"PreLaunchTask '{prelaunch_task_name}' depends on '{depends_task_name}'") - - # Extract command details from dependsOn task - depends_task_command = depends_task["command"] - depends_task_args = depends_task.get("args", []) - self.logger.debug(f"Would execute dependsOn task: {depends_task_command} {' '.join(depends_task_args)}") - runCmd(f"{depends_task_command} {' '.join(depends_task_args)}", output_log=self._cmd_logger) + # Execute preLaunchTask prerequisites exactly like VS Code dependsOn + # handling, but keep starting the debug server in this method. + self._run_vscode_task_with_dependencies( + tempdir, prelaunch_task_name, run_main_task=False) # Verify task structure and extract command details self.assertEqual(prelaunch_task["type"], "shell", f"Task '{prelaunch_task_name}' should be shell type") @@ -4569,6 +4617,12 @@ class DevtoolIdeSdkClangTests(DevtoolIdeSdkTests): self.assertIsNotNone(prelaunch_task, "preLaunchTask '%s' not found in tasks.json" % prelaunch_task_name) + # Run compile/install/deploy prerequisites exactly as VS Code would, + # but keep starting the debug server itself in this method so we can + # retain explicit readiness handling and diagnostics. + self._run_vscode_task_with_dependencies( + tempdir, prelaunch_task_name, run_main_task=False) + # Extract the SSH command and start lldb-server on the target task_command = prelaunch_task["command"] task_args = prelaunch_task["args"] From patchwork Mon Sep 7 06:36:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2240DC79FA7 for ; Mon, 7 Sep 2026 06:37:39 +0000 (UTC) Received: from mta-64-225.siemens.flowmailer.net (mta-64-225.siemens.flowmailer.net [185.136.64.225]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28899.1788763051702421824 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=RCqqWCcl; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.225, mailfrom: fm-1329275-20260907063729031ffcf3cf0002073d-mf8ib5@rts-flowmailer.siemens.com) Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 20260907063729031ffcf3cf0002073d for ; Mon, 07 Sep 2026 08:37:29 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=+VkBOLln7N50XDcExWSaiDHl8S8HyFAp6IcJgrUfoxo=; b=RCqqWCclJUSP3MYkpeyCq9ZJZSxgtaCP2hk4p0vmlav3FGMj19Xy3dPFw9slK4Tm548rv2 CaOQgN2I7HP4hSmWmVIBljkzEd6EQwI+DMmypwoPP2Kzz27CHwW2FLR601O1U8Q2M24RKqc/ FNnDgIYltJGFHB/yff6gZ6vy01dERQ6VsPKHMHYwcWU4nBfhtQ0avnk3VA5Ec1izSPUnGhxP IP2nZ2j84C1TFKc1TjvU98A25Pn4oDgPm8tXTeCfk2aJe1haOLG4sFx21vne3CWfCFe2bKaJ xU/tnY75v0LnYPV/DKoxenNHZfNRe1sDoj4n7Bu4aJtWKCMV5LEtPp1Q==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 7/9] runqemu-export-rootfs: set PSEUDO_INCLUDE_PATHS for unfsd Date: Mon, 7 Sep 2026 08:36:13 +0200 Message-ID: <20260907063720.56742-8-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:39 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245232 From: Adrian Freihofer pseudo inverted its path-matching logic some time ago: when set, PSEUDO_INCLUDE_PATHS acts as an ownership-tracking allowlist, and anything outside it silently falls through to real chown()/chmod() instead of being recorded by pseudo. This script never set it, so an inherited restrictive value could leave files touched by unfsd on behalf of NFS clients with wrong ownership. Since this script only ever touches NFS_EXPORT_DIR, setting PSEUDO_INCLUDE_PATHS to it is enough. Signed-off-by: Adrian Freihofer --- scripts/runqemu-export-rootfs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/runqemu-export-rootfs b/scripts/runqemu-export-rootfs index 6a8acd0d5a..150513bc50 100755 --- a/scripts/runqemu-export-rootfs +++ b/scripts/runqemu-export-rootfs @@ -56,6 +56,8 @@ MOUNTPID=~/.runqemu-sdk/mount$NFS_INSTANCE.pid PSEUDO_OPTS="-P $OECORE_NATIVE_SYSROOT/usr" PSEUDO_LOCALSTATEDIR="$NFS_EXPORT_DIR/../$(basename $NFS_EXPORT_DIR).pseudo_state" export PSEUDO_LOCALSTATEDIR +PSEUDO_INCLUDE_PATHS="$NFS_EXPORT_DIR" +export PSEUDO_INCLUDE_PATHS if [ ! -d "$PSEUDO_LOCALSTATEDIR" ]; then echo "Error: $PSEUDO_LOCALSTATEDIR does not exist." From patchwork Mon Sep 7 06:36:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97439 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC3B4C79FA3 for ; Mon, 7 Sep 2026 06:37:38 +0000 (UTC) Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28903.1788763051702754762 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=MNOR2yB/; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-1329275-202609070637292e1adc35270002074c-nmbknn@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 202609070637292e1adc35270002074c for ; Mon, 07 Sep 2026 08:37:29 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=y4/o320ZnJGz8ndz7TqwxLbxosK772fsbOZ/LTHTpQ4=; b=MNOR2yB/sDwSOPlpjnETZWJfNoQmIGyjvNx1YxgYXzLOsvBcBTWdnknBhOAjfzp2S7txvn Xo7VSo4c9MfKMiljKuNxrZ+wSkFeIylrwOx0qxcp7l7JYvQU58W2O+rr9qCH0RVK+mCjUVyh XTj1XwNrElFjnnGpBZKTftp2c6w0ZaQHoUYNBtGaRCDDRrtqpBNJgvnNNJPvZXrKEExm71UO VLwol5Dpq57AVMhFZZuq8UgGvpSegYTHbSa5ai48H3++O8+ybI+JutugSyc4ETe/3D/XE+WG gbMHtssTkUVLRhwEon4iwZ2y846wd7WlRAar7iW2ctM0QXvpZ7UvCyCg==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 8/9] devtool: deploy: make pseudo calls independent of bitbake.conf Date: Mon, 7 Sep 2026 08:36:14 +0200 Message-ID: <20260907063720.56742-9-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245231 From: Adrian Freihofer Relying on bitbake.conf's global PSEUDO_INCLUDE_PATHS to cover the stripped-copy directory is fragile, and will only get more fragile as devtool deploy learns to deploy to more kinds of places. Add an env_overrides parameter to exec_fakeroot_no_d() and use it to state PSEUDO_INCLUDE_PATHS explicitly for each pseudo call in the --strip path, so bitbake.conf no longer needs a devtool-specific entry. Signed-off-by: Adrian Freihofer --- meta/conf/bitbake.conf | 2 +- scripts/lib/devtool/__init__.py | 11 ++++++++++- scripts/lib/devtool/deploy.py | 11 +++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf index 63d84cf37b..a21223e216 100644 --- a/meta/conf/bitbake.conf +++ b/meta/conf/bitbake.conf @@ -752,7 +752,7 @@ SRC_URI = "" PSEUDO_LOCALSTATEDIR ?= "${WORKDIR}/pseudo/" PSEUDO_PASSWD ?= "${STAGING_DIR_TARGET}:${PSEUDO_SYSROOT}" PSEUDO_SYSROOT = "${COMPONENTS_DIR}/${BUILD_ARCH}/pseudo-native" -PSEUDO_INCLUDE_PATHS = "/proc,${WORKDIR}/image,${WORKDIR}/package,${WORKDIR}/rootfs,${WORKDIR}/sstate-build-package/,${WORKDIR}/sstate-install-package/,${WORKDIR}/pkgdata,${WORKDIR}/minidebuginfo,${WORKDIR}/devtool-deploy-target-stripped" +PSEUDO_INCLUDE_PATHS = "/proc,${WORKDIR}/image,${WORKDIR}/package,${WORKDIR}/rootfs,${WORKDIR}/sstate-build-package/,${WORKDIR}/sstate-install-package/,${WORKDIR}/pkgdata,${WORKDIR}/minidebuginfo" export PSEUDO_DISABLED = "1" #export PSEUDO_PREFIX = "${STAGING_DIR_NATIVE}${prefix_native}" diff --git a/scripts/lib/devtool/__init__.py b/scripts/lib/devtool/__init__.py index 58b02eb460..32a7bc0098 100644 --- a/scripts/lib/devtool/__init__.py +++ b/scripts/lib/devtool/__init__.py @@ -77,7 +77,14 @@ def exec_watch(cmd, **options): return buf, None -def exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, cmd, **kwargs): +def exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, cmd, env_overrides=None, **kwargs): + """Run cmd under pseudo using a recipe's own FAKEROOTCMD/FAKEROOTENV. + + env_overrides, if given, is applied after fakerootenv so callers can point + pseudo at a different database/allow-list, e.g. a target rootfs's own + PSEUDO_LOCALSTATEDIR/PSEUDO_INCLUDE_PATHS instead of the ambient ones from + FAKEROOTENV. + """ if not os.path.exists(fakerootcmd): logger.error('pseudo executable %s could not be found - have you run a build yet? pseudo-native should install this and if you have run any build then that should have been built') return 2 @@ -88,6 +95,8 @@ def exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, cmd, **kwargs): if '=' in varvalue: splitval = varvalue.split('=', 1) newenv[splitval[0]] = splitval[1] + if env_overrides: + newenv.update(env_overrides) return subprocess.call("%s %s" % (fakerootcmd, cmd), env=newenv, **kwargs) def setup_tinfoil(config_only=False, basepath=None, tracking=False): diff --git a/scripts/lib/devtool/deploy.py b/scripts/lib/devtool/deploy.py index d11b04aea2..7a83d4a23a 100644 --- a/scripts/lib/devtool/deploy.py +++ b/scripts/lib/devtool/deploy.py @@ -277,8 +277,10 @@ def deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_proce srcdir = recipe_outdir recipe_outdir = os.path.join(workdir, 'devtool-deploy-target-stripped') if os.path.isdir(recipe_outdir): - exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, "rm -rf %s" % recipe_outdir, shell=True) - exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, "cp -af %s %s" % (os.path.join(srcdir, '.'), recipe_outdir), shell=True) + exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, "rm -rf %s" % recipe_outdir, + env_overrides={'PSEUDO_INCLUDE_PATHS': recipe_outdir}, shell=True) + exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, "cp -af %s %s" % (os.path.join(srcdir, '.'), recipe_outdir), + env_overrides={'PSEUDO_INCLUDE_PATHS': '%s,%s' % (srcdir, recipe_outdir)}, shell=True) # Strip under pseudo so that it records any inode replacements made by # the strip tool before the deployment tar reads this directory. @@ -292,7 +294,7 @@ def deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_proce ret = exec_fakeroot_no_d( fakerootcmd, fakerootenv, path, '%s -c %s' % (shlex.quote(sys.executable), shlex.quote(strip_script)), - shell=True) + env_overrides={'PSEUDO_INCLUDE_PATHS': recipe_outdir}, shell=True) if ret != 0: raise DevtoolError('Failed to strip files for deployment') @@ -418,7 +420,8 @@ def deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_proce remote_cmd = '%s | %s %s %s %s \'sh %s %s %s %s\'' % ( tar_cmd, ssh_sshexec, ssh_port, extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist) - ret = exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, remote_cmd, cwd=recipe_outdir, shell=True) + ret = exec_fakeroot_no_d(fakerootcmd, fakerootenv, path, remote_cmd, cwd=recipe_outdir, + env_overrides={'PSEUDO_INCLUDE_PATHS': recipe_outdir}, shell=True) finally: if tar_filelist_path: os.remove(tar_filelist_path) From patchwork Mon Sep 7 06:36:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 97438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52554C79F89 for ; Mon, 7 Sep 2026 06:37:38 +0000 (UTC) Received: from mta-65-227.siemens.flowmailer.net (mta-65-227.siemens.flowmailer.net [185.136.65.227]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.28904.1788763051709714317 for ; Sun, 06 Sep 2026 23:37:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=DwIW3b91; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.227, mailfrom: fm-1329275-202609070637298fd15167ac000207ab-nd1w9v@rts-flowmailer.siemens.com) Received: by mta-65-227.siemens.flowmailer.net with ESMTPSA id 202609070637298fd15167ac000207ab for ; Mon, 07 Sep 2026 08:37:29 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=zYG0e4ej8TNUoQk2tx+r2uj0vaZOTs/okZIRpj3iVQk=; b=DwIW3b91xQ7srjVSgZ7rs3Jq6wWNEvfr2SKqYjiczgHVLWxHATqvGJrP429hyO6V46eIyv hoADxRuKLAkeEH38D1jd0I0ODBMa1+I+aFWk1sEZzzJgIWGjrEzhQM/r1/Z6iCeAh74pkpTN KvnXmjFwZ5xxgmOfl1mwB+JBzEADIeJFcauury1LadcGWBs5RvrTvl1oN+XArJIoH20PvWkw ijfG94yaGasREPky8/hFJPGbnA/2SLzdwNqZcuGhPbE4FKaX3TgNPx97oBlNHqMyHOSuZX8b sjxZdYAemukf2Vf/zu6bf8kmpndiJ3Nvp+Ot2y8GKxt+HVIQq5bIyVrQ==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v2 9/9] devtool: deploy: remove dead files_list computation Date: Mon, 7 Sep 2026 08:36:15 +0200 Message-ID: <20260907063720.56742-10-adrian.freihofer@siemens.com> In-Reply-To: <20260907063720.56742-1-adrian.freihofer@siemens.com> References: <20260907063720.56742-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Mon, 07 Sep 2026 06:37:38 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/245236 From: Adrian Freihofer deploy_no_d() built a files_list from os.walk(recipe_outdir) after a successful deploy but never used it. It fed a host-side manifest file written via open(deploy_file, 'w') until commit a16a0c9334b7 ("devtool: deploy-target: write deployed files list to target", 2016-02-19), which moved manifest writing to the target's shell script and dropped that write, leaving the list-building loop as dead code ever since. Signed-off-by: Adrian Freihofer --- scripts/lib/devtool/deploy.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/lib/devtool/deploy.py b/scripts/lib/devtool/deploy.py index 7a83d4a23a..51a1944f38 100644 --- a/scripts/lib/devtool/deploy.py +++ b/scripts/lib/devtool/deploy.py @@ -431,12 +431,6 @@ def deploy_no_d(srcdir, workdir, path, strip_cmd, libdir, base_libdir, max_proce logger.info('Successfully deployed %s' % recipe_outdir) - files_list = [] - for root, _, files in os.walk(recipe_outdir): - for filename in files: - filename = os.path.relpath(os.path.join(root, filename), recipe_outdir) - files_list.append(os.path.join(destdir, filename)) - return 0 def undeploy(args, config, basepath, workspace):