[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 173.   Gestione dei dischi in modo ridondante

Le unità a disco sono componenti meccanici sottoposti a usura e soggetti a deterioramento. Questo fatto si comprende subito per ciò che riguarda i dischi rimovibili (compresi i CD o i DVD) e di solito ci si organizza con più copie della stessa cosa se si tratta di dati importanti, ma per i dischi fissi il problema è diverso.

In generale è necessario premunirsi dalle perdite di dati dovute alla rottura di un disco fisso con delle copie di sicurezza, da eseguire periodicamente; tuttavia, anche predisponendo una procedura efficace per le copie di sicurezza, l'impegno necessario per il ripristino del funzionamento del proprio elaboratore è sempre rilevante.

Dal momento che la frequenza con cui si verifica una rottura di un disco fisso è maggiore rispetto ad altri eventi che possono procurare la perdita dei dati (per esempio il furto, l'atto vandalico, l'incendio, l'allagamento, il terremoto, ecc.), vale la pena di attenuare l'effetto di questo tipo di problema con la realizzazione di un insieme di dischi ridondante, noto normalmente con la sigla «RAID».

173.1   RAID

La sigla RAID sta per Redundancy array of inexpensive disks e rappresenta quindi un insieme di tecniche per mettere assieme dei dischi aggiungendo qualche forma di ridondanza. Si distinguono diversi livelli, alcuni dei quali sono descritti brevemente nell'elenco seguente.

Livello RAID Descrizione
RAID-0 Il livello zero dei sistemi RAID è privo di ridondanza e si occupa soltanto di unire assieme più dischi, all'interno dei quali i dati vengono suddivisi equamente, in modo da bilanciare anche il carico di operazioni di lettura e scrittura che li riguardano. In pratica, il livello zero consente di realizzare un disco virtuale di grandi dimensioni, più efficiente, ma la rottura di uno dei dischi porta alla perdita di tutti i dati. RAID-0 è noto anche con la definizione block striping.
RAID-1 Il livello uno dei sistemi RAID si occupa di unire assieme due o più dischi (ma di solito sono solo due) che si trovano a riprodurre fedelmente tutti la stessa cosa. In questo caso, la rottura di un disco non pregiudica l'utilizzo dei dati che sono disponibili nel disco o nei dischi rimanenti. RAID-1 è noto anche con la definizione disk mirroring.
RAID-3 Il livello tre dei sistemi RAID si occupa di unire assieme più dischi, all'interno dei quali i dati vengono suddivisi equamente, in modo da bilanciare anche il carico di operazioni di lettura e scrittura che li riguardano, dedicando uno di questi dischi al contenimento di un sistema di codici di controllo che permettono di ricostruire i dati nel caso uno degli altri dischi si rompa. In pratica, il livello tre crea una forma di ridondanza, ma meno affidabile del livello uno. Naturalmente, per attuare un livello tre servono almeno tre dischi.
RAID-4 Il livello quattro dei sistemi RAID è simile al livello tre, con la differenza che vengono distribuiti in modo differente (più efficiente) tra i dischi, ma rimane compito di un disco separato il sistema di codici di controllo che permette la ricostruzione dei dati.
RAID-5 Il livello cinque dei sistemi RAID equivale al livello quattro, dove però le informazioni che servono per la ricostruzione dei dati sono distribuite tra i dischi, senza essere così concentrate in uno soltanto. In questo modo si aumenta l'efficienza, in termini di tempi di accesso ai dati.

I livelli RAID possono essere anche combinati assieme; per esempio è possibile realizzare due insiemi di dischi RAID-0, che si associano a loro volta in un insieme RAID-1, in modo da non perdere i dati nel caso uno dei dischi smetta di funzionare. In questo caso si parla anche di RAID-10

173.2   RAID hardware e software

La realizzazione di un insieme di dischi secondo uno dei vari livelli RAID può essere ottenuta attraverso sistemi hardware, oppure software. Nel primo caso si tratta di unità di controllo che gestiscono tutto autonomamente, facendo sì che il sistema operativo veda in pratica un disco normale; nel secondo caso, è il sistema operativo che associa i dischi e li gestisce usando una forma di ridondanza.

Come si può comprendere, le unità di controllo RAID sono più costose di quelle normali; tuttavia, se non si creano altri tipi di problemi, hanno il vantaggio di non creare difficoltà al sistema operativo.

173.3   RAID-1 via software con i sistemi GNU/Linux

Con i sistemi GNU/Linux, disponendo di un kernel 2.4.* o superiore, è relativamente agevole la creazione di un insieme di dischi RAID senza l'ausilio di unità di controllo specializzate. In questa sezione si descrive brevemente la realizzazione di un sistema composto da due dischi che riproducono esattamente gli stessi dati, ovvero un sistema RAID-1, utilizzando semplicemente dischi ATA (cosa che in generale rappresenta la situazione più semplice da affrontare per chiunque).

Se la propria distribuzione GNU/Linux offre una procedura di installazione che prevede anche la gestione di un sistema RAID-1 software, dovrebbe essere sufficiente disporre dei due dischi perché tutto venga predisposto senza interventi particolari; tuttavia, qui si vuole mostrare un procedimento più brutale, che si affronta normalmente quando si vuole travasare un sistema GNU/Linux preesistente in un insieme di dischi RAID-1. In pratica, si fa affidamento sul fatto che sia disponibile un terzo disco, contenente il sistema GNU/Linux da trasferire, che successivamente si intende rimuovere dall'elaboratore, oppure destinare ad altri scopi. Naturalmente è necessario organizzarsi in modo da poter avviare questo sistema transitorio anche quando lo si sposta in un'altra unità di controllo o comunque in un'altra posizione del bus ATA.

173.3.1   Predisposizione del kernel

Per poter avviare un sistema GNU/Linux che utilizza un insieme di dischi RAID (gestiti via software), è indispensabile che il kernel includa tutte le funzionalità necessarie, senza avvalersi per questo di moduli. Se possibile, è meglio includere tutte le funzionalità associate ai livelli RAID della voce {Multi-device support (RAID and LVM)}. Se non è possibile includere tutte le funzionalità corrispondenti, occorre selezionare almeno {RAID support} e {RAID-1 (mirroring) mode} (dal momento che si vuole realizzare un sistema RAID-1).

Se il kernel che si utilizza è predisposto per la gestione di dischi RAID, appare il file virtuale /proc/mdstat, dal quale, successivamente, si possono ottenere le informazioni sull'attività del sistema RAID. Tanto per cominciare si può vedere quali livelli RAID sarebbero disponibili:

cat /proc/mdstat[Invio]

Personalities : [linear] [raid0] [raid1] [raid5] [multipath] 
...

Dall'esempio si comprende che RAID-1 è disponibile (insieme anche ad altri livelli RAID).

173.3.2   Dischi, partizioni e installazione

Disponendo di due dischi ATA, meglio se identici, è necessario decidere come collegarli all'elaboratore. Dal momento che di solito i bus ATA sono due, è meglio mettere ogni disco su un bus differente, in modo da distribuire meglio il carico di lavoro e per prevenire anche le rotture dovute a uno dei due bus ATA.

Il passo successivo è decidere la suddivisione in partizioni, in modo tale da soddisfare anche le esigenze che potrebbero porsi in un secondo momento. Infatti, se si realizza un sistema RAID, lo si fa presumibilmente per mantenere intatta la situazione nel tempo. Probabilmente, nelle situazioni più semplici è sufficiente predisporre tre partizioni: una per i file necessari all'avvio (kernel incluso), una per la memoria virtuale e la terza per tutto il resto.

È possibile inserire i file necessari all'avvio del sistema operativo anche in una partizione gestita attraverso un sistema RAID, ma in generale è una cosa sconsigliabile e comunque non esiste una reale necessità di agire in questo modo, se ci si organizza correttamente.

Con il sistema GNU/Linux attualmente in funzione (quello che poi deve essere travasato), si procede alla suddivisione in partizioni. Seguendo l'ipotesi che è stata formulata si dividono entrambi i dischi in modo da avere una piccola partizione (da 10 Mibyte in su) di tipo 8316 (Linux-nativa), una partizione di tipo 8216 (Linux-swap) e una partizione di tipo FD16. Il tipo FD16 (autorilevamento RAID) dichiara esplicitamente che si tratta di una partizione usata per la realizzazione di sistemi RAID e permette al kernel di attivarla prima di innestare il file system principale.

Teoricamente sarebbe possibile utilizzare in modo speculare anche le partizioni per la memoria virtuale; in pratica questo non conviene e l'intenzione, qui, è solo quella di utilizzarle in modo da sommare la loro capacità.

Una volta predisposte le partizioni, facendo in modo che siano il più possibile uguali, si può procedere a una prima inizializzazione che in pratica attiva la funzionalità RAID-1.

Per rendere l'esempio a cui si fa riferimento più realistico, si suppone di avere collocato un disco nella prima posizione del primo bus ATA e l'altro nella prima posizione del secondo. Pertanto, le partizioni potrebbero essere organizzate così:

/dev/hda1 /dev/hdc1 partizioni per il kernel e gli altri file necessari all'avvio;
/dev/hda2 /dev/hdc2 partizioni per la memoria virtuale;
/dev/hda3 /dev/hdc3 partizioni da gestire in modo speculare secondo il modello RAID-1.

La partizione virtuale RAID-1 viene associata a un file di dispositivo differente, secondo il modello /dev/mdn, dove il numero n dipende da una scelta abbastanza libera. Si ritiene qui che sia più conveniente utilizzare lo stesso numero che individua la partizione nel disco, in modo da non creare confusione; pertanto si intende creare il partizione RAID /dev/md3. A questo punto occorre accertarsi di disporre del file di dispositivo relativo; se manca deve essere creato:

mknod -m 0660 /dev/md3 b 9 3[Invio]

Tabella 173.4. Creazione dei primi file di dispositivo necessari alla gestione di dischi RAID.

File di dispositivo Comando
/dev/md0

mknod -m 0660 /dev/md0 b 9 0[Invio]

/dev/md1

mknod -m 0660 /dev/md1 b 9 1[Invio]

/dev/md2

mknod -m 0660 /dev/md2 b 9 2[Invio]

/dev/md3

mknod -m 0660 /dev/md3 b 9 3[Invio]

/dev/md4

mknod -m 0660 /dev/md4 b 9 4[Invio]

/dev/md5

mknod -m 0660 /dev/md5 b 9 5[Invio]

/dev/md6

mknod -m 0660 /dev/md6 b 9 6[Invio]

Per creare l'unità RAID-1 si procede con questo comando, con Mdadm:(1)

mdadm --create /dev/md3 --level=raid1 --raid-devices=2 \
  \      /dev/hda3 /dev/hdc3
[Invio]

Se tutto procede regolarmente, l'unità RAID-1 viene attivata quasi subito, ma inizia una scansione che serve ad allineare le due partizioni (in pratica si può vedere che i dischi sono attivi in modo costante per lungo tempo). Durante questa fase, è già possibile procedere a inizializzare l'unità RAID-1 con il tipo di file system che si preferisce; in questo caso si sceglie il tipo Ext3:

mkfs.ext3 /dev/md3[Invio]

Terminata l'inizializzazione si può innestare la partizione e procedere con la copia del sistema attivo (o di un altro se necessario). Si suppone di volere innestare la partizione nella directory /mnt/ e di procedere con la copia di conseguenza:

mount -t ext3 /dev/md3 /mnt[Invio]

cd /[Invio]

cp -dpRv /bin /mnt[Invio]

cp -dpRv /etc /mnt[Invio]

cp -dpRv /home /mnt[Invio]

cp -dpRv /lib /mnt[Invio]

cp -dpRv /root /mnt[Invio]

cp -dpRv /sbin /mnt[Invio]

cp -dpRv /usr /mnt[Invio]

cp -dpRv /var /mnt[Invio]

mkdir /mnt/boot[Invio]

mkdir /mnt/dev[Invio]

mkdir /mnt/mnt[Invio]

mkdir /mnt/proc[Invio]

mkdir /mnt/tmp[Invio]

chmod 1777 /mnt/tmp[Invio]

cd /mnt/tmp/dev[Invio]

MAKEDEV generic[Invio]

Questa sequenza di operazioni fa riferimento a un sistema GNU/Linux generico e non tiene conto delle particolarità che ha ogni singola distribuzione; pertanto va adattato alla propria realtà.

Fatta la copia, è necessario modificare immediatamente il file etc/fstab della partizione innestata nella directory /mnt/ (pertanto si tratta temporaneamente del file /mnt/etc/fstab), in modo da fare riferimento correttamente al file di dispositivo /dev/md3 per il file system principale. In base all'esempio a cui si sta facendo riferimento, il file etc/fstab che si va a predisporre dovrebbe contenere le righe seguenti:

/dev/hda2       none            swap    sw                          0  0
/dev/hdc2       none            swap    sw                          0  0
/dev/md3        /               auto    defaults,errors=remount-ro  0  1
/dev/hda1       /boot           auto    defaults,errors=remount-ro  0  1
/dev/hdc1       /boot-mirror    auto    defaults,errors=remount-ro  0  1
proc            /proc           proc    defaults                    0  0

Come si può osservare, la partizione corrispondente al file di dispositivo /dev/hdc1 viene innestata per comodità nella directory /boot-mirror/, in modo da rammentare all'amministratore del sistema operativo che deve occuparsi di mantenere il suo contenuto allineato a quello della partizione innestata invece nella directory /boot/.

Il problema di cui ci si deve occupare prima di arrestare il sistema operativo è delle partizioni usate per l'avvio: /dev/hda1 e /dev/hdc1, secondo gli esempi mostrati. La cosa più semplice da fare è copiare il contenuto della directory /boot/ attuale in quella nelle due partizioni (che pertanto vanno innestate da qualche parte anche durante la fase di installazione). Quello che segue è un esempio di come potrebbe essere organizzato il file /boot/grub/menu.lst di GRUB 1 nella partizione /dev/hda1:

default 0
timeout 5

title GNU/Linux
kernel (hd0,0)/vmlinuz root=/dev/md3 ro

Per converso, nella partizione /dev/hdc1 il file dovrebbe essere così:

default 0
timeout 5

title GNU/Linux
kernel (hd2,0)/vmlinuz root=/dev/md3 ro

Si osservi che il kernel appare indicato in (hd0,0)/vmlinuz, oppure (hd2,0)/vmlinuz, ovvero nella prima partizione del primo o del terzo disco fisso con il nome vmlinuz.

Dal momento che di solito non si può avviare il sistema operativo in mancanza del primo disco fisso, ci si può limitare a copiare il contenuto della partizione /dev/hda1 nella partizione /dev/hdc1, contando sul fatto che in caso di rottura del primo disco fisso si può avviare il sistema utilizzando un dischetto che contiene GRUB 1. Pertanto, dopo aver eseguito il distacco di queste partizioni, si può procedere a installare il sistema di avvio nel primo disco:

grub[Invio]

grub> root (hd0,0)[Invio]

grub> setup (hd0)[Invio]

grub> quit[Invio]

Eventualmente si può consultare il capitolo 51 a proposito di GRUB 1.

Prima di riavviare il sistema operativo per vedere se funziona effettivamente, conviene controllare che l'attività di sincronizzazione delle due partizioni sia stata completata, osservando il file /proc/mdstat:

cat /proc/mdstat[Invio]

Personalities : [linear] [raid0] [raid1] [raid5] [multipath] 
read_ahead 1024 sectors
md3 : active raid1 hda3[0] hdc3[1]
      53897920 blocks [2/2] [UU]
      
unused devices: <none>

L'esempio mostra una situazione di riposo.

173.3.3   Sostituzione di un disco difettoso

Quando si verifica l'evento che si teme, ovvero che uno dei due dischi risulti difettoso, teoricamente il sistema RAID dovrebbe continuare a funzionare escludendo quel disco. Una volta appurato questo fatto, occorre provvedere alla sua sostituzione. Se non ci sono altre conseguenze, ovvero se il danno è limitato a questo, la cosa spiacevole che può capitare è che si rompa proprio il disco usato per l'avvio del sistema operativo, cosa che richiede temporaneamente l'utilizzo di un dischetto con GRUB 1 o con un altro sistema di avvio del genere per rimettere in funzione il sistema operativo. È bene comunque non spostare il disco sano in una posizione diversa del bus ATA.

È necessario quindi procurare un altro disco, con una capacità uguale o maggiore di quello che si deve sostituire, cercando di riprodurre la stessa suddivisione precedente. Probabilmente, trattandosi di dischi di grandi dimensioni, la geometria apparente dovrebbe risultare compatibile (255 testine; 63 settori per traccia e una quantità di tracce uguale o maggiore rispetto al disco precedente). A ogni modo, si possono riprodurre fedelmente le stesse partizioni anche se la geometria non dovesse essere la stessa, pertanto, prima di rimuovere il disco difettoso, si potrebbe salvare la mappa delle partizioni con il comando seguente:

sfdisk -d /dev/hda > /root/mappa[Invio]

Come si intende, il disco difettoso dovrebbe essere in questo caso quello corrispondente al file di dispositivo /dev/hda. Il file che si ottiene potrebbe avere l'aspetto seguente:

# partition table of /dev/hda
unit: sectors

/dev/hda1 : start=       63, size=    48195, Id=83
/dev/hda2 : start=    48258, size=   963900, Id=82
/dev/hda3 : start=  1012158, size=107796087, Id=fd

Una volta sostituito il disco, si possono riprodurre le stesse partizioni (avanzando probabilmente dello spazio libero alla fine, se il disco ha una capacità maggiore del precedente) con il comando seguente:

sfdisk /dev/hda < /root/mappa[Invio]

A questo punto, conviene controllare con fdisk, ma non dovrebbe essere il caso di modificare la suddivisione in partizioni, anche se questa non è conforme alla geometria del disco. Quindi si può procedere all'inizializzazione delle partizioni che sono escluse dal sistema RAID (in questo caso /dev/hda1 usata per il sistema di avvio e /dev/hda2 usata per la memoria virtuale); inoltre, se necessario, occorre ripristinare il sistema di avvio. Quindi si può informare il sistema RAID che si può riappropriare della partizione /dev/hda3 con il comando seguente:

mdadm --add /dev/md3 /dev/hda3[Invio]

Naturalmente si sta facendo riferimento all'esempio che appare nella sezione precedente; in ogni caso, /dev/md3 deve essere quanto risulta dalla lettura del file /proc/mdstat.

Dopo l'uso di questo comando il sistema RAID si prende possesso della partizione e inizia la ricostruzione della copia speculare al suo interno.

173.3.4   Situazioni più gravi

Il sistema RAID-1 attuato via software attraverso un kernel Linux ha il vantaggio di mantenere leggibili le partizioni RAID come se fossero partizioni inizializzate normalmente. In pratica, le informazioni che riguardano l'insieme dei dischi RAID vengono collocate alla fine della partizione, in quello che viene chiamato «superblocco», che consente al kernel di conoscere la struttura dell'insieme di dischi RAID senza bisogno di file di configurazione. Pertanto, se per qualche ragione non si può fare diversamente, si può accedere a questi dati, avendo cura di farlo soltanto in lettura, ignorando il sistema RAID-1.

In conclusione, se un evento accidentale rendesse inutilizzabile l'insieme di dischi RAID-1, dovrebbe rimanere almeno la possibilità di recuperare i dati da uno dei dischi accedendo alle partizioni nel modo normale, ovvero non attraverso i dispositivi /dev/mdn.

173.3.5   Aggiungere un disco

Una volta fatta l'esperienza con una coppia di dischi RAID-1, quando si manifestano i primi problemi e si comprende quanto è importante disporre di un sistema di memorizzazione affidabile, è facile desiderare di migliorare l'affidabilità del sistema con l'aggiunta di una terza copia speculare. Si tratta naturalmente di un'idea lodevole, anche se comporta una spesa per l'aggiunta di un altro disco.

Seguendo l'esempio già proposto in precedenza, si parte da una situazione in cui esistono due dischi ATA, dove le partizioni /dev/hda3 e /dev/hdc3 compongono un sistema RAID-1 /dev/md3. Si vuole aggiungere un disco, nel quale riprodurre più o meno la stessa suddivisione in partizione di quelli già installati, in modo da utilizzare la partizione /dev/hdd3 come terza copia speculare del sistema RAID-1 /dev/md3. Dopo aver installato fisicamente il disco aggiuntivo e avere riavviato il sistema, occorre informare della presenza di un terzo disco:

mdadm --grow --raid-devices=3 /dev/md3[Invio]

Si può verificare nel file virtuale /proc/mdstat:

cat /proc/mdstat[Invio]

Personalities : [linear] [raid0] [raid1] [raid5] [multipath] 
read_ahead 1024 sectors
md3 : active raid1 hda3[0] hdc3[1]
      53897920 blocks [3/2] [UU_]
      
unused devices: <none>

Come si può osservare, pur essendo previste tre partizioni in gioco, in realtà solo due sono operative. Pertanto, occorre aggiungere la partizione mancante:

mdadm --add /dev/md3 /dev/hdd3[Invio]

A questo punto parte la sincronizzazione della partizione /dev/hdd3 e al termine si dovrebbe osservare il funzionamento parallelo delle tre partizioni:

cat /proc/mdstat[Invio]

Personalities : [linear] [raid0] [raid1] [raid5] [multipath] 
read_ahead 1024 sectors
md3 : active raid1 hda3[0] hdc3[1] hdd3[2]
      53897920 blocks [3/3] [UUU]
      
unused devices: <none>

173.3.6   Creare un sistema RAID-1 senza dover travasare i dati

È possibile realizzare un sistema RAID-1 utilizzando una partizione che contiene già un file system Second-extended (Ext2 o Ext3), senza bisogno di travasare i dati e, soprattutto, senza perderli.

Si suppone di avere una situazione come quella della tabella successiva, dove la partizione /dev/hda2 è quella che viene utilizzata:

/dev/hda1 /dev/hdc1 partizioni per il kernel e gli altri file necessari all'avvio;
/dev/hda2 /dev/hdc2 partizioni da gestire in modo speculare secondo il modello RAID-1.
/dev/hda4 /dev/hdc4 partizioni per la memoria virtuale.

Per poter fare le trasformazioni necessarie è necessario avviare il sistema con un disco esterno, come un CD autoavviabile, che però deve disporre del programma Mdadm.

Si procede con la modifica del tipo di partizione, sia per /dev/hda2, sia per /dev/hdc2, in modo che corrisponda a FD16 (autorilevamento RAID); per questo basta usare fdisk, avendo cura di non modificare altro.

Con Mdadm si dichiara l'unità RAID /dev/md2 (si ricordi che potrebbe essere necessario provvedere alla creazione del file di dispositivo /dev/md2), associando inizialmente solo la partizione /dev/hda2:

mdadm --create /dev/md2 --level=raid1 --raid-devices=2 \
  \      /dev/hda2 missing
[Invio]

Si osservi alla fine della riga di comando dell'esempio appena mostrato la presenza della parola chiave missing, con la quale si evita temporaneamente l'indicazione della seconda partizione.

mdadm: /dev/hda2 appears to contain an ext2fs file system
    size=35782656K  mtime=Sat Aug  6 09:55:20 2005

Continue creating array? y[Invio]

mdadm: array /dev/md2 started.
md: bind<hda2>
raid1: raid set md2 active with 1 out of 2 mirrors

Le informazioni sulla gestione RAID vengono inserite alla fine della partizione, che, di conseguenza, ne risulta ridotta. È necessario procedere a un aggiustamento:

fsck.ext3 -f /dev/md2[Invio]

e2fsck 1.37 (21-Mar-2005)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/md2: 404645/4481568 files (2.5% non-contiguous), 5216591/8945664 blocks

resize2fs /dev/md2[Invio]

resize2fs 1.37 (21-Mar-2005)
Resizing the filesystem on /dev/md2 to 8946176 (4k) blocks.
The filesystem on /dev/md2 is now 8945664 blocks long.

Infine si aggiunge l'altra partizione, che prima è stata lasciata da parte:

mdadm --add /dev/md2 /dev/hdc2[Invio]

Naturalmente occorre ricordare di modificare il file /etc/fstab nell'unità /dev/md2 e di sistemare il sistema di avvio, come già descritto.

173.4   Riferimenti


1) Mdadm   GNU GPL


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome gestione_dei_dischi_in_modo_ridondante.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory