Como um programa de log pode continuar registrando em um arquivo excluído?


12

Na Unix Power Tools, 3ª Edição : em vez de remover um arquivo, esvazie a seção:

Se um processo ativo tiver o arquivo aberto (não é incomum para arquivos de log), remover o arquivo e criar um novo não afetará o programa de registro; essas mensagens continuarão indo para o arquivo que não está mais vinculado . O esvaziamento do arquivo não interrompe a associação e, portanto, limpa o arquivo sem afetar o programa de registro.

( ênfase minha )

Não entendo por que um programa continuará registrando em um arquivo excluído. É porque a entrada do descritor de arquivo não foi removida da tabela de processos?

Respostas:


11

Ao excluir um arquivo, você realmente remove um link para o arquivo (para o inode). Se alguém já tiver esse arquivo aberto, ele manterá o descritor de arquivo que possui. O arquivo permanece no disco, ocupando espaço, e pode ser gravado e lido se você tiver acesso a ele.

A unlinkfunção é definida com este comportamento pelo POSIX:

Quando a contagem de links do arquivo se tornar 0 e nenhum processo tiver aberto o arquivo, o espaço ocupado pelo arquivo será liberado e o arquivo não estará mais acessível. Se um ou mais processos tiverem o arquivo aberto quando o último link for removido, o link será removido antes do retorno de unlink (), mas a remoção do conteúdo do arquivo será adiada até que todas as referências ao arquivo sejam fechadas .

Este conselho por causa desse comportamento. O daemon terá o arquivo aberto e não notará que ele foi excluído (a menos que o estivesse monitorando especificamente, o que é incomum). Ele continuará gravando alegremente o descritor de arquivo existente: você continuará ocupando (mais) espaço no disco, mas não poderá ver nenhuma das mensagens gravadas; portanto, você está realmente no pior dos dois mundos. Se você truncar o arquivo com tamanho zero, o espaço será liberado imediatamente e quaisquer novas mensagens serão anexadas no novo final do arquivo, onde você poderá vê-las.

Eventualmente, quando o daemon finalizar ou for closeo arquivo , o espaço será liberado. Entretanto, ninguém novo pode abrir o arquivo (exceto por meio de interfaces reflexivas específicas do sistema, como as do Linux/proc/x/fd/... ). Também é garantido que:

Se a contagem de links do arquivo for 0, quando todos os descritores de arquivos associados ao arquivo forem fechados, o espaço ocupado pelo arquivo será liberado e o arquivo não estará mais acessível.

Portanto, você não perde seu espaço em disco permanentemente, mas não ganha nada ao excluir o arquivo e perde acesso a novas mensagens.


1
O que ocorrerá se um usuário (digamos root aqui) tentar desvincular /proc/x/fd/y? Isso faria com que o processo falhasse ao gravar no descritor de arquivo ou é uma operação ilegal?
Nanofarad

@hexafraction /proc/*/fd/*são links simbólicos para arquivos reais, portanto, removê-los não excluirá o arquivo. Eu sugiro que você experimente :) (não no sistema de produção, é claro!)
Ruslan

1
@MichaelHomer Talvez você possa esclarecer em sua resposta que, uma vez que um arquivo é desvinculado, o processo com um descritor de arquivo apontando para ele pode vinculá-lo novamente, no mesmo caminho ou não. Às vezes, isso pode ser útil.
Lgeorget

@hexafraction Bem, essas são apenas representações (no espaço do sistema de arquivos) do estado do processo e dos objetos. Se você remover essas representações no espaço do sistema de arquivos, nada deverá acontecer com o processo real - a menos que ele (ou algum outro processo) dependa da representação existente. Não tenho certeza se você pode usá-lo rmincontinentemente dentro /procou /syssem ser avisado pelo sistema de qualquer maneira.
David Tonhofer

@lgeorget Como isso é realizado?
Michael

8

Exatamente.

Os arquivos são divididos em três partes.

  • O conteúdo, ou seja, uma matriz plana de bytes, gravada em algum lugar do disco ou gerada on-the-fly.
  • O nó de índice , ou inode, para abreviar, que é uma estrutura de dados preenchida e usada pelo kernel. Ele contém todos os metadados (tamanho, permissão, etc.) sobre o arquivo e também ponteiros para o local do conteúdo do arquivo.
  • Uma ou mais entradas de diretório , que são locais, manipulados como caminhos como /home/user/personal_file, que agem como alças através do qual você pode usar o arquivo, modificar seu conteúdo, alterar seus metadados, etc.

Ao abrir um arquivo, você indica o caminho para o sistema operacional e ele retorna um identificador diretamente para o inode. Com esse identificador, chamado de descritor de arquivo, você pode manipular o arquivo como desejar (ou pelo menos conforme permitido pelo sistema operacional).

Você nunca pode excluir diretamente um inode, é necessário fornecer um caminho para o sistema operacional para exigir a exclusão. Portanto, quando você deseja excluir um arquivo, exclua apenas a entrada do diretório. Se o arquivo tiver outras entradas de diretório, ele continuará acessível, e mesmo se não tiver, seu inode não será excluído enquanto ainda houver descritores de arquivo apontando para ele. A resposta do @ MichaelHomer é mais técnica e mais detalhada sobre esse tópico específico.


4

As outras 2 respostas explicam bem o problema - um arquivo não é "excluído" até que todos os links de diretório e todos os descritores de arquivos abertos acabem.

Para evitar isso, é um bom hábito usar

> /var/log/bigfile

ao invés de

rm -f /var/log/bigfile

pois isso redefine o conteúdo para 0 bytes, em vez de excluí-lo, e você ainda pode ver o que está escrito nele.

Se você excluiu o arquivo e está no linux em que possui um sistema de arquivos / proc / fd, ainda pode usar

> /proc/12345/fd/3

para zerar o conteúdo do arquivo (assumindo que 12345 é o seu ID de processo e 3 é o número fd do arquivo grande). Isso pode salvar vidas se o disco estiver cheio e você não conseguir interromper o processo que está gravando o arquivo de log por algum motivo.


> /var/log/bigfileremove os dados existentes no arquivo, mas não impede que programas sejam gravados lá. Existem muito poucas circunstâncias em que é a coisa certa. Eu diria que é um mau hábito entrar. Se você deseja excluir um arquivo, use rm. Se você deseja interromper os programas que estão gravando lá, mate-os ou faça-os parar de gravar, antes ou depois da exclusão.
Gilles 'SO- stop be evil'

1
@ Giles, este tópico é sobre o fato de que a exclusão não ajudará se um programa ainda tiver o arquivo aberto. E se o seu disco está cheio porque alguns misbehaves programa e syslogdpreenchimentos /var/log/messages, > /var/log/messagesé um muito melhor opção do que matar syslogd. Obviamente, isso não deve impedir você de analisar qual é o problema.
Guntram Blohm apoia Monica
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.