Cómo limpiar la carpeta tmp de forma segura en Linux

Cómo limpiar la carpeta tmp de forma segura en Linux

Utilizo RAM para mi tmpfs/tmp, 2 GB, para ser exactos. Normalmente, esto es suficiente, pero a veces los procesos crean archivos allí y no logran limpiarlos por sí solos. Esto puede suceder si chocan. Necesito eliminar estos archivos tmp huérfanos o, de lo contrario, el proceso futuro se quedará sin espacio en /tmp.

¿Cómo puedo recolectar basura /tmp de forma segura? Algunas personas lo hacen comprobando la marca de tiempo de la última modificación, pero este método no es seguro porque puede haber procesos de larga duración que aún necesiten esos archivos. Un enfoque más seguro es combinar la condición de marca de tiempo de la última modificación con la condición de que ningún proceso tenga un identificador de archivo para el archivo. ¿Existe algún programa/script/etc. que incorpore este enfoque o algún otro enfoque que también sea seguro?

Por cierto, ¿Linux/Unix permite un modo de apertura de archivos con creación en el que el archivo creado se elimina cuando finaliza el proceso de creación, incluso si se debe a un bloqueo?

Respuesta1

Quizás quieras probar algo como esto:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

buscar se utiliza para buscar archivos que coincidan con ciertos criterios.

  • -mtime +7solo selecciona archivos que tengan más de 7 días (puede usar cualquier otro valor)
  • -exec fuser -s {} ';'llama al fusor en modo silencioso para cada archivo que coincida con los criterios de antigüedad. fuser devuelve 0 (= verdadero) para cada archivo al que se ha accedido en este momento y 1 (= falso) para los que no se han accedido. Como sólo nos interesan los que no se han accedido, ponemos un -notdelante de esto-exec
  • -exec echo {} ';'simplemente imprime todos los nombres de archivos que coinciden con los criterios. es posible que quieras usarlo -exec rm {} ';'aquí, pero como esto puede eliminar algunos archivos que aún están en uso, creo que es más seguro hacer un eco simple primero.
  • editar:Es posible que desee agregar algo como -name 'foo*.bar'limitar -uid 123los efectos de la limpieza a patrones de archivos específicos o ID de usuario para evitar efectos accidentales.

Hasta el último punto: considere que puede haber archivos que sólo se escriben una vez (por ejemplo, al iniciar el sistema) pero se leen con frecuencia (por ejemplo, cualquier cookie de sesión X). Por lo tanto, recomiendo agregar algunas comprobaciones de nombres para afectar sólo a los archivos creados por sus programas defectuosos.

editar2: A su última pregunta: un archivo no se eliminará del disco hasta que ningún proceso tenga un identificador abierto (al menos para los sistemas de archivos nativos de Linux). El problema es que la entrada del directorio se elimina inmediatamente, lo que significa que desde el momento en que elimina el archivo, ningún proceso nuevo puede abrir el archivo (ya que no tiene ningún nombre de archivo adjunto).

Para más detalles ver: https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

editar3:Pero ¿y si quisiera automatizar todo el proceso?

Como dije, puede haber archivos que se escriben una vez y luego se leen de vez en cuando (por ejemplo, cookies de sesión X, archivos PID, etc.). Estos no serán excluidos por este pequeño script de eliminación (que es la razón por la que quizás quieras hacer una prueba primero echoantes de eliminar archivos).

Una forma de implementar una solución segura es utilizar atime.
atimealmacena la hora en la que se accedió por última vez a cada archivo. Pero esa opción del sistema de archivos a menudo está deshabilitada porque tiene bastante impacto en el rendimiento (segúneste blogen algún lugar en la región del 20-30%). Lo hay relatime, pero ese solo escribe el tiempo de acceso si mtimeha cambiado, por lo que este no nos ayudará.

Si desea utilizar atime, le recomendaría tener /tmpuna partición separada (idealmente un disco RAM) para que el impacto en el rendimiento de todo el sistema no sea demasiado grande.

Una vez atimehabilitado, todo lo que tiene que hacer es reemplazar el -mtimeparámetro en la línea de comando anterior con -atime.
Es posible que puedas eliminar el archivo -not -exec fuser -s {} ';', pero yo lo dejaría allí sólo para estar seguro (en caso de que las aplicaciones mantengan los archivos abiertos durante un largo período de tiempo).

¡Pero tenga en cuenta probar el comando echoantes de terminar eliminando cosas que su sistema aún necesita!

Respuesta2

No hagas el tuyo.

Debian/Ubuntu tiene tmpreaper, probablemente también esté disponible en otras distribuciones.

# tmpreaper - cleans up files in directories based on their age

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 

Respuesta3

Respecto a la última parte de tu pregunta:

Si bien no creo que exista un modo de apertura/creación de 'eliminar esto si-muero', un proceso puede eliminar de forma segura un archivo directamente después de crearlo, siempre y cuando mantenga abierto un identificador de dicho archivo. Luego, el kernel mantendrá el archivo en el disco y tan pronto como salga el último proceso que abrió el archivo (ya sea por falla o normalmente), se liberará el espacio ocupado por el archivo.

Para solucionar el problema general de que algunos procesos a veces no limpian /tmp, sugeriría echar un vistazo a los espacios de nombres de montaje, descritos, por ejemploaquíoaquí. Si el proceso en cuestión es un demonio del sistema,sistemady su característica nativa para permitir sistemas de archivos privados /tmp podría ser de interés.

Respuesta4

Obtenga una lista de archivos anteriores a esa fecha, excluya los archivos que estén abiertos por cualquier cosa de esa lista:

find /tmp -mtime +7 |\
    egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`" 

lsof -n +D /tmp: busque archivos abiertos en /tmp
awk 'NR>1 {print $9}': imprima solo la novena columna de la salida de lsof, excluyendo los encabezados
tr \\n \|: reemplace la nueva línea por barra (O en egrep)
egrep -v "foo|moo|bar": imprima líneas que NO contengan foo o moo o bar

información relacionada