venerdì 18 dicembre 2009

ZFS: always consistent on disk (parte 3)

Terminiamo questa serie di articoli (parte 1, parte 2) sulla consistenza su disco di ZFS analizzando una comoda proprietà impostabile a livello di filesystem che ci consente di aumentare le probabilità di ripristino di un file in caso di errore anche avendo a disposizione un solo disco fisso. Purtroppo in molti casi ci è impossibile disporre di un secondo disco per impostare il mirroring a livello di pool; pensate ad esempio ai portatili, potrei aggiungere come secondo disco di mirror un disco esterno collegato via USB, ma le prestazioni ne risentirebbero!
Grazie alla proprietà copies, impostabile a livello di filesystem, possiamo indicare a ZFS quante copie deve fare di ogni singolo blocco dati, nel caso in cui uno di questi blocchi fosse danneggiato ZFS provvederà a recuperarlo dalla seconda copia così come avrebbe fatto da un secondo disco. Il limite massimo di copie impostabili è pari a tre.

ATTENZIONE: i test comportano l’alterazione dei dati presenti nei dischi utilizzati nei pool, quindi effettuate questi test su filesystem di prova, che non contengono dati e sopratutto A VOSTRO RISCHIO E PERICOLO!!!!



Andiamo a valutare il comportamento di ZFS in caso di alterazione del disco come visto negli altri esempi.
Cominciamo creando il nostro pool di test con un solo disco:
$ mkfile 150m disk1
$ pfexec zpool create testPool `pwd`/disk1

impostiamo a due il numero delle copie settando l'apposita opzione in fase di creazione del filesystem:
$ pfexec zfs create -o copies=2 testPool/fs1

copiamo il solito file di test e rileviamo l'Object-ID e il DVA del primo blocco dati:
$ pfexec cp /etc/bash/bash_completion /testPool/fs1/
$ ls -li /testPool/fs1/
total 1
5 -rwxr-xr-x 1 root root 217434 2009-12-16 11:37 bash_completion*
$ pfexec zdb -ddddd testPool/fs1 5
Dataset testPool/fs1 [ZPL], ID 30, cr_txg 6, 547K, 5 objects,
rootbp DVA[0]=<0:5c800:200> DVA[1]=<0:1c5c800:200> DVA[2]=<0:3814a00:200> [L0 DMU objset]
fletcher4 lzjb LE contiguous unique triple size=800L/200P
birth=10L/10P fill=5
cksum=155932587a:748a6697e34:1521b17e820db:2b3b6c4032fb3a

Object lvl iblk dblk dsize lsize %full type
5 2 16K 128K 515K 256K 100.00 ZFS plain file
264 bonus ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 1
path /bash_completion
uid 0
gid 0
atime Wed Dec 16 11:37:03 2009
mtime Wed Dec 16 11:37:03 2009
ctime Wed Dec 16 11:37:03 2009
crtime Wed Dec 16 11:37:03 2009
gen 10
mode 100755
size 217434
parent 3
links 1
xattr 0
rdev 0x0000000000000000
Indirect blocks:
0 L1 0:5a000:400 4000L/400P F=2 B=10/10
0 L0 0:19e00:20000 20000L/20000P F=1 B=10/10
20000 L0 0:39e00:20000 20000L/20000P F=1 B=10/10

segment [0000000000000000, 0000000000040000) size 256K

frammentiamo, sporchiamo e ricostruiamo il disco come al solito:
$ pfexec zpool export testPool
$ ./zsplit.sh disk1 0x19e00
8399+0 records in
8399+0 records out
4300288 bytes (4.3 MB) copied, 0.100184 s, 42.9 MB/s
256+0 records in
256+0 records out
131072 bytes (131 kB) copied, 0.00666101 s, 19.7 MB/s
298545+0 records in
298545+0 records out
152855040 bytes (153 MB) copied, 3.43945 s, 44.4 MB/s
$ head disk1-p2
#
# This file contains an example set of shell completions that can be used with
# bash(1). These completions allow a user to complete filenames, commands
# name, command line options, and command line arguments using the [tab] key.
# The completions defined here are specific to the GNU command set, as a result
# they will provide the choice of GNU command line options in response to the
# [tab] key. For the completed options to match the command implementation,
# you may have to have /usr/gnu/bin at the head of your PATH.
#
# These completions are not included in the default bash(1) environment. To
$ sed "s/ file / FILE /g" disk1-p2 > disk1-p2-bad
$ cat disk1-p1 disk1-p2-bad disk1-p3 > disk1

ora non ci resta che accedere nuovamente al file e vedere come si comporta ZFS:
$ pfexec zpool import -d `pwd` testPool
$ zpool status testPool
pool: testPool
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 0

errors: No known data errors
$ head /testPool/fs1/bash_completion
#
# This file contains an example set of shell completions that can be used with
# bash(1). These completions allow a user to complete filenames, commands
# name, command line options, and command line arguments using the [tab] key.
# The completions defined here are specific to the GNU command set, as a result
# they will provide the choice of GNU command line options in response to the
# [tab] key. For the completed options to match the command implementation,
# you may have to have /usr/gnu/bin at the head of your PATH.
#
# These completions are not included in the default bash(1) environment. To
$ zpool status testPool
pool: testPool
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: http://www.sun.com/msg/ZFS-8000-9P
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 1

errors: No known data errors

benissimo, ZFS è riuscito a recuperare il contenuto del file dalla seconda copia e ci informa dell'accaduto, spetterà poi a noi valutare se è giunti il momento di sostituire il disco!
Ricordate che è possibile variare il numero di copie impostando l'apposita opzione:
$ pfexec zfs set copies=3 testPool/fs1

tuttavia il nuovo numero di copie riguarderà solo i nuovi file che verranno scritti o modificati dopo la modifica della proprietà.

giovedì 17 dicembre 2009

ZFS: always consistent on disk (parte 2)

Con il precedente articolo abbiamo analizzato il comportamento di ZFS in caso di danneggiamento di alcuni blocchi su disco vediamo cosa accade mettendo a disposizione del filesystem un minimo di ridondanza. Negli esempi utilizzerò due dischi in mirroring, tuttavia lo stesso identico discorso vale in caso di utilizzo di RAIDZ.

ATTENZIONE: i test comportano l’alterazione dei dati presenti nei dischi utilizzati nei pool, quindi effettuate questi test su filesystem di prova, che non contengono dati e sopratutto A VOSTRO RISCHIO E PERICOLO!!!!



Anche qui andiamo a creare il nostro pool e un filesystem al suo interno, copiamo un file e andiamo a leggere il suo Object-ID:
$ mkfile 150m disk1 disk2
$ pfexec zpool create testPool mirror `pwd`/disk1 `pwd`/disk2
$ pfexec zfs create testPool/fs1
$ pfexec zpool status testPool
pool: testPool
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk2 ONLINE 0 0 0

errors: No known data errors
$ pfexec cp /etc/bash/bash_completion /testPool/fs1/
$ ls -li /testPool/fs1/
total 1
5 -rwxr-xr-x 1 root root 217434 2009-12-16 11:29 bash_completion*

ora identifichiamo il DVA del primo blocco dati del nostro file ricorrendo sempre al tool zdb(1M):
$ pfexec zdb -ddddd testPool/fs1 5
Dataset testPool/fs1 [ZPL], ID 30, cr_txg 6, 280K, 5 objects,
rootbp DVA[0]=<0:5a600:200> DVA[1]=<0:1c1a600:200> [L0 DMU objset]
fletcher4 lzjb LE contiguous unique double size=800L/200P
birth=9L/9P fill=5
cksum=15c4f5e074:7dbede02443:17c06031a984a:31d9454fbe4275

Object lvl iblk dblk dsize lsize %full type
5 2 16K 128K 258K 256K 100.00 ZFS plain file
264 bonus ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 1
path /bash_completion
uid 0
gid 0
atime Wed Dec 16 11:29:43 2009
mtime Wed Dec 16 11:29:43 2009
ctime Wed Dec 16 11:29:43 2009
crtime Wed Dec 16 11:29:43 2009
gen 9
mode 100755
size 217434
parent 3
links 1
xattr 0
rdev 0x0000000000000000
Indirect blocks:
0 L1 0:55a00:400 4000L/400P F=2 B=9/9
0 L0 0:15800:20000 20000L/20000P F=1 B=9/9
20000 L0 0:35800:20000 20000L/20000P F=1 B=9/9

segment [0000000000000000, 0000000000040000) size 256K

e come al solito esportiamo il filesystem, spezzettiamo il disco, sporchiamo il settore che inizia al blocco 0x15800, ricomponiamo il tutto e rimontiamo il filesystem:
$ pfexec zpool export testPool
$ ./zsplit.sh disk1 0x15800
8364+0 records in
8364+0 records out
4282368 bytes (4.3 MB) copied, 0.101551 s, 42.2 MB/s
256+0 records in
256+0 records out
131072 bytes (131 kB) copied, 0.00645801 s, 20.3 MB/s
298580+0 records in
298580+0 records out
152872960 bytes (153 MB) copied, 3.40133 s, 44.9 MB/s
$ head disk1-p2
#
# This file contains an example set of shell completions that can be used with
# bash(1). These completions allow a user to complete filenames, commands
# name, command line options, and command line arguments using the [tab] key.
# The completions defined here are specific to the GNU command set, as a result
# they will provide the choice of GNU command line options in response to the
# [tab] key. For the completed options to match the command implementation,
# you may have to have /usr/gnu/bin at the head of your PATH.
#
# These completions are not included in the default bash(1) environment. To
$ sed "s/ file / FILE /g" disk1-p2 > disk1-p2-bad
$ cat disk1-p1 disk1-p2-bad disk1-p3 > disk1
$ pfexec zpool import -d `pwd` testPool
$ pfexec zpool status testPool
pool: testPool
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk2 ONLINE 0 0 0

errors: No known data errors

proviamo ad accedere al nostro file:
$ head /testPool/fs1/bash_completion
#
# This file contains an example set of shell completions that can be used with
# bash(1). These completions allow a user to complete filenames, commands
# name, command line options, and command line arguments using the [tab] key.
# The completions defined here are specific to the GNU command set, as a result
# they will provide the choice of GNU command line options in response to the
# [tab] key. For the completed options to match the command implementation,
# you may have to have /usr/gnu/bin at the head of your PATH.
#
# These completions are not included in the default bash(1) environment. To
$ pfexec zpool status testPool
pool: testPool
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: http://www.sun.com/msg/ZFS-8000-9P
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 1
/export/home/luca/itl-osug/zfs/disk2 ONLINE 0 0 0

errors: No known data errors

in questo caso siamo riusciti ad accedere al nostro file e tutto sembra essere al suo posto, tuttavia lo status di ZFS ci riporta che è stato riscontrato un errore di checksum nel disco numero 1 (quello da noi alterato) e ci "invita" a prendere qualche decisione in merito (sostituire il disco oppure azzerare il conteggio degli errorri)!!

Nella terza ed ultima parte scopriremo come aumentare la sicurezza dei nostri dati anche disponendo di un solo disco fisso.

mercoledì 16 dicembre 2009

ZFS: always consistent on disk (parte 1)

Ieri sera (15 dicembre), durante la LinuxNight di dicembre (foto), organizzata dal Linux User Group di Perugia ho avuto modo di presentare alcune caratteristiche di OpenSolaris, nell'ambito degli incontri organizzati dal Gruppo Italiano degli Utenti OpenSolaris (ITL-OSUG).

Si è parlato di numerosissimi aspetti di OpenSolaris: DTrace, SMF, Time Slider e sopratutto ZFS. Proprio riguardo al motto "always consistent on disk" di ZFS si sono concentrate alcune demo (non tutte portate a termine per mancanza di tempo), per chi non ha potuto seguire "in diretta" la presentazione ecco riportati i vari passaggi dei test effettuati.

ATTENZIONE: i test comportano l'alterazione dei dati presenti nei dischi utilizzati nei pool, quindi effettuate questi test su filesystem di prova, che non contengono dati e sopratutto A VOSTRO RISCHIO E PERICOLO!!!!



Cominciamo creando un nuovo pool (denominato "testPool") senza nessuna ridondanza dei dati attiva in cui creeremo un filesystem (denominato "fs1"), come dischi ho utilizzato un file (chiamato "disk1"):
$ mkfile 150m disk1
$ pfexec zpool create testPool `pwd`/disk1
$ pfexec zfs create testPool/fs1
$ zpool status testPool
pool: testPool
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 0

ora copiamo un file qualsiasi nel nostro filesystem e andiamo a leggere l'i-node attribuito al file (per essere precisi sotto ZFS dovremmo usare il termine ObjectID al posto di i-node):
$ pfexec cp /etc/bash/bash_completion /testPool/fs1/
$ ls -li /testPool/fs1/
total 259
5 -rwxr-xr-x 1 root root 217434 2009-12-16 11:21 bash_completion*

ora, grazie al tool di diagnostica zdb(1M) andiamo a leggere in quali blocchi fisici è stato memorizzato il nostro file (con Object-ID uguale a 5):
$ pfexec zdb -ddddd testPool/fs1 5
Dataset testPool/fs1 [ZPL], ID 30, cr_txg 6, 280K, 5 objects,
rootbp DVA[0]=<0:58200:200> DVA[1]=<0:1c18200:200> [L0 DMU objset]
fletcher4 lzjb LE contiguous unique double size=800L/200P
birth=8L/8P fill=5
cksum=15525a36dc:7f4d019c8fa:18a35fbbba8d3:349cb86bc37272

Object lvl iblk dblk dsize lsize %full type
5 2 16K 128K 258K 256K 100.00 ZFS plain file
264 bonus ZFS znode
dnode flags: USED_BYTES USERUSED_ACCOUNTED
dnode maxblkid: 1
path /bash_completion
uid 0
gid 0
atime Wed Dec 16 11:21:45 2009
mtime Wed Dec 16 11:21:45 2009
ctime Wed Dec 16 11:21:45 2009
crtime Wed Dec 16 11:21:45 2009
gen 8
mode 100755
size 217434
parent 3
links 1
xattr 0
rdev 0x0000000000000000
Indirect blocks:
0 L1 0:53200:400 4000L/400P F=2 B=8/8
0 L0 0:13000:20000 20000L/20000P F=1 B=8/8
20000 L0 0:33000:20000 20000L/20000P F=1 B=8/8

segment [0000000000000000, 0000000000040000) size 256K

tra le tante informazioni visualizzate andiamo ad estrapolare i blocchi che ci interessano, ovvero quelli di livello 0 (L0): il nostro file è stato scritto usando due blocchi con i seguenti DVA (Data Virtual Address): 0:13000:20000 e 0:33000:20000. Il significato dei tre numeri (in esadecimale) è: device sul quale è scritto il blocco (nel nostro caso ne abbiamo uno solo, quindi troveremo sempre zero), offset del blocco rispetto all'inizio del disco (a cui dovremmo aggiungere 4 MegaByte di spazio riservato ai metadati e al boot block) e per finire la grandezza del blocco.

Ora che conosciamo le "coordinate" del nostro file possiamo divertirci a fare qualche danno, prima però esportiamo il nostro pool per poter accedere senza problemi al disco da rovinare!
$ pfexec zpool export testPool

ora, per agevolare la demo ho creato uno script che prende il disco e lo divide in tre parti: la prima conterrà tutto il disco fino al blocco di inizio del file (escluso), la seconda con il blocco richiesto e la terza parte tutto il resto del disco. Lo script richiede due parametri: il nome del disco e l'offset del file (ricavato precedentemente con zdb), lo script è così composto:
$ cat zsplit.sh
#!/bin/sh

DISK=$1

# converte da esadecimale a decimale
START=`echo $2 | awk --non-decimal-data '{print ($1)+0}'`
# aggiunge i 4M di offset (fissi) iniziali e divide per 512 (block size)
START=$(((4194304+$START)/512))
# se non specificato "estrae" 256 blocchi
SIZE=${3:-256}
END=$(($START+$SIZE))

# esegue la "frammentazione"
dd if=$DISK of=$DISK-p1 bs=512 count=$START
dd if=$DISK of=$DISK-p2 bs=512 skip=$START count=$SIZE
dd if=$DISK of=$DISK-p3 bs=512 skip=$END

ora "sezioniamo" il nostro disco e controlliamo che la parte 2 contegga effettivamente il file presente sul nostro disco:
$ ./zsplit.sh disk1 0x13000
8344+0 records in
8344+0 records out
4272128 bytes (4.3 MB) copied, 0.104004 s, 41.1 MB/s
256+0 records in
256+0 records out
131072 bytes (131 kB) copied, 0.00671322 s, 19.5 MB/s
298600+0 records in
298600+0 records out
152883200 bytes (153 MB) copied, 3.6703 s, 41.7 MB/s
$ head disk1-p2
#
# This file contains an example set of shell completions that can be used with
# bash(1).  These completions allow a user to complete filenames, commands
# name, command line options, and command line arguments using the [tab] key.
# The completions defined here are specific to the GNU command set, as a result
# they will provide the choice of GNU command line options in response to the
# [tab] key.  For the completed options to match the command implementation,
# you may have to have /usr/gnu/bin at the head of your PATH.
#
# These completions are not included in the default bash(1) environment.  To

per simulare una "rottura" sporcherò il file con sed(1) mettendo in maiuscolo tutte le occorrenze della parola "file":
$ sed "s/ file / FILE /g" disk1-p2 > disk1-p2-bad

ora "ricomponiamo" il disco, facciamo di nuovo l'import del nostro pool e controlliamo il suo stato:
$ cat disk1-p1 disk1-p2-bad disk1-p3 > disk1
$ pfexec zpool import -d `pwd` testPool
$ zpool status testPool
pool: testPool
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 0
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 0

come vedete zfs ancora non si è accorto della presenza di eventuali errori, ma se proviamo ad accedere al nostro file ci accorgiamo che qualcosa non và:
$ head /testPool/fs1/bash_completion
head: error reading `/testPool/fs1/bash_completion': I/O error
$ pfexec zpool status -v testPool
pool: testPool
state: ONLINE
status: One or more devices has experienced an error resulting in data
corruption. Applications may be affected.
action: Restore the file in question if possible. Otherwise restore the
entire pool from backup.
see: http://www.sun.com/msg/ZFS-8000-8A
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
testPool ONLINE 0 0 1
/export/home/luca/itl-osug/zfs/disk1 ONLINE 0 0 2

errors: Permanent errors have been detected in the following files:

/testPool/fs1/bash_completion

ZFS ci avverte che il file è inutilizzabile e ci "invita" a ripristinarlo da un eventuale backup, visto che non ha la possibilità di farlo lui!!! E' importante eseguire ad intervalli regolari uno "scrub" dei nostri pool, altrimenti ci accorgeremmo di eventuali problemi solo al momento dell'accesso a potenziali file danneggiati; invece con lo scrub (comando zpool scrub nome_pool) sarà ZFS che andrà a controllorare i dati presenti su disco e la loro consistenza!

Bene, nella seconda parte di questo articolo vedremo invece come si comporterà ZFS in caso di ridondanza dei dati, a presto!

venerdì 11 dicembre 2009

Javaday Roma, a day in a different universe

A day in a differtent universe è quello che si vivrà partecipando alla quarta edizione del Javaday Roma, sabato 30 gennaio 2010.

Una full immersion di sei ore ad altissima velocità verso nuovi universi di conoscenza. Un evento che permetterà a studenti, utenti esperti ed a semplici appassionati sia di approfondire la tecnologia sia di conoscere le ultime novità del mondo Java.

La manifestazione, organizzata direttamente dai membri della community Java romana in maniera volontaria, ha coinvolto nelle scorse edizioni migliaia di professionisti.

Durante l’evento si potrà consegnare alle aziende Sponsor il proprio curriculum vitae per avere nuove opportunità professionali.

E’ possibile partecipare anche come relatori dei seminari sottoponendo la propria proposta al comitato tecnico tramite la Call for paper pubblica.

L’ingresso al Javaday Roma è come sempre gratuito.

Per ogni informazione: http://roma.javaday.it/

martedì 8 dicembre 2009

ZFS deduplication

Con l'uscita della build 128a di OpenSolaris viene aggiunta una nuova ed importante funzionalità a ZFS: la "deduplication" (evito di tradurre la parola...). Grazie a questa nuova funzionalità il filesystem è in grado di riconoscere eventuali blocchi duplicati e scriverli una volta solo... risparmiando così spazio su disco! I blocchi vengono riconosciuti grazie ad una chiave di hash generata da un algoritmo (selezionabile) e verificata prima di ogni scrittura.
Prima di entrare nel dettaglio mettiamo subito alla prova tale feature; creiamo tre dischi "su file" (da 150 Mega ciascuno) che andranno a comporre il nostro pool:
$ mkfile 150m disk1 disk2 disk3

ora creiamo il nuovo pool, chiamandolo con molta fantasia "dedup":
$ pfexec zpool create dedup \
/export/home/luca/tmp/disk1 \
/export/home/luca/tmp/disk2 \
/export/home/luca/tmp/disk3

controllandone le caratteristiche vediamo subito che la dimensione è pari a 435 Megabyte e notiamo che il rapporto di "deduplication" è pari a uno (visto che ancora non abbiamo scritto nulla):
$ zpool get all dedup
NAME   PROPERTY       VALUE       SOURCE
dedup  size           435M        -
dedup  capacity       0%          -
dedup  altroot        -           default
dedup  health         ONLINE      -
dedup  guid           598651376828683765  default
dedup  version        22          default
dedup  bootfs         -           default
dedup  delegation     on          default
dedup  autoreplace    off         default
dedup  cachefile      -           default
dedup  failmode       wait        default
dedup  listsnapshots  off         default
dedup  autoexpand     off         default
dedup  dedupratio     1.00x       -
dedup  free           435M        -
dedup  allocated      79.5K       -

ora andiamo ad abilitare la "deduplication" a livello di filesystem:
$ pfexec zfs set dedup=on dedup

da questo momento in poi, per ogni nuovo blocco che ZFS andrà a scrivere effettuerà il controllo di duplicazione: copiamo alcuni file nel nuovo filesystem e controlliamo. Per il test ho scelto di copiare alcuni MP3 presenti sul mio disco fisso, vediamo l'occupazione dei file prescelti:
$ du -h /export/home/luca/Documents/Music/aavv_80/
72M    /export/home/luca/Documents/Music/aavv_80/

ora creiamo tre cartelle nel nostro filesystem su cui andremo a copiare i file
$ cd /dedup
$ pfexec mkdir d1
$ pfexec mkdir d2
$ pfexec mkdir d3
$ pfexec mkdir d4

e copiamo i file:
$ pfexec cp /export/home/luca/Documents/Music/aavv_80/* d1
$ pfexec cp /export/home/luca/Documents/Music/aavv_80/* d2
$ pfexec cp /export/home/luca/Documents/Music/aavv_80/* d3
$ pfexec cp /export/home/luca/Documents/Music/aavv_80/* d4

ora controlliamo lo spazio occupato:
$ du -h .
72M    ./d1
72M    ./d2
72M    ./d3
72M    ./d4
287M    .

i conti tornano; su tutte e quattro le cartelle sono presenti 72 Megabyte di MP3... mmmm... e la "deduplication" che fine ha fatto... non ha funzionato?!?!??? Controlliamo meglio:
$ zpool list dedup
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
dedup   435M  72.5M   363M    16%  4.00x  ONLINE  -

ecco svelato il mistero!!! Il comando "du" (come anche ls e molti altri) agendo a livello user "vede" la dimensione reale del file (la stessa cosa accade per i filesystem compressi), ma se controlliamo meglio lo spazio allocato a livello di pool vediamo che in realtà sono stati utilizzati "solo" 72.5 Megabyte e il rapporto di "deduplication" è salito a 4; ora i conti tornano alla perfezione!!!

Bene, dopo la pratica torniamo a parlare di teoria, analizzando le varie opzioni legate a questa nuova caratteristica. In precedenza abbiamo semplicemente attivato la deduplication, accettando così le impostazioni di default, tuttavia esistono diverse opzioni settabili per la proprietà dedup:

  • off: dedup disattivata;

  • on: dedup attivata, il blocchi vengono controllati con l'algoritmo SHA256;

  • verify: come sopra l'algoritmo di hash è sempre SHA256, ma in caso di rilevamento di un blocco uguale, viene verificata l'esattezza bit a bit;

  • fletcher4,verify: viene usato l'algoritmo di hash "fletcher4", che risulta essere molto più veloce ma che produce con maggiore probabilità delle duplicazioni di chiavi e quindi è per questo che la verifica è obbligatoria.


Non è detto che in futuro vengano implementati anche altri algoritmi per la verifica delle duplicazioni dei blocchi, il consiglio è quello di attivare la deduplication con l'opzione verify per stare tranquilli :)