给定文件系统上的文件由其索引节点 aka inode引用。只要有对这个inode的引用,无论是在磁盘上(链接为文件名,可以多次存在)还是“在内存中”(打开文件描述符,也就是fd,挂载点,mmaped ......)文件和它的数据保留在磁盘上。当没有更多的引用时,它会被真正删除并回收空间。当磁盘引用变为0时,即使仍然存在“内存中”引用,也无法使用新名称重新链接它,因为用户没有内核API,例如可以链接由其fd引用的inode或者inode的值本身,它是唯一可用的文件名(除非使用适当的文件系统的黑暗和危险的魔法:debugfs ln
)。
Linux内核仍提供一些使用/proc
伪文件系统访问此文件的工具。每个打开的文件都显示为指向文件的符号链接。该文件的名称是化妆品信息(以及可能是错的当文件是未链接),但文件本身是被视为在实际的文件,由内核所看到。/proc/PID/fd/
因此,对于这种情况,只要VM正在运行,用作VM的磁盘后端的文件仍然存在,但无法重新链接到磁盘上。可以轻松完成的是使用适当的命令复制它,例如:
cp --sparse=always /proc/PID/fd/12 > backup
。
由于VM正在运行,因此执行此操作可能会产生不一致的结果:文件系统(文件内部)可能在复制期间发生更改,并且可能会变得不一致和损坏。因此,要么在虚拟机管理程序允许的情况下冻结虚拟机,并在冻结时不关闭虚拟机的磁盘文件,要么添加对无名文件的新引用并停止虚拟机。如果您不想冒任何风险,请在冻结之前添加参考。任何读取文件并且持续时间足够长的命令都可以。例如:
$ sleep 99999 < /proc/PID/fd/12 &
[1] 12087
您现在应该验证/proc/12087/fd/0
引用相同的... (deleted)
文件。
VM现在可以被冻结甚至停止(但是之后将无法再次启动)。由于文件系统上没有更多活动,因此备份应该是一致的(如果简单冻结,则使用文件系统日志恢复)。如果VM的磁盘文件是“懒惰”配置并且大部分为空,则使用cp
with选项--sparse=always
似乎是一个不错的选择,以减少占用空间。