Va premesso che questa situazione avviene molto raramente e non è la prassi di ogni crash come molti credono. Fortunatamente questo problema ora fa parte del passato, ivi di seguito vi spiegherò come risolverlo una volta per tutte ed ottenere una migliore affidabilità del filesystem anche nei momenti più critici.
XFS è progettato affinchè non scriva immediatamente i file, ma prima di farlo aspetta che i suoi buffer di scrittura siano saturi (e/o allineati con lo stripe size dell'array RAID) dopodichè rigira i dati al journaling sotto forma di metadatas; sarà il journaling ad occuparsi della loro scrittura al momento opportuno garantendo l'integrità del filesystem stesso nei momenti critici. Proprio qui inizia il paradosso, il journaling di XFS, che dovrebbe garantire l'affidabilità dei dati, non riesce nel suo intento determinando la perdita dei metadatas.
Il punto è: perchè il journaling di XFS non fa quello che dovrebbe?, la risposta è molto semplice e potrebbe essere sconcertante per qualcuno: non è colpa del journaling di XFS, ma del kernel e di certi hard drive che fanno troppo e lo fanno pure male. Mi spiego meglio, quando il journal decide di scrivere i metadatas, i dati vengono inviati all'HD, ma se questo ha la write cache abilitata, i metadatas restano nella suddetta cache e non vengono scritti realmente sull'HD fino a quando non sarà completamente satura. E' proprio in questo frangente che se capita un crash o un freeze di sistema avviene la perdita di dati, non perchè XFS è inefficiente o ha dei BUG (non ne ha da questo punto di vista), ma per il semplice fatto che l'HD non ha scritto i dati nel momento in cui gli è stato detto di farlo, non solo, la write cache quando riceve un dato restituisce al filesystem la conferma dell'avvenuta scrittura dello stesso, anche se in realtà è ancora nella cache (perchè non è piena).
XFS non ha modo di verificare l'effettivo flusso dei dati dalla write cache verso il disco di silicio, per cui per il filesystem i dati sono stati scritti e quindi procede oltre con le sue operazioni. Va da se, che se nel frattempo avviene un imprevisto, il filesystem si ritrova con delle inconsistenze tra il journaling e il filesystem stesso e la fastidiosa perdita sporadica di qualche file.
Generalmente questo problema della write cache che non fa il flush dei dati quando deve, è una prerogativa degli hard drive ATA e PATA di classe economica, o di drive ATA/SCSI molto vecchi; gli hard drive di una certa qualità abbinano alla write cache le write barrier hardware il cui scopo è proprio quello di evitare il problema sopra esposto. Le write barrier sono supportate dal kernel linux da tempo immemore, sia quelle 'hardware' che quelle 'software' (cioè emulate per quegli hard drive di cui ne sono sprovvisti); purtroppo dal kernel 2.5.x tale supporto è stato disabilitato perchè dava dei problemi e lo è rimasto fino alla serie 2.6.15 (quindi per diversi anni), per poi essere nuovamente disabilitato fino alla serie 2.6.17, dalla cui versione invece è abilitata di default.
E' proprio per colpa della mancanza di questa feature nel kernel che si verifica la perdita di dati in caso di crash, quindi per risolvere il problema abbiamo 2 soluzioni:
- per chi possiede un kernel precedente al 2.6.17 bisogna disabilitare la write cache dell'hard drive, oppure forzare l'uso delle barrier nel kernel sperando che queste vengano riconosciute e/o emulate correttamente (ogni major e minor release ha i suoi problemi con le barrier, quindi è impossibile dire quale versione risolva il problema e quale no).
- usare un kernel 2.6.17 o superiori
Determinare se la write cache è attiva
per gli hard drive ATA/PATA/SATA:
Code: Select all
hdparm -I /dev/hda | grep Writel'asterisco indica che è abilitata, la sua assenza invece indica che è disabilitata
per gli hard drive SCSI:
Code: Select all
sdparm --get=WCE /dev/sdXDisabilitare la write cache
per gli hard drive ATA/PATA/SATA:
Code: Select all
hdarm -W0 -k1 -K1 /dev/hdXper gli hard driver SCSI:
Code: Select all
sdparm --clear=WCE --save /dev/sdXForzare il supporto del kernel per le write barrier
Per abilitare forzatamente le write barrier per i kernel che hanno tale funzione disabilitata di default, è sufficiente montare la partizione desiderata con questa opzione:
Code: Select all
/dev/hdXY / xfs barrier 0 0




