我错误地删除了一个 lxc 图像文件。容器仍在运行,因此在我停止容器之前该文件尚未实际删除。我想避免停止容器,因为它非常敏感。
我尝试使用以下命令查找已删除的文件:
for i in $(ls /proc/|grep '^[0-9]*$'); do ls -l /proc/$i/fd|grep delete; done
但这找不到我的循环设备。与简单的一样lsof | vm-
如果我在另一个未删除的图像上运行 lsof,它不会向我显示任何使用它的进程:lsof /var/lib/vz/images/100/vm-100-disk-0.raw
。可能是因为它是由内核而不是进程打开的。
正如评论中所建议的:
# losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO
/dev/loop1 0 0 1 0 /var/lib/vz/images/200/vm-200-disk-0.raw (deleted) 0
/dev/loop0 0 0 1 0 /var/lib/vz/images/100/vm-100-disk-0.raw 0
我试过:
debugfs /dev/mapper/pve-data
debugfs: cd images/200
debugfs: lsdel
Inode Owner Mode Size Blocks Time deleted
0 deleted inodes found.
我想那是因为它还没有被删除。让它被删除并希望它出现在这里并且不会被损坏有点冒险(它> 300Gb)
在容器内,mount
给出:
/var/lib/vz/images/200/vm-200-disk-0.raw (deleted) on / type ext4 (rw,relatime,data=ordered)
除了转储整个文件系统并完全重新创建容器之外,还有什么解决方案吗? (另外,主机驱动器几乎已满,我现在没有足够的空间来在它旁边创建第二个容器。我担心缩小存储空间实际上会导致实际删除。:(
答案1
[不是完整的答案,但太长,无法发表评论]
LOOP_GET_STATUS
您可以使用或ioctl找到循环设备(可能已删除)的后备文件的索引节点LOOP_GET_STATUS64
:它是和结构.lo_inode
的字段。loop_info
loop_info64
由于我无法找到任何公开该信息的命令行实用程序,因此这里有 perl one-liner 应该可以做到这一点:
perl -le 'ioctl STDIN, 0x4C05, $s = pack "a512" or die "ioctl: $!"; print unpack "x[Q]Q", $s' </dev/loop1
1179684
更多信息请参见loop(4)
联机帮助页和文件/usr/include/linux/loop.h
。
但我不知道是否有任何安全的方法可以通过其 inode 恢复已删除的文件:我不认为您可以debugfs(8)
在已安装的实时文件系统上使用而不损坏它而无法修复,并且有决不创建指向已删除文件的链接。
我能想到的唯一安全的方法是在整个循环设备/分区仍然存在时复制它:
cp --sparse=always /dev/loop1 /path/where/to/save/it
答案2
只要容器正在运行,就不应该从硬盘中删除该文件。
您可以找到 inodelsof
并可能恢复文件,debugfs
如 Andrew Gallagher 的答案中所述这个问题。
如果您可以将外部磁盘安装到服务器,您可以尝试接受的答案并将文件复制到那里。