在 Docker 容器内/etc/resolv.conf
文件不是普通的常规文件。 Docker 以一种特殊的方式对其进行管理:容器引擎将容器特定的配置写入容器外部的文件中,并绑定安装 it to /etc/resolv.conf
容器内。
当您的 VPN 客户端运行时mv /etc/resolv.conf /etc/resolv.conf.orig
,事情归结为rename(2)
系统调用(或来自该系列的类似调用),并且根据此系统调用的联机帮助页,EBUSY
(Device or resource busy
) 错误可能由多种原因返回,包括原始文件是挂载点的情况:
EBUSY
重命名失败,因为 oldpath 或 newpath 是某个进程正在使用的目录(可能作为当前工作目录,或作为根目录,或
因为它已开放供阅读)或正在被系统使用(例如作为挂载点),而系统认为这是一个错误。 (请注意,没有
在这种情况下要求返回 EBUSY — 无论如何进行重命名都没有问题 — 但如果系统无法以其他方式处理此类情况,则允许返回 EBUSY。)
虽然有评论说错误是不保证在这种情况下生成,它似乎总是为绑定安装目标触发(我猜这可能会发生here https://github.com/torvalds/linux/blob/63849c8f410717eb2e6662f3953ff674727303e7/fs/namei.c#L4637-L4639):
$ touch sourcefile destfile
$ sudo mount --bind sourcefile destfile
$ mv destfile anotherfile
mv: cannot move 'destfile' to 'anotherfile': Device or resource busy
所以,同样,你不能移动/etc/resolv.conf
在容器内部,因为它是绑定安装,并且没有直接的解决方案。
鉴于绑定安装/etc/resolv.conf
是一种读写挂载,而不是只读挂载,仍然可以覆盖此文件:
$ mount | grep resolv.conf
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)
所以,可能的解决方法是尝试copying这个文件到.orig
备份然后重写原来的而不是renaming原始文件,然后重新创建它。
不幸的是,这不符合您的限制(I can 't change the VPN client code.
),所以我敢打赌你在这里运气不好。