当您升级或重新安装软件包dpkg
(以及最终使用它的任何东西,如 apt-get 等)时,它会在替换之前通过创建到该文件的硬链接来备份现有文件。这样,如果解压失败,它可以轻松放回现有文件。这很棒,因为它可以保护操作系统免受 Bad Things™ 发生的影响。
除了...它只有效如果您的文件系统支持硬链接。并非所有文件系统都这样做 - 例如 FAT 文件系统。
我正在为特定的嵌入式 ARM 平台开发 Debian 发行版,引导环境要求某些文件(包括内核)位于 FAT 文件系统上,以便引导代码能够找到并加载它们。
当您升级内核软件包(或在该 FAT 分区中包含文件的任何其他软件包)时,安装失败并显示:
dpkg: error processing archive linux-image3.18.11+_3.18.11.2.armadillian_armhf.deb (--install):
unable to make backup link of `./boot/vmlinuz-3.18.11+' before installing new version: Operation not permitted
并且整个升级失败。
我搜索过网络,我能找到的唯一参考资料是在进行特定升级时遇到特定问题的特定人员,答案通常是“删除 /boot/vmlinuz-3.18.11+ 并重试”,是的,那修复该特定问题。
但这不是我的答案。我是操作系统分销商,而不是操作系统用户,因此我需要一种方法来解决此问题,并且不涉及最终用户在升级之前手动删除其内核文件。我需要一种方法来告诉 dpkg 对 /boot 上的文件(或我关心的所有文件,尽管这会稍微减慢升级操作)“复制,而不是硬链接”,或者更好的是“如果硬链接失败,不要抱怨,只需复制它即可”。
我尝试过诸如--force-unsafe-io
甚至--force-all
标记为 之类的事情dpkg
,但没有任何效果。
答案1
您所看到的行为是在源代码archives.c
中实现的dpkg
,1030号线(对于版本 1.18.1):
debug(dbg_eachfiledetail, "tarobject nondirectory, 'link' backup");
if (link(fnamevb.buf,fnametmpvb.buf))
ohshite(_("unable to make backup link of '%.255s' before installing new version"),
ti->name);
在我看来,您可以通过使用第 1003 行及以下行的重命名行为来处理链接失败;类似的东西(未经测试):
debug(dbg_eachfiledetail, "tarobject nondirectory, 'link' backup");
if (link(fnamevb.buf,fnametmpvb.buf)) {
debug(dbg_eachfiledetail,"link failed, nonatomic");
nifd->namenode->flags |= fnnf_no_atomic_overwrite;
if (rename(fnamevb.buf,fnametmpvb.buf))
ohshite(_("unable to move aside '%.255s' to install new version"),
ti->name);
}
不过,我不是dpkg
专家...(并且没有可用的选项来dpkg
提供这种行为。)