如何找到已删除文件的进程的pid?


13

我正在从事与VM迁移相关的项目。有时VM映像会消失,我只想知道谁是罪魁祸首。我尝试对可疑进程使用strace,但无济于事。


我希望找到一种跟踪每个进程而不是每个进程的取消链接系统调用的方法,但是我想没有简单的方法可以做到这一点……
Mohammad

Answers:



1

您可以找到进程的PID,使用打开了一些文件lsof

关闭并删除文件后,您将无法获取该信息。

顺便说一句。请记住,删除文件是对其所在目录的操作,而不是对文件本身的操作。


不幸的是,无需打开文件即可将其删除。至少例如,“ strace rm some-file”输出未显示rm命令首先打开文件,然后将其删除。因此,我猜lsof没有帮助。
Mohammad

阅读我的回答的最后一句话
vartec

1

让我提出一个替代sysdig如上答案老化。让我们显示pidname删除文件的过程/tmp/test。首先,我们使用创建文件touch /tmp/test。然后,我们从sysdig以下过滤器开始:

$ sudo sysdig -p'%proc.pid,%proc.name' '(evt.type=unlinkat and (evt.arg.name=test or evt.arg.name=/tmp/test)) or (evt.type=unlink and evt.arg.path=/tmp/test)'

unlinkat(2)or如果路径(例如evt.arg.name)可能是相对的,则需要过滤器。要同时处理unlink(调用unlink(2))和rmunlinkat(2)在其GNU版本中调用),过滤器应匹配两个syscall。

sysdig当进程删除文件时,它应该正在运行。然后,当我们执行这样的命令时:

$ unlink /tmp/test
$ touch /tmp/test
$ rm /tmp/test
$ cd /tmp; touch test; rm test

它将显示这样的输出:

11380,unlink
11407,rm
11662,rm

请参考sysdig用户指南以获取有关过滤和输出的说明。

由于过滤器很长,我发现写凿子很方便。这是一个与sysdig命令关联的lua脚本:

description = "displays processes that delete a file"
short_description = "spy file deletion"
category = "files"

args = 
{
    {
        name = "path", 
        description = "the path of the file to monitor", 
        argtype = "string"
    },
}

function on_set_arg(name, val)
    path = val
    return true
end

function on_init()
    local filename = path
    for i in string.gmatch(path, "[^/]+") do
        filename = i
    end
    chisel.set_event_formatter("%proc.pid\t%proc.name")
    chisel.set_filter(
        "(evt.type=unlinkat and (evt.arg.name=" .. path .. " or \
                             evt.arg.name=" .. filename .. ")) or \
     (evt.type=unlink and evt.arg.path=" .. path .. ")")
    return true
end

随时发表评论并加以改进。您可以将lua脚本spy_deletes.lua放在目录中的文件中,然后sysdig在此目录中执行以使凿子可用。键入时,sudo sysdig -cl您将看到:

Category: files
---------------
spy_deletes         spy file deletion

现在您可以调用它:

$ sudo sysdig -c spy_deletes /tmp/test

在另一个终端中输入:

$ touch test; unlink test
$ touch test; unlink /tmp/test
$ touch test; rm test
$ touch test; rm /tmp/test

它将输出:

16025   unlink
16033   unlink
16041   rm
16049   rm

unlinkat过滤器会应得到更准确,只有匹配的绝对路径。这将需要检索传递给的目录的fd unlinkat(2)


我的命令没有输出。
AB

rm /tmp/test在另一个终端输入。我编辑了答案以使其更清楚。
Greg Leclercq
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.