Vous lancez umount /mnt/data et Linux répond par le haussement d’épaules immémorial : target is busy. Maintenant vous hésitez entre faire la bonne chose (trouver le détenteur) et faire la chose rapide (rebooter et prétendre que c’était une « maintenance planifiée »).
Ce guide de terrain pour Debian 13 explique comment identifier le processus, le fichier, le répertoire, l’espace de noms ou le consommateur noyau exact qui empêche un démontage, en utilisant lsof, fuser et quelques astuces avec /proc qui fonctionnent quand les outils « amicaux » mentent.
Ce que signifie réellement « device busy » (et ce que ça n’est pas)
Quand umount échoue avec « device busy », le noyau refuse de détacher un montage parce que quelque chose y fait encore référence. Ce « quelque chose » peut être :
- Un processus avec un descripteur de fichier ouvert sous le point de montage.
- Un processus dont le répertoire de travail courant (
cwd) se trouve quelque part dans cet arbre. - Un processus dont le répertoire racine (
chrootou pivot root) est à l’intérieur. - Un bind mount, un overlay ou la propagation de montage qui maintient l’arbre incrusté.
- Un consommateur noyau (swapfile, device loop, cible dm-crypt, état client NFS).
- Un autre namespace de montage (conteneur, service systemd) qui l’utilise encore.
Ce que ce n’est généralement pas : « le périphérique est lent » ou « le système de fichiers est corrompu ». Ceux-ci peuvent provoquer des blocages, erreurs d’E/S ou délais, mais « busy » concerne les références, pas la santé.
Il y a deux modes de douleur distincts :
- « busy » immédiat : le noyau sait qu’il y a des références actives et refuse le démontage propre.
- Démontage bloqué : vous avez lancé
umountet il bloque. C’est souvent des systèmes de fichiers réseau (NFS) ou des E/S bloquées, pas seulement un fichier ouvert.
Pour corriger ça de façon fiable, cessez de deviner et commencez à interroger le noyau : « Qui tient ce montage ? » Le chemin le plus rapide reste lsof et fuser, mais il faut connaître leurs angles morts et comment les contourner.
Plan de diagnostic rapide (premiers/deuxièmes/troisièmes contrôles)
Quand vous êtes d’astreinte, vous n’avez pas de temps pour danser autour de umount. Faites ceci.
1) Premier contrôle : quelqu’un tient-il des fichiers ou le cwd sous ce montage ?
- Exécutez
findmntpour confirmer que vous ciblez bien le bon montage. - Exécutez
fuser -vmpour une liste rapide des PID et types d’accès. - Exécutez
lsof +f -- /mountpointlorsque vous avez besoin des chemins de fichiers et des utilisateurs.
2) Deuxième contrôle : s’agit-il d’une pile de montages / bind / propagation ?
- Recherchez les sous-montages :
findmnt -R /mountpoint. - Recherchez les bind mounts :
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONSet vérifiezbind,rbind,shared. - Si vous démontez le parent alors qu’un enfant est monté, le parent sera « busy » pour une bonne raison.
3) Troisième contrôle : le détenteur est-il hors de votre namespace (conteneurs/systemd) ou côté noyau ?
- Vérifiez les namespaces de conteneurs : regardez
/proc/<pid>/mountinfoetlsns. - Vérifiez les swapfiles et les devices loop :
swapon --show,losetup -a. - Vérifiez l’empilement dm/lvm :
lsblk -o NAME,TYPE,MOUNTPOINTS,PKNAME,dmsetup ls --tree.
Si vous ne retenez qu’une chose : n’utilisez pas umount -l avant d’avoir identifié le détenteur. Lazy unmount est un outil, pas un mode de vie.
Flux principal : lsof → fuser → /proc → espaces de noms
Voici le flux que j’utilise sur les systèmes Debian quand « device busy » survient. Il couvre du « le développeur a laissé un shell dedans » au « le runtime de conteneur a épinglé un bind mount dans un autre namespace ».
Commencez par la vérité du montage : findmnt
La sortie de mount est correcte, mais findmnt est plus structurée et moins trompeuse. Vous voulez : target, source, fstype et options, et voir les sous-montages.
Puis demandez qui tient : fuser et lsof
fuser est brutal et rapide : « ces PID touchent ce montage ». Il peut indiquer si le processus a le cwd là, exécute un binaire depuis là, ou a simplement des fichiers ouverts.
lsof est plus lent mais plus riche : il montre les chemins de fichiers, les numéros de fd, et si le processus tient un fichier supprimé (classique).
Quand les outils ne sont pas d’accord : /proc est la source de vérité
Parfois lsof manque des choses à cause des permissions, des namespaces, ou d’un nombre énorme de fichiers ouverts. Alors vous allez dans /proc et lisez les liens des processus directement (cwd, root, fd), ou la table des montages du noyau (/proc/self/mountinfo).
Enfin : conscience des espaces de noms
Si le montage est détenu à l’intérieur d’un conteneur ou d’un autre namespace de montage, vous pouvez exécuter lsof au niveau hôte et pourtant « ne rien voir ». Utilisez lsns et nsenter pour regarder depuis la perspective du détenteur.
Une vérité sèche : Linux se plaît à laisser deux mondes différents penser que des montages différents existent. Ce n’est pas un bug. C’est un mardi.
Tâches pratiques (commandes, interprétation, décisions)
Voici des tâches réelles que j’exécute en production, à peu près dans l’ordre. Chaque tâche inclut : la commande, ce que signifie la sortie, et la décision suivante.
Task 1: Confirm the exact mount and its source
cr0x@server:~$ findmnt /mnt/data
TARGET SOURCE FSTYPE OPTIONS
/mnt/data /dev/sdb1 ext4 rw,relatime
Ce que cela signifie : Vous démontez /mnt/data, provenant de /dev/sdb1. Si SOURCE est quelque chose comme server:/export (NFS) ou /dev/mapper/vg-lv (LVM), vous savez déjà quels cas particuliers s’appliquent.
Décision : Si ce n’est pas le montage visé (commun avec des slashs finaux ou des montages imbriqués), arrêtez-vous et reciblez. Sinon, continuez.
Task 2: Check for submounts that make the parent “busy”
cr0x@server:~$ findmnt -R /mnt/data
TARGET SOURCE FSTYPE OPTIONS
/mnt/data /dev/sdb1 ext4 rw,relatime
/mnt/data/cache tmpfs tmpfs rw,nosuid,nodev
/mnt/data/containers overlay overlay rw,relatime,lowerdir=...
Ce que cela signifie : Vous ne pouvez pas démonter /mnt/data tant que /mnt/data/cache ou /mnt/data/containers est encore monté. Les montages parents n’évincet pas magiquement les enfants.
Décision : Démontez d’abord les enfants (chemin le plus profond en premier), ou utilisez umount -R avec précaution.
Task 3: Quick “who touches this mount” with fuser
cr0x@server:~$ sudo fuser -vm /mnt/data
USER PID ACCESS COMMAND
/mnt/data: root 1321 ..c.. bash
www-data 1874 ..c.. nginx
postgres 2440 ..c.. postgres
Ce que cela signifie : Ces processus ont quelque chose sous ce montage comme cwd ou un fichier ouvert (les flags ACCESS varient ; c indique souvent current directory). C’est généralement suffisant pour expliquer « busy ».
Décision : Décidez d’arrêter proprement le service, de déplacer le shell, ou de tuer seulement les PID spécifiques qui tiennent le montage.
Task 4: Get filenames and file descriptors with lsof
cr0x@server:~$ sudo lsof +f -- /mnt/data | head -n 8
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1874 www-data 10u REG 8,17 4096 212 /mnt/data/www/access.log
postgres 2440 postgres 12u REG 8,17 1048576 877 /mnt/data/pg_wal/0000000100000000000000A1
Ce que cela signifie : Vous avez maintenant les chemins concrets. C’est la différence entre « quelque chose l’utilise » et « nginx écrit encore dans les logs ici ».
Décision : Si c’est un service, arrêtez-le. Si c’est un processus ponctuel, tuez-le. Si c’est un fichier de log, faites une rotation/reload proprement.
Task 5: Catch the classic “shell sitting in the directory”
cr0x@server:~$ sudo ls -l /proc/1321/cwd
lrwxrwxrwx 1 root root 0 Dec 29 11:05 /proc/1321/cwd -> /mnt/data
Ce que cela signifie : Le PID 1321 a pour répertoire de travail un chemin à l’intérieur du montage. Cela suffit à épingler le montage.
Décision : Si c’est votre shell, faites cd /. Si c’est la session de quelqu’un d’autre, coordonnez-vous ou terminez-la.
Task 6: Find processes whose root is inside the mount (chroot/pivot_root)
cr0x@server:~$ sudo ls -l /proc/2890/root
lrwxrwxrwx 1 root root 0 Dec 29 11:06 /proc/2890/root -> /mnt/data/chroots/buildenv
Ce que cela signifie : Ce processus a son root à l’intérieur du montage. C’est courant avec des systèmes de build, des outils de récupération et certaines configurations de conteneurs.
Décision : Arrêtez proprement ce processus si possible. Le tuer peut laisser des enfants ; soyez prêt à suivre les groupes de processus.
Task 7: When lsof is slow or incomplete, scan /proc for cwd/root offenders
cr0x@server:~$ sudo bash -lc 'for p in /proc/[0-9]*; do
pid=${p#/proc/}
cwd=$(readlink -f $p/cwd 2>/dev/null || true)
root=$(readlink -f $p/root 2>/dev/null || true)
if [[ "$cwd" == /mnt/data* || "$root" == /mnt/data* ]]; then
printf "%s cwd=%s root=%s\n" "$pid" "$cwd" "$root"
fi
done | head'
1321 cwd=/mnt/data root=/
2890 cwd=/ root=/mnt/data/chroots/buildenv
Ce que cela signifie : Vous avez rapidement énuméré les « pins » évidents sans dépendre du parcours des tables de fichiers de lsof.
Décision : Inspectez chaque PID avec ps et décidez d’arrêter/tuer ou de relocaliser.
Task 8: Confirm what the process actually is (and whether it’s expected)
cr0x@server:~$ ps -p 1874 -o pid,user,comm,args
PID USER COMMAND COMMAND
1874 www-data nginx nginx: worker process
Ce que cela signifie : Pas de mystère : c’est nginx. Le « busy » est légitime.
Décision : Arrêtez/rechargez nginx, ou redirigez logs/contenu hors du montage avant de démonter.
Task 9: Check if systemd created or manages the mount (and can re-mount it)
cr0x@server:~$ systemctl status mnt-data.mount
● mnt-data.mount - /mnt/data
Loaded: loaded (/etc/fstab; generated)
Active: active (mounted) since Mon 2025-12-29 10:02:10 UTC; 1h 4min ago
Where: /mnt/data
What: /dev/sdb1
Ce que cela signifie : systemd connaît ce montage. Si c’est une paire automount, il peut être remonté dès qu’un processus accède au chemin.
Décision : Si vous voulez qu’il reste démonté, arrêtez/désactivez l’unit .automount concernée ou retirez l’entrée fstab avant de continuer.
Task 10: Detect systemd automount that re-triggers “busy” immediately
cr0x@server:~$ systemctl status mnt-data.automount
● mnt-data.automount - Automount /mnt/data
Loaded: loaded (/etc/fstab; generated)
Active: active (waiting) since Mon 2025-12-29 10:01:59 UTC; 1h 4min ago
Where: /mnt/data
Ce que cela signifie : Même après démontage, la prochaine accès à /mnt/data peut le remonter. De plus, certains processus « qui vérifient » (indexeurs, monitoring, complétion de shell) peuvent continuer à fouiller le chemin.
Décision : Pour une fenêtre de maintenance, arrêtez explicitement l’unité automount : systemctl stop mnt-data.automount, puis démontez.
Task 11: Confirm whether a mount is shared/slave (propagation can surprise you)
cr0x@server:~$ findmnt -o TARGET,PROPAGATION /mnt/data
TARGET PROPAGATION
/mnt/data shared
Ce que cela signifie : La propagation de montage est en jeu. Un montage « shared » peut propager des sous-montages entre namespaces. C’est courant avec les runtimes de conteneurs.
Décision : Si vous diagnostiquez un hôte de conteneurs, supposez qu’un autre namespace peut le détenir. Passez à l’inspection des namespaces.
Task 12: Identify mount namespaces and find the likely holder
cr0x@server:~$ sudo lsns -t mnt | head
NS TYPE NPROCS PID USER COMMAND
4026531840 mnt 168 1 root /sbin/init
4026532501 mnt 15 6123 root /usr/bin/containerd
4026532710 mnt 3 9012 root /usr/sbin/cron
Ce que cela signifie : Vous avez plusieurs namespaces de montage. Si un montage est busy dans un namespace, il peut ne pas apparaître comme vous l’attendez dans un autre.
Décision : Inspectez les propriétaires probables de namespace (containerd, dockerd, podman, services systemd) et regardez depuis l’intérieur de ce namespace.
Task 13: Enter the mount namespace of a suspected PID and run findmnt there
cr0x@server:~$ sudo nsenter -t 6123 -m -- findmnt /mnt/data
TARGET SOURCE FSTYPE OPTIONS
/mnt/data /dev/sdb1 ext4 rw,relatime
Ce que cela signifie : Le montage existe aussi dans le namespace de containerd. Il se peut qu’un conteneur y ait fait un bind-mount et le maintienne monté.
Décision : Utilisez nsenter pour exécuter fuser/lsof dans ce namespace, ou arrêtez le conteneur/service responsable.
Task 14: When a deleted-but-open file pins space (and sometimes pins expectations)
cr0x@server:~$ sudo lsof +L1 -- /mnt/data | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
java 7777 app 25u REG 8,17 5242880 0 901 /mnt/data/app/logs/app.log (deleted)
Ce que cela signifie : Le fichier a été supprimé mais est toujours ouvert. Cela ne bloque pas toujours le démontage en soi, mais c’est souvent un indice : un processus utilise encore activement le système de fichiers.
Décision : Redémarrez/rechargez ce processus ou forcez-le à fermer les fichiers de log (logrotate avec postrotate approprié). Ne supprimez pas juste les fichiers en espérant que ça suffira.
Task 15: Check swapfiles (a kernel-level “busy” you can’t lsof away)
cr0x@server:~$ sudo swapon --show
NAME TYPE SIZE USED PRIO
/mnt/data/swapfile file 8G 2G -2
Ce que cela signifie : Le swap est sur ce système de fichiers. Le noyau ne vous laissera pas démonter le système de fichiers tant qu’il fournit du swap.
Décision : swapoff /mnt/data/swapfile (et assurez-vous d’avoir assez de RAM ou un swap alternatif), puis retentez le démontage.
Task 16: Find loop devices backed by files on the mount
cr0x@server:~$ sudo losetup -a
/dev/loop2: [0801]:123456 (/mnt/data/images/debian.qcow2)
Ce que cela signifie : Un device loop utilise un fichier sur le montage. C’est une référence noyau ; le démontage échouera tant que le loop n’est pas détaché.
Décision : Arrêtez ce qui utilise le loop (outils VM, montage du loop), puis losetup -d /dev/loop2.
Task 17: See device-mapper/LVM stacking that keeps a block device busy
cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MOUNTPOINTS,PKNAME
sdb disk 500G
└─sdb1 part 500G /mnt/data
Ce que cela signifie : Cas simple : partition directe. Si vous voyez des nœuds dm-* ou des volumes logiques LVM, le « busy » peut venir de détenteurs au-dessus ou en dessous de la couche filesystem.
Décision : Si LVM/dm-crypt est impliqué, vérifiez que vous démontez d’abord le système de fichiers, puis désactivez les LV/fermez les mappings luks une fois le montage retiré.
Task 18: Check open file descriptors directly (when you distrust lsof)
cr0x@server:~$ sudo ls -l /proc/1874/fd | head
total 0
lr-x------ 1 www-data www-data 64 Dec 29 11:10 0 -> /dev/null
l-wx------ 1 www-data www-data 64 Dec 29 11:10 10 -> /mnt/data/www/access.log
lr-x------ 1 www-data www-data 64 Dec 29 11:10 11 -> /mnt/data/www/index.html
Ce que cela signifie : Preuve concrète : nginx a des descripteurs de fichiers vers ce montage. Pas de débat.
Décision : Arrêtez/rechargez nginx, ou modifiez la config pour qu’il n’utilise plus ces chemins.
Task 19: Attempt a clean unmount with context
cr0x@server:~$ sudo umount /mnt/data
umount: /mnt/data: target is busy.
Ce que cela signifie : Toujours épinglé. Maintenant vous n’errez plus : vous itérez selon les preuves de détenteurs.
Décision : Résolvez les détenteurs (arrêtez services, détachez loops, swapoff, démontez les sous-montages) et réessayez.
Task 20: Use a lazy unmount when you’ve decided it’s acceptable
cr0x@server:~$ sudo umount -l /mnt/data
Ce que cela signifie : Le montage est détaché du namespace maintenant, mais le nettoyage effectif est différé jusqu’à ce que les références disparaissent. Les processus peuvent continuer d’accéder au système de fichiers via des FDs existants.
Décision : Ne le faites que si vous pouvez tolérer des « accès zombies » et si vous êtes certain que le périphérique sous-jacent ne disparaîtra pas pendant des E/S actives. Si vous êtes sur le point de retirer le stockage, lazy unmount peut transformer une « maintenance » en « post-mortem ».
Task 21: Force unmount (last resort, mostly for network mounts)
cr0x@server:~$ sudo umount -f /mnt/data
umount: /mnt/data: umount failed: Operation not permitted
Ce que cela signifie : Sur Linux, -f est significatif principalement pour certains systèmes de fichiers réseau et situations spécifiques ; pour ext4/xfs locaux, il ne se comportera souvent pas comme vous l’espérez.
Décision : Ne traitez pas -f comme une sledgehammer universelle. Réglez le détenteur, ou utilisez lazy unmount en connaissance de cause.
Task 22: Verify it’s really gone (and not re-mounted by automount)
cr0x@server:~$ findmnt /mnt/data
Ce que cela signifie : Pas de sortie : il n’est pas monté dans votre namespace courant.
Décision : Si la commande renvoie une sortie immédiatement après le démontage, quelque chose touche le chemin et déclenche un automount. Arrêtez l’unité automount ou corrigez le consommateur.
Blague 1 : « Device busy » est la façon pour le noyau de dire qu’il a des projets ce soir et que vous n’êtes pas sur la liste.
Cas particuliers : systemd, NFS, conteneurs, bind mounts, loop/LVM/dm-crypt
systemd mounts and automounts: your filesystem has a manager now
Sur Debian 13, systemd est généralement impliqué même si vous ne l’avez pas demandé. Les entrées dans /etc/fstab deviennent des unités générées. C’est utile pour un comportement de démarrage cohérent, mais cela peut vous surprendre pendant une maintenance :
- Automount rend le démontage instable : vous démontez, puis un processus « stat » le réveille et il se remonte.
- Dépendances d’unité peuvent garder des montages actifs parce qu’un service les Requires=.
Lorsque vous avez besoin qu’il reste bas, arrêtez d’abord l’automount et envisagez de masquer temporairement le mount si un service gênant le réactive.
NFS and “umount hangs” versus “device busy”
NFS est un type de douleur différent. Vous pouvez voir « device busy », mais plus souvent umount attend… et attend… parce que le noyau tente d’écrire/vider ou de résoudre des opérations en cours.
Adaptations de workflow pour NFS :
- Si
umountbloque, vérifiez d’abord la connectivité réseau et la santé du serveur. « Busy » peut être secondaire. - Utilisez plus souvent
umount -lpour NFS quand un serveur est parti et que vous devez récupérer le client, mais comprenez le compromis. - Les handles de fichier obsolètes et les montages « hard » peuvent rendre les listings de processus trompeurs.
Containers: the holder is in a different mount namespace
Les stacks modernes de conteneurs adorent les bind mounts et overlayfs. Elles adorent aussi les namespaces de montage séparés. Voici le scénario classique :
- Hôte : « Rien n’utilise
/mnt/data». - Noyau : « Je ne suis pas d’accord. »
- Réalité : un conteneur a fait un bind mount de
/mnt/datadans son namespace, et un processus y tient un fichier.
La correction est ennuyeuse mais simple : identifiez le namespace, entrez-y, trouvez le détenteur, arrêtez le conteneur/service. Essayer de déjouer les namespaces avec des outils host-only est comment vous perdez une heure.
Bind mounts and mount propagation: the invisible glue
Les bind mounts peuvent créer des situations « busy » qui semblent irrationnelles si vous ne regardez que la cible évidente. L’arbre des montages compte. La propagation aussi :
- Un bind mount d’un répertoire à l’intérieur de
/mnt/datavers ailleurs signifie que des processus peuvent tenir le système de fichiers sans jamais toucher les chemins/mnt/datadirectement. - Les montages partagés peuvent propager des sous-montages et maintenir des références actives entre namespaces.
Utilisez findmnt -R pour visualiser le sous-arbre. Utilisez findmnt -o TARGET,SOURCE,OPTIONS,PROPAGATION pour voir pourquoi ça se comporte comme une hydre.
Loop devices, swapfiles, dm-crypt, LVM: kernel consumers don’t show up as “a file open”
Si vous traitez des images, volumes chiffrés ou swapfiles « temporaires », vous pouvez avoir des références au niveau noyau :
- Swapfile empêche le démontage jusqu’à swapoff.
- Loop device mappé sur un fichier empêche le démontage jusqu’à détachement.
- Empilements device-mapper peuvent garder des périphériques bloc occupés même après le démontage du système de fichiers, ce qui importe si vous voulez retirer le périphérique sous-jacent.
Erreurs fréquentes : symptôme → cause racine → correction
Ce sont les schémas que je retrouve dans les tickets, salons et timelines d’incident. Les symptômes sont familiers ; les causes racines sont généralement terre-à-terre.
1) Symptom: “umount says busy but lsof shows nothing”
Cause racine : Un autre namespace de montage le détient ; ou vous avez lancé lsof sans privilèges suffisants ; ou la référence « busy » est un consommateur noyau (swap/loop) plutôt qu’un fichier ouvert en espace utilisateur.
Correction : Lancez sudo. Vérifiez les namespaces avec lsns -t mnt et inspectez avec nsenter -t PID -m. Vérifiez swapon --show et losetup -a.
2) Symptom: Parent mount won’t unmount, but you “stopped all apps”
Cause racine : Il y a un sous-montage quelque part sous le parent (tmpfs, overlay, bind mount, montage de conteneur).
Correction : findmnt -R /mnt/data, démontez d’abord les enfants les plus profonds. Si vous faites un teardown, envisagez umount -R mais comprenez les conséquences.
3) Symptom: You unmounted successfully, but it mounts again immediately
Cause racine : automount systemd, autofs, ou un service qui monte à la demande. Parfois c’est aussi votre shell ou un agent de monitoring qui touche le répertoire.
Correction : Arrêtez l’unité automount (systemctl stop mnt-data.automount). Vérifiez avec systemctl status. Masquez temporairement si nécessaire pour la maintenance. Déplacez les sondes hors du chemin.
4) Symptom: “device busy” only when trying to detach the block device (not when unmounting)
Cause racine : Vous avez peut-être démonté le système de fichiers, mais le périphérique bloc est toujours détenu par dm-crypt, LVM, multipath, MD RAID, ou loop devices.
Correction : Utilisez lsblk pour cartographier les détenteurs ; vérifiez dmsetup ls --tree ; fermez les mappings luks ou désactivez les LV après que le système de fichiers est proprement démonté.
5) Symptom: “umount hangs” rather than failing quickly
Cause racine : Habituellement des problèmes de système de fichiers réseau (NFS serveur injoignable, mount hard), ou E/S bloquées lors de la vidange. Ce n’est pas le même problème que « busy ».
Correction : Vérifiez dmesg -T pour des erreurs NFS ou E/S bloquées. Vérifiez la santé réseau. Envisagez lazy unmount pour NFS comme tactique de récupération si vous acceptez le compromis.
6) Symptom: You killed the PID, but “busy” persists
Cause racine : Vous avez tué le mauvais processus (leader de thread vs worker), ou des enfants ont hérité du cwd, ou un service a redémarré instantanément via systemd, ou un détenteur dans un autre namespace persiste.
Correction : Relancez fuser -vm. Inspectez les arbres de processus (ps --ppid ou pstree si installé). Arrêtez l’unité systemd plutôt que de jouer au marteau-piqueur sur les PID.
7) Symptom: “busy” after a chroot-based maintenance task
Cause racine : Le shell chroot ou un processus auxiliaire a gardé le root à l’intérieur du montage.
Correction : Trouvez les coupables via les vérifications /proc/*/root ; sortez du chroot ; tuez les processus persistants.
8) Symptom: You used umount -l, storage got unplugged, apps exploded later
Cause racine : Lazy unmount a permis des accès continus via des FDs existants. Quand le périphérique sous-jacent a disparu, ces FDs ont commencé à renvoyer des erreurs de façon spectaculaire.
Correction : N’utilisez pas lazy unmount sur un système de fichiers que vous allez retirer à moins d’avoir aussi terminé les détenteurs ou d’être dans une séquence d’arrêt contrôlée.
Listes de contrôle / plan étape par étape (débloquer sans risque)
Ceci est le plan « ne pas improviser sous pression ». Servez-vous-en pour les systèmes de fichiers locaux, et adaptez pour NFS et hôtes de conteneurs.
Checklist A: Standard local filesystem unmount (ext4/xfs/btrfs)
- Confirmer le montage et les sous-montages:
findmnt /mnt/datafindmnt -R /mnt/data
Décision : S’il y a des sous-montages, planifiez l’ordre de démontage (les plus profonds en premier).
- Trouver les détenteurs en espace utilisateur:
sudo fuser -vm /mnt/datasudo lsof +f -- /mnt/data
Décision : Arrêtez les services proprement ; ne tuez pas aveuglément.
- Vérifier les pins cwd/root:
- Scannez
/proc/*/cwdet/proc/*/rootpour des chemins sous le montage.
Décision : Déplacez les shells, sortez des chroots, arrêtez les jobs de build.
- Scannez
- Vérifier les consommateurs noyau:
swapon --showlosetup -a
Décision : swapoff, détachez les loops, puis retentez.
- Démontez les enfants, puis le parent:
sudo umount /mnt/data/cacheetc.sudo umount /mnt/data
Décision : Si c’est encore busy, relancez fuser ; quelque chose est encore vivant.
- Seulement alors envisagez lazy unmount:
sudo umount -l /mnt/data
Décision : Si vous allez retirer le stockage, ne laissez pas des détenteurs en marche.
Checklist B: Container host unmount (namespaces expected)
- Identifier propagation et bind mounts:
findmnt -o TARGET,SOURCE,OPTIONS,PROPAGATION /mnt/datafindmnt -R /mnt/data
Décision : Si c’est shared, supposez que d’autres namespaces participent.
- Trouver les propriétaires de namespace:
sudo lsns -t mnt
Décision : Ciblez les PID du runtime de conteneur pour
nsenter. - Inspecter depuis l’intérieur du namespace suspect:
sudo nsenter -t <pid> -m -- fuser -vm /mnt/data
Décision : Arrêtez le conteneur ou workload responsable.
- Arrêter proprement les services orchestrés:
Décision : Arrêtez via systemd ou l’orchestrateur, pas en jouant au killer avec des SIGKILL.
Checklist C: NFS client unmount (when timeouts and hangs show up)
- Vérifier si c’est « busy » ou « bloqué »:
- Est-ce que
umountéchoue immédiatement ou bloque ?
Décision : Si ça bloque, enquêtez d’abord sur le serveur/réseau.
- Est-ce que
- Trouver les processus:
sudo fuser -vm /mnt/nfs
Décision : Arrêtez les détenteurs ; pour des clients bloqués, envisagez lazy unmount.
- Tactique de récupération:
sudo umount -l /mnt/nfs
Décision : À utiliser quand le serveur est parti et que vous devez restaurer l’opérabilité locale ; nettoyez ensuite.
Trois mini-récits d’entreprise tirés du terrain
Mini-story 1: The incident caused by a wrong assumption
L’équipe faisait une migration de stockage de routine sur une flotte Debian. Le plan était propre : drainer le trafic, arrêter l’appli, démonter l’ancien système de fichiers, basculer sur le nouveau, redémarrer l’appli. Ils l’avaient répété en staging et c’était ennuyeux. Ça aurait dû être l’indice que la production trouverait une nouvelle façon d’être intéressante.
Sur le premier hôte, umount a renvoyé « target is busy ». L’astreint a supposé que c’était « un processus résiduel », a lancé lsof sur le montage, n’a rien vu, et a décidé que le lazy unmount était sûr. Le montage a disparu, le script a continué, et le volume physique a été détaché quelques minutes plus tard.
Une dizaine de minutes après, l’appli a commencé à produire des erreurs d’E/S sporadiques. Pas sur toutes les requêtes. Pas de façon cohérente. Seulement sur des jobs en arrière-plan utilisant un worker long-vivant. Le chemin de requête principal allait bien, parce que ces processus redémarraient plus souvent et « oubliaient » les anciens descripteurs.
La mauvaise supposition était subtile : « si lsof ne montre rien, personne ne l’utilise ». En réalité, le détenteur était dans un autre namespace de montage créé par un service auxiliaire lançant des workers dans un contexte isolé. L’outil lsof côté hôte ne voyait pas la vue complète qu’ils croyaient regarder.
La correction fut simple une fois qu’ils ont cessé de deviner : identifier les namespaces avec lsns, entrer avec nsenter dans le namespace du worker, exécuter fuser, arrêter l’unité correcte proprement, puis démonter normalement. L’action postmortem n’a pas été « ne plus utiliser lazy unmount ». Ce fut « ne pas utiliser lazy unmount avant d’avoir prouvé qui le tient, y compris dans d’autres namespaces ».
Mini-story 2: The optimization that backfired
Une autre organisation avait pour habitude, lorsque les fenêtres de maintenance étaient courtes, d’utiliser l’automount dans /etc/fstab pour des datasets volumineux. L’idée était raisonnable : ne pas monter de gros volumes au boot ; monter à la demande ; gagner du temps au démarrage ; réduire la surface d’impact. Ils avaient même du monitoring autour de la latence de montage.
Puis un agent de scan de sécurité est arrivé. Il parcourait les arbres de fichiers à la recherche de types intéressants. Il ne savait pas qu’« accéder à un chemin » pouvait monter un dataset, et il s’en fichait. Soudainement, des datasets étaient automatiquement montés pendant la préparation de maintenance, juste après que l’équipe les ait démontés « avec succès ».
La phase de démontage a commencé à osciller : démontage réussi, une seconde plus tard remonté, et umount retournait busy parce que le scanner maintenait des fichiers ouverts. L’équipe a réagi comme les humains quand ils sont agacés : tuer le processus scanner. Il redémarrait. Encore des tuages. Finalement quelqu’un a eu l’idée de masquer l’unité automount.
L’optimisation s’est retournée contre eux parce que l’automount transforme « un répertoire existe » en « un périphérique doit être présent ». C’est pratique jusqu’à ce que vous souhaitiez que l’état démonté persiste. La correction ennuyeuse était d’arrêter/désactiver l’automount pendant la maintenance et d’exclure ces chemins des scanners. La correction culturelle était meilleure : traiter l’automount comme une fonctionnalité nécessitant des contrôles opérationnels, pas comme un défaut pour tout ce qui est volumineux et gênant.
Blague 2 : L’automount est génial jusqu’à ce qu’il devienne un stagiaire hyperactif qui rebranche tout parce que « ça avait l’air débranché ».
Mini-story 3: The boring but correct practice that saved the day
Il y avait un service lourd en stockage avec un contrôle de changement strict. L’équipe SRE disposait d’un playbook exigeant : identifier les détenteurs avec deux méthodes indépendantes, arrêter les services par nom d’unité (pas par PID), et vérifier les montages disparus avec findmnt dans le namespace correct. Tout le monde se plaignait que c’était trop lent. Ça ressemblait à de la bureaucratie déguisée en rigueur.
Pendant une panne matérielle, ils devaient évacuer des données et détacher un disque défaillant. Le système de fichiers ne voulait pas se démonter. Le junior d’astreinte a commencé à paniquer et a cherché à utiliser umount -l, parce que c’est ce qu’il avait vu sur internet. Le lead a demandé le playbook. Pas de débat. Exécutez les étapes.
fuser a pointé un processus d’agent de sauvegarde. lsof a montré qu’il écrivait dans un fichier temporaire sur le montage. Arrêter l’agent via systemd ne l’a pas stoppé, parce qu’il était lancé par une unité timer qui redémarrait immédiatement une nouvelle instance. La deuxième méthode du playbook a attrapé ça : systemctl list-timers et le statut d’unité ont montré le coupable.
Ils ont arrêté le timer, arrêté le service, vérifié l’absence de détenteurs, démonté proprement, puis détaché le disque sans surprise supplémentaire. Personne n’a applaudi. C’est le but. En réponse aux incidents, la condition de victoire est « ennuyeux », pas « brillant ».
Faits intéressants et contexte historique
- 1) « EBUSY » vient de l’ADN Unix ancien. L’erreur « device or resource busy » remonte à des décennies ; c’est un refus au niveau noyau de détacher quelque chose encore référencé.
- 2) Les namespaces de montage Linux ont changé la signification de « qui l’utilise ». Depuis les namespaces, un montage peut être busy « ailleurs » même si votre shell ne le voit pas.
- 3)
lsofn’est pas un appel système ; c’est un enquêteur. Il parcourt les tables de processus et descripteurs pour inférer les fichiers ouverts, ce qui signifie que permissions et échelle comptent. - 4)
fuserest antérieur aux conteneurs mais reste gagnant sur la vitesse. Il est souvent plus rapide pour « donnez-moi les PID », car il interroge le noyau différemment que la résolution complète des chemins de lsof. - 5) Lazy unmount existe parce que la réalité est bordélique.
umount -la été créé pour les cas où il faut détacher un chemin même si des références restent, couramment en récupération. - 6) « Busy » n’est pas seulement à propos de fichiers. Le cwd/root d’un processus est une référence à un inode de ce système de fichiers. Suffit pour empêcher le détachement.
- 7) Les swapfiles sont un piège classique. Ils ressemblent à « juste un fichier » jusqu’à ce que vous appreniez que le noyau les traite comme un périphérique de pagination et refuse le démontage.
- 8) Les loop devices transforment un fichier en périphérique bloc. C’est pourquoi les images loop-backed gardent les systèmes de fichiers occupés même quand aucun processus utilisateur n’affiche un fichier ouvert de façon évidente.
- 9) systemd générant des unités de montage depuis fstab a changé les attentes opérationnelles. Les montages sont désormais des « objets gérés » avec dépendances, timeouts et comportement automount.
FAQ
Q1: What’s the fastest single command to find what blocks umount?
R : Commencez par sudo fuser -vm /mnt/data. C’est rapide, lisible, et indique quels PID sont impliqués. Suivez avec lsof pour les chemins de fichiers.
Q2: Why does lsof sometimes take forever on big systems?
R : Cela peut être proportionnel à « processus × descripteurs de fichiers », et il résout souvent des chemins. Sur des hôtes avec beaucoup de conteneurs et des milliers de FDs par processus, il fait un vrai boulot. Utilisez fuser d’abord, ou un lsof ciblé par PID une fois que vous avez des suspects.
Q3: Why does umount -f not work for local filesystems?
R : Sur Linux, le démontage forcé est utile principalement pour certains systèmes de fichiers réseau ou cas spécifiques. Pour ext4/xfs locaux, le noyau ne va pas simplement l’arracher si c’est busy, parce que cela crée des problèmes de cohérence.
Q4: Is umount -l safe?
R : Ça peut être sûr dans des scénarios contrôlés : vous avez besoin que le point de montage soit détaché et vous savez que le stockage sous-jacent restera accessible jusqu’à la sortie des détenteurs. C’est dangereux si vous comptez retirer le stockage pendant que des détenteurs tournent encore.
Q5: How do I know if a container is holding my mount?
R : Vérifiez les namespaces de montage avec sudo lsns -t mnt, identifiez les PID runtime probables, puis nsenter -t PID -m et exécutez findmnt/fuser là-dedans. Si vous trouvez des détenteurs, arrêtez proprement le conteneur/service.
Q6: Can a “current directory” really block unmount even with no files open?
R : Oui. Le cwd d’un processus est une référence à un inode sur ce système de fichiers. Le noyau ne détachera pas un système de fichiers qui a encore des références actives.
Q7: Why does it re-mount right after I unmount?
R : Automount (systemd ou autofs) ou un service qui touche le chemin. Désactivez/arrêtez l’unité automount pendant la maintenance, et identifiez qui sonde le répertoire.
Q8: What if fuser shows PIDs but killing them doesn’t help?
R : Vous pouvez tuer des workers pendant qu’un superviseur les redémarre (systemd, cron, timers), ou le détenteur est dans un autre namespace. Arrêtez l’unité, pas le symptôme, et revérifiez les namespaces.
Q9: What’s a reliable way to prove it’s unmounted?
R : Utilisez findmnt /mnt/data (pas de sortie signifie démonté dans ce namespace). Vérifiez aussi findmnt -R /mnt/data pour des sous-montages persistants. Si des namespaces sont impliqués, vérifiez aussi depuis le namespace en question.
Q10: Any operational philosophy here, beyond commands?
R : Oui : identifiez le détenteur avant de choisir la méthode pour débloquer. Comme l’a souligné le penseur des systèmes John Allspaw (idée paraphrasée), la résilience vient de la compréhension de la manière dont le travail est réellement fait, pas de ce que vous espériez.
Prochaines étapes à faire réellement
Quand la page se calme et que vous ne fixez plus « device busy », faites les petits correctifs qui évitent la prochaine ronde de douleur :
- Encoderez le workflow dans un runbook :
findmnt→findmnt -R→fuser→lsof→ namespaces → consommateurs noyau. - Arrêtez de tuer des PID comme première réponse. Préférez arrêter l’unité systemd propriétaire, le conteneur, ou le timer. Les processus reviennent.
- Auditez la présence de swapfiles et d’images loop-backed sous des montages amovibles. Si vous devez les utiliser, documentez-les et créez une procédure de teardown.
- Pour les automounts, définissez un mode maintenance : une séquence de commandes connue qui arrête l’automount et supprime les sondes « utiles ».
- Formez votre équipe aux namespaces. Ce n’est plus avancé ; c’est du Linux normal. « Je ne le vois pas » n’équivaut pas à « ça n’existe pas ».