Como encontrar o pid do processo que excluiu um arquivo?


13

Estou trabalhando em um projeto relacionado à migração de VM. Às vezes, a imagem da VM desaparece e eu só quero saber quem é o culpado. Tentei rastrear processos suspeitos, mas sem sucesso.


Eu estava esperando para encontrar uma maneira de rastrear chamada de sistema unlink em cada processo em vez de apenas um, mas eu acho que não há nenhuma maneira fácil de fazer isso ...
Mohammad

Respostas:



1

Você pode descobrir o PID de um processo, que possui algum arquivo aberto usando lsof.

Depois que o arquivo é fechado e excluído, você não pode obter essas informações.

Entre. Lembre-se de que a exclusão de um arquivo é uma operação no diretório em que está, não no próprio arquivo.


Infelizmente, não há necessidade de abrir um arquivo para excluí-lo. Pelo menos, por exemplo, a saída "strace rm some-file" não mostra que o comando rm primeiro abre o arquivo e depois o exclui. Então eu acho que lsof não é útil.
Mohammad

Leia a última frase da minha resposta
vartec 15/06

1

Deixe-me sugerir uma alternativa com o sysdig, pois as respostas acima estão envelhecendo. Vamos exibir o pide namedos processos que excluir o arquivo /tmp/test. Primeiro, criamos o arquivo com touch /tmp/test. Começamos sysdigcom o seguinte filtro:

$ 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)requer um orfiltro se o caminho (por exemplo evt.arg.name) puder ser relativo . Para lidar com unlink(que chamadas unlink(2)) e rm(que chamadas unlinkat(2)em sua versão GNU), o filtro deve corresponder aos dois syscalls.

sysdigdeve estar em execução quando um processo excluir o arquivo. Então, quando executamos esses comandos:

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

Ele exibirá essa saída:

11380,unlink
11407,rm
11662,rm

Consulte o guia do usuário do sysdig para obter uma explicação sobre filtragem e saída.

Como o filtro é bastante longo, achei conveniente escrever um cinzel. É um script lua associado a um sysdigcomando:

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

Sinta-se livre para comentar e melhorá-lo. Você pode colocar o script lua em um spy_deletes.luaarquivo dentro de um diretório e executá sysdig-lo para tornar o cinzel disponível. Ao digitar, sudo sysdig -clvocê o verá como:

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

Agora você pode chamá-lo:

$ sudo sysdig -c spy_deletes /tmp/test

E em outro tipo de terminal:

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

Ele produzirá:

16025   unlink
16033   unlink
16041   rm
16049   rm

O unlinkatfiltro merece ser mais preciso e corresponder apenas ao caminho absoluto. Isso exigiria recuperar o fd do diretório passado para unlinkat(2).


Não tenho saída com seu comando.
AB

Eu estava digitando rm /tmp/testem outro terminal. Editei minha resposta para torná-la mais clara.
Greg Leclercq
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.