Linux运行中文件因误删除后的恢复参考
2013-04-01 15:32:47 阿炯

本站赞助商链接,请多关照。 这里汇集了Linux下的一些文件恢复实例参考,包括在不同一情形与工具下的操作方法。

1、借助lsof恢复已打开的误删除文件

2、Nginx配置信息损毁又无备份时恢复


===============================

1、借助lsof恢复已打开的误删除文件

应用场景:文件正在被使用中,却被其它用户或进程删除掉了,需要对其进行恢复。

先介绍一些文件的基本概念,linux下文件实际上是一个指向inode的链接,inode链接包含了文件的所有属性:比如权限和所有者,数据块地址(文件存储在磁盘的这些数据块中)。当你删除一个文件时,实际删除了指向inode的链接,并没有删除inode的内容,数据依然在磁盘的某个位置。进程可能还在使用,只有当inode的所有链接完全移除时,这些数据块才可以写入新的数据。

proc文件系统可以帮助我们恢复数据,系统上的每个进程在/proc都有一个目录和名字,里面包含了一个fd(文件描述符)子目录(进程需要打开文件的所有链接),如果从文件系统中删除一个文件,此处还有一个inode的引用,即:
/proc/进程号/fd/文件描述符

然后你需要知道打开文件的进程号(pid)和文件描述符(fd),这些都可以通过lsof工具方便获得,lsof的意思是”list open files, 列出(进程)打开的文件”,然后你将可以从/proc复制出需要恢复的数据。

下面介绍在debian6系统上使用lsof恢复误删的文件。
 
首先, 我们需要创建一个文本文件, 删除然后恢复:
$ man lsof | col -b > lsof.man
可以看一下文件内容:
$ less lsof.man

现在按Ctrl+Z(停止进程并放入后台)退出less命令,然后在shell提示符下查看文件属性信息:
$ stat lsof.man
File: "lsof.man"
Size: 116425        Blocks: 240        IO Block: 4096   普通文件
Device: fe01h/65025d    Inode: 7810        Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     hto)   Gid: (    0/    root)
Access: 2013-04-01 15:19:44.000000000 +0800
Modify: 2013-04-01 15:19:44.000000000 +0800
Change: 2013-04-01 15:19:44.000000000 +0800

Ok, 继续下面工作:
$ rm lsof.man
$ ls -l lsof.man
ls: lsof.man: No such file or directory
$ stat lsof.man
stat: cannot stat `lsof.man’: No such file or directory

以上两种操作可以证明'lsof.man'文件被删除了。

注意:此时不要终止仍在使用文件的进程,因为一旦终止,文件将很难恢复。

现在我们开始找回数据,首先用lsof查看一下被删除文件的进程信息:
$ lsof | grep lsof.man
less      3389         hto    4r      REG  254,1   116425   7810 /home/hto/lsof.man (deleted)

第一列是进程的名称(命令名),第二列是进程号(PID),第四列是文件描述符(r意思是普通文件),可以知道3389进程仍有打开文件,文件描述符是4。那我们可以开始从/proc里面复制出数据,当你直接复制时会发现那只是一个指向被删除文件的符号链接而已。
$ ls -l /proc/3389/fd/4
lr-x------ 1 hto root 64  4月  1 15:20 /proc/3389/fd/4 -> /home/hto/lsof.man (deleted)
$ cp -a /proc/3389/fd/4 lsof.man.wrong
$ ls -l lsof.man.wrong
lrwxrwxrwx 1 hto root 28  4月  1 15:20 lsof.man.wrong -> /home/hto/lsof.man (deleted)
$ file lsof.man.wrong
lsof.man.wrong: broken symbolic link to `/home/hto/lsof.man (deleted)'

$ file /proc/3389/fd/4
/proc/3389/fd/4: broken symbolic link to `/home/hto/lsof.man (deleted)'

使用cp复制出数据:
$ cp /proc/3389/fd/4 lsof.man.saved
最后, 确认一下文件:
$ ls -l lsof.man.saved
-rw-r--r-- 1 hto root 116425  4月  1 15:26 lsof.man.saved
$ man lsof | col -b > lsof.man.new
$ cmp lsof.man.saved lsof.man.new

$ diff lsof.man.saved lsof.man.new

它们之间并无差异,说明恢复是有效的。


2、Nginx配置信息损毁又无备份时恢复参考

这里介绍在一个Nginx运行时,在没有备份的情况下,将整个的nginx目录全部删除后如何利用Nginx进程的虚拟内存恢复配置信息。恢复思路是看Nginx进程的内存中有没有存储配置信息,如果有那能不能dump出来。文章 Dump Current Nginx Config 提供了个小脚本 dump.sh,这个脚本需要 GDB: The GNU Project Debugger 工具的支持。

安装gdb之后,找到Nginx master的进程ID,然后执行下面命令即可。

# Set pid of nginx master process here
pid=1239

# generate gdb commands from the process's memory mappings using awk
cat /proc/$pid/maps | awk '$6 !~ "^/" {split ($1,addrs,"-"); print "dump memory mem_" addrs[1] " 0x" addrs[1] " 0x" addrs[2] ;}END{print "quit"}' > gdb-commands

# use gdb with the -x option to dump these memory regions to mem_* files
gdb -p $pid -x gdb-commands

# look for some (any) nginx.conf text
grep worker_connections mem_*
grep server_name mem_*

/proc/$pid/maps 文件包含了当前进程内存映射区域和访问权限信息,下面是部分样例数据。

最后 grep server_name mem_* 命令输出了包含 server_name 的文件。下载文件之后,用 Visual Studio Code(虽为二进制文件,也可以使用notepad++之类的高级文件工具打开,但大部分是乱码)打开,全局检索一下,会有相关一部分配置文件在其中。将配置拷贝出来恢复nginx即可,能将大部分配置找回。


除了关注数据安全之外,对于配置类的信息也要做好备份和版本管理。