当作为 python 子进程调用时,tar 在符号链接上失败

当作为 python 子进程调用时,tar 在符号链接上失败

将我的 Debian 从 Buster 升级到 Bullseye 后,我的 yocto 构建过程失败,do_package: Function failed: perform_packagecopy并显示数百条消息,例如

tar: ./dir/linkfile: Cannot change mode to rwxrwxrwx: No such file or directory

linkfile是目录中的任何符号链接)。实际的复制操作已执行,文件及其符号链接以预期的模式设置出现。看起来符号链接是在它指向的文件之前复制的,并且 tar 认为它需要适应符号链接的模式,但收到错误,因为符号链接指向的文件不存在(但这只是一个假设) 。

不幸的是,我无法重现执行时的错误

tar -cf - -C /full/path/image -p -S . | tar -xf - -C /full/path/package

直接地。这不会给出任何错误。就在python从 yocto 脚本地狱作为子进程执行时,我收到这些错误。以防万一,tar

$ tar --version
tar (GNU tar) 1.34

答案1

我们遇到了同样的问题,我们通过修补 Yocto 以使用 BSD tar 而不是 GNU tar 来避免它。您需要libarchive-tools在 Debian 中安装才能获取此版本的 tar。

我们还尝试将 BSDtar作为 放入 PATH 中tar,但这被 Yocto 拒绝,它检查版本号是否大于 1.28(忽略非 GNU 版本具有不同版本号tar的事实)。tar

这对我们来说似乎没有问题。

From aebcd4668cc3500d6072b7ef3fba2e6ea2cf9f43 Mon Sep 17 00:00:00 2001
From: Florian Viguier <[email protected]>
Date: Wed, 3 Nov 2021 09:15:47 +0100
Subject: [PATCH 1/2] [LCB-318] Switch Gnu tar for bsd tar for Debian 11
 compatibility

---
 meta/classes/package.bbclass | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass
index 5a32e5c2e3..db47edc92a 100644
--- a/meta/classes/package.bbclass
+++ b/meta/classes/package.bbclass
@@ -814,7 +814,7 @@ python perform_packagecopy () {
     # Start by package population by taking a copy of the installed
     # files to operate on
     # Preserve sparse files and hard links
-    cmd = 'tar -cf - -C %s -p -S . | tar -xf - -C %s' % (dest, dvar)
+    cmd = '/usr/bin/bsdtar -cf - -C %s -p -S . | /usr/bin/bsdtar -xf - -C %s' % (dest, dvar)
     subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
 
     # replace RPATHs for the nativesdk binaries, to make them relocatable
-- 
2.30.2

From 7680a3ba35c321fc915714fb835782f0b03d105e Mon Sep 17 00:00:00 2001
From: Adrien Destugues <[email protected]>
Date: Thu, 4 Nov 2021 17:43:47 +0100
Subject: [PATCH 2/2] [FIX] Use bsdtar also in sstate

---
 meta/classes/sstate.bbclass | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index d08d950e76..4e0be994c7 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -849,7 +849,7 @@ python sstate_report_unihash() {
 # Will be run from within SSTATE_INSTDIR.
 #
 sstate_unpack_package () {
-   tar -xvzf ${SSTATE_PKG}
+   /usr/bin/bsdtar -xvzf ${SSTATE_PKG}
    # update .siginfo atime on local/NFS mirror
    [ -O ${SSTATE_PKG}.siginfo ] && [ -w ${SSTATE_PKG}.siginfo ] && [ -h ${SSTATE_PKG}.siginfo ] && touch -a ${SSTATE_PKG}.siginfo
    # Use "! -w ||" to return true for read only files
-- 
2.30.2

答案2

我最近在使用旧的 Yocto 版本 (sumo) 升级 OpenSUSE 发行版时遇到了同样的问题。该问题与 tar 本身并不直接相关,因为它在 Yocto 之外工作,但在与“pseudo”(Yocto 的 fakeroot 实现)一起使用时出现。事实上,旧版本的“pseudo”无法正确支持 tar 中O_NOFOLLOW/标志的处理方式。AT_SYMLINK_NOFOLLOW

为了解决这个问题,我只是升级了“伪”配方以060058bb29f70b244e685b3c704eb0641b736f73使其再次工作。

答案3

升级到 Bullseye 后出现类似问题。

tar: ./var/log: Cannot change mode to rwxrwxrwx: No such file or directory

Debian 11 是不支持。临时解决方案是使用 Debian 10 docker 容器。

相关内容