Come può un programma di registro continuare a accedere a un file eliminato?


12

Da Unix Power Tools, 3a edizione : invece di rimuovere un file, svuotalo sezione:

Se un processo attivo ha il file aperto (non insolito per i file di registro), rimuovere il file e crearne uno nuovo non influirà sul programma di registrazione; quei messaggi continueranno semplicemente ad andare al file che non è più collegato . Lo svuotamento del file non interrompe l'associazione, quindi cancella il file senza influire sul programma di registrazione.

( enfatizzare il mio )

Non capisco perché un programma continuerà a accedere a un file eliminato. È perché la voce del descrittore di file non viene rimossa dalla tabella dei processi?

Risposte:


11

Quando elimini un file, rimuovi davvero un collegamento al file (all'inode). Se qualcuno ha già quel file aperto, riesce a mantenere il descrittore di file che ha. Il file rimane sul disco, occupando spazio e può essere scritto e letto se si ha accesso ad esso.

La unlinkfunzione è definita con questo comportamento da POSIX:

Quando il conteggio dei collegamenti del file diventa 0 e nessun processo ha il file aperto, lo spazio occupato dal file deve essere liberato e il file non sarà più accessibile. Se uno o più processi hanno il file aperto quando viene rimosso l'ultimo collegamento, il collegamento deve essere rimosso prima che unlink () ritorni, ma la rimozione del contenuto del file deve essere posticipata fino alla chiusura di tutti i riferimenti al file .

Questo consiglio a causa di quel comportamento. Il demone avrà il file aperto e non noterà che è stato eliminato (a meno che non lo stesse monitorando in modo specifico, il che è insolito). Continuerà a scrivere in modo beato sul descrittore di file esistente che ha: continuerai a occupare (più) spazio sul disco, ma non sarai in grado di vedere nessuno dei messaggi che scrive, quindi sei davvero nel peggiore di entrambi i mondi. Se invece il file viene troncato a zero, lo spazio viene immediatamente liberato e tutti i nuovi messaggi verranno aggiunti alla nuova fine del file in cui è possibile visualizzarli.

Alla fine, quando il demone termina o closes il file , lo spazio verrà liberato. Nel frattempo nessuno può aprire il file (se non attraverso interfacce riflettenti specifiche del sistema come quelle di Linux/proc/x/fd/... ). È inoltre garantito che:

Se il conteggio dei collegamenti del file è 0, quando tutti i descrittori di file associati al file sono chiusi, lo spazio occupato dal file deve essere liberato e il file non sarà più accessibile.

Quindi non perdi lo spazio su disco in modo permanente, ma non guadagni nulla eliminando il file e perdi l'accesso a nuovi messaggi.


1
Cosa accadrà se un utente (diciamo root qui) tenta di scollegare /proc/x/fd/y? Ciò causerebbe la mancata scrittura del processo nel descrittore di file nel processo o si tratta di un'operazione illegale?
nanofarad,

@hexafraction /proc/*/fd/*sono collegamenti simbolici a file reali, quindi rimuoverli non eliminerà il file. Ti suggerirei di sperimentare :) (ovviamente non sul sistema di produzione!)
Ruslan,

1
@MichaelHomer Forse potresti chiarire nella tua risposta che una volta che un file è scollegato, il processo che ha un descrittore di file che lo punta può collegarlo di nuovo, nello stesso percorso o meno. Questo a volte può essere utile.
lgeorget,

@hexafraction Bene, queste sono solo rappresentazioni (nello spazio del filesystem) dello stato del processo e degli oggetti. Se rimuovete quelle rappresentazioni nello spazio del filesystem, nulla dovrebbe accadere al processo reale - a meno che (o qualche altro processo) non si basi sul fatto che quella rappresentazione sia lì. Non sono sicuro di poterlo utilizzare in modo rmincontinente all'interno /proco /syssenza essere informato dal sistema.
David Tonhofer,

@lgeorget Come viene realizzato?
Michael,

8

Esattamente.

I file sono tripartiti.

  • Il contenuto, ovvero una matrice piatta di byte, scritta da qualche parte su un disco o generata al volo.
  • Il nodo indice , o inode in breve, che è una struttura di dati popolata e utilizzata dal kernel. Contiene tutti i metadati (dimensioni, autorizzazioni, ecc.) Relativi al file e inoltre indica la posizione del contenuto del file.
  • Una o più voci della directory , che sono posizioni, manipolate come percorsi simili /home/user/personal_file, che fungono da handle attraverso i quali è possibile utilizzare il file, modificarne il contenuto, modificarne i metadati, ecc.

Quando apri un file, dai il percorso al sistema operativo e ti restituisce un handle direttamente all'inode. Con questo handle, chiamato descrittore di file, è possibile manipolare il file come desiderato (o almeno, come consentito dal sistema operativo).

Non è mai possibile eliminare direttamente un inode, è necessario fornire un percorso al sistema operativo per richiedere l'eliminazione. Pertanto, quando si desidera eliminare un file, si elimina solo la voce della directory. Se il file ha altre voci di directory, continuerà ad essere accessibile e, anche se non lo è, il suo inode non verrà eliminato mentre ci sono ancora descrittori di file che puntano ad esso. @La risposta di MichaelHomer è più tecnica e più dettagliata su questo argomento specifico.


4

Le altre 2 risposte spiegano bene il problema: un file non viene "cancellato" fino a quando tutte le directory non si collegano ad esso e tutti i descrittori di file aperti non scompaiono.

Per evitare questo, è una buona abitudine da usare

> /var/log/bigfile

invece di

rm -f /var/log/bigfile

dal momento che reimposta il contenuto a 0 byte invece di eliminarlo e puoi ancora vedere cosa è scritto su di esso.

Se hai eliminato il file e sei su Linux in cui hai un filesystem / proc / fd, puoi ancora usare

> /proc/12345/fd/3

per azzerare il contenuto del file (supponendo che 12345 sia il tuo ID di processo e 3 sia il numero fd del file grande). Questo può essere un salvavita se il disco è pieno e non è possibile interrompere il processo che sta scrivendo il file di registro per qualche motivo.


> /var/log/bigfilerimuove i dati esistenti nel file ma non impedisce ai programmi di scrivere lì. Ci sono pochissime circostanze in cui è la cosa giusta. Direi che è una cattiva abitudine entrare. Se si desidera eliminare un file, utilizzare rm. Se si desidera interrompere i programmi che stanno scrivendo lì, ucciderli o altrimenti farli smettere di scrivere, prima o dopo l'eliminazione.
Gilles 'SO- smetti di essere malvagio' il

1
@Giles, questo argomento riguarda il fatto che l'eliminazione non aiuterà se un programma ha ancora il file aperto. E se il tuo disco è pieno perché alcuni programmi si comportano male e si syslogdriempiono /var/log/messages, > /var/log/messagesè un'opzione molto migliore dell'uccisione syslogd. Naturalmente, ciò non dovrebbe impedirti di analizzare quale sia il problema in primo luogo.
Guntram Blohm sostiene Monica il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.