news 2026/8/16 22:26:24

Failed to take /etc/passwd lock: Invalid argument解决方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Failed to take /etc/passwd lock: Invalid argument解决方案

在 x86 宿主机上构建 ARM64 Ubuntu 24.04 rootfs 时遇到Failed to take /etc/passwd lock: Invalid argument的完整解决记录

一、问题现象

环境

  • 宿主机:VMware Ubuntu 20.04(x86_64,内核 6.6)

  • 构建方式:通过debootstrap+qemu-user-static在 chroot 环境中构建 ARM64 架构的 Ubuntu 24.04 (Noble) rootfs

错误信息

bash

Setting up systemd (255.4-1ubuntu8) ... Failed to take /etc/passwd lock: Invalid argument dpkg: error processing package systemd (--configure): installed systemd package post-installation script subprocess returned error exit status 1

该问题发生在debootstrap --second-stage阶段,systemd 包的 postinst 脚本执行时触发。systemd 包配置失败后,整个构建过程卡死,无法继续安装其他包。

二、根本原因分析

2.1 systemd v254 移除了 OFD 锁的 fallback 机制

在 systemd v253 及更早版本中,文件锁的实现逻辑是:先尝试 Linux 特有的fcntl(F_OFD_SETLKW)(OFD 锁),如果失败(返回EINVAL),则回退到传统的 POSIXflock(F_SETLKW)

systemd v254 开始,这个 fallback 被彻底移除(commited70a34ec0)。systemd 现在硬性要求底层环境必须支持F_OFD_SETLKW。受影响的版本包括 Ubuntu 24.04 自带的 systemd 255.4-1ubuntu8.1。

关键时间点:该问题于2024年6月5日systemd 版本255.4-1ubuntu8.1发布后开始被大规模报告。

2.2 qemu-user-static 不支持 OFD 锁

QEMU 的用户态模拟(linux-user不支持 Open File Description (OFD) 锁。在linux-user/syscall.c中,target_to_host_fcntl_cmd函数没有处理F_OFD_SETLK/F_OFD_SETLKW/F_OFD_GETLK的 case 分支,任何调用都直接返回EINVAL

QEMU Bug #1893010于 2020 年 8 月报告,有人在 2020 年提交了补丁(qemu-5.0.0-ofd-fcntl.patch),但至今未被合并到 QEMU 主线,状态仍为New

2.3 报错调用链

text

systemd.postinst ↓ pwconv (shadow-utils 包) ↓ libshadow.so → pw_lock() ↓ fcntl(F_OFD_SETLKW) → qemu-user-static 不支持 → 返回 EINVAL

注意:这是一个常见的认知误区。很多网上教程说"替换/bin/systemd-sysusersecho可解决",但这个方案只适用于 WSL1 环境(报错来自systemd-sysusers本身)。在qemu-user-static+ chroot 场景下,报错来自pwconvlibshadow.so替换systemd-sysusers完全无效

三、尝试过的无效方案(踩坑记录)

3.1 替换/bin/systemd-sysusersecho

操作

bash

cd /bin && mv -f systemd-sysusers systemd-sysusers.org && ln -s echo systemd-sysusers

结果:无效。报错来自pwconv,不是systemd-sysusers。该方案只适用于 WSL1 环境下systemd-sysusers自身报错的场景。

3.2 修改 postinst 脚本,在systemd-sysusers后添加|| true

操作

bash

find /var/lib/dpkg/info -name "*.postinst" -exec sed -i 's/systemd-sysusers/systemd-sysusers || true/g' {} \;

结果:无效。systemd.postinstpwconvsystemd-sysusers之前执行,脚本在pwconv行就报错退出了,根本跑不到systemd-sysusers

3.3 预创建 systemd 所需用户和组

操作:在--customize-hook中手动写入/etc/group/etc/passwd/etc/shadow

结果:无效。报错来自pwconvlibshadow.sopw_lock()fcntl(F_OFD_SETLKW),预创建用户绕不过这个锁调用。

3.4 升级宿主机 QEMU 到 8.0.x(分场景有效)

Ask Ubuntu 上有用户报告通过 backports 升级 QEMU 到 8.0.x 解决了问题。但该方案有以下限制:

适用场景

  • 宿主机直接 chroot 构建,文件系统为普通 ext4/btrfs 等

  • 宿主机 Ubuntu 20.04 通过 backports 升级到 8.0.x

不适用场景

  • Docker overlay2 存储驱动环境下

  • 即使升级到 8.0.x,QEMU 官方 OFD 锁补丁(2020 年提交)从未被合并到主线,因此升级版本不一定保证解决

操作命令

bash

sudo add-apt-repository ppa:canonical-server/server-backports sudo apt-get update sudo apt-get upgrade qemu-user-static

3.5 使用multiarch/qemu-user-static --reset -p yes

操作

bash

docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

结果:无效。该命令只修复 binfmt 注册(解决"找不到 arm64 解释器"的问题),不修复 QEMU TCG 中struct flock跨架构 ABI 转换的缺陷。该方案仅在 Docker 环境下被尝试,属于坑点之一

3.6 使用ischroot技巧

操作:在--essential-hook中将/usr/bin/ischroot链接到/bin/false

结果:无效。systemd.postinst没有用ischroot保护pwconv调用,ischroot返回什么都无法阻止pwconv执行。

四、最终可行的方案

4.1 方案一:升级宿主机的 QEMU

在宿主机 Ubuntu 20.04 上,通过 backports 将 QEMU 升级到 8.0.x 版本,可能解决该问题。此方案仅在宿主机直接 chroot 构建(非 Docker 环境)且文件系统为普通 ext4/btrfs(非 overlay2)时可能有效。在 Docker overlay2 环境下,该方案无效。

4.1.1 方法一:通过 backports PPA 升级

bash

sudo add-apt-repository ppa:canonical-server/server-backports sudo apt-get update sudo apt-get upgrade qemu-user-static
4.1.2 方法二:手动安装 8.0.4 定制版 deb 包

定制版qemu-user-staticbinfmt-support包存在冲突。binfmt-support提供 SysVinit 启动脚本/etc/init.d/binfmt-support,而定制版提供 systemd 服务单元/lib/systemd/system/systemd-binfmt.service,两者执行顺序会导致 systemd 设置被覆盖。因此需要先移除binfmt-support,再安装定制版。

bash

# 1. 移除冲突的 binfmt-support sudo apt-get purge binfmt-support -y # 2. 下载 8.0.4 定制版 deb 包 wget https://archive.spacemit.com/qemu/qemu-user-static_8.0.4%2Bdfsg-1ubuntu3.23.10.1_amd64.deb # 3. 安装 deb 包 sudo dpkg -i qemu-user-static_8.0.4+dfsg-1ubuntu3.23.10.1_amd64.deb # 4. 重启 systemd-binfmt 服务,将 qemu-user-static 注册到内核 sudo systemctl restart systemd-binfmt.service
4.1.3 验证安装

bash

qemu-aarch64-static --version # 应显示类似 8.0.4 的版本号

注意:QEMU 官方 OFD 锁补丁(2020 年提交)从未被合并到 QEMU 主线,因此升级到 8.0.x 并不保证在所有环境下都能解决该问题。

本次移植过程就是通过这个解决的!升级宿主机的 QEMU

4.2 方案二:替换pwconv(chroot + qemu-user-static 场景)

debootstrap --second-stage执行之前,在宿主机上直接替换 chroot 内的/usr/sbin/pwconv

bash

ROOTFS="$HOME/ubuntu_rootfs" # 备份原 pwconv sudo mv "$ROOTFS/usr/sbin/pwconv" "$ROOTFS/usr/sbin/pwconv.real" # 替换为空操作脚本 sudo bash -c 'printf "#!/bin/sh\nexit 0\n" > '"$ROOTFS/usr/sbin/pwconv" sudo chmod +x "$ROOTFS/usr/sbin/pwconv" # 然后执行 debootstrap --second-stage sudo chroot "$ROOTFS" /debootstrap/debootstrap --second-stage

原理pwconv被替换为空操作后,systemd.postinst调用pwconv时直接返回成功,不会触发F_OFD_SETLKW锁。

代价pwconv永久返回 0,/etc/shadow/etc/passwd不同步。需要在目标系统首次启动后执行一次真实的pwconv

4.3 方案三:修改 systemd 源码

Launchpad Bug #2069555 中明确指出:

"The only real fix for this issue is a modified systemd package which changes the locking mechanism."

具体修改位置:src/basic/lock-util.cfcntl_lock()fcntl_unlockpp()调用的ofd参数,从true改为false。或者增加检测逻辑:检测到F_OFD_SETLKW不支持时,自动回退到F_SETLKW

这个方案需要自行修改源码并重新编译 systemd 包,操作复杂但能根本解决问题。

4.4 方案四:改用完整虚拟机qemu-system-aarch64

放弃qemu-user-static,改用qemu-system-aarch64完整系统模拟。虚拟机内部运行完整的 ARM64 内核,原生支持F_OFD_SETLKW,不存在模拟缺陷。这是最可靠但速度最慢的方案。

五、官方 Bug 追踪链接

来源链接状态
Ubuntu LaunchpadBug #2069555Confirmed
QEMUBug #1893010New
DebianBug #1126304fixed‑upstream
systemd GitHubIssue #29512公开讨论
Microsoft/WSLIssue #10397公开讨论
GitHub WorkaroundInfoXMax/linux‑apt‑fix‑broken‑issue社区方案

核心结论:
该问题的根源是 systemd v254+ 硬性要求 F_OFD_SETLKW,而 qemu-user-static 不支持该锁。systemd 和 QEMU 两边都未修复此问题,只能通过 workaround 绕过。升级 QEMU 在 Docker overlay2 环境下无效,在宿主机直接 chroot 环境下可能有效,但需验证文件系统类型。

----------------------------------------------------------------------------------------

📝 后续补充内容优先同步至 GitHub,如有疏漏欢迎指正。

📌全部相关技术笔记托管于 GitHub 仓库,欢迎访问。

🔗 GitHub仓库:kyshipit/tech‑notes

------------------------------------------------------------------------------------------

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/16 22:24:40

Go语言AI Agent极致压缩:从编译优化到容器化部署的工程实践

1. 项目缘起:为什么我们需要一个“极致压缩”的AI Agent?最近在折腾AI Agent,发现一个挺有意思的现象:很多开源项目,功能确实强大,但一上手,资源占用就让人头疼。动辄几个G的内存,启…

作者头像 李华
网站建设 2026/8/16 22:21:13

题解:AtCoder AT_awc0125_a Warehouse Package Inspection

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大…

作者头像 李华
网站建设 2026/8/16 22:20:53

AI时代程序员转型:从编码到架构与协作的核心能力重塑

1. 从“码农”到“AI协作者”:一场静默的范式转移最近和几个老同事吃饭,聊起一个挺有意思的现象:十年前,我们这帮人聚在一起,话题离不开“哪个框架性能更好”、“怎么解决高并发”、“数据库索引又调优了”。现在呢&am…

作者头像 李华
网站建设 2026/8/16 22:16:27

OpenClaw上下文窗口压缩实战:滑动窗口、摘要记忆与RAG技术解析

1. 项目概述:当AI智能体遇上“记忆”瓶颈 最近在折腾本地AI智能体部署的朋友,估计没少为“上下文窗口”这事儿头疼。你兴冲冲地给OpenClaw接上了最新的Llama 3.1 405B大模型,准备让它帮你处理一份几十页的PDF报告,结果聊到第三页&…

作者头像 李华
网站建设 2026/8/16 22:13:09

Keil vs VSCode vs STM32CubeIDE:嵌入式IDE对比

新手入门STM32,第一个问题就是"用什么IDE"。 网上推荐一大堆,但很多人连"IDE"“编译器”"调试器"都分不清,更别提CMake、OpenOCD这些词了。 这篇先用大白话解释这些概念,再对比三种主流IDE&#xf…

作者头像 李华
网站建设 2026/8/16 22:11:42

现代CLI工具配置管理:openclaw.mjs、config.yaml与环境变量分层实践

1. 项目概述:一个现代CLI工具的配置哲学在构建现代命令行工具(CLI)时,开发者常常面临一个核心矛盾:如何平衡配置的灵活性与使用的简洁性。一个功能强大的工具,如果配置过程过于繁琐或混乱,其价值…

作者头像 李华