Eu vi esta pergunta sobre o stackoverflow, mas eu não gostei de nenhuma das respostas, e é realmente uma questão que deve estar aqui no U & L de qualquer maneira.
Basicamente, um inode é usado para cada arquivo no sistema de arquivos. Então, ficar sem inodes geralmente significa que você tem muitos arquivos pequenos por aí. Então a questão realmente se torna "qual diretório possui um grande número de arquivos?"
Neste caso, o sistema de arquivos que nos interessa é o sistema de arquivos raiz /
, então podemos usar o seguinte comando:
find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n
Isto irá mostrar uma lista de todos os diretórios no sistema de arquivos prefixados com o número de arquivos (e subdiretórios) naquele diretório. Assim, o diretório com o maior número de arquivos estará na parte inferior.
No meu caso, isso é o seguinte:
1202 /usr/share/man/man1
2714 /usr/share/man/man3
2826 /var/lib/dpkg/info
306588 /var/spool/postfix/maildrop
Então, basicamente /var/spool/postfix/maildrop
está consumindo todos os inodes.
Note que esta resposta tem três advertências que eu posso pensar. Ele não manipula adequadamente nada com novas linhas no caminho. Eu sei que meu sistema de arquivos não tem arquivos com novas linhas, e como isso só está sendo usado para consumo humano, o problema em potencial não vale a pena ser resolvido (e sempre é possível substituir o \n
por
e usar sort -z
-xdev
acima) . Ele também não manipula se os arquivos estão espalhados entre um grande número de diretórios. Isso não é provável, então considero o risco aceitável. Ele também contará hard links para um mesmo arquivo (usando apenas um inode) várias vezes. Mais uma vez, é improvável que dê falsos positivos
A principal razão pela qual eu não gostei de nenhuma das respostas na resposta do stackoverflow é que elas cruzam todos os limites do sistema de arquivos. Como o meu problema estava no sistema de arquivos raiz, isso significa que ele atravessaria todos os sistemas de arquivos montados. Lançar /mnt/foo
nos comandos find nem funcionaria corretamente.
Por exemplo, a resposta mais votada é esta:
for i in 'find . -type d '; do echo 'ls -a $i | wc -l' $i; done | sort -n
Se mudarmos isso para
for i in 'find . -xdev -type d '; do echo 'ls -a $i | wc -l' $i; done | sort -n
mesmo que find . -mount -type d
seja uma montagem, ela também é um diretório no sistema de arquivos raiz, então ela aparecerá em ls -a $i
e, em seguida, será transmitida para o find
, que será analisado o monte.
O %code% na minha resposta lista o diretório de cada arquivo na montagem. Então basicamente com uma estrutura de arquivos como:
/foo/bar
/foo/baz
/pop/tart
terminamos com
/foo
/foo
/pop
Então, só precisamos contar o número de linhas duplicadas.