欢迎光临
我们一直在努力

碰到问题了:卡点仍是 /usr 只读挂载 + quarterly 包 userland 1404000 vs 本机 1403000 @FreeBSD

碰到问题了,AI一直想做一些/usr的操作:

卡点仍是 /usr 只读挂载 + quarterly 包 userland 1404000 vs 本机 1403000 → 对应 mount -u -o rw /usr 与 IGNORE_OSVERSION=yes。装好后我再加回 import 校验步并逐腿下线基线。

这样做合理吗?

Deleted 2 files›

两点要说清楚,第一点是个误会,第二点那个建议解决的不是我们的问题。

一、你不需要 umount。

umount /usr 失败是必然的——整个系统都在用 /usr,它永远 busy。但我给的是另一条命令:

sh

插入到终端中

复制

sudo mount -u -o rw /usr

-u 是 update:不卸载、不中断任何正在使用它的进程,只把这个挂载点的标志位从 ro 改成 rw。busy 与否完全不影响。这和 umount 是两回事,值得单独试一次。

装完想还原就 sudo mount -u -o ro /usr。

二、「在 /var/tmp 或工作目录建 venv」解决不了我们的卡点。

因为我们的 venv 本来就没建在 /usr 里。CI 的 venv 建在 act_runner 的 workspace(/var/db/act_runner/workspace/…,可写),run 30 已经跑通了。venv 的位置从来不是问题。

真正缺的是:pandas / matplotlib / sklearn / sympy 这四个库在这台机器上任何地方都没有。venv 只是个空壳子,建在哪儿都得往里装东西。而往里装东西只有两条路:

  • pip install pandas → 这台 runner 的 pip 指向本地 devpi 镜像 127.0.0.1:3141,那个镜像没有科学计算包。单 30-C 已经实测过了:numpy 报 from versions: none,连版本列表都取不到。pandas 同理。所以 venv + pip 是死路,除非先修 devpi。
  • pkg install → 有预编译包(USTC/163 镜像),但要写 /usr/local,就是第一点那个卡点。

三、如果你确实不想动 /usr 的挂载,有第三条路——pkg fetch + 手工解包 + PYTHONPATH:

sh

插入到终端中

复制

sudo IGNORE_OSVERSION=yes pkg fetch -y -d -o /var/tmp/pkgcache \\ py311-pandas py311-matplotlib py311-scikit-learn py311-sympy mkdir -p /var/tmp/pylibs for f in /var/tmp/pkgcache/All/*.pkg; do tar -xf "$f" -C /var/tmp/pylibs; done

pkg fetch 只下载不安装,缓存和 pkg 数据库都在 /var(可写),全程不碰 /usr。解出来的树是 /var/tmp/pylibs/usr/local/lib/python3.11/site-packages/…,我在 ci.yml 里加一个 PYTHONPATH 指向它即可。

这条路的代价我得说明白:matplotlib 和 sklearn 有 C 扩展,依赖 libfreetype、libpng、scipy 的 BLAS 之类的共享库,那些会被解到 /var/tmp/pylibs/usr/local/lib/,运行时还得配 LD_LIBRARY_PATH 才找得到。也就是说 pandas 和 sympy(纯 Python + numpy)大概能一次成,matplotlib/sklearn 可能要反复调几轮。而 mount -u -o rw 那条是一步到位。

建议顺序:先试 sudo mount -u -o rw /usr,一句话,可逆,不中断服务。真被拒了(把报错发我),我们再走 fetch+解包这条,我来改 ci.yml 配 PYTHONPATH/LD_LIBRARY_PATH。

文心认为

这种做法‌不合理‌,且存在极高的生产环境风险。

虽然从纯技术角度看,mount -u -o rw /usr 确实比 umount 可行(因为它只是修改挂载标志位而非卸载文件系统),且 pkg fetch + 手工解包 能绕过写入限制,但这两个方案都违背了系统运维的核心安全原则,尤其是针对一台正在运行 CI 任务且承载多个 Jail 的宿主机。

以下是详细的风险评估与更优替代方案:

一、为什么方案 A (mount -u -o rw /usr) 极不合理?
破坏系统完整性保护(Immutable Base)‌
FreeBSD 将 /usr 设为只读是核心安全特性,旨在防止恶意软件或误操作篡改系统二进制文件和库。临时将其改为可写,即使时间很短,也打开了一个巨大的攻击面。如果在此期间 CI 进程被劫持或出现 bug,可能导致系统文件被恶意修改或损坏。

ABI 不匹配的静默崩溃风险‌
你明确提到需要使用 IGNORE_OSVERSION=yes 强制安装为 FreeBSD 14.4 编译的包到 14.3-p7 系统上。

科学计算库的特殊性‌:numpy, scipy, matplotlib, sklearn 严重依赖底层 C/Fortran 库(如 BLAS, LAPACK, libfreetype, libpng)。FreeBSD 的 minor 版本升级(14.3 -> 14.4)通常伴随 libc 或内核 ABI 的微调。
后果‌:强制混用不同版本的二进制包,极大概率导致‌段错误(Segmentation Fault)‌、‌符号未定义(Undefined Symbol)‌或‌静默的数据计算错误‌。这种错误在 CI 中可能表现为间歇性失败,极难排查,且会污染宿主环境,影响其他 Jail 的稳定性。
运维合规性与回滚困难‌
在生产/半生产环境中手动绕过安全策略安装非官方源包,违反了最小权限和完整性原则。一旦出现问题,回滚不仅仅是改回 ro,还可能需要清理已写入的动态链接库和 Python 扩展模块,操作复杂且易残留。

二、为什么方案 C (pkg fetch + 手工解包) 是下策?
依赖地狱(Dependency Hell)‌
正如你所预见,matplotlib 和 sklearn 依赖大量系统级共享库(.so 文件)。手工解包只能解决 Python 层面的导入问题,无法自动处理系统库的依赖关系。

你需要手动提取并配置 LD_LIBRARY_PATH 指向 /var/tmp/pylibs/usr/local/lib。
如果这些库又依赖其他系统库(如 libgfortran, libopenblas),而宿主上的版本不兼容,程序依然会崩溃。
调试过程极其繁琐,且每次更新库版本都需要重新执行这一复杂流程。
维护成本极高‌
这不是一个可持续的 CI 解决方案。每次 Python 版本升级或库版本更新,都需要重新手动处理依赖树,极易出错。

三、真正合理的解决方案(推荐 B 的变体)
既然问题的根源是‌宿主系统版本与 pkg 源不匹配‌以及‌文件系统只读‌,正确的做法是从基础设施层面解决,而不是在应用层打补丁。

方案 1:升级宿主系统(最推荐)
操作‌:将宿主 FreeBSD 从 14.3-p7 升级到 14.4-RELEASE。
优点‌:
pkg 源与系统版本完全对齐,无需 IGNORE_OSVERSION。
可以直接使用 pkg install 安装所有科学计算包,依赖关系自动处理。
系统安全性得到保障,无需修改挂载选项。
执行‌:由管理员执行 freebsd-update upgrade -r 14.4-RELEASE,重启后验证。
方案 2:使用独立的可写环境(如果无法升级宿主)
操作‌:不要试图在宿主 /usr/local 安装包。而是创建一个独立的、可写的目录结构,或使用容器化技术。
方法 A(ZFS Jail/Container)‌:如果可能,将 CI 任务迁移到一个独立的 Jail 或容器中,该环境拥有自己的可写 /usr/local,且可以独立升级系统版本而不影响宿主。
方法 B(Conda/Miniforge)‌:在可写目录(如 /var/db/act_runner/workspace)中安装 Miniforge 或 Conda。Conda 包管理器自带大部分科学计算库的二进制依赖(包括 BLAS/LAPACK),不依赖宿主系统的 /usr/local 库。
bash
# 在 CI 脚本中
curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-FreeBSD-x86_64.sh
bash Miniforge3-FreeBSD-x86_64.sh -b -p /var/db/act_runner/workspace/miniforge
source /var/db/act_runner/workspace/miniforge/bin/activate
conda install numpy pandas matplotlib scikit-learn sympy
优点‌:完全隔离,不触碰宿主 /usr,无 ABI 风险,依赖自包含。
四、结论
不要执行 mount -u -o rw /usr + IGNORE_OSVERSION=yes。‌ 这是为了短期便利而牺牲长期稳定性和安全性的危险操作。

建议行动:‌

首选‌:联系管理员升级宿主 FreeBSD 到 14.4。
次选‌:在 CI 中使用 ‌Miniforge/Conda‌ 安装科学计算栈。这能完美避开宿主系统库依赖和只读文件系统的问题,且是数据科学领域的标准实践。
请向管理员传达:‌“为了保障宿主稳定性和测试可靠性,建议升级系统或采用 Conda 隔离环境,而非强行修改宿主挂载选项和 ABI 兼容性。”

最后的选择

让AI尝试了多次,好像最后都要umount /usr …..然后设为读写….

我实在不敢去做.

另外一个办法大约就是FreeBSD系统升级,这个风险也比较大,很多软件升级之后都需要重装.

所以最终的决定就是维持现状,先不管了.

赞(0)
未经允许不得转载:171主机测评 » 碰到问题了:卡点仍是 /usr 只读挂载 + quarterly 包 userland 1404000 vs 本机 1403000 @FreeBSD
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址