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

14

Yo uso RAM para mi tmpfs / tmp, 2GB, para ser exactos. Normalmente, esto es suficiente, pero a veces, los procesos crean archivos allí y no pueden limpiarse por sí mismos. Esto puede suceder si se estrellan. 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 manera segura? Algunas personas lo hacen comprobando la marca de tiempo de la última modificación, pero este enfoque no es seguro porque puede haber procesos de larga ejecución que todavía necesitan 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 un 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 trata de un bloqueo?

Sincopado
fuente
Compruebe si puede usar tmpfs en lugar de / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Relacionado: askubuntu.com/questions/380238/how-to-clean-tmp
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

15

Es posible que desee probar algo así:

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

find se usa para buscar archivos que coinciden con ciertos criterios.

  • -mtime +7 solo selecciona archivos que tienen 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. El fusor devuelve 0 (= verdadero) para cada archivo al que se ha accedido en este momento y 1 (= falso) para los no accedidos. Como solo estamos interesados ​​en los no accesibles, ponemos un -notfrente a este-exec
  • -exec echo {} ';'solo imprime todos los nombres de archivos que coinciden con los criterios. es posible que desee usarlo -exec rm {} ';'aquí, pero como esto puede eliminar algunos archivos aún en uso, creo que es más seguro hacer primero un eco simple.
  • editar: es posible que desee agregar algo como -name 'foo*.bar'o -uid 123limitar los efectos de la limpieza a patrones de archivo específicos o ID de usuario para evitar efectos accidentales.

Hasta el último punto: tenga en cuenta que puede haber archivos que solo se escriben una vez (por ejemplo, en el arranque del sistema) pero que se leen con frecuencia (por ejemplo, cualquier cookie de sesión X). Por lo tanto, recomiendo agregar algunas comprobaciones de nombre para afectar solo los archivos creados por sus programas defectuosos.

edit2: 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 de inmediato, lo que significa que desde el momento en que elimina el archivo ya no pueden abrirse nuevos procesos (ya que no hay un nombre de archivo adjunto).

Para más detalles, consulte: /programming/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: 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.). Esos no serán excluidos por esta pequeña secuencia de comandos de eliminación (que es la razón por la que es posible que desee hacer una prueba echoantes de eliminar archivos).

Una forma de implementar una solución segura es usarla atime.
atimealmacena la hora a 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ún este blog en algún lugar de la región del 20-30%). Hay relatime, pero ese solo escribe el tiempo de acceso si mtimeha cambiado, por lo que este no nos ayudará.

Si desea usar 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 pueda eliminarlo -not -exec fuser -s {} ';', pero lo mantendría allí solo 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 usando echoantes de terminar eliminando cosas que su sistema todavía necesita!

mreithub
fuente
bonito. ¿Qué pasa con los archivos cerrados por un proceso de larga ejecución mientras no los actualiza? Si se trata de archivos de contexto, podría perder el contexto del proceso (es cierto que no es un proceso muy inteligente; pero es necesario conocer los efectos secundarios esperados de una /tmp/limpieza 'lateral' ).
Nik
Ese es el problema de este enfoque (como estaba señalando en el último párrafo). El mejor enfoque aquí podría ser agregar uid / gid o verificaciones de patrones de archivo (editó la respuesta en consecuencia)
mreithub
¿Debería colocarse esto en un script cron ...?
CMCDragonkai
@CMCDragonkai Por supuesto, puedes poner esto en crontab. Pero como mencioné, puede haber archivos a los que se accede pero no se escriben y, por lo tanto, es posible que este pequeño script no los filtre. Es por eso que es más seguro imprimir primero la lista de archivos afectados y luego decidir si desea eliminarlos o no. Si /tmpestá en una partición separada (por ejemplo, un disco RAM), puede habilitarla atimey usar el -atimeparámetro de find.
mreithub
Estoy planeando hacer esto en un servidor. Por lo tanto, no puedo estar allí para contar todos los archivos en tmp todo el tiempo. ¿Habría algún problema? ¿También pensé que estábamos destinados a usar relatime no atime?
CMCDragonkai
4

No ruedes el tuyo.

Debian / Ubuntu tiene tmpreaper, probablemente también esté disponible en otros discos.

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Gringo Suave
fuente
En el /etc/tmpreaper.confarchivo, si configuro ambos /tmpy /var/tmpcomo directorios de limpieza, ¿puede recomendarme durante mucho tiempo que se TMPREAPER_TIMEelimine el parámetro o el máximo de los archivos tmp? He oído que es mejor mantener una antigüedad más larga para los /var/tmparchivos que los /tmparchivos. Pero si solo se pueden configurar con la misma edad máxima, no tengo idea.
Xiaodong Qi
2

Con respecto a la última parte de su pregunta:

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

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

Claudio
fuente
0

Obtenga una lista de archivos más antiguos que eso, excluya los archivos que están abiertos por algo de esa lista:

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

lsof -n +D /tmp: busca archivos abiertos en / tmp
awk 'NR>1 {print $9}': imprime solo la novena columna de salida de lsof, excluyendo los encabezados
tr \\n \|: reemplaza new-line por bar (O en egrep)
egrep -v "foo|moo|bar": imprime líneas que NO contienen foo o moo o bar

Ярослав Рахматуллин
fuente
0

Sin embargo, estoy de acuerdo con lo anterior, para agregarle: siempre ejecuto lsof +L1 | grep tmpy elimino o reinicio los procesos que retienen los archivos tmp "eliminados": EJEMPLO-

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)
SeaPhor
fuente
2
SU organiza aleatoriamente las publicaciones, por lo que no hay arriba ni abajo. ¿A qué publicación te refieres?
Journeyman Geek
0

Podrías hacerlo rm -rf /tmp/*y esperar que nada se rompa ...

Solomon Ucko
fuente
1
Sugiriendo hacer algo "y esperar que nada se rompa" realmente no responde a los OP "¿hay alguna forma segura de hacerlo? ¿Quizás podría explicar por qué su sugerencia es segura?"
Dijo el
@bertieb Buen punto. Supongo que probablemente sea seguro si no se ejecuta como root, pero ...
Solomon Ucko