¿Cómo encontrar el pid del proceso que ha eliminado un archivo?
13
Estoy trabajando en un proyecto relacionado con la migración de VM. A veces, la imagen de VM desaparecerá y solo quiero saber quién es el culpable. Traté de seguir procesos sospechosos pero fue en vano.
Tenía la esperanza de encontrar una manera de rastrear la llamada al sistema de desvinculación de todos los procesos en lugar de sólo uno, pero supongo que no hay manera fácil de hacer esto ...
Lamentablemente, no es necesario abrir un archivo para eliminarlo. Al menos, por ejemplo, la salida "strace rm some-file" no muestra que el comando rm abra primero el archivo y luego lo elimine. Entonces supongo que lsof no es útil.
Mohammad
Lea la última oración de mi respuesta
vartec
1
Permítanme sugerir una alternativa con sysdig ya que las respuestas anteriores están envejeciendo. Deje visualizar el pidy namede los procesos que eliminan el archivo /tmp/test. Primero creamos el archivo con touch /tmp/test. Luego comenzamos sysdigcon el siguiente 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)requiere un orfiltro si la ruta (por ejemplo evt.arg.name) puede ser relativa . Para manejar tanto unlink(qué llamadas unlink(2)) como rm(qué llamadas unlinkat(2)en su versión GNU), el filtro debe coincidir con ambas llamadas al sistema.
sysdigdebe ejecutarse cuando un proceso elimina el archivo. Luego, cuando ejecutamos dichos comandos:
$ unlink /tmp/test
$ touch /tmp/test
$ rm /tmp/test
$ cd /tmp; touch test; rm test
Como el filtro es bastante largo, me pareció conveniente escribir un cincel. Es un script lua asociado con un 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
returntrueendfunction 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 ..")")returntrueend
Siéntase libre de comentar y mejorarlo. Puede colocar el script lua en un spy_deletes.luaarchivo dentro de un directorio y ejecutarlo sysdigen este directorio para que el cincel esté disponible. Al escribir sudo sysdig -cllo verá como:
Respuestas:
Finalmente encontré la respuesta aquí .
El demonio de Auditoría de Linux hará el truco.
y entonces
fuente
Puede encontrar el PID de un proceso, que tiene algún archivo abierto usando
lsof
.Una vez que el archivo se cierra y se elimina, no puede obtener esa información.
Por cierto. Tenga en cuenta que eliminar un archivo es una operación en el directorio en el que se encuentra, no en un archivo en sí.
fuente
Permítanme sugerir una alternativa con sysdig ya que las respuestas anteriores están envejeciendo. Deje visualizar el
pid
yname
de los procesos que eliminan el archivo/tmp/test
. Primero creamos el archivo contouch /tmp/test
. Luego comenzamossysdig
con el siguiente filtro:unlinkat(2)
requiere unor
filtro si la ruta (por ejemploevt.arg.name
) puede ser relativa . Para manejar tantounlink
(qué llamadasunlink(2)
) comorm
(qué llamadasunlinkat(2)
en su versión GNU), el filtro debe coincidir con ambas llamadas al sistema.sysdig
debe ejecutarse cuando un proceso elimina el archivo. Luego, cuando ejecutamos dichos comandos:Mostrará tal salida:
Consulte la guía del usuario de sysdig para obtener una explicación sobre el filtrado y la salida.
Como el filtro es bastante largo, me pareció conveniente escribir un cincel. Es un script lua asociado con un
sysdig
comando:Siéntase libre de comentar y mejorarlo. Puede colocar el script lua en un
spy_deletes.lua
archivo dentro de un directorio y ejecutarlosysdig
en este directorio para que el cincel esté disponible. Al escribirsudo sysdig -cl
lo verá como:Ahora puedes llamarlo:
Y en otro tipo de terminal:
Producirá:
El
unlinkat
filtro merecería ser más preciso y solo coincidir con la ruta absoluta. Esto requeriría recuperar el fd del directorio pasadounlinkat(2)
.fuente
rm /tmp/test
en otra terminal. Edité mi respuesta para hacerlo más claro.