Como limpar a pasta tmp com segurança no Linux

14

Uso RAM para meus tmpfs / tmp, 2 GB, para ser exato. Normalmente, isso é suficiente, mas, às vezes, os processos criam arquivos e não conseguem limpar depois deles mesmos. Isso pode acontecer se eles falharem. Preciso excluir esses arquivos tmp órfãos, caso contrário, o processo futuro ficará sem espaço em / tmp.

Como posso coletar o lixo com segurança / tmp? Algumas pessoas fazem isso verificando o carimbo de data e hora da última modificação, mas essa abordagem não é segura, pois pode haver processos de execução demorada que ainda precisam desses arquivos. Uma abordagem mais segura é combinar a condição de carimbo de data e hora da última modificação com a condição de que nenhum processo possui um identificador de arquivo para o arquivo. Existe um programa / script / etc que incorpore essa abordagem ou alguma outra abordagem que também seja segura?

Aliás, o Linux / Unix permite um modo de abertura de arquivo com a criação em que o arquivo criado é excluído quando o processo de criação termina, mesmo que seja de uma falha?

Syncopated
fonte
Verifique se você poderia usar tmpfs em vez de / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Veja também: askubuntu.com/questions/380238/how-to-clean-tmp
Ciro Santilli 事件 改造 中心 法轮功 六四

Respostas:

15

Você pode tentar algo assim:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

find é usado para encontrar arquivos que correspondem a determinados critérios.

  • -mtime +7 somente seleciona arquivos com mais de 7 dias (você pode usar qualquer outro valor)
  • -exec fuser -s {} ';'chama o fusor no modo silencioso para todos os arquivos que correspondam aos critérios de oldness. o fusor retorna 0 (= verdadeiro) para cada arquivo acessado no momento e 1 (= falso) para os não acessados. Como estamos interessados apenas nos mais acedido, nós colocamos um -notem frente a esta-exec
  • -exec echo {} ';'apenas imprime todos os nomes de arquivos que correspondem aos critérios. convém usar -exec rm {} ';'aqui, mas como isso pode excluir alguns arquivos ainda em uso, acho mais seguro fazer um eco simples primeiro.
  • editar: convém adicionar algo como -name 'foo*.bar'ou -uid 123limitar os efeitos da limpeza a padrões de arquivos 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 freqüência (por exemplo, qualquer cookie de sessão X). Portanto, recomendo adicionar algumas verificações de nome para afetar apenas os arquivos criados pelos seus programas defeituosos.

edit2: Para sua última pergunta: Um arquivo não será excluído do disco até que nenhum processo tenha um identificador aberto (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 abrir o arquivo (pois não há um nome de arquivo anexado).

Para obter detalhes, consulte: /programming/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Mas e se eu quisesse automatizar todo o processo?

Como eu disse, pode haver arquivos que são gravados uma vez e depois 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ê deve fazer um teste echoantes de excluir os arquivos).

Uma maneira de implementar uma solução segura é usar atime.
atimearmazena a hora em que cada arquivo foi acessado pela última vez. Mas essa opção de sistema de arquivos geralmente é desativada porque tem algum impacto no desempenho (de acordo com este blog em algum lugar na região de 20 a 30%). Existe relatime, mas esse apenas escreve o tempo de acesso se mtimetiver mudado, portanto este não nos ajudará.

Se você quiser usar atime, eu recomendo que você tenha /tmpuma 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 atimeativado, tudo o que você precisa fazer é substituir o -mtimeparâ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 echoantes de remover as coisas que seu sistema ainda precisa!

mreithub
fonte
legais. E os arquivos fechados por um processo demorado enquanto não os está atualizando? Se forem arquivos de contexto, você poderá perder o contexto do processo (reconhecidamente, não é um processo muito inteligente; mas é necessário conhecer os efeitos colaterais esperados de uma /tmp/limpeza 'lateral' ).
Nik
Esse é o problema dessa abordagem (como eu estava apontando no último parágrafo). A melhor abordagem aqui seria afaik ser adicionar uid / gid ou cheques padrão de arquivo (editado a resposta em conformidade)
mreithub
Isso deve ser colocado em um script cron ...?
precisa saber é o seguinte
@CMCDragonkai É claro que você pode colocar isso no crontab. Mas, como mencionei, pode haver arquivos acessados, mas não gravados, e, portanto, podem não ser filtrados por esse pequeno script. É por isso que é mais seguro imprimir a lista de arquivos afetados primeiro e depois decidir se deseja excluí-los ou não. Se você /tmpestiver em uma partição separada (por exemplo, um ramdisk), você poderá habilitá atime-la e usar o -atimeparâmetro de find.
Mreithub 5/06
Estou planejando fazer isso em um servidor. Portanto, não posso estar lá para contar todos os arquivos em tmp o tempo todo. Haveria algum problema? Também pensei que devíamos usar relacionime e não atime?
precisa saber é o seguinte
4

Não role sozinho.

O Debian / Ubuntu possui o tmpreaper, provavelmente também está disponível em outros discos.

# tmpreaper - cleans up files in directories based on their age

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Gringo Suave
fonte
No /etc/tmpreaper.confarquivo, se eu definir ambos /tmpe /var/tmpcomo os diretórios de limpeza, você recomendaria por muito tempo o TMPREAPER_TIMEparâmetro ou o número máximo máximo de arquivos tmp a serem removidos? Ouvi dizer que é melhor manter uma idade mais longa para /var/tmparquivos do que para /tmparquivos. Mas se eles puderem ser configurados com a mesma idade máxima, não faço ideia.
Xiaodong Qi
2

Em relação à última parte da sua pergunta:

Embora eu não ache que exista um modo de abertura / criação 'excluir-se-eu-morrer', um processo pode excluir um arquivo com segurança diretamente após a sua criação, desde que mantenha um identificador para o arquivo aberto. O kernel manterá o arquivo em disco e assim que o último processo que abriu o arquivo for encerrado (seja por um travamento ou normalmente), o espaço ocupado pelo arquivo será liberado.

Para uma maneira geral de contornar o problema que alguns processos às vezes não limpam / tmp, sugiro dar uma olhada nos namespaces de montagem, descritos, por exemplo, aqui ou aqui . Se o processo em questão for um daemon do sistema, o systemd e seu recurso nativo para permitir sistemas de arquivos private / tmp podem ser interessantes.

Cláudio
fonte
0

Obtenha uma lista de arquivos mais antigos e exclua os arquivos que estiverem 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 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 barra (OU no egrep)
egrep -v "foo|moo|bar": imprima as linhas NÃO contendo foo ou moo ou bar

Ярослав Рахматуллин
fonte
0

Eu concordo com o acima exposto, para acrescentar a ele - eu sempre corro lsof +L1 | grep tmpe ou mato ou reinicio os processos que mantêm os arquivos tmp "excluídos": EXEMPLO-

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)
SeaPhor
fonte
2
O SU organiza aleatoriamente as postagens - para que não haja acima ou abaixo. A qual post você está se referindo?
Journeyman Geek
0

Você poderia simplesmente fazer rm -rf /tmp/*e esperar que nada quebre ...

Solomon Ucko
fonte
1
Sugerindo que fazer alguma coisa "e nada quebra esperança" não responde realmente OP de "é que há um caminho seguro para fazer isso Talvez você possa elaborar a respeito de porque a sua sugestão é seguro.?
bertieb
@bertieb Bom ponto. Eu acho que é provavelmente seguro se não for executado como root, mas ...
Solomon Ucko