Corrigindo "device is busy" no umount

Corrigindo "device is busy" no umount

O que "device is busy" realmente significa?

Conclusão: Algo ainda está usando o filesystem que você está tentando desmontar - um processo, uma montagem empilhada ou swap. O kernel retorna EBUSY e recusa o umount. O primeiro passo é encontrar o que está segurando, não forçar.

Uma falha típica se parece com isto:

umount: /mnt/data: target is busy.

Em distribuições mais antigas ou algumas ferramentas, a mesma condição aparece como device is busy ou device or resource busy (o errno EBUSY). A redação difere, mas a causa é idêntica: algo ainda referencia o alvo.

Os mantenedores se dividem em alguns grupos. Faça a triagem nesta ordem:

  • A. Um processo tem um arquivo aberto (mais comum) - um arquivo aberto sob a montagem, um binário em execução, um log sendo escrito
  • B. Um diretório atual dentro da montagem - um shell ou daemon cujo cwd está sob /mnt/data
  • C. Uma montagem aninhada - um bind mount ou overlay empilhado sobre ela
  • D. Usado como swap / loop - o dispositivo serve de base para swap ou um loop device

device is busy e Read-only file system são problemas diferentes. O primeiro significa "em uso, não pode desconectar"; o segundo significa "escritas estão bloqueadas". Não confunda as mensagens. Para read-only, veja Corrigindo "Read-only file system".

Como encontrar o que está segurando a montagem?

Conclusão: Comece com fuser -vm <ponto-de-montagem> para listar cada processo usando aquele filesystem. A coluna ACCESS distingue arquivo aberto (f), diretório atual (c), binário em execução (e) e mmap (m). Use lsof para detalhes por arquivo.

Varredura por montagem com fuser

-m trata o argumento como ponto de montagem (ou dispositivo de bloco) e retorna cada processo usando aquele filesystem. -v adiciona detalhes.

fuser -vm /mnt/data
                     USER        PID ACCESS COMMAND
/mnt/data:           root     kernel mount /mnt/data
                     alice       2314 ..c.. bash
                     alice       2890 F.... tail

Leia a coluna ACCESS - ela é a resposta direta para "por que está busy?"

  • c ... o diretório atual do processo está sob a montagem (padrão B)
  • e ... um binário sob a montagem está executando
  • f ... um arquivo está aberto (maiúsculo F significa aberto para escrita)
  • r ... usado como diretório raiz
  • m ... um arquivo está em mmap (bibliotecas compartilhadas, etc.)

No exemplo acima, bash (cwd dentro) e tail (arquivo aberto) são os mantenedores.

Detalhar arquivos individuais com lsof

Para saber exatamente qual arquivo está mantido, use lsof. Use +D para recursão sob um ponto de montagem, ou +f -- para consultar por dispositivo.

# Arquivos abertos sob o ponto de montagem
lsof +D /mnt/data

# Por dispositivo de bloco (util quando o caminho do ponto de montagem esta quebrado)
lsof +f -- /dev/sdb1

lsof +D faz stat de toda a árvore e é lento em diretórios grandes. Na prática, execute fuser -vm primeiro para encontrar a causa, depois use lsof para detalhes.

Como parar os mantenedores e desmontar?

Conclusão: Encerre os mantenedores graciosamente primeiro (saia do diretório / pare o serviço / SIGTERM), depois faça umount. Se persistirem, fuser -k mata forcadamente - mas SIGKILL arrisca perda de dados, então mantenha como último recurso.

1. A ordem segura: sair ou parar de forma limpa

  • Se é apenas o cwd do seu próprio shell, saia:
cd /
  • Se um serviço está segurando, pare o serviço (mais confiável e seguro que kill):
sudo systemctl stop myapp.service
  • Para processos individuais, encontre o PID e comece com um sinal gentil:
kill 2890        # SIGTERM (permite limpeza)

2. Último recurso: fuser -k para matar em massa

Processos que não encerram de forma limpa podem ser mortos juntos com fuser -k. Mas -k envia SIGKILL por padrão, o que pode corromper dados no meio de uma escrita.

# Confirmar primeiro (-i pede confirmacao por processo)
sudo fuser -kim /mnt/data
/mnt/data:            2890c  2314c
Kill process 2890 ? (y/N) y
  • -k ... envia um sinal aos mantenedores (padrão SIGKILL)
  • -i ... confirma cada um (fortemente recomendado)
  • -m ... por montagem

Depois que os mantenedores forem liberados, desmonte novamente:

sudo umount /mnt/data

Devo usar lazy ou force umount?

Conclusão: Para desconectar imediatamente da árvore, use umount -l (lazy). Para uma montagem NFS sem resposta, use umount -f (force). Ambos são workarounds que não resolvem o mantenedor, então não confie neles rotineiramente.

Lazy umount (-l)

Desconecta o filesystem da árvore imediatamente e limpa quando as referências desaparecem. Uma saída de emergência quando você não pode (ou não quer) matar os mantenedores.

sudo umount -l /mnt/data

Ressalvas:

  • O ponto de montagem desaparece, mas FDs abertos continuam ativos (processos continuam segurando os arquivos antigos). A liberação completa acontece apenas após eles encerrarem.
  • Remontar o mesmo dispositivo imediatamente pode conflitar com referências persistentes.
  • Não garante que dados não escritos sejam flushed. Em filesystems críticos, corrija a causa primeiro.

Force umount (-f)

Principalmente para uma montagem NFS sem resposta - desconecta forcadamente uma montagem travada cujo servidor está fora.

sudo umount -f /mnt/nfs

Em ext4/xfs local, -f raramente ajuda (a causa busy é um processo local). Para travamentos NFS, leia também Corrigindo "Stale file handle" em NFS.

E se está busy mas nenhum processo aparece?

Conclusão: Se fuser/lsof não mostram nada mas ainda está busy, a causa não é um arquivo aberto. Verifique quatro coisas na ordem: montagens aninhadas, swap, loop devices e exports NFS.

1. Verificar montagens aninhadas (bind / overlay)

Se outra montagem está empilhada em cima, a pai continua busy. Inspecione a árvore com findmnt -R e desmonte os filhos primeiro.

findmnt -R /mnt/data
TARGET            SOURCE    FSTYPE OPTIONS
/mnt/data         /dev/sdb1 ext4   rw,relatime
+-/mnt/data/cache tmpfs     tmpfs  rw

Aqui, desmonte o filho /mnt/data/cache primeiro. Comum com overlays Docker e mount --bind.

2. Está sendo usado como swap?

Se a partição serve de base para swap, obviamente você não pode desmontá-la. Verifique com swapon --show e execute swapoff.

swapon --show
sudo swapoff /dev/sdb2

3. Um loop device está segurando?

Se você montou uma imagem via loop, uma referência pelo loop device permanece. Verifique com losetup -a e desconecte.

losetup -a
sudo losetup -d /dev/loop0

4. Está exportado via NFS?

Se o filesystem está exportado por um servidor NFS, ele continua busy. Libere exports com exportfs.

sudo exportfs -ua          # temporariamente desexportar tudo

Caminho mais rápido: (1) fuser -vm /mnt/data para ver quem segura -> (2) encerrar graciosamente (cd / systemctl stop / kill) -> (3) umount novamente -> se persistir (4) verificar causas não-processo com findmnt -R, swapon --show, losetup -a -> (5) somente em emergências, umount -l. Nunca pule a identificação da causa - essa é a única regra que previne acidentes.

Resumo / Próximas leituras