我的Docker容器(ubuntu:18.04
)中有一个VPN客户端。
客户端必须执行以下操作:
mv /etc/resolv.conf /etc/resolv.conf.orig
然后,客户端应使用其DNS服务器创建新的
/etc/resolv.conf
。但是,移动失败并出现错误:mv: cannot move '/etc/resolv.conf' to '/etc/resolv.conf.orig': Device or resource busy
这个可以解决吗?谢谢你提前。
附注:我无法更改VPN客户端代码。
最佳答案
在Docker容器中,/etc/resolv.conf
文件不是普通的常规文件。 Docker以一种特殊的方式对其进行管理:容器引擎将特定于容器的配置写入容器外部的文件中,并将其绑定(bind)安装到容器内部的/etc/resolv.conf
中。
当您的VPN客户端运行mv /etc/resolv.conf /etc/resolv.conf.orig
时,事情归结为rename(2)
syscall(或来自该家族的类似调用),并且根据此syscall的联机帮助页,由于多种原因(包括当出现以下情况时,会返回EBUSY
(Device or resource busy
)错误)原始文件是一个安装点:
尽管有种说法是不能保证在这种情况下会产生该错误,但似乎总是会向绑定(bind)安装目标触发该错误(我想这可能会发生here):
$ touch sourcefile destfile
$ sudo mount --bind sourcefile destfile
$ mv destfile anotherfile
mv: cannot move 'destfile' to 'anotherfile': Device or resource busy
因此,类似地,您不能在容器内移动
/etc/resolv.conf
,因为它是绑定(bind)安装,并且没有直接的解决方案。鉴于
/etc/resolv.conf
的绑定(bind)安装是读写安装,而不是只读安装,仍然可以覆盖此文件:$ mount | grep resolv.conf
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)
因此,可能的解决方法是尝试将此文件复制到
.orig
备份,然后重写原始文件,而不是重命名原始文件然后重新创建。不幸的是,这不符合您的限制(
I can 't change the VPN client code.
),所以我敢打赌,您在这里很不幸。