domenica 17 giugno 2012

Backup on Poweroff

Anni fa, tra le pagine di un vecchio blog, parlai di uno stupendo strumento per il backup chiamato rdiff-backup .

Oggi a distanza di anni e dopo una profonda evoluzione di interfacce e sistemi operativi, ritengo che uno dei migliori strumenti per il backup in circolazione sia rdiff-backup che tra l'altro fa da backend a molti famosi programmi in circolazione.

Cos'è e come funziona 

Rdiff-backup, è un programma scritto in Python per linea di comando, ovviamente multi-piattaforma, che unisce svariati concetti e tecnologie, con risultati decisamente interessanti.

Prima di tutto è un backup incrementale inverso, cioè tiene traccia diretta dell'ultima versione e un backup incrementale delle versioni precedenti di ogni singolo oggetto del file system : quindi non occorre inserire tutti i volumi a ritroso per arrivare al backup finale. Le precedenti versioni più vecchie possono poi essere rimosse automaticamente dopo un certo numero di giorni/mesi/anni.

Seconda caratteristica, è che tale struttura incrementale è implementata sulle differenze binarie, che lo rendono lento ma estremamente efficiente. Da tale caratteristica deriva anche il nome rdiff, visto che questo era il vecchio sistema di patch binaria (prima dell'arrivo degli xdelta, già da me citati in un precedente post ).

Terza cosa importante è che l'ultima versione dei files salvati, è direttamente accessibile nella cartella come semplice copia, cioè si dispone di copia fisica direttamente accessibile di questi dati e non sperduta in qualche intricato archivio.

Se ci aggiungete che integra rsync, consentendo i backup in remoto e che soprattutto il file system di destinazione è ininfluente cioè, potete ripristinare qualsiasi file, cartella, link o file speciale, con tanto di date e permessi, anche se il backup è su un volume ntfs o vfat , vi potete rendere facilmente conto di quanto il tutto sia conveniente.

Per quanto riguarda le critiche che si possono fare a rdiff-backup vi è sicuramente la complessità della riga di comando che è piuttosto laboriosa e l'uso improprio che molti programmi ne fanno.

Infatti, nonostante il sistema rsync permetta un backup in tempi ragionevolmente rapidi, se per qualche motivo si interrompe un backup in corso, alla successiva ripartenza rdiff-backup esegue un complesso rollback che può allungare senza preavviso il backup di alcune ore, con la conseguenza che poi l'utente si arrabbia e tende ad interromperlo nuovamente.

È altresì altamente sconsigliato lavorare su un disco mentre si fa il backup, per una ovvia questione di consistenza tra copia salvata e copia attuale.

Il comando rdiff-backup

Come accennavo, rdiff-backup sebbene estremamente versatile, è sempre stato piuttosto ostico ed è questo il motivo per cui di solito è usato attraverso frontend grafici.

Vi sono decine di modi diversi con i quali si può ottenere esattamente quello che si vuole (sempre ammesso che lo si sappia).

Io di solito lo uso così :

/usr/bin/rdiff-backup --force --include-globbing-filelist <filelist> <backup-dir> <backup-dest>

dove <backup-dir>, è la cartella sulla quale di solito eseguo il backup.

Salvo soltanto /home perché uso degli stratagemmi per fare in modo che tutto risieda su home e che stia per altro in una partizione separata, ma riguarda strettamente la mia visione di Linux per desktop e sui server ovviamente c'è ben altro da memorizzare.

La <filelist> è la lista delle eccezioni che di fatto è semplice elenco dove si possono escludere ed includere cartelle, per esempio usando questa semplice lista  :

- /home/user/.mozilla/firefox/Profiles/euuiqw19823.default/Cache
- /home/user/.cache
- /home/user/.thumbnails
- /home/user/.adobe
- /home/user/.googleearth

che è interamente esclusiva (segno -), si escludono dalla home dell'utente, alcune cartelle con le cache che sono di solito migliaia di files inutili.

Non mettendo il segno meno, la cartella o la sottocartella si re-include nella lista. Quindi immaginiamo di non volere salvare la cartella chiamata useless tranne la sotto-cartella useful, possiamo scrivere :

- /home/user/useless
/home/user/useless/useful

Sono ammesse anche alcune espressioni regolari.
 
In questo modo avrete capito che potete benissimo gestire, anche la cartella / cioè tutto il disco, prima escludendo tutto e poi includendo solo le cartelle interessanti, qui trovate una completa descrizione dei comandi e i relativi esempi.

Infine <backup-dest> è la cartella locale o remota che ospita il backup, se è un disco USB sarà automaticamente montato o da montare manualmente, in qualche parte in una sotto-cartella di /media o /mnt .

Backoff

Nei server, il backup è generalmente eseguito durante le ore di basso utilizzo (se ve ne sono), per i server aziendali le procedure partono di solito a notte fonda mediante schedulazione temporale (cron).

Per un desktop, il momento ideale per eseguire un backup è quando si smette di lavorarci, istante che nel mondo Windows da qualche anno è chiamato "il magico momento delle patch".

Poiché come tanti, per tenere una copia dei dati, uso un disco esterno USB che lascio normalmente staccato dalla rete elettrica e dal computer, ho cercato di pensare ad un sistema automatico che rilevasse la presenza di questo disco allo spegnimento della macchina Linux e nel caso facesse in automatico il backup prima di spegnerla.

Quindi non so se è il termine più appropriato ma backoff è quello che mi è venuto in mente associando backup a poweroff.

Spegnimento 

Vediamo innanzi tutto, come modificare la procedura di shutdown.

Poiché è palese per coloro che gestiscono i server usare un apposito comando, occupiamoci di coloro che usano un desktop e cliccano su "spegni" e qui ovviamente la situazione cambia da interfaccia ad interfaccia, da sistema a sistema.

I comandi come quelli di spegnimento della macchina, non sono gestiti direttamente nello spazio utente, perché gli utenti normali non potrebbero spegnere la macchina, quindi di solito ci pensano i login manager grafici come kdm e gdm3.

Con KDE la cosa è estremamente semplice, perché immaginando di avere il comando backoff un /usr/local/sbin, possiamo aprire il System Settings, e accedere a Login Screen che è appunto il gestore di kdm :


come possiamo vedere è stato inserito nel campo Halt il comando /usr/local/sbin/backoff, che sarà eseguito come root ; ovviamente per evitare un buco di sicurezza notevole, per fare questa modifica è richiesta la password di super user (poi ovviamente anche le cartelle e il file del programma devono essere scrivibili solo da root altrimenti siamo da capo).

Il fatto che questo comando sia eseguito da un UID 0, ci dà numerosi vantaggi, in quanto il backup potrà avvenire anche su cartelle che all'utente normale sarebbero inaccessibili (attenzione che comunque finiscono in un backup leggibilissimo).

Se non usate KDE le cose sono più complesse per due motivi : primo perché non potete lanciare lo script da root senza eseguire il sudo, secondo perché è complesso a seconda dell'ambiente, trovare il modo di cambiare lo script di shutdown.

Il mio consiglio in questo caso è di creare un apposito comando tipo "backup" da mettere nei menu.

Giusto per dare una indicazione potete scrivere qualcosa tipo questo :

#!/bin/bash

function looping
{
while true
do
        echo "message:WARNING BACKUP IN PROGRESS"
        /bin/sleep 10
done
}

/usr/local/sbin/backoff &
(looping &) | /usr/bin/zenity --notification --listen
e lanciarlo con gksu.


Verifica del collegamento

La seconda fase è verificare che un particolare disco, sia connesso alla nostra macchina.

Questo disco come spiegato non deve avere requisiti particolari, io uso tranquillamente un pre-formattato ntfs da 1Tbyte. L'unica accortezza è creare una cartella che ho chiamato BACKUP, dove finirà il backup, giusto per poter poi usare il disco anche per altro, senza disturbare la procedura incrementale.

Questo si può fare grazie agli UUID , quindi occorre prima di tutto individuare quale è l'UUID del disco di backup eseguendo prima e dopo avere attaccato il disco  :

ls -l /dev/disk/by-uuid/

e verificare qual'è l'UUID del nuovo arrivato.

Poi nello script, controlleremo la sua "esistenza".

Lo Script

Lo script è un tipico programma da mettere in sbin, con dati in etc , per esempio /usr/local/sbin.

In questo caso, dobbiamo creare in /usr/local/etc (quindi da root) la cartella backoff e metterci i seguenti files :

  • /usr/local/etc/backoff/backup.lst , contenente la <filelist>.
  • /usr/local/etc/backoff/diskid , da echo "il diskid di prima" >/usr ...

Poi possiamo copiare il seguente script in /usr/local/sbin/backoff :


#!/bin/bash
DATAFOLDER=${0%%/sbin/*}/etc/backoff
DISKID=$(<$DATAFOLDER/diskid)
if [ -e /dev/disk/by-uuid/$DISKID ]
then
  TMPDIR=`/bin/mktemp -d -p /mnt`
  /bin/umount /dev/disk/by-uuid/$DISKID 2>/dev/null
  /bin/mount /dev/disk/by-uuid/$DISKID $TMPDIR
  /usr/bin/rdiff-backup --force --exclude-other-filesystems --include-globbing-filelist $DATAFOLDER/backup.lst /home $TMPDIR/BACKUP
  /bin/sync
  /bin/umount $TMPDIR
  /bin/rmdir $TMPDIR
fi
/sbin/shutdown -h -P now


Lanciando backoff, si analizzerà la presenza del disco, se quel particolare disco di backup non è connesso avverrà un semplice shutdown -h -P .

Se il disco è connesso invece, viene montato/rimontato correttamente su una cartella temporanea ed è eseguito il backup della cartella home con le modalità già viste, poi il disco si sincronizza, la cartella è smontata e rimossa e solo allora si procede allo shutdown definitivo della macchina.

Attenzione, che l'opzione "--exclude-other-filesystems" serve ad evitare che ogni file system eventualmente montato in /home o comunque nella cartella da salvare, sia incluso. Al di là del fatto che nel nostro caso la cartella temporanea è creata in /mnt, ciò evita tra l'altro il pericolo di tentare di salvare lo stesso volume di backup nel qual caso il sistema andrebbe in loop con nefaste conseguenze.

Se si mette come script di shutdown,  spegnendo il sistema con quel particolare disco staccato, si procederà normalmente mentre spegnendolo con quel disco attaccato, si potrà andare tranquillamente a dormire e lasciare che il sistema faccia il resto.

Restore

Giusto per accennarvi come funziona il restore di rdiff-backup, di cui potete trovare lunghe spiegazioni in altra sede, una volta che avete ripristinato il sistema primario, per ripristinare l'intero disco col comando che abbiamo dato (cioè salvando la /home direttamente in /BACKUP), basta scrivere :
rdiff-backup -r now <mount-point>/BACKUP /home
dove mount-point, è il punto dove montate il disco, e il sistema si ripristina all'ultima copia.

Se vi interessa invece un singolo file o una singola cartella, potete dare :
rdiff-backup -r now <mount-point>/BACKUP/<path> <new-path>
dove path è il percorso dalla home e new-path è la cartella dove il contenuto della cartella path sarà espanso.

Per un file specifico occorre indicare il nome del file sia in path che in new-path.

Ma vediamo un esempio con risvolti ancora più interessanti.

Immaginiamo per esempio di volere recuperare un documento mydoc.odt di tre mesi fa che avevamo cancellato, e che il documento fosse  /home/user/Documents, possiamo dare questo comando :
rdiff-backup -r 90D <mount-point>/BACKUP/user/Documents/mydoc.odt myolddocument.odt
dove 90D sta proprio per 90 giorni fa. Il documento è salvato nella cartella corrente col nuovo nome cioè myolddocument.odt.

Con un comando tipo :
rdiff-backup -r 2012-2-21 <mount-point>/BACKUP/user/Documents ./oldDocumentsFolder
possiamo estrarre l'intera cartella Documenti risalente a una data (prossima per difetto) al 21 febbraio 2012 e metterla in un nuovo folder per esempio per fare un confronto.

Per sapere quanti backup sono stati fatti di tale cartella, possiamo scrivere :
rdiff-backup -l <mount-point>/BACKUP/user/Documents
E ancora ... tutti gli ultimi documenti sono immediatamente raggiungibili come semplici files, nella cartella <mount-point>/BACKUP/user/Documents che è il famoso mirror fisico.

Che volete di più ?


Nessun commento:

Posta un commento