Comment trouver le pid du processus qui a supprimé un fichier?

13

Je travaille sur un projet lié à la migration des VM. Parfois, l'image VM disparaît et je veux juste savoir qui est le coupable. J'ai essayé Strace sur des processus suspects, mais en vain.

Mohammad
la source
J'espérais trouver un moyen de tracer les appels système de dissociation sur chaque processus au lieu d'un seul, mais je suppose qu'il n'y a pas de moyen facile de le faire ...
Mohammad

Réponses:

1

Vous pouvez trouver le PID d'un processus, qui a un fichier ouvert à l'aide lsof.

Une fois le fichier fermé et supprimé, vous ne pouvez pas obtenir ces informations.

BTW. Gardez à l'esprit que la suppression d'un fichier s'effectue sur le répertoire dans lequel il se trouve, et non sur un fichier lui-même.

vartec
la source
Malheureusement, il n'est pas nécessaire d'ouvrir un fichier pour le supprimer. Au moins, par exemple, la sortie "strace rm some-file" ne montre pas que la commande rm ouvre d'abord le fichier puis le supprime. Je suppose donc que lsof n'est pas utile.
Mohammad
Lire la dernière phrase de ma réponse
vartec
1

Permettez-moi de suggérer une alternative avec sysdig car les réponses ci-dessus vieillissent. Permet d'afficher le pidet namedes processus qui suppriment le fichier /tmp/test. Nous créons d'abord le fichier avec touch /tmp/test. Ensuite, nous commençons sysdigavec le filtre suivant:

$ 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)nécessite un orfiltre si le chemin (par exemple evt.arg.name) peut être relatif . Pour gérer à la fois unlink(quels appels unlink(2)) et rm(quels appels unlinkat(2)dans sa version GNU), le filtre doit correspondre aux deux appels système.

sysdigdevrait être en cours d'exécution lorsqu'un processus supprime le fichier. Ensuite, lorsque nous exécutons de telles commandes:

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

Il affichera une telle sortie:

11380,unlink
11407,rm
11662,rm

Veuillez vous référer au guide de l'utilisateur sysdig pour une explication sur le filtrage et la sortie.

Comme le filtre est assez long, j'ai trouvé pratique d'écrire un burin. Il s'agit d'un script lua associé à une sysdigcommande:

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

N'hésitez pas à la commenter et à l'améliorer. Vous pouvez placer le script lua dans un spy_deletes.luafichier à l'intérieur d'un répertoire et l'exécuter sysdigdans ce répertoire pour rendre le burin disponible. Lors de la frappe, sudo sysdig -clvous le verrez comme:

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

Vous pouvez maintenant l'appeler:

$ sudo sysdig -c spy_deletes /tmp/test

Et dans un autre type de terminal:

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

Il produira:

16025   unlink
16033   unlink
16041   rm
16049   rm

Le unlinkatfiltre mériterait d'être plus précis et de ne correspondre qu'au chemin absolu. Cela nécessiterait de récupérer le fd du répertoire passé à unlinkat(2).

Greg Leclercq
la source
Je n'ai aucune sortie avec votre commande.
AB
Je tapais rm /tmp/testdans un autre terminal. J'ai modifié ma réponse pour la rendre plus claire.
Greg Leclercq