Eu mesmo resolvi o mistério, com a ajuda do mantenedor da aufs, Junjiro Okajima.
O primeiro passo, para depurar o problema, foi reproduzi-lo de maneira controlada. Demorei algum tempo (agora me pergunto por que tanto) descobrir que o problema ocorre quando os arquivos são escritos e excluídos via aufs.
Reproduzindo o problema
criar pontos de montagem:
# cd /tmp
# mkdir rw
# mkdir mnt
monte o tmpfs:
# mount -t tmpfs none /tmp/rw
monte o aufs, sobrepondo / usr com / tmp / rw:
# mount -t aufs -n -o "br:/tmp/rw:/usr" none "/tmp/mnt"
agora posso ver o conteúdo de / usr em / tmp / mnt:
# ls /tmp/mnt
bin games include lib lib64 local sbin share src
o que me interessa é o espaço usado / disponível no tmpfs abaixo:
# du -sk /tmp/rw
0 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 24 1031104 1% /tmp/rw
Nenhum arquivo em / tmp / rw, mas 24 blocos alocados. Ainda não é um grande problema.
Eu posso escrever um arquivo para o aufs, ele será armazenado em tmpfs em / tmp / rw:
# dd if=/dev/zero of=/tmp/mnt/test bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000343903 s, 298 MB/s
# du -sk /tmp/rw
100 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 128 1031000 1% /tmp/rw
Observe como as estatísticas de uso foram alteradas. du
mostra 100kB adicionado, como esperado, mas o valor 'Usado' na saída df
aumentou em 104 blocos.
Quando eu removo o arquivo:
# du -sk /tmp/rw
0 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 28 1031100 1% /tmp/rw
Quatro blocos são perdidos.
Quando repito os comandos dd
e rm
algumas vezes, obtenho:
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 36 1031092 1% /tmp/rw
Mais e mais blocos de tmpfs se foram e eu não sabia onde…
Onde eu fiz o mesmo - dd
e rm
diretamente no / tmp / rw nada foi perdido dessa maneira. E depois de desmontar os aufs, o espaço perdido no tmpfs foi recuperado. Então, pelo menos, eu sabia que era aufs, não tmpfs para culpar.
O que vem acontecendo
Sabendo o que culpar, descrevi meu problema na lista de discussão aufs-users. Eu recebi rapidamente as primeiras respostas. O de J. R. Okajima me ajudou a explicar o que está acontecendo com os blocos tmpfs que estão faltando.
Era um arquivo excluído, de fato. Ele não foi mostrado por lsof
ou em qualquer lugar em /proc/<pid>/*
, pois o arquivo não foi aberto ou mmapeado por nenhum processo de espaço do usuário. O arquivo, o 'arquivo xino', é uma tabela de conversão de números de inodes externos do aufs e é usado internamente pelo módulo aufs do kernel.
O caminho para o arquivo pode ser lido em sysfs:
# cat /sys/fs/aufs/si_*/xi_path
/tmp/rw/.aufs.xino
Mas, como o arquivo é excluído, ele não pode ser visto diretamente:
# ls -l /tmp/rw/.aufs.xino
ls: cannot access /tmp/rw/.aufs.xino: No such file or directory
No entanto, informações sobre seu tamanho e tamanho dos outros arquivos aufs especiais podem ser lidas a partir do debugfs:
# for f in /sys/kernel/debug/aufs/si_8c8d888a/* ; do echo -n "$f: " ; cat $f ; done
/sys/kernel/debug/aufs/si_8c8d888a/xi0: 1, 32x4096 132416
/sys/kernel/debug/aufs/si_8c8d888a/xi1: 1, 24x4096 626868
/sys/kernel/debug/aufs/si_8c8d888a/xib: 8x4096 4096
/sys/kernel/debug/aufs/si_8c8d888a/xigen: 8x4096 88
Os detalhes estão descritos na página de manual do aufs .
A solução
O 'arquivo xino' pode ser truncado manualmente por:
# mount -o remount,itrunc_xino=0 /tmp/mnt
O truncamento automático de arquivos xino pode ser solicitado usando a opção trunc_xino durante a montagem do aufs:
# mount -t aufs -n -o "br:/tmp/rw:/usr,trunc_xino" none "/tmp/mnt"
Ainda não sei como isso afeta o desempenho do sistema de arquivos ou se isso realmente resolverá meus problemas de falta de espaço de tmpfs na produção ... mas aprendi muito.