web-dev-qa-db-fra.com

Comment nettoyer le dossier tmp en toute sécurité sous Linux

J'utilise RAM pour mon tmpfs/tmp, 2 Go, pour être exact. Normalement, cela suffit, mais parfois, les processus créent des fichiers et ne parviennent pas à se nettoyer par eux-mêmes. Cela peut arriver s'ils se plantent. Je dois supprimer ces fichiers tmp orphelins, sinon les processus futurs manqueront d’espace sur/tmp.

Comment puis-je en toute sécurité ramasser des ordures/tmp? Certaines personnes le font en vérifiant l'horodatage de la dernière modification, mais cette approche est dangereuse car des processus de longue durée peuvent nécessiter encore ces fichiers. Une approche plus sûre consiste à combiner la dernière condition d'horodatage de modification avec la condition qu'aucun processus ne dispose d'un descripteur de fichier pour le fichier. Existe-t-il un programme/script/etc qui incarne cette approche ou une autre approche également sûre?

Incidemment, Linux/Unix autorise-t-il un mode d'ouverture de fichier avec création dans lequel le fichier créé est supprimé à la fin du processus de création, même s'il s'agit d'un crash?

13
Syncopated

Vous voudrez peut-être essayer quelque chose comme ça:

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

find est utilisé pour trouver les fichiers qui correspondent à certains critères.

  • -mtime +7 sélectionne uniquement les fichiers de plus de 7 jours (vous pouvez utiliser toute autre valeur)
  • -exec fuser -s {} ';' appelle l'unité de fusion en mode silencieux pour chaque fichier correspondant aux critères d'ancienneté. L'unité de fusion renvoie 0 (= vrai) pour chaque fichier auquel on a accédé en ce moment et 1 (= faux) pour les fichiers non accédés. Comme nous ne nous intéressons qu'aux non-accédés, nous mettons un -not devant ce -exec
  • -exec echo {} ';' imprime simplement tous les noms de fichiers correspondant aux critères. vous voudrez peut-être utiliser -exec rm {} ';' à la place ici, mais comme cela peut supprimer certains fichiers encore en usage, je pense qu'il est plus sûr de faire un simple écho en premier.
  • modifier: Vous voudrez peut-être ajouter quelque chose comme -name 'foo*.bar' ou -uid 123 pour limiter les effets du nettoyage à des modèles de fichier ou à des ID utilisateur spécifiques afin d'éviter des effets accidentels.

Jusqu'au dernier point: considérez qu'il peut y avoir des fichiers qui ne sont écrits qu'une fois (par exemple au démarrage du système) mais lus fréquemment (par exemple tout cookie X-session). Par conséquent, je recommande d’ajouter des vérifications de noms pour n’affecter que les fichiers créés par vos programmes défectueux.

edit2: Pour répondre à votre dernière question: un fichier ne sera pas supprimé du disque tant qu'aucun processus ne disposera d'un descripteur ouvert (du moins pour les systèmes de fichiers natifs linux ). Le problème est que l'entrée de répertoire est supprimée immédiatement, ce qui signifie qu'à partir du moment où vous supprimez le fichier, aucun nouveau processus ne peut plus l'ouvrir (car aucun nom de fichier n'y est associé).

Pour plus de détails, voir: https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Mais si je voulais automatiser l’ensemble du processus?

Comme je l'ai dit, il est possible que certains fichiers soient écrits une fois, puis lus de temps à autre (p. Ex. Cookies de session X, fichiers PID, etc.). Celles-ci ne seront pas exclues par ce petit script de suppression (raison pour laquelle vous voudrez peut-être effectuer un test avec echo avant de supprimer réellement des fichiers).

Une façon de mettre en œuvre une solution sûre consiste à utiliser atime.
atime enregistre l'heure du dernier accès à chaque fichier. Mais cette option de système de fichiers est souvent désactivée car elle a un impact non négligeable sur les performances (selon ce blog quelque part dans la région de 20 à 30%). Il y a relatime, mais celui-ci n'écrit l'heure d'accès que si mtime a changé, donc celui-ci ne nous aidera pas.

Si vous souhaitez utiliser atime, nous vous recommandons d’utiliser /tmp sur une partition séparée (idéalement un disque mémoire virtuel) pour que l’impact sur les performances de l’ensemble du système ne soit pas trop important.

Une fois que atime est activé, tout ce que vous avez à faire est de remplacer le paramètre -mtime dans la ligne de commande ci-dessus par -atime.
Vous pourrez peut-être supprimer le -not -exec fuser -s {} ';', mais je le garderais juste pour être sûr (au cas où les applications maintiendraient les fichiers ouverts pendant une longue période).

Mais n'oubliez pas de tester la commande avec echo avant de supprimer les éléments dont votre système a encore besoin!

14
mreithub

Ne roulez pas les vôtres.

Debian/Ubuntu a tmpreaper, il est probablement disponible aussi dans d’autres distributions.

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

Sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
3
Gringo Suave

En ce qui concerne la dernière partie de votre question:

Bien que je ne pense pas qu’il existe un mode d’ouverture/création "supprimer-si-je-meurs", un processus peut supprimer en toute sécurité un fichier directement après sa création, tant qu’il conserve un descripteur ouvert. Le noyau conservera alors le fichier sur le disque et, dès que le dernier processus ayant ouvert le fichier sera fermé (que ce soit par plantage ou normalement), l’espace occupé par le fichier sera libéré.

Pour résoudre le problème de manière générale, certains processus ne nettoient parfois pas/tmp, je vous conseillerais donc de consulter les espaces de noms de montage, décrits par exemple ici ou ici . Si le processus en question est un démon système, systemd et sa fonctionnalité native permettant d'autoriser les systèmes de fichiers privés/tmp peuvent présenter un intérêt.

2
Claudius

Je suis d'accord avec ce qui précède, à ajouter cependant- J'exécute toujours lsof +L1 | grep tmp et je tue ou redémarre les processus conservant des fichiers tmp "supprimés": EXEMPLE-

# 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)
0
SeaPhor

pour une interface graphique, essayez ceci; http://bleachbit.sourceforge.net/

nettoie et gommage. mode de prévisualisation.

0
wuxmedia

Vous pouvez juste faire rm -rf /tmp/* et espérer que rien ne casse ...

0
Solomon Ucko

Obtenez une liste de fichiers plus anciens, excluez les fichiers ouverts par n'importe quel élément de cette liste:

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

lsof -n +D /tmp: recherche les fichiers ouverts dans/tmp
awk 'NR>1 {print $9}': affiche uniquement la neuvième colonne de la sortie lsof, à l'exclusion des en-têtes
tr \\n \|: remplace new-line par bar (OR in egrep)
egrep -v "foo|moo|bar": lignes d'impression ne contenant PAS foo ou moo ou bar