[英]"Device or resource busy" when i try move /etc/resolv.conf in ubuntu:18.04. How fix it?
I have a VPN client in my Docker container ( ubuntu:18.04
).我的 Docker 容器中有一个 VPN 客户端( ubuntu:18.04
)。
The client must do the following:客户必须执行以下操作:
mv /etc/resolv.conf /etc/resolv.conf.orig
Then the client should create new /etc/resolv.conf
with their DNS servers.然后客户端应该使用他们的 DNS 服务器创建新的/etc/resolv.conf
。 However, the move fails with an error:但是,移动失败并出现错误:
mv: cannot move '/etc/resolv.conf' to '/etc/resolv.conf.orig': Device or resource busy
Can this be fixed?这可以解决吗? Thank you advance.谢谢你提前。
PS: I can 't change the VPN client code. PS:我无法更改 VPN 客户端代码。
Within the Docker container the /etc/resolv.conf
file is not an ordinary regular file.在 Docker 容器中,/etc/ /etc/resolv.conf
文件不是普通的常规文件。 Docker manages it in a special manner: the container engine writes container-specific configuration into the file outside of the container and bind-mounts it to /etc/resolv.conf
inside the container. Docker 以一种特殊的方式对其进行管理:容器引擎将特定于容器的配置写入容器外部的文件中,并将其绑定挂载到容器内部的/etc/resolv.conf
中。
When your VPN client runs mv /etc/resolv.conf /etc/resolv.conf.orig
, things boil down to the rename(2)
syscall (or similar call from this family), and, according to the manpage for this syscall, EBUSY
( Device or resource busy
) error could be returned by few reasons, including the situation when the original file is a mountpoint:当您的 VPN 客户端运行mv /etc/resolv.conf /etc/resolv.conf.orig
时,事情归结为rename(2)
系统调用(或该系列的类似调用),并且根据此系统调用的手册页, EBUSY
( Device or resource busy
)错误可能由几个原因返回,包括原始文件是挂载点的情况:
EBUSY忙
The rename fails because oldpath or newpath is a directory that is in use by some process (perhaps as current working directory, or as root directory, or because it was open for reading) or is in use by the system ( for example as mount point ), while the system considers this an error.重命名失败,因为 oldpath 或 newpath 是某个进程正在使用的目录(可能作为当前工作目录,或者作为根目录,或者因为它已打开以供读取)或正在被系统使用(例如作为挂载点),而系统认为这是一个错误。 (Note that there is no requirement to return EBUSY in such cases — there is nothing wrong with doing the rename anyway — but it is allowed to return EBUSY if the system cannot otherwise handle such situations.) (请注意,在这种情况下不需要返回 EBUSY ——无论如何进行重命名并没有错——但如果系统无法以其他方式处理这种情况,则允许返回 EBUSY。)
Though there is a remark that the error is not guaranteed to be produced in such circumstances, it seems that it always fires for bind-mount targets (I guess that probably this happens here ):虽然有人说在这种情况下不能保证会产生错误,但它似乎总是针对绑定挂载目标触发(我想这可能发生在这里):
$ touch sourcefile destfile
$ sudo mount --bind sourcefile destfile
$ mv destfile anotherfile
mv: cannot move 'destfile' to 'anotherfile': Device or resource busy
So, similarly, you cannot move /etc/resolv.conf
inside the container, for it is a bind-mount, and there is no straight solution.因此,类似地,您不能在容器内移动/etc/resolv.conf
,因为它是绑定安装,并且没有直接的解决方案。
Given that the bind-mount of /etc/resolv.conf
is a read-write mount, not a read-only one, it is still possible to overwrite this file:鉴于/etc/resolv.conf
的绑定挂载是读写挂载,而不是只读挂载,仍然可以覆盖此文件:
$ mount | grep resolv.conf
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)
So, the possible fix could be to try copying this file to the .orig
backup and then rewriting the original one instead of renaming the original file and then re-creating it.因此,可能的解决方法是尝试将此文件复制到.orig
备份,然后重写原始文件,而不是重命名原始文件然后重新创建它。
Unfortunately, this does not meet your restrictions ( I can 't change the VPN client code.
), so I bet that you are out of luck here.不幸的是,这不符合您的限制( I can 't change the VPN client code.
),所以我敢打赌,您在这里不走运。
Any method that requires moving a file onto /etc/resolv.conf
fails in docker container.任何需要将文件移动到/etc/resolv.conf
的方法在 docker 容器中都会失败。 The workaround is to rewrite the original file instead of moving or renaming a modified version onto it.解决方法是重写原始文件,而不是在其上移动或重命名修改后的版本。
For example, use the following at a bash
prompt:例如,在bash
提示符下使用以下命令:
(rc=$(sed 's/^\(nameserver 192\.168\.\)/# \1/' /etc/resolv.conf)
echo "$rc" > /etc/resolv.conf)
This works by rewriting /etc/resolv.conf
as follows:这可以通过重写/etc/resolv.conf
来实现,如下所示:
/etc/resov.conf
through the stream editor, sed
通过流编辑器sed
读取和修改/etc/resov.conf
的当前内容nameserver 192.168.
此示例中的 sed 脚本用于注释掉以nameserver 192.168.
rc
将更新的内容保存在变量rc
中/etc/resolv.conf
with updated contents in "$rc"
用"$rc"
中的更新内容覆盖原始文件/etc/resolv.conf
The command list is in parentheses to operate in a sub-shell to avoid polluting the current shell's name space with a variable name rc
, just in case it happens to be in use.括号中的命令列表用于在子 shell 中操作,以避免使用变量名rc
污染当前 shell 的名称空间,以防万一它正在使用中。
Note that this command does not require sudo
since it is taking advantage of the super user privileges available by default inside the container.请注意,此命令不需要sudo
,因为它利用了容器内默认可用的超级用户权限。
Note that sed -i
(editing in-place) involves moving the updated file onto the original and will not work.请注意, sed -i
(就地编辑)涉及将更新的文件移动到原始文件上,并且不起作用。
But if the visual editor, vi
, is available in the container, editing and saving /etc/resolv.conf
with vi
works, since vi
modifies the original file directly.但如果可视化编辑器vi
在容器中可用,则使用vi
编辑和保存/etc/resolv.conf
是可行的,因为vi
会直接修改原始文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.