Disco di Backup Avviabile con rsync (RAID freddo)

Una problematica comune riguardo ai sistemi sui quali risiedono dati senibili e/o configurazioni e servizi specifici è quella del backup, cioè poter disporre di una copia del contenuto del disco che assicuri la ridondanza in caso di guasti ai supporti di informazione. Essa si rivela di primaria importanza quando, il computer, a causa di errori dell'operatore o guasti interni, abbia perso in modo irrecuperabile dati fondamentali o configurazioni essenziali per il suo corretto funzionamento. Le procedure quì elencate vogliono essere un riassunto per descrivere come è stato affrontato questo problema a livello semi-professionale al fine di ottenere un sistema sicuro in termini di backup. Le nostre esigenze sono quelle di avere un secondo supporto di informazioni che sia completamente uguale a quello principale e sia avviabile manualmente, ma la sincronizzazione tre i due supporti non deve avvenire in tempo reale. E’ capitato che i nostri server si siano bloccati a seguito di aggiornamenti del sistema operativo scaricati dalla rete, che un operatore abbia cancellato distrattamente una directory o che abbia cambiato una configurazione e abbia provocato danni a catena. In tutti questi casi, un RAID con due dischi fissi avrebbe immediatamente duplicato i danni sui due supporti e quindi sarebbe stato inutile per far ripartire il sistema. Per le nostre esigenze si è voluto adottare un sistema in cui normalmente sia attivo un solo disco fisso. Ogni giorno, nel periodo di minor utilizzo del server, il secondo disco fisso viene automaticamente montato, sincronizzato con il disco fisso principale e poi smontato in modo da ridurne l’usura. Questa scelta ha lo svantaggio di lasciare il computer bloccato in caso di guasto al supporto principale e richiedere l’intervento di un operatore per avviare il sistema dal supporto secondario.
Questa piccola guida vorrebbe essere un utile punto di partenza per migliorare il livello di affidabilità di una piccola rete domestica o d'ufficio.
Il layout di sistema dal quale si è partiti, indipendentemente dal resto dell'hardware, presenta due dischi fissi identici, e si è operato con l'obiettivo di mantenere su uno dei due dischi la copia esatta, aggiornata giornalmente tramite l'utility rsync, di quello in funzione nel quale è presente il sistema operativo, avendo la possibilità, inoltre, di poterlo avviare in caso di rottura del primo. In particolare si illustreranno le procedure di configurazione per due sistemi:

Sebbene le tecnologie con cui si è avuto a che fare siano sostanzialmente diverse, dal punto di vista dell'utente finale ciò non comporta un cambiamento d'approccio, poiché le istruzioni seguenti, per entrambi i sistemi hanno portato a configurazioni funzionanti.

Partendo da un sistema in cui nel primo disco è già presente  un sistema funzionante, si deve creare una tabella di partizioni specifica sul secondo disco fisso. Per fare ciò si possono utilizzare i tool cfdisk o fdisk come illustreremo, ricordando, e ciò vale per tutti i riferimenti seguenti, che ci si riferisce a sda per il primo disco fisso e a sdb per il secondo. E’ utile prendere visione della tabella delle partizioni del primo disco per crearne una, in questo caso identica, sul secondo. Per fare ciò

root@system:~# cfdisk /dev/sda

oppure

root@system:~# fdisk /dev/sda
Command (m for help): p

Disk /dev/sda: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x08090808

Device    Boot  Start     End     Blocks   Id  System
/dev/sda1   *    1         13     104391    83  Linux
/dev/sda2       14        318    2449912+   82  Linux swap/Solaris
/dev/sda3      319      48641   388154497+  83  Linux

Nel sistema preso in considerazione le associazioni sono le seguenti:

 

A questo punto si replica la struttura, in modo che sia identica sul secondo hard disk, poiché ciò evita dei disallineamenti che potrebbero portare all'impossibilità di effettuare una copia di backup per spazio insufficiente. Partendo da un disco vuoto si prosegue come riportato

root@system:~# fdisk /dev/sdb
Command (m for help): p

Disk /dev/sdb: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000b052f

   Device Boot      Start         End      Blocks   Id  System

 

Per creare unanuova partizione usare l'opzione 'n'
Command (m for help): n

Command action
   e   extended
   p   primary partition (1-4)

indicare se la partizione è primaria o logica, in questo caso selezioniamo la prima con 'p'
p

Partition number (1-4): 1
First cylinder (1-48641, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-48641, default 48641): +100M          

si indica con +100M la dimensione della partizione creata, ossia 100MB, dopodichè si verifica il risultato con 'p'. La seguente è la partizione di boot '/boot'

Command (m for help): p

Disk /dev/sdb: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Disk identifier: 0x000b052f

Device Boot      Start         End      Blocks   Id   System
/dev/sdb1            1          13      104391   83   Linux

 

a questo punto si replica il procedimento per le ulteriori partizioni, rispettivamente di swap e di root '/'

Command (m for help): n

Command action
   e   extended
   p   primary partition (1-4)
p

Partition number (1-4): 2
First cylinder (14-48641, default 14):
Using default value 14
Last cylinder or +size or +sizeM or +sizeK (14-48641, default 48641): +2500M

 

Command (m for help): p
Disk /dev/sdb: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000b052f

 

Device Boot      Start         End      Blocks    Id  System
/dev/sdb1            1          13      104391    83   Linux
/dev/sdb2           14         318     2449912+   83   Linux

 

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p

Partition number (1-4): 3
First cylinder (319-48641, default 319):
Using default value 319
Last cylinder or +size or +sizeM or +sizeK (319-48641, default 48641):
Using default value 48641

 

Command (m for help): p

Disk /dev/sdb: 400.0 GB, 400088457216 bytes
255 heads, 63 sectors/track, 48641 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000b052f

 

Device    Boot    Start         End      Blocks   Id  System
/dev/sdb1             1          13      104391   83  Linux
/dev/sdb2            14         318     2449912+  83  Linux
/dev/sdb3           319       48641   388154497+  83  Linux

Command (m for help): w

A questo punto è stata ottenuta la tabella di partizioni desiderata, quindi è necessario creare al loro interno il filesystem adatto, per esempio Ext3

root@system:~# mkfs.ext3 /dev/sdb1
[...]
root@system:~# mkfs.ext3 /dev/sdb3
[...]
root@system:~# mkswap /dev/sdb2
[...]

Il prossimo passo è quello di fare in modo che il contenuto delle singole partizioni sul primo disco sia copiato nelle rispettive partizioni del secondo. A tale scopo si utilizza rsync, un tool fondamentale per il backup dei dati, poiché permette la creazione di copie in maniera intelligente evitando di copiare di volta in volta l'intero filesystem e riportando solo i file che presentano, ad esempio, variazione dei metadati (ad esempio la data di ultimo accesso o la dimensione del file). Poiché i comandi da utilizzare sono ripetitivi, è utile la crezione di un piccolo script che li inglobi tutti. Fondamentalmente ciò che è necessario fare è:

 

A tal fine si riporta un possibile script minimale

root@system:~# nano -w /usr/sbin/mirroring

#!/bin/sh

/bin/mount /dev/sdb3 /mnt/sdb/sdb3

/usr/bin/rsync -a -E --exclude=/mnt/* --exclude=/etc/fstab --exclude=/etc/mtab \

     --exclude=/sys/* --exclude=/tmp/* --exclude=/proc/* --exclude=/var/run/* \

     --exclude=/var/lock/* --exclude=/boot/* / /mnt/sdb/sdb3

/bin/umount /dev/sdb3

/bin/mount /dev/sdb1 /mnt/sdb/sdb1

/usr/bin/rsync -a -E --delete --exclude=/boot/grub/menu.lst \

     --exclude=/boot/grub.conf /boot/* /mnt/sdb/sdb1

/bin/umount /dev/sdb1

ricordarsi a questo punto di creare le directory necessarie allo script all'interno della cartella '/mnt', come '/mnt/sdb/sdb1' e '/mnt/sdb/sdb1' e di assegnare il permesso di esecuzione al file appena creato.

root@system:~# chmod +x /usr/sbin/mirroring

A questo punto è possibile effettuare le procedure sopra descritte semplicemente digitando

root@system:~# /usr/sbin/mirroring

Innanzitutto bisogna notare che le partizioni sincronizzate sono quella di boot '/boot' e quella di root '/', poiché la partizione utilizzata come swap non è adibita al contenimento di dati appartenenti alla struttura del filesystem; tuttavia gli utenti che utilizzino un metodo per l'ibernazione del sistema, ovvero della copia dell'immagine della ram e dello stato del sistema su disco, dovrebbero provvedere anche alla sincronizzazione della partizione di swap, proprio per il fatto che essa eventualmente mantiene una tale immagine.

Ora è utile soffermarsi sulle opzioni utilizzate con il comando rsync, in particolare su '--exclude=PATH'. Quest'ultima è necessaria allo scopo di escludere determinate posizioni all'interno della struttura del filesystem dall'essere copiate: ciò è utile in vista del fatto che il disco di backup, poiché si vuole che sia avviabile, possa contenere un sistema operativo, con i rispettivi dati, completamente funzionante;  questo lo si può ottenere, come meglio spiega l'esempio seguente, solo non compromettendo configurazioni che riguardino strettamante il disco utilizzato e file creati ed utilizzati a run-time. Per comprendere meglio, si può pensare al caso in cui il file '/etc/fstab', il quale è responsabile di mantenere la lista delle partizioni presenti sul sistema, utilizzi un metodo “diverso dal solito” per indicare le partizioni stesse. UUID, ossia Universal Unique Identifier, è un modo, utilizzato tra gli altri nella distribuzione Ubuntu 8.04, per riferirsi alle partizioni in maniera indipendente dal nome del disco o dal punto di mount, ed è costituito da un insieme di caratteri esadecimali ricavati tramite una procedura univoca. Dunque di questo metodo si deve tener conto, poiché, il file 'fstab' presente sul secondo disco non potrà presentare gli stessi valori di quello presente sul primo, pena l'impossibilità di avviare il disco di backup nonostante la presenza di un bootloader quale GRUB (la cui procedura di installazione verrà trattata in seguito).
Per i  motivi sopra spiegati è opportuno escludere, da valutarsi dipendenemente dal sistema utilizzato, i percorsi qui riportati:

 

Da ricordare che qualora tali cartelle non venissero create sul secondo disco, bisognerebbe provvedere manualmente, considerando il secondo disco montato in /mnt/mirror, come segue

root@system:~# cd /mnt/mirror
root@system:~# mkdir -m 1777 tmp
root@system:~# mkdir -m 1777 var/tmp
root@system:~# mkdir -m 555 proc
root@system:~# mkdir -m 755 sys
root@system:~# mkdir -m 755 mnt
root@system:~# mkdir -m 755 var/lock
root@system:~# mkdir -m 755 var/run

Per ciò che riguarda il file /etc/fstab bisogna copiarlo dal primo disco ma modificarlo in base alle partizioni presenti sul secondo disco, in modo che il sistema ne sia a conoscenza.

root@system:~# cp /etc/fstab /mnt/mirror/etc/fstab

Uno stralcio del contenuto potrebbe presentarsi così, nel caso di utilizo degli UUID

root@system:~# cat /etc/fstab
# /etc/fstab: static file system information.

#

# <file system>    <mount point>  <type>  <options>      <dump>  <pass>

proc     /proc    proc     defaults      0       0

# /dev/sda3

UUID=eb1b27c7-36e1-40c2-8e0d-cbaf23842bee /    ext3      relatime,errors=remount-ro 0       1

# /dev/sda1

UUID=baf54ec1-48c3-4506-870d-b37d9a6b2c54 /boot    ext3     relatime      0       2

/dev/sda2     none     swap     sw       0       0
[...]

Dunque per apportare modifiche in maniera opportuna bisogna sostituire gli UUID relativi alle partizioni del primo disco con quelli delle partizioni del secondo, utilizzando l'utiliy blkid oppure il comando vol_id

root@system:~# vol_id --uuid /dev/sdb1

2e692df8-c9c8-4181-b55c-ff05379f38e5

oppure

root@system:~# blkid /dev/sdb1

/dev/sdb1:    UUID="d9792df8-c9c8-4181-b55c-5f0f279f38e5" SEC_TYPE="ext2" TYPE="ext3"

Se invece in fstab sono presenti voci con la dicitura 'LABEL=', come accade nella distribuzione Red Hat Enterprise 5, ciò segnala che per indicare le singole partizioni si fà riferimento alle etichette assegnate loro al momento della creazione del filesystem.

root@system:~# cat /etc/fstab
LABEL=/       /        ext3 defaults 1 1
LABEL=/boot   /boot    ext3 defaults 1 2
[...]

A meno di non studiare una configurazione più particolareggiata, e le casistiche a cui può essere applicata, è opportuno non utilizzare i LABEL nei file di configurazione, a favore dell'utilizzo del nome del diso assegnato da udev (ossia /dev/sda o /dev/hda etc) oppure gli stessi UUID desritti precedentemente. Per conoscere le associazoni tra LABEL e dispositivi, si può utilizzare il comando

root@system:~# dumpe2fs -h /dev/sda1

così, alla prima delle tante voci che compare come output del comando, è mostrata quella del LABEL relativo alla partizione sda1. Qualora se ne volesse far uso, per assegnare e sovrascrivere un LABEL ad una partizione si può digitare il seguente comando

root@system:~# e2label /dev/sdb1 NUOVO_LABEL

Molto importante è sottolineare il fatto che in caso di malfunzionamento del primo disco, questo,  come da ipotesi inziale, verrà scollegato manualmente dal sistema per far sì che l’avvio avvenga dal secondo disco: a questo punto il disco di backup che prima era identificato come /dev/sdb, rimanendo l'unico sul sistema, verrà riconosciuto come /dev/sda, quindi, a parte il caso (consigliato) di utilizzo di UUID univoci, nel file fstab del secondo disco ci si deve riferire alle partizioni di backup sempre con il nome /dev/sda1 – sda2 – sda3 invece che /dev/sdb1 – sdb2 – sdb3.
Una nota aggiuntiva riguarda la cartella /sys per la Red Hat Enterprise 5: essa non è stata esclusa dalla prima sincronizzazione, poiché, per il corretto avvio del secondo disco, è stato necessario replicare la struttura delle sue sottodirectory. Nelle sincronizzazioni successive anche /sys è stata inclusa come cartella da non aggiornare nella copia di backup.
A questo punto, una volta indicati i necessari cambiamenti su fstab, si riportano le istruzioni per consentire l'avvio del sistema a partire dal secondo disco, con all'interno una copia di backup valida.
Innanzitutto si suppone che venga utilizzato un boot loader per l'avvio del sistema, GRUB nello specifico, e che l'installazione sul primo disco sia funzionante essendo avvenuta in fase di prima configurazione del sistema operativo. Lo scenario preso in considerazione, si ribadisce, è il seguente:

Si vuole che in caso di malfunzionamento, o di perdita accidentale di dati, sia possibile, a sistema spento, scollegare fisicamente il primo disco lasciando il secondo collegato, consentendo comunque il successivo avvio.
Si precisa che a questo punto dovrebbe essere disponibile una copia affidabile di backup sul secondo disco, quindi si conta sulla presenza del file di configurazione di GRUB anche sul disco di backup. Il file in questione è grub.conf, a volte sostituito o link-ato dal file menu.lst, da constatare sul sistema, situato nella cartella /boot/grub. Per la modifica sono valide tutte le considerazioni fatte per il file fstab e supponendo che la partizione di boot del secondo disco sia montata su /mnt/mirror/boot, si procede come segue

root@system:~# nano -w /mnt/mirror/boot/menu.lst
[...]
Title    Ubuntu 8.04.1, kernel 2.6.24-19-generic

Root (hd0,0)

kernel   /vmlinuz-2.6.24-19-generic root=UUID=eb1b27c7-36e1-40c2-8e0d-cbaf23842bee ro quiet splash

initrd   /initrd.img-2.6.24-19-generic

quiet

 

title    Ubuntu 8.04.1, kernel 2.6.24-19-generic (recovery mode)

root (hd0,0)

kernel   /vmlinuz-2.6.24-19-generic root=UUID=eb1b27c7-36e1-40c2-8e0d-cbaf23842bee ro single

initrd   /initrd.img-2.6.24-19-generic

 

title    Ubuntu 8.04.1, memtest86+

root     (hd0,0)

kernel   /memtest86+.bin

quiet
[...]

Considerando che, ad esempio, la partizione di root '/' sul secondo disco si trova su /dev/sda3 bisogna modificare le voci del file in cui si riporta lo UUID con quello corretto, sostituendolo. Nel caso siano presenti anche quì record che utilizzano LABEL, è necessario modificarli come fatto per il file fstab. Per evitare incomprensioni si precisa che l'identificativo root nella riga

root            (hd0,0)

si riferisce alla partizione su cui risiede la cartella di configurazione di GRUB , nel caso /boot/grub, mentre nella riga

kernel   /vmlinuz-2.6.24-19-generic root=UUID=eb1b27c7-
36e1-40c2-8e0d-cbaf23842bee [...]

si riferisce alla partizione di root del sistema, cioè quella dove risiede la radice del filesystem '/'.
L'espressione (hd0,0) indica con 'hd0' il primo disco individuato nel sistema e con '0' la prima partizione sullo stesso disco, in accordo con il fatto che al momento di un’eventuale partenza dal disco di backup, esso risulterebbe l'unico disco e quindi il primo presente. A titolo esplicativo la terza partizione del disco di backup sarebbe indicata in grub come (hd1,2).
Una volta modificato il file grub.conf, ovvero menu.lst, sul secondo disco, si provvede all'installazione del vero e proprio bootloader GRUB.

root@system:~# grub
Probing devices to guess BIOS drives. This may take a long time.

[ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. ]

A queto punto comparirà la shell di Grub. Ipotizzando che a queto punto si sta effettuando la prima installazione e che il disco di backup sia il secondo disco del sistema, cioè /dev/sdb, si può digitare il seguente comando per indicare che la configurazione adottata nelle successive operazioni sarà quella situata nella partizione di boot del secondo disco, /dev/sdb1

grub> root(hd1,0)
[...]

è dunque ora possibile l'installazione del bootloader nel MBR (Master Boot Record) del secondo disco

grub> setup(hd1)
[...]

grub> quit

In caso di errore si verifichi che entrambi i dischi siano presenti nel file /boot/grub/device.map e anche nel file di backup, in caso contrario aggiungere quelo mancante e ripetere l'installazione di GRUB

root@system:~# cat /boot/grub/device.map

(hd0)    /dev/sda

(hd1)    /dev/sdb

 

Infine, se tutta la procedura fin qui desritta è andata a buon termine, sul secondo disco è presente una copia del primo con la configurazione adatta per un avvio corretto del sistema, a patto che il primo disco venga scollegato. Il passo finale è far si che la procedura di aggiornamento del backup avvenga giornalmente, per esempio alle 02:01AM, aggiungendo una riga al file /etc/crontab nella quale si richiama lo script utilizzato per il backup, come mostrato di seguito

root@system:~# nano -w /etc/crontab
SHELL=/bin/sh

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

 

# m h dom mon dow user  command

17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly

25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

#

01 2  * * *  root   /usr/sbin/mirroring >> /var/log/mirroring.log

 

In ultimo, qualora si verificassero problemi al login dopo l'avvio del disco di backup, assicurarsi, in caso di utilizzo del sistema SElinux, di aver aggiornato la configurazione di tutto l'albero delle directory copia (-- inserire comando--), pena l'impossibilità di accesso al sistema.

Per concludere si ricorda che tutte le procedure qui riportate sono state realmente applicate e derivano da una reale situazione in cui la necessità di avere un sistema di backup affidabile e avvibile ha portato ad uno studio, anche se non a livello professionale, dello scenario e alla successiva personale soluzione, la quale può presentare discordanze in caso di diversi sistemi, architetetture o applicativi utilizzati, ma che rimane comunque un buon punto di partenza.
Qualsiasi consiglio, correzione o aggiunta può essere inoltrato all'autore, che provvederà con piacere alla miglioria del testo.

Antonio Casolaro