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

14

J'utilise la RAM pour mes tmpfs / tmp, 2 Go, pour être exact. Normalement, cela suffit, mais parfois, les processus créent des fichiers et ne parviennent pas à se nettoyer après eux-mêmes. Cela peut arriver en cas de plantage. J'ai besoin de supprimer ces fichiers tmp orphelins, sinon le processus futur manquera d'espace sur / tmp.

Comment puis-je récupérer les déchets / tmp en toute sécurité? Certaines personnes le font en vérifiant l'horodatage de la dernière modification, mais cette approche n'est pas sûre car il peut y avoir des processus de longue durée qui ont encore besoin de 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 qui est également sûre?

Par ailleurs, 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 plantage?

Syncopé
la source
Vérifiez si vous pouvez utiliser tmpfs au lieu de / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Connexe: askubuntu.com/questions/380238/how-to-clean-tmp
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

15

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 rechercher des fichiers correspondant à certains critères.

  • -mtime +7 sélectionne uniquement les fichiers datant de plus de 7 jours (vous pouvez utiliser toute autre valeur)
  • -exec fuser -s {} ';'appelle fuser en mode silencieux pour chaque fichier correspondant aux critères d'ancienneté. fuser renvoie 0 (= true) pour chaque fichier auquel vous avez accédé en ce moment et 1 (= false) pour ceux qui ne sont pas accessibles. Comme nous ne sommes intéressés que par ceux qui ne sont pas traités, nous mettons un -notdevant ce-exec
  • -exec echo {} ';'imprime simplement tous les noms de fichiers correspondant aux critères. vous voudrez peut-être utiliser à la -exec rm {} ';'place ici, mais comme cela peut supprimer certains fichiers encore en cours d'utilisation, je pense qu'il est plus sûr de faire d'abord un écho simple.
  • modifier: vous souhaiterez peut-être ajouter quelque chose comme -name 'foo*.bar'ou -uid 123limiter les effets du nettoyage à des modèles de fichiers spécifiques ou à des ID utilisateur pour éviter les effets accidentels.

Pour le dernier point: considérez qu'il peut y avoir des fichiers qui ne sont écrits qu'une seule 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 nom pour n'affecter que les fichiers créés par vos programmes défectueux.

edit2: À votre dernière question: Un fichier ne sera pas supprimé du disque tant qu'aucun processus ne sera ouvert (au 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 ouvrir le fichier (car aucun nom de fichier n'est attaché).

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

edit3: Et si je voulais automatiser l'ensemble du processus?

Comme je l'ai dit, il peut y avoir des fichiers qui sont écrits une fois puis lus de temps en temps (par exemple les cookies de session X, les fichiers PID, etc.). Ceux-ci ne seront pas exclus par ce petit script de suppression (c'est la raison pour laquelle vous voudrez peut-être faire un test avec d' echoabord avant de supprimer les fichiers).

Une façon d'implémenter une solution sûre est d'utiliser atime.
atimestocke l'heure de dernier accès à chaque fichier. Mais cette option de système de fichiers est souvent désactivée car elle a un certain impact sur les performances (selon ce blog quelque part dans la région des 20 à 30%). Il y a relatime, mais celui-ci n'écrit que le temps d'accès s'il mtimea changé, donc celui-ci ne nous aidera pas.

Si vous souhaitez utiliser atime, je vous recommande d'avoir /tmpsur une partition séparée (idéalement un ramdisk) afin que l'impact sur les performances sur l'ensemble du système ne soit pas trop important.

Une fois atimeactivé, il vous suffit de remplacer le -mtimeparamètre de 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 garderaient les fichiers ouverts pendant une longue période).

Mais gardez à l'esprit de tester la commande echoavant de supprimer des éléments dont votre système a toujours besoin!

mreithub
la source
agréable. Qu'en est-il des fichiers fermés par un processus de longue durée alors qu'il ne les met pas à jour? S'il s'agit de fichiers de contexte, vous pouvez perdre le contexte du processus (certes, ce n'est pas un processus très intelligent, mais il faut connaître les effets secondaires attendus d'un /tmp/nettoyage «latéral» ).
nik
C'est le problème de cette approche (comme je le soulignais dans le dernier paragraphe). La meilleure approche ici serait afaik d'ajouter des vérifications uid / gid ou de modèle de fichier (édité la réponse en conséquence)
mreithub
Doit-il être placé dans un script cron ...?
CMCDragonkai
@CMCDragonkai Bien sûr, vous pouvez mettre cela dans crontab. Mais comme je l'ai mentionné, il peut y avoir des fichiers accessibles mais non écrits et donc non filtrés par ce petit script. C'est pourquoi il est plus sûr d'imprimer la liste des fichiers concernés en premier, puis de décider vous-même de les supprimer ou non. Si votre /tmpest sur une partition séparée (par exemple un disque virtuel), vous pouvez l'activer atimeet utiliser le -atimeparamètre de find.
mreithub
Je prévois de le faire sur un serveur. Je ne peux donc pas être là pour compter tous les fichiers en tmp tout le temps. Y aurait-il des problèmes? Je pensais aussi que nous étions censés utiliser relatime pas atime?
CMCDragonkai
3

Ne roulez pas le vôtre.

Debian / Ubuntu ont tmpreaper, il est probablement également disponible dans d'autres dists.

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Gringo Suave
la source
Dans le /etc/tmpreaper.conffichier, si je définis les deux /tmpet en /var/tmptant que répertoires de nettoyage, pouvez-vous recommander TMPREAPER_TIMElongtemps de supprimer le paramètre ou le nombre maximal de fichiers tmp? J'ai entendu dire qu'il vaut mieux garder un âge plus long pour les /var/tmpfichiers que pour les /tmpfichiers. Mais s'ils ne peuvent être installés qu'avec le même âge maximum, je n'en ai aucune idée.
Xiaodong Qi
2

Concernant la dernière partie de votre question:

Bien que je ne pense pas qu'il existe un mode d'ouverture / création `` supprimer-ce-si-je-meurs '', un processus peut supprimer un fichier en toute sécurité directement après sa création, tant qu'il garde un descripteur ouvert sur ledit fichier. Le noyau gardera alors le fichier sur le disque et dès que le dernier processus qui avait ouvert le fichier se fermera (que ce soit par plantage ou normalement), l'espace occupé par le fichier sera libéré.

Pour une solution générale au problème que certains processus ne nettoient parfois pas / tmp, je suggère de jeter un œil aux 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 pour autoriser les systèmes de fichiers privés / tmp pourraient être intéressants.

Claudius
la source
0

Obtenez une liste de fichiers plus anciens que so an so, excluez les fichiers ouverts par quoi que ce soit de cette liste:

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

lsof -n +D /tmp: rechercher les fichiers ouverts dans / tmp
awk 'NR>1 {print $9}': imprimer uniquement la neuvième colonne de la sortie lsof, à l'exclusion des en-têtes
tr \\n \|: remplacer la nouvelle ligne par la barre (OU dans egrep)
egrep -v "foo|moo|bar": imprimer les lignes ne contenant pas foo ou moo ou bar

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

Je suis d'accord avec ce qui précède, pour y ajouter cependant- je lance toujours lsof +L1 | grep tmpet je tue ou redémarre les processus qui s'accrochent aux 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)
SeaPhor
la source
2
SU organise au hasard les messages - il n'y a donc pas de dessus ou de dessous. De quel poste parlez-vous?
Journeyman Geek
0

Vous pourriez juste faire rm -rf /tmp/*et espérer que rien ne se brise ...

Solomon Ucko
la source
Suggérer de faire quelque chose "et espérer que rien ne casse" ne répond pas vraiment aux PO "existe-t-il un moyen sûr de le faire. Peut-être pourriez-vous expliquer pourquoi votre suggestion est sûre?
bertieb
@bertieb Bon point. Je suppose que c'est probablement sûr s'il n'est pas exécuté en tant que root, mais ...
Solomon Ucko