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 :)

venerdì 23 ottobre 2009

Solaris 10 branded zone

Finalmente ci siamo!!! Dalla build 127 (disponibile all'incirca tra un mesetto, visto che ora siamo alla 125) sarà possibile configurare in OpenSolaris delle zone di tipo Solaris 10. La fase di integrazione del codice è stata ultimata, ovviamente le prime build serviranno per "allineare" i due mondi e per correggere i bachi che emergeranno, ma una volta stabilizzata questa tecnologia permetterà di "virtualizzare" all'interno di una installazione OpenSolaris "n" istanze di Solaris (dalla 10u8 e successive).

L'annuncio ufficiale è disponibile qui, mentre nella guida degli sviluppatori potrete trovare tante preziose informazioni, mentre per essere sempre informati sull'evoluzione di questa feature aggiuntiva delle zone è disponibile l'apposita pagina del progetto "Solaris 10 branded zone".

martedì 8 settembre 2009

Prima conferenza ITL-OSUG

L'Italian OpenSolaris User Group (ITL-OSUG) è lieta di annunciare il primo meeting ufficiale del gruppo, che si terra' a Roma il giorno venerdi' 2 Ottobre, presso la sede di Sun Microsystem.

Per conoscere gli argomenti trattati e partecipare troverete maggiori informazioni sul sito del gruppo: http://www.opensolaris.org/os/project/itl-osug/events/

Vi aspettiamo numerosi!!!!

Mirror Italiano per pkg.opensolaris.org/dev

Ragazzi, finalmente è disponibile il mirror Italiano ufficiale per il repository IPS di OpenSolaris (solo per il branch di sviluppo).
Il repository è raggiungibile all'url http://pkg.mirror.garr.it:8080/ e potete aggiungerla facilmente tramite il Package Manager, oppure da linea di comando con pochi semplici passaggi.

Per primo controlliamo l'elenco dei nostri "publisher" utilizzati:
$ pfexec pkg publisher
PUBLISHER                     TYPE     STATUS   URI
opensolaris.org  (preferred)  origin   online   http://pkg.opensolaris.org/dev/
contrib                       origin   online   http://pkg.opensolaris.org/contrib/
extra                         origin   online   https://pkg.sun.com/opensolaris/extra/

ora andiamo ad aggiungere il nuovo mirror con:
$ pfexec pkg set-publisher -m http://pkg.mirror.garr.it:8080/ opensolaris.org

e controlliamo che sia attivo:
$ pfexec pkg publisher
PUBLISHER                     TYPE     STATUS   URI
opensolaris.org  (preferred)  origin   online   http://pkg.opensolaris.org/dev/
opensolaris.org  (preferred)  mirror   online   http://pkg.mirror.garr.it:8080/
contrib                       origin   online   http://pkg.opensolaris.org/contrib/
extra                         origin   online   https://pkg.sun.com/opensolaris/extra/

a questo punto quando andremo ad installare nuovi pacchetti (oppure quando aggiorneremo il sistema), i dati verranno prelevati dal mirror, mentre i metadati (ovvero tutte le informazioni del pacchetto) continueranno ad essere prelevate dal publisher principale.

Un ringraziamento particolare a:

mercoledì 12 agosto 2009

Migrazione da CVS a Mercurial

E' giunto il momento di cambiare, e vista la (relativa) calma di questi giorni estivi mi sono deciso e ho cominciato la migrazione del repository aziendale dal (vecchio) sistema CVS al nuovo Mercurial. Chiaramente i motivi che mi hanno spinto a fare questa migrazione sono tanti, CVS è un programma stabile che ha funzionato (e funzionerà) per anni, ma c'erano delle funzionalità di cui non potevo fare a meno, tra cui quella di poter lavorare su repository offline e una migliore gestione dei branch.

Se ancora non conoscete Mercurial vi consiglio di leggere questo ottimo tutorial e vi consiglio di provarlo!

Se anche voi avete uno o più progetti sotto CVS potete fare una conversione automatica, grazie ad una "extension" di Mercurial verranno importati automaticamente tutti i commenti di commit e i vari branch con un solo comando!

Prima di vedere come effettuare l'import occorre abilitare l'apposita estenzione modificando il file .hgrc che troverete nella vostra home aggiungendo le righe:
[extensions]
hgext.convert=

a questo punto basterà digitare:
$ hg convert --authors ./aut.txt <repository cvs>

dove <repository cvs> è la directory che contiene il vostro progetto, sarà compito di Mercurial andare a pescare dal relativo server CVS tutti i dati che occorrono (log compresi) per la conversione. Sulla riga di comando ho anche aggiunto l'opzione per la conversione dei nomi degli autori, questi devono essere elencati in un file di testo nel seguente modo:
luca=Luca Morettoni <luca@morettoni.net>

Terminata la conversione troverete una nuova cartella denominata <repository cvs>-hg che contiene il nuovo repository in formato Mercurial pronto all'uso! Inoltre, se i vostri file "sotto CVS" dovessero essere modificati, vi basterà rilanciare il comando di conversione per "allineare" le modifiche!

Ovviamente, nella directory appena creata troverete il branch principale dei sorgenti, tuttavia come già detto Mercurial importa tutti i branch, quindi se vogliamo lavorare su un branch differente basterà clonare il nostro reporitory con:
$ hg clone progetto-hg progetto-2.1

e successivamente passare al branch che vogliamo (ad esempio quello denominato release_2_1):
$ hg up -C release_2_1

se vogliamo conoscere quali branch sono disponibili all'interno del repository basta digitare:
$ hg branches

mentre per conoscere quello "attivo" nel nostro repository di lavoro:
$ hg branch

Facile vero? Per convertire tutti i miei progetti ci sono voluti veramente pochi minuti...
enjoy HG :)

mercoledì 29 luglio 2009

Problemi con il mouse su OpenSolaris 2010.02?

Come segnalato nel precedente articolo riguardo il nuovo ramo di sviluppo che porterà alla release 2010.02 di OpenSolaris è presente un baco (#6849925) nelle piattaforme a 32 bit che ogni tanto fa "schizzare" il mouse in alto a destra, rendendo fastidioso l'utilizzo di qualsiasi applicazione.

Per fortuna è stata trovata una soluzione temporanea, basta modificare il binario di xorg in questo modo:
cp -p /usr/X11/bin/i386/Xorg /usr/X11/bin/i386/Xorg.orig
echo 'xf86SigioReadInput+9?w 770f 9090 9090' | mdb -w /usr/X11/bin/i386/Xorg

e il gioco è fatto, al prossimo riavvio il problema del mouse non si dovrebbe più ripetere!
Ricordatevi inoltre di eseguire nuovamente le istruzioni dopo ogni aggiornamento nel caso in cui i file di xorg vengano sovrascritti!

martedì 21 luglio 2009

Mirror Italiano per OpenSolaris

E' con molto piacere che annuncio la disponibilità del primo mirror Italiano per le ISO di OpenSolaris!

Grazie al GARR e all'impegno di Paolo Marcheschi è stato possibile avere uno spazio (e banda) a disposizione, per il momento troverete solo le ISO ma stiamo già lavorando alla possibilità di fare un mirroring anche per i pacchetti IPS.

Grazie ancora a tutti e buon download all'indirizzo http://opensolaris.mirror.garr.it/mirrors/opensolaris/

domenica 19 luglio 2009

OpenSolaris snv_118

Ecco puntualmente disponibile la nuova build di sviluppo di OpenSolaris, giunta alla snv_118. Con i soliti passi di installazione tutto è filato liscio (ovviamente potete utilizzare anche l'interfaccia grafica dell'Update Manager):
$ pfexec pkg install SUNWipkg
$ pfexec pkg image-update

unica accortezza se state aggiornando dalla build 117: prima di effettuare il reboot occorre eliminare una entry da una config, pena il mancato boot del sistema al prossimo riavvio. Per evitare basta digitare i seguenti comandi:
$ pfexec beadm mount opensolaris-118 /mnt
$ pfexec svccfg
svc:> repository /mnt/etc/svc/repository.db
svc:> delete network/fcoe_config
svc:> end
$ pfexec beadm unmount -f opensolaris-118

ovviamente se il vostro nuovo boot environment si chiama diversamente da opensolaris-118 aggiustate il nome di conseguenza e il gioco è fatto!

Tra le novità di questa release troviamo Firefox 3.5 in versione stabile e OpenJDK 7!

venerdì 3 luglio 2009

Lezioni di (in)civiltà

Purtroppo lo sappiamo fin troppo bene, l'essere civile è una virtù che è sempre più rara al giorno d'oggi, ma trovarne due casi in rapida successione e dello stesso tipo è veramente disarmante, considerando poi che chi deve "sorvegliare" o "agire" per impedire tali comportamenti sono lì... e non fanno NULLA!!!

Veniamo al fatto, era un pò di tempo fa quando ero a passeggio per la mia città (Bastia Umbra), quando mi trovo davanti ad un passaggio pedonale una autovettura parcheggiata di traverso appunto sulle strisce pedonali e che impedisce il passaggio ai pedoni (ma anche a carrozzine e mezzi simili). Sono rimasto ad osservare la scena per diversi minuti, il conducente non ha effettuato una fermata ma una vera e propria sosta, allontanandosi per diverso tempo, il tutto mentre pochi metri più indietro erano presenti dei parcheggi liberi, e le forze dell'ordine circolavano per la via senza battere ciglio!

Proseguendo la mia passeggiata a poco più di cinquanta metri dal passaggio pedonale di cui sopra, mentre stò per risalire sul marciapiede, un altro simpatico "parcheggiatore" mi taglia la strada, mette la macchina di traverso davanti ad uno scivolo di accesso al marciapiede e se ne va tranquillamente a vedere le vetrine dei negozi, impedendo l'uso dello scivolo stesso (utile sopratutto ai passeggini e ai portatori di handicap); ovviamente a soli due (e dico dure) metri da lì c'erano dei parcheggi liberi (e questa volta anche gratuiti, solo a tempo).

Cosa dire a queste persone? Bhe, a loro nulla, ogni parola sarebbe sprecata, ma chiedo a chi di dovere di aprire di più gli occhi...

[gallery link="file" columns="2"]

giovedì 2 luglio 2009

CUPS e OpenSolaris

Chi come me ha scelto CUPS come sistema di stampa sotto OpenSolaris potrebbe incorrere in un "fastidioso" problema: ovvero la quasi totalità delle applicazioni sotto GNOME non visualizzano l'elenco delle stampanti disponibili.

[caption id="attachment_298" align="aligncenter" width="150" caption="Elenco stampanti vuoto"]Elenco stampanti vuoto[/caption]

Per ovviare a questo problema basta editare il file .printers che si trova nella propria home eliminando la riga che inizia per _all, inoltre sempre questa riga viene aggiunta al file /etc/printer.conf e va eliminata anche da qui, tuttavia questo file al prossimo riavvio verrà ricreato da CUPS rendendo vane le modifiche, per impedire che ciò avvenga basta digitare:
pfexec cupsctl PrintcapFormat=BSD

Per chi ancora non avesse attivato CUPS sulla propria macchina può farlo con il comando:
print-service -s cups

inoltre se dovete accedere a stampanti in rete condivise tramite Windows dovrete installare anche il pacchetto Samba:
pfexec pkg install SUNWsmba

fatto ciò potrete comodamente gestire le vostre stampanti tramite l'apposito tool "Print Manager" che trovate nel menu System -> Administration, oppure tramite browser all'indirizzo http://localhost:631/

[caption id="attachment_299" align="aligncenter" width="150" caption="Gestione delle stampanti CUPS"]Gestione delle stampanti CUPS[/caption]

martedì 30 giugno 2009

OpenSolaris snv_117

Dopo le "fatiche" per il rilascio della release 2009.06 di OpenSolaris il team di sviluppo si è rimesso al lavoro e qualche giorno fà è stata resa disponibile la build 117 del branch di sviluppo.
Il "salto" dalla 111b alla 117 è notevole, primo tra tutti noterete il passaggio a GNOME 2.26.1. Essendo una build di sviluppo non aspettatevi una piena stabilità, tuttavia non ho notato particolari problemi salvo alcuni trascurabili:

  • subito dopo l'installazione il servizio di indicizzazione tracker deve ricostruire completamente gli indici, pena un consumo eccessivo di CPU

  • a volte il mouse "schizza" nell'angolo in alto a sinistra del monitor, per poi tornarnare a rispondere ai comandi senza problemi (bug #6849925)


le procedure di aggiornamento sono le solite:
$ pfexec pkg refresh --full
$ pfexec pkg install SUNWipkg
$ pfexec pkg image-update --be-name opensolaris-117

seguito dal classico riavvio!

Ultima nota, per coloro che hanno installato la release 2009.06 oppure stanno semplicemente seguendo il ramo "stabile" per effettuare l'aggiornamento devono dare il seguente comando PRIMA di quelli visti sopra:
$ pfexec pkg set-publisher -O http://pkg.opensolaris.org/dev opensolaris.org

Disponibile NetBeans 6.7

Da ieri è disponibile per il download NetBeans 6.7, le novità di questa release sono numerose, eccone alcune:

  • integrazione della piattaforma Kenai

  • supporto nativo di Maven

  • supporto migliorato di GlassFish v3, che rappresenta una anteprima della prossima piattaforma JavaEE 6

  • features on demand, ovvero l'attivazione di alcuni componenti dell'IDE solo quando necessari


Chiunque voglia provarlo è possibile scaricare il file di installazione da qui.

[gallery link="file" columns="2"]

domenica 31 maggio 2009

Finalmente OpenSolaris 2009.06!

Questa volta il rilascio della nuova release stabile di OpenSolaris avviene addirittura con qualche giorno di anticipo, infatti la sua presentazione "ufficiale" avverrà domani al CommunityOne.

Le novità di questa release sono numerose, oltre alla maturazione del codice troviamo:

  • supporto completo della piattaforma SPARC (sia come sistema base che con numerosi pacchetti);

  • miglioramento del sistema dei pacchetti (sia a livello grafico che dell'interfaccia a linea di comando)

    • è possibile effettuare ricerche di pacchetti con un linguaggio "evoluto"

    • la ricerca avviene di default nei repository online

    • possibilità di installare nuovi pacchetti con un semplice click

    • migliorate le performance del package manager

    • integrazione del progetto SourceJuicer per automatizzare il processo di realizzazione di nuovi pacchetti



  • aggiunta di numerosi driver (sono supportati oltre 2500 tipi di laptop);

  • miglioramento delle performance in generale e del layer di rete

    • integrazione del progetto "crossbow" per la gestione della virtualizzazione del networking

    • miglioramento del layer iSCSI e del CIFS (progetto comstar)

    • miglioramento di prestazioni di ZFS



  • supporto dell'installazione automatica


Dal punto di vista del software troviamo:

  • xorg 1.5

  • flash player 10

  • JDK 6 update 13

  • JavaFX

  • Glassfish 2.1

  • OpenDS 1.2

  • NetBeans 6.5.1

  • Eclipse 3.4.2

  • Python 2.6


Tutte queste (e altre informazioni) potete trovarle nelle slide ufficiali di presentazione di Peter Dennis (Sun Microsystem).

Aggionamento

Se proprio siete impazienti e desiderate provare la nuova release vi basterà aggiornare la vostra installazione (oppure scaricare l'immagine ISO dal sito disponibile tra qualche ora...), i passi da fare sono i soliti (da linea di comando):
$ pfexec pkg refresh --full
$ pfexec pkg install SUNWipkg
...
$ pfexec pkg image-update --be-name opensolaris-111b
DOWNLOAD                                    PKGS       FILES     XFER (MB)
Completed                                672/672   1885/1885   47.26/47.26

PHASE                                        ACTIONS
Removal Phase                                971/971
Install Phase                                896/896
Update Phase                               3378/3378
PHASE                                          ITEMS
Reading Existing Index                           8/8
Indexing Packages                            672/672
Optimizing Index...
PHASE                                          ITEMS
Indexing Packages                            674/674

A clone of opensolaris-111a exists and has been updated and activated.
On the next boot the Boot Environment opensolaris-111b will be mounted on '/'.
Reboot when ready to switch to this updated BE.

---------------------------------------------------------------------------
NOTE: Please review release notes posted at:

http://opensolaris.org/os/project/indiana/resources/relnotes/200906/x86/
---------------------------------------------------------------------------

Oppure potete utilizzare l'Update Manager (dal menu System, Administration).

venerdì 24 aprile 2009

OpenSolaris snv_111a

E questa mattina siamo arrivati alla build 111a di OpenSolaris! Si tratta di un "affinamento" della già conosciuta build 111 e che porterà nel giro di poco tempo (speriamo) alla release 2009.06, prevista come dice il nome per giugno.

Ovviamente questa build appartiene ancora al branch developer, quindi ancora non è garantita una piena stabilità (in poche parole... aggiornate a vostro rischio e pericolo!!!); per aggiornare potete usare Update Manager (dal menu System - Administration) oppure da linea di comando con il solito:
$ pfexec pkg image-update --be-name opensolaris-111a

noterete che ho aggiunto l'opzione --be-name utile per scegliere il nome da assegnare al nuovo boot environment che pkg andrà a creare.
Terminato l'aggiornamento possiamo riavviare e cominciare a testare!

[caption id="attachment_270" align="aligncenter" width="150" caption="OpenSolaris 2009.06"]OpenSolaris 2009.06[/caption]

giovedì 23 aprile 2009

Aggiungere dischi ai mirror di ZFS

Come già detto nei precedenti post inerenti ZFS è un filesystem "nato sicuro", ovvero per sua natura abbiamo la massima garanzia di affidabilità per quello che riguarda le memorizzazioni su disco; tuttavia se veramente vogliamo dormire sonni tranquilli e sfruttare tutte le features di sicurezza di ZFS è consigliabile fornire più di un disco al sistema in modo che si possa quantomeno implementare un mirroring dei dati (sistema minimo di ridondanza).

Se al momento dell'installazione di OpenSolaris (o dell'ultima release di Solaris 10) avevate a disposizione un solo disco ZFS creerà in automatico un mirror "zoppo", finchè non gli fornirete il secondo disco, se avete un disco nuovo nuovo basterà digitare:
# zpool attach -f rpool c0t0d0s0 c0t1d0s0

dove rpool è il nome del vostro pool, seguito dal device del vecchio disco e da quello del nuovo. Se invece il disco che andate ad aggiungere non è nuovo (magari proviene da una vecchia macchina o contiene una versione di Solaris che andate ad aggiornare) riceverete un bel messaggio di errore:
# zpool attach -f rpool c0t0d0s0 c0t1d0s0
cannot attach c0t1d0s0 to c0t0d0s0: device is too small

questo perchè con molta probabilità il vostro disco contiene già una label in formato EFI e questo tipo di label non "copre" totalmente la dimensione del disco, quindi occorrerà passare al formato SMI, per fare questo useremo il comando format (ho evidenziato in grassetto le scelte effettuate):
# format -e
Searching for disks...done

AVAILABLE DISK SELECTIONS:
       0. c0t0d0 <DEFAULT cyl 8921 alt 2 hd 255 sec 63>
          /pci@0,0/pci8086,25f8@4/pci1000,3150@0/sd@0,0
       1. c0t1d0 <DEFAULT cyl 8915 alt 2 hd 255 sec 63>
          /pci@0,0/pci8086,25f8@4/pci1000,3150@0/sd@1,0
Specify disk (enter its number): 1
selecting c0t1d0
[disk formatted]

FORMAT MENU:
        disk       - select a disk
        type       - select (define) a disk type
        partition  - select (define) a partition table
        current    - describe the current disk
        format     - format and analyze the disk
        fdisk      - run the fdisk program
        repair     - repair a defective sector
        label      - write label to the disk
        analyze    - surface analysis
        defect     - defect list management
        backup     - search for backup labels
        verify     - read and display labels
        save       - save new disk/partition definitions
        inquiry    - show vendor, product and revision
        scsi       - independent SCSI mode selects
        cache      - enable, disable or query SCSI disk cache
        volname    - set 8-character volume name
        !<cmd>     - execute <cmd>, then return
        quit
format> label
[0] SMI Label
[1] EFI Label
Specify Label type[0]: 0
Ready to label disk, continue? y

format> quit
#

fatto questo potremo ripetere il comando di attach e in automatico ZFS comincerà il resilvering del disco in modo da sincronizzare i dati.
# zpool status
pool: rpool
state: ONLINE
scrub: resilver completed after 0h11m with 0 errors on Thu Apr 23 15:09:22 2009
config:

NAME          STATE     READ WRITE CKSUM
rpool         ONLINE       0     0     0
mirror      ONLINE       0     0     0
c0t0d0s0  ONLINE       0     0     0
c0t1d0s0  ONLINE       0     0     0

errors: No known data errors

C'è da aggiungere una piccola nota, alcune volte è necessario cancellare tutte le vecchie partizioni presenti sul disco prima di cambiare il formato delle label, basta entrare nel sottomenu fdisk e rimuovere tutte le partizioni e poi ripetere le operazioni viste prima.

I servizi di OpenSolaris (SMF) parte #2

Nella precedente puntata abbiamo visto rapidamente come creare un nuovo SMF, oggi cercheremo di approfondire alcuni aspetti riprendendo sempre il manifesto creato come esempio.

Per quello che riguarda il prologo del nostro manifesto è possibile andare a definire alcune tipologie differenti rispetto a quelle utilizzate; per il tag service_bundle è possibile indicare:

  • type='manifest' (il nostro caso) indichiamo che stiamo descrivendo un servizio vero e proprio

  • type='profile' indica che stiamo descrivendo un profilo (simile ad una collezione di servizi)


per il tag service possiamo avere tre tipologie differenti:

  • type='service' indica un servizio vero e proprio

  • type='restarter' definisce un servizio "speciale" che si occupa di controllare lo status (partenza/arresto e riavvio) di una sottocategoria di servizi, di default viene usato svc.startd ma ad esempio per i servizi di rete viene usato come restarter inetd

  • type='milestone' rappresenta un servizio che in realtà aggrega più servizi e proprietà, sono a tutti gli effetti paragonabili con i "vecchi" runlevel (ad esempio in runlevel 3 corrisponde alla milestone milestone/multi-user-server:default)


Passando invece alle dipendenze (tag dependency) possiamo innanzi tutto definire la tipologia di dipendenze:

  • type='service' in questo caso andremo a descrivere una o più dipendenze da altri servizi

  • type='path' così indicheremo la dipendenza da uno o più file presenti nel sistema, attualmente viene controllata solo l'esistenza del file ma non vengono monitorati eventuali cambiamenti o cancellazioni


successivamente possiamo indicare il grado di dipendenza dai servizi (o dai file) con la proprietà grouping:

  • grouping='require_any' occorre che almeno un servizio tra quelli elencati sia online per far partire il nostro (oppure deve essere presente almeno un file)

  • grouping='require_all' tutti i servizi indicati devono essere online prima che possa partire il nostro (oppure tutti i file devono essere presenti)

  • grouping='optional_all' tutti i servizi devono essere online oppure possono essere anche in offline purchè questa disabilitazione non sia stata espressamente settata dall'operatore

  • grouping='exclude_all' tutti i servizi elencati devono essere offline (oppure i file indicati non devono esistere)


Infine possiamo decidere il legame tra il nostro servizio e le sue dipendenze nel caso in cui queste ultime subiscano delle variazioni, in particolare:

  • restart_on='none' ignora errori o cambiamenti di stato della dipendenza

  • restart_on='restart' il nostro servizio viene riavviato al riavviarsi della dipendenza

  • restart_on='refresh' se il servizio da cui dipendiamo subisce un refresh

  • restart_on='error' in caso errore di una (o più dipendenze) il nostro servizio verrà riavviato.


Termina qui questa seconda parte di approfondimento, la prossima volta analizzeremo nel dettaglio le proprietà e i metodi di esecuzione dei nostri servizi.

sabato 18 aprile 2009

I servizi di OpenSolaris (SMF) parte #1

Era da tempo che volevo parlare di questa interessantissima caratteristica di OpenSolaris (ma presente anche in Solaris 10): i Service Management Facility. Grazie agli SMF il sistema è in grado di gestire l'avvio di tutti i servizi al momento del boot, il loro corretto arresto in fase di shutdown ed anche la loro ripartenza in caso di problemi.
Quest'ultima caratteristica rende gli SMF unici ma non è la sola a rappresentare un punto di vantaggio al sistema, infatti nel descrittore dei servizi è possibile definire una serie di dipendenze che legano tra di loro i servizi stessi. Indicheremo ad esempio da quali servizi dipende un nostro servizio, quindi essi precederanno il nostro nella fase di avvio, oppure il nostro servizio non potrà essere avviato se prima non verranno fatte partire le sue dipendenze.

Visto che in questi giorni mi sono cimentato nella realizzazione di un SMF per gestire il Sun Java System Web Server 7 che usiamo qui in azienda vorrei condividere con coi questa esperienza, analizzando passo passo le varie sezioni che costituiscono il servizio.

Il servizio SMF viene descritto tramite un file XML (il manifesto), come punto di partenza potete analizzare e prendere spunto da quelli forniti di base con OpenSolaris, memorizzati in /var/svc/manifest/, ecco come è composto il mio:
<?xml version="1.0"?>
<!DOCTYPE service_bundle
SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='webserver7'>
<service
name='network/webserver7'
type='service'
version='1'>
<single_instance />

questa prima parte è puramente descrittiva, dove scegliamo un nome per il nostro "manifesto" (io ho scelto webserver7) e il nome che andrà ad identificare in maniera univoca il nostro servizio nel sistema (il nome "parziale" sarà svc:/network/webserver7 a cui successivamente aggiungeremo le varie istanze), questo identificatore univoco lo troverete spesso indicato nella documentazione e nelle man pages con la sigla FMRI (ovvero Fault Management Resource Identifier).
<dependency
name='multi-user-server'
grouping='optional_all'
type='service'
restart_on='none'>
<service_fmri value='svc:/milestone/multi-user-server' />
</dependency>

questa seconda sezione troviamo l'unica dipendenza che ho definito, ovvero che il sistema sia stato avviato in modalità multi-user-server. In realtà è possibile definire meglio le dipendenze, ad esempio avrei potuto mettere due dipendenze di base: il "montaggio" dei dischi locali e la partenza dei servizi di rete, dichiarando inoltre che se quest'ultima venisse riavviata anche il mio servizio doveva essere riavviato.
<exec_method
type='method'
name='start'
exec='/lib/svc/method/webserver %m %i %{webserver/home} %{webserver/user}'
timeout_seconds='60'>
</exec_method>

<exec_method
type='method'
name='restart'
exec='/lib/svc/method/webserver %m %i %{webserver/home} %{webserver/user}'
timeout_seconds='60'>
</exec_method>

<exec_method
type='method'
name='stop'
exec='/lib/svc/method/webserver %m %i %{webserver/home} %{webserver/user}'
timeout_seconds='60'>
</exec_method>

queste tre direttive rapprensentano il cuore del servizio SMF in fase di realizzazione, infatti descrivono come far partire, arrestare o riavviare la nostra applicazione; tutti e tre richiamano lo stesso script di shell (sempre da me sviluppato) passando tre paramenti: il primo (%m) rapprensenta il metodo che si sta eseguendo (start, stop o restart), seguito da %i che rappresenta il nome dell'istanza (che vedremo successivamente) e per concludere due proprietà del servizio webserver/home e webserver/user.
<property_group name="webserver" type="application">
<propval name="home" type="astring" value="/sun/webserver7" override="true"/>
<propval name="user" type="astring" value="webservd" override="true"/>
</property_group>

come anticipato il nostro servizio fa uso di due proprietà passandole allo script di gestione visto prima, grazie ad esse l'utilizzatore potrà personalizzarle secondo la sua specifica installazione (essendo state dichiarate tutte e due con la proprietà ovverride settata su true), comunque vedremo come impostare dei valori differenti successivamente.
<instance name='https-myhost' enabled='false'>
<property_group name="instance" type="application">
<propval name="name" type="astring" value="https-myhost" override="false"/>
</property_group>
</instance>

<instance name='admin-server' enabled='false'>
<property_group name="instance" type="application">
<propval name="name" type="astring" value="admin-server" override="false"/>
</property_group>
</instance>

queste due sezioni praticamente identiche vanno a definire due istanze del nostro servizio, identificandone ognuna con un nome. Grazie a questa caratteristica risulta molto semplice gestire istanze multiple di uno stesso servizio, con la possibilità ad esempio di definire delle proprietà specifiche per ognuna di esse.
  <template>
<common_name>
<loctext xml:lang='C'>WebServer 7</loctext>
</common_name>
</template>
</service>
</service_bundle>

infine indichiamo una breve descrizione del servizio, qui potremmo inserire anche una serie di link o riferimenti a specifiche man page utili per gestire/utilizzare l'applicazione gestita dal servizio.

Conclusa la fase di creazione del nostro file non resta altro da fare che controllare la sua correttezza con il comando:
# svccfg validate webserver.xml

in caso di presenza di errori ci verranno segnalate le linee non corrette, in caso contrario possiamo passare alla fase di importazione del nostro manifesto con il comando:
# svccfg import webserver.xml

quindi controlliamo la presenza nella lista dei servizi del nostro appena creato:
# svcs webserver7
STATE          STIME    FMRI
disabled       Apr_16   svc:/network/webserver7:admin-server
disabled       Apr_16   svc:/network/webserver7:https-myhost

come vedete tutte e due le istanze sono disabilitate in quanto tutte e due, al momento della loro dichiarazione, avevano l'attributo enabled='false', prima di abilitarle controlliamo le loro proprietà con il comando:
# svcprop webserver7:admin-server
instance/name astring admin-server
general/enabled boolean false
general/single_instance boolean true
webserver/home astring /export/home/www/webserver7
webserver/user astring www
multi-user-server/entities fmri svc:/milestone/multi-user-server
multi-user-server/grouping astring optional_all
multi-user-server/restart_on astring none
multi-user-server/type astring service
startd/duration astring transient
start/exec astring /lib/svc/method/webserver\ %m\ %i\ %{webserver/home}\ %{webserver/user}
start/timeout_seconds count 60
start/type astring method
restart/exec astring /lib/svc/method/webserver\ %m\ %i\ %{webserver/home}\ %{webserver/user}
restart/timeout_seconds count 60
restart/type astring method
stop/exec astring /lib/svc/method/webserver\ %m\ %i\ %{webserver/home}\ %{webserver/user}
stop/timeout_seconds count 60
stop/type astring method
tm_common_name/C ustring WebServer\ 7
restarter/start_pid count 11703
restarter/start_method_timestamp time 1239890611.150876000
restarter/start_method_waitstatus integer 0
restarter/logfile astring /var/svc/log/network-webserver7:admin-server.log
restarter/transient_contract count
restarter/auxiliary_state astring none
restarter/next_state astring none
restarter/state astring disabled
restarter/state_timestamp time 1239890652.156404000
restarter_actions/refresh integer
general_ovr/enabled boolean false

noterete che sono presenti anche numerose altre proprietà di default dei servizi (come ad esempio il file di log utilizzato per memorizzare i messaggi generati durante le operazioni di start/stop), in più ho provveduto a personalizzare le due proprietà webserver/home e webserver/user per rispondere alle specifiche della mia installazione, per fare questo basta digitare:
# svccfg -s webserver7 setprop webserver/home=/export/home/www/webserver7
# svccfg -s webserver7 setprop webserver/user=luca

noterete che ho settato le proprietà omettendo volontatiamente la parte di istanza, essendo queste proprietà definite a livello di servizio (quindi hanno valore per tutte le istanze del webserver), a questo punto possiamo far partire la nostra istanza (e rimarrà attiva fino al prossimo reboot):
# svcadm enable -t webserver7:admin-server

mentre per per farla ripartire anche in caso di reboot della macchina basterà digitare:
# svcadm enable webserver7:admin-server

Appuntamento al prossimo post per l'analisi dello script usato dal servizio.