lsof usage and complete file deletion and recovery

Introduction to lsof
lsof (list open files) is a tool to list open files on the current system. In the linux environment, everything exists in the form of files, through which you can access not only regular data, but also network connections and hardware. Therefore, such as Transmission Control Protocol (TCP) and User Datagram Protocol (UDP) sockets, the system allocates a file descriptor for the application in the background, no matter what the nature of the file is, the file descriptor is for the application. Interaction with the underlying operating system provides a common interface. Because the list of descriptors for files opened by an application provides a lot of information about the application itself, being able to view this list with the lsof tool can be helpful for system monitoring and troubleshooting.
lsof use
 
lsof output information meaning
Enter lsof under the terminal to display the files opened by the system. Because lsof needs to access the core memory and various files, it must be run as the root user to fully exert its functions.
COMMAND    PID      USER   FD      TYPE     DEVICE     SIZE       NODE      NAME
init       1         root  cwd      DIR       3,3       1024       2         /
init       1         root  rtd      DIR       3,3       1024       2         /
init       1         root  txt      REG       3,3       38432      1763452  /sbin/init
init       1         root  mem      REG       3,3       106114     1091620  /lib/libdl-2.6.so
init       1         root  mem      REG       3,3       7560696    1091614  /lib/libc-2.6.so
init       1         root  mem      REG       3,3       79460      1091669  /lib/libselinux.so.1
init       1         root  mem      REG       3,3       223280     1091668  /lib/libsepol.so.1
init       1         root  mem      REG       3,3       564136     1091607  /lib/ld-2.6.so
init       1         root  10u      FIFO      0,15                  1309     /dev/initctl
Displays one open file per line. If no condition is specified, it will display all files opened by all processes by default. The meaning of lsof outputting each column information is as follows:
COMMAND: the name of the process
PID: Process identifier
USER: process owner
FD: file descriptor, the application identifies the file by the file descriptor. Such as cwd, txt, etc.
TYPE: file type, such as DIR, REG, etc.
DEVICE: Specifies the name of the disk
SIZE: the size of the file
NODE: inode (identification of the file on disk)
NAME: The exact name of the open file
where the file descriptor cwd value in the FD column represents the application's current working directory, which is the directory from which the application was started, unless it itself makes changes to this directory.
A file of type txt is program code, such as the application binary itself or a shared library, such as the /sbin/init program shown in the list above. The second value indicates the application
The program's file descriptor, which is an integer returned when the file was opened. The last line of the file /dev/initctl above has a file descriptor of 10. u means that
The file is opened in read/write mode, not read-only® or write-only (w) mode. There is also a capital W to indicate that the application has write access to the entire file
Lock. This file descriptor is used to ensure that only one instance of the application can be opened at a time. Each application is initially opened with three file descriptors, from 0 to 2,
Represent standard input, output, and error streams, respectively. So the FD of most files opened by applications starts at 3.
Compared with the FD column, the Type column is more intuitive. Files and directories are called REG and DIR, respectively. CHR and BLK, respectively, represent character and block devices;
Or UNIX, FIFO, and IPv4, for UNIX domain sockets, first-in-first-out (FIFO) queues, and Internet Protocol (IP) sockets, respectively.
lsof common parameters
A common use of lsof is to find the name and number of files opened by an application. Can be used to find out where a particular application is logging data, or is tracking down a problem.
For example, linux limits the number of files a process can open. Usually this value is large so there is no problem, and the application can request a larger value if needed (until some
upper limit). If you suspect that your application is running out of file descriptors, you can use lsof to count the number of open files to verify. The lsof syntax format is:
lsof [options] filename
List of commonly used parameters:
lsof filename displays all processes that have the specified file open
lsof -a indicates that both parameters must be satisfied before displaying the result
lsof -c string Displays all open files of the process that contains the specified character in the COMMAND column
lsof -u username displays the files opened by the user process
lsof -g gid displays the process status of the belonging gid
lsof +d /DIR/ Displays the files opened by the process in the directory
lsof +D /DIR/ Same as above, but it will search all directories under the directory, which takes a relatively long time
lsof -d FD show the process with the specified file descriptor
lsof -n does not convert IP to hostname, the default is not to add the -n parameter
lsof -i is used to display eligible processes
lsof -i[46] [protocol][@hostname|hostaddr][:service|port]
            46 --> IPv4 or IPv6
            protocol --> TCP or UDP
            hostname --> Internet host name
            hostaddr --> IPv4 address
            service --> service name in /etc/service (can be more than one)
            port --> port number (can be more than one)
For example: See what port 22 is running now
# lsof -i :22
COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
sshd    1409 root    3u  IPv6   5678       TCP *:ssh (LISTEN)
View files of file type txt opened by the root user process:
# lsof -a -u root -d txt
COMMAND    PID USER  FD      TYPE DEVICE    SIZE    NODE NAME
init       1    root txt       REG    3,3   38432 1763452 /sbin/init
mingetty  1632 root txt       REG    3,3   14366 1763337 /sbin/mingetty
mingetty  1633 root txt       REG    3,3   14366 1763337 /sbin/mingetty
mingetty  1634 root txt       REG    3,3   14366 1763337 /sbin/mingetty
mingetty  1635 root txt       REG    3,3   14366 1763337 /sbin/mingetty
mingetty  1636 root txt       REG    3,3   14366 1763337 /sbin/mingetty
mingetty  1637 root txt       REG    3,3   14366 1763337 /sbin/mingetty
kdm        1638 root txt       REG    3,3  132548 1428194 /usr/bin/kdm
X          1670 root txt       REG    3,3 1716396 1428336 /usr/bin/Xorg
kdm        1671 root txt       REG    3,3  132548 1428194 /usr/bin/kdm
startkde  2427 root txt       REG    3,3  645408 1544195 /bin/bash
... ...  
lsof使用实例
 
一、查找谁在使用文件系统
在卸载文件系统时,如果该文件系统中有任何打开的文件,操作通常将会失败。那么通过lsof可以找出那些进程在使用当前要卸载的文件系统,如下: 
# lsof  /GTES11/
COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
bash    4208 root  cwd    DIR    3,1 4096    2 /GTES11/
vim     4230 root  cwd    DIR    3,1 4096    2 /GTES11/
在这个示例中,用户root正在其/GTES11目录中进行一些操作。一个 bash是实例正在运行,并且它当前的目录为/GTES11,另一个则显示的是vim正在编辑/GTES11下的文件。要成功地卸载/GTES11,应该在通知用户以确保情况正常之后,中止这些进程。 这个示例说明了应用程序的当前工作目录非常重要,因为它仍保持着文件资源,并且可以防止文件系统被卸载。这就是为什么大部分守护进程(后台进程)将它们的目录更改为根目录、或服务特定的目录(如 sendmail 示例中的 /var/spool/mqueue)的原因,以避免该守护进程阻止卸载不相关的文件系统。 
二、恢复删除的文件
当Linux计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧日志时,意外地删除了数据库的活动事务日志。有时可以通过lsof来恢复这些文件。 
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。 
在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与 lsof 相关的信息都存储于以进程的 PID 命名的目录中,即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。 
  
当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容。 假如由于误操作将/var/log/messages文件删除掉了,那么这时要将/var/log/messages文件恢复的方法如下: 
首先使用lsof来查看当前是否有进程打开/var/logmessages文件,如下: 
# lsof |grep /var/log/messages
syslogd   1283      root    2w      REG        3,3  5381017    1773647 /var/log/messages (deleted)
从上面的信息可以看到 PID 1283(syslogd)打开文件的文件描述符为 2。同时还可以看到/var/log/messages已经标记被删除了。因此我们可以在 /proc/1283/fd/2 (fd下的每个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,如下: 
# head -n 10 /proc/1283/fd/2
Aug  4 13:50:15 holmes86 syslogd 1.4.1: restart.
Aug  4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started.
Aug  4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 ([email protected]) (gcc version 4.2.0) #1 SMP Wed Jul 18 11:18:32 EDT 2007
Aug  4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map:
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved)
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable)
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved)
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved)
Aug  4 13:50:15 holmes86 kernel:  BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved)
从上面的信息可以看出,查看 /proc/8663/fd/15 就可以得到所要恢复的数据。如果可以通过文件描述符查看相应的数据,那么就可以使用 I/O 重定向将其复制到文件中,如: 
cat /proc/1283/fd/2 > /var/log/messages 
对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。 


本文转自:http://blog.csdn.net/guoguo1980/article/details/2324454

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326641086&siteId=291194637