Domanda

Qual è il modo corretto per rinominare durevolmente un file in un file system POSIX? In particolare chiedendo circa fsyncs sul directory . (Se questo dipende dalla OS / FS, sto chiedendo di Linux e ext3 / ext4).

Nota : ci sono altre domande su StackOverflow su rinomina durevoli, ma AFAICT non affrontano fsync-zione le directory (che è quello che conta per me - io non sono nemmeno la modifica dei dati di file ).

Al momento ho (in Python):

dstdirfd = open(dstdirpath, O_DIRECTORY|O_RDONLY)
rename(srcdirpath + '/' + filename, dstdirpath + '/' + filename)
fsync(dstdirfd)

Domande specifiche :

  • Fa questo anche implicitamente fsync la directory di origine? O potrei finire con il file mostrando in entrambe le directory dopo un ciclo di alimentazione (nel senso che avrei dovuto controllare il conteggio hard link ed eseguire manualmente il recupero), vale a dire che è impossibile garantire un'operazione di spostamento durevolmente atomica?
  • Se io fsync la directory di origine al posto della directory di destinazione , voglio che anche implicitamente fsync la directory di destinazione?
  • Ci sono alcun test utile ad / debug / strumenti (iniettori di guasto, strumenti di introspezione, filesystem finte, ecc.) L'apprendimento?

Grazie in anticipo.

È stato utile?

Soluzione

POSIX definisce che la href="http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html" rel="nofollow funzione rinomina deve essere atomica .

Quindi, se si rinomina (A, B), in nessun caso si dovrebbe mai vedere uno stato con il file in entrambe le directory o nessuna directory. Ci saranno sempre esattamente uno, non importa quello che fai con fsync (), oppure se il sistema si blocca.

Ma questo non risolve il problema di fare in modo l'operazione di ridenominazione () è durevole. POSIX risponde a questa domanda :

  

Se _POSIX_SYNCHRONIZED_IO è definita, la funzione fsync () è costringere tutti attualmente I coda / O operazioni associate al file indicato da fildes file descriptor allo stato di completamento I / O sincronizzato. Tutte le operazioni di I / O devono essere compilate secondo quanto stabilito per il completamento integrità del file sincronizzato di I / O.

Quindi, se si fsync () in una directory, le operazioni di ridenominazione in sospeso deve essere trasferito su disco per il momento in questo ritorni. fsync () di una directory dovrebbe essere sufficiente perché atomicità della operazione di ridenominazione () richiederebbe che i cambiamenti entrambe le directory essere sincronizzati in modo atomico.

Infine, in contrasto con l'affermazione nel post del blog citato in un'altra risposta, il razionale per questo spiega quanto segue:

  

La funzione fsync () destinato a forzare una scrittura fisica dei dati dalla cache di buffer, e per assicurare che dopo un arresto di sistema o un altro errore che tutti i dati fino al momento della chiamata fsync () viene registrato sulla disco. Dal momento che i concetti di "buffer cache", "crash di sistema", "scrittura fisica", e "memoria non volatile" non sono definiti qui, il testo deve essere più astratto.

Un sistema che ha affermato di essere conforme a POSIX e che ritenuto comportamento corretto (cioè non un fallimento bug o hardware) per completare un fsync () e non persistono quei cambiamenti attraverso un crash di sistema dovrebbe essere deliberatamente dichiarazioni false rispetto alle specifiche.

(aggiornato con informazioni aggiuntive Re: contro il comportamento portatile specifico Linux)

Altri suggerimenti

Purtroppo la risposta di Dave è sbagliata.

Non tutti i sistemi POSIX potrebbe anche avere un deposito di lunga durata. E se lo fanno, è ancora “permesso” ad essere bloccato dopo un crash di sistema. Per questi sistemi un no-op fsync () ha un senso, e tale fsync () è espressamente consentito dalla POSIX. E 'anche legale per il file recuperabili nella vecchia directory, la nuova directory, sia, o in qualsiasi altro luogo. POSIX non fornisce alcuna garanzia per i crash di sistema o recuperi di file system.

La vera domanda dovrebbe essere:

Come fare una ridenominazione durevole sui sistemi che di supporto che attraverso l'API POSIX?

Hai bisogno di fare un fsync () su entrambi, fonte di e directory di destinazione, perché il minimo quelli fsync) s (si suppone di fare è persistere come directory di origine o di destinazione dovrebbe essere simile.

Fa un fsync (destdirfd) anche implicitamente fsync directory dei sorgenti?

  • POSIX in generale: no, niente implica che
  • ext3 / 4: Non sono sicuro se entrambe le modifiche alla fonte e la destinazione dir finiscono nella stessa transazione nella rivista. Se lo fanno, ottengono entrambi commesso insieme.

O potrei finire con il file mostrando in entrambe le directory dopo un ciclo di alimentazione ( “crash”), vale a dire che è impossibile garantire un'operazione di spostamento durevolmente atomica?

  • POSIX in generale: non ci sono garanzie, ma si suppone che fsync () entrambe le directory, che potrebbe non essere atomica durevole
  • ext3 / 4: quanta fsync () si minimamente bisogno dipende dalle opzioni di montaggio. Per esempio. se montato con “dirsync” non hai bisogno di nessuno di questi due fsync () s. Al massimo è necessario sia fsync () s, ma sono quasi sicuro che uno è sufficiente (atomica-resistente poi).

Se io fsync la directory di origine invece che la directory di destinazione, voglio che anche implicitamente fsync la directory di destinazione?

  • POSIX: no
  • ext3 / 4: Credo davvero sia finiscono nella stessa transazione, quindi non importa quale di essi si fsync ()
  • vecchio kernel ext3: (se non sono nella stessa transazione) un po 'di implementazione non-così-ottimale ha fatto modo troppo sincronizzazione su fsync (), scommetto che ha commesso ogni operazione che è venuto prima. E sì, un'implementazione normale sarebbe prima collegarlo alla destinazione e poi rimuoverlo dalla sorgente. Così il fsync (srcdirfd) innescherebbe il fsync () della destinazione come bene.
  • ext4 / ultime ext3: se non sono nella stessa transazione, si potrebbe essere in grado di completamente sincronizzati in modo indipendente (così fanno entrambi)

Ci sono delle utili relative testing / debug / strumenti di apprendimento (iniettori di guasto, strumenti di introspezione, filesystem finte, ecc.)?

Per un incidente vero e proprio, no. Tra l'altro, un incidente vero e proprio va oltre il punto di vista del kernel. L'hardware potrebbe riordinare scrive (e non riescono a tutto scrittura), corrompere il file system. Ext4 è meglio preparato contro questo, perché consente barries scrittura (opzioni di montaggio) per impostazione predefinita (ext3 non lo fa) e in grado di rilevare la corruzione con checksum rivista (anche l'opzione di montaggio).

E per l'apprendimento: scoprire se entrambe le variazioni sono in qualche modo collegati sulla rivista! :-P

La risposta alla tua domanda sta andando a dipendere molto dal sistema operativo specifico utilizzato, il tipo di file system in uso e se la sorgente e dest sono sullo stesso dispositivo oppure no.

Mi piacerebbe iniziare leggendo la (2) pagina man rename sulla piattaforma che si sta utilizzando.

Sembra a me come si sta cercando di fare il lavoro del filesystem. Se si sposta un file del kernel e il file-system sono responsabili per il funzionamento atomica e fault-recupero, non è il vostro codice.

In ogni caso, questo articolo sembra rispondere alle vostre domande riguardanti fsync: http://blogs.gnome.org/ alexl / 2009/03/16 / ext4-vs-fsync-my-prendere /

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top