
Eu uso RAM para meu tmpfs/tmp, 2 GB, para ser exato. Normalmente, isso é suficiente, mas às vezes os processos criam arquivos lá e não conseguem limpá-los. Isso pode acontecer se eles falharem. Preciso excluir esses arquivos tmp órfãos ou o processo futuro ficará sem espaço em/tmp.
Como posso coletar lixo /tmp com segurança? Algumas pessoas fazem isso verificando o carimbo de data e hora da última modificação, mas essa abordagem não é segura porque pode haver processos de longa execução que ainda precisam desses arquivos. Uma abordagem mais segura é combinar a condição de carimbo de data/hora da última modificação com a condição de que nenhum processo tenha um identificador de arquivo para o arquivo. Existe um programa/script/etc que incorpore esta abordagem ou alguma outra abordagem que também seja segura?
Aliás, o Linux/Unix permite um modo de abertura de arquivo com criação em que o arquivo criado é excluído quando o processo de criação termina, mesmo que seja devido a uma falha?
Responder1
Você pode querer tentar algo assim:
find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'
find é usado para localizar arquivos que correspondam a determinados critérios.
-mtime +7
seleciona apenas arquivos com mais de 7 dias (você pode usar qualquer outro valor)-exec fuser -s {} ';'
chama o fusor no modo silencioso para cada arquivo que corresponda aos critérios de antiguidade. fuser retorna 0 (=true) para cada arquivo que foi acessado no momento e 1 (=false) para os não acessados. Como estamos interessados apenas nos não acessados, colocamos um-not
na frente deste-exec
-exec echo {} ';'
apenas imprime todos os nomes de arquivos que correspondem aos critérios. você pode querer usar-exec rm {} ';'
aqui, mas como isso pode excluir alguns arquivos ainda em uso, acho mais seguro fazer um eco simples primeiro.- editar:Você pode querer adicionar algo como
-name 'foo*.bar'
ou-uid 123
limitar os efeitos da limpeza a padrões de arquivo ou IDs de usuário específicos para evitar efeitos acidentais.
Até o último ponto: Considere que pode haver arquivos que são gravados apenas uma vez (por exemplo, na inicialização do sistema), mas lidos com frequência (por exemplo, qualquer cookie de sessão X). Portanto, recomendo adicionar algumas verificações de nome para afetar apenas os arquivos criados por seus programas defeituosos.
editar2: Para sua última pergunta: um arquivo não será excluído do disco até que nenhum processo tenha um identificador aberto para ele (pelo menos para sistemas de arquivos Linux nativos). O problema é que a entrada do diretório é removida imediatamente, o que significa que a partir do momento em que você remove o arquivo, nenhum novo processo pode mais abri-lo (pois não há nome de arquivo anexado a ele).
Para obter detalhes, consulte: https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux
editar3:Mas e se eu quisesse automatizar todo o processo?
Como eu disse, pode haver arquivos que são gravados uma vez e lidos de vez em quando (por exemplo, cookies de sessão X, arquivos PID, etc.). Eles não serão excluídos por este pequeno script de remoção (que é a razão pela qual você pode querer fazer um teste echo
antes de realmente excluir os arquivos).
Uma maneira de implementar uma solução segura é usar atime
.
atime
armazena a hora em que cada arquivo foi acessado pela última vez. Mas essa opção do sistema de arquivos geralmente é desativada porque tem algum impacto no desempenho (de acordo comeste blogem algum lugar na região de 20-30%). Tem relatime
, mas aquele só escreve o tempo de acesso se mtime
tiver mudado, então este não vai nos ajudar.
Se você quiser usar o atime
, recomendo ter /tmp
uma partição separada (de preferência um ramdisk) para que o impacto no desempenho de todo o sistema não seja muito grande.
Uma vez atime
habilitado, tudo que você precisa fazer é substituir o -mtime
parâmetro na linha de comando acima por -atime
.
Você pode remover o -not -exec fuser -s {} ';'
, mas eu o manteria lá apenas para ter certeza (caso os aplicativos mantenham os arquivos abertos por um longo período de tempo).
Mas lembre-se de testar o comando echo
antes de remover coisas que seu sistema ainda precisa!
Responder2
Não role o seu próprio.
Debian/Ubuntu tem tmpreaper, provavelmente também está disponível em outras dists.
# tmpreaper - cleans up files in directories based on their age
sudo apt-get install tmpreaper
cat /etc/tmpreaper.conf
Responder3
Em relação à última parte da sua pergunta:
Embora eu não ache que exista um modo de abertura/criação 'exclua-se-eu-morrer', um processo pode excluir com segurança um arquivo diretamente após criá-lo, desde que mantenha um identificador para o arquivo aberto. O kernel então manterá o arquivo no disco e assim que o último processo que abriu o arquivo sair (seja por crash ou normalmente), o espaço ocupado pelo arquivo será liberado.
Para uma maneira geral de contornar o problema de que alguns processos às vezes não limpam /tmp, sugiro dar uma olhada nos namespaces de montagem, descritos, por exemploaquiouaqui. Se o processo em questão for um daemon do sistema,sistemae seu recurso nativo para permitir sistemas de arquivos privados /tmp pode ser interessante.
Responder4
Obtenha uma lista de arquivos mais antigos e exclua os arquivos abertos por qualquer coisa dessa lista:
find /tmp -mtime +7 |\
egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`"
lsof -n +D /tmp
: procure por arquivos abertos em /tmp
awk 'NR>1 {print $9}'
: imprima apenas a nona coluna da saída lsof, excluindo os cabeçalhos
tr \\n \|
: substitua a nova linha por bar (OU em egrep)
egrep -v "foo|moo|bar"
: imprima linhas NÃO contendo foo ou moo ou bar