Usare Rsync per convertire il charset dei files
Rsync (versioni recenti) supporta il magico comando --iconv per convertire il charset dei files da un formato ad un altro. Questa funzione` e` molto utile quando si copiano dati da una macchina vecchia a una nuova che ragiona in utf-8, o anche da un mac in utf-8 a un Linux in utf-8, perche` ovviamente il mac ha un formato utf-8 che non e` standard.
Se non e` chiaro quale sia il charset di partenza, occorrera` fare delle prove fino a scoprirlo. Ricordatevi che ogni prova che fate creera` dei files che poi andranno ad accumularsi e fare quasi sicuramente casino. Fate le prove in un ambiente pulito che poi cancellate e riprovate fino a che non ci siete riusciti.
La sintassi del comando --iconv e` nel manuale di rsync, e vi consiglio di verificare se non e` cambiata fra una versione e l'altra. Attualmente prende due parametri: charset di partenza e charset di arrivo, in questo ordine. Dunque, per convertire da cp850 a utf-8, diremo --iconv=cp850,utf8.
Posso applicare il comando --iconv a una copia di files oppure anche fare una cosa abbastanza ardita, cioe` modificare i files in loco e cancellare i vecchi (TERRORE!).
Per questa ultima opzione suicida, facciamo un esempio. Alterare il charset dei files (e delle directory) dalla directory corrente in giu`, da cp850 a utf-8, cancellando i files con il vecchio nome dopo averli convertiti. Prima lo facciamo in modo prova, senza cioe` eseguire davvero il comando:
rsync --iconv=cp850,utf8 -anv --stats --times --progress --delete-after . .
Notare i due "punto" in fondo alla command line, che vogliono dire "dalla directory corrente alla directory corrente". Il parametro "n" significa "non fare niente, fai solo finta".
Se lo volete fare davvero, togliete "n" dalla command line (-anv diventa -av). Nel farvi notare che se lo eseguite (per davvero, non in test) due volte di fila, farete un casino allucinante perche` ri-convertirete in modo errato i files gia` convertiti, vi auguro buon danno.
Usare Rsync per fare backup remoti via ssh
Questo documento descrive come usare rsync (attraverso ssh) per fare i backup remoti di una directory da una macchina ad un'altra. E` consigliata comunque una lettura dei manuali di Rsync perche` ha un milione di opzioni alcune delle quali potenzialmente pericolose.
Il sistema qui descritto esegue di fatto un mirror della directory, quindi ha alcuni limiti da prendere bene in considerazione:
- Se si cancella un file nell'originale, viene cancellato anche nella copia. Questo e` voluto, per non accumulare nella copia mucchi di files inutili, pero` e` importante sottolinearlo.
- ATTENZIONE, LA CANCELLAZIONE E` POTENZIALMENTE DANNOSISSIMA. UN ERRORE E CIAO FILE SYSTEM DI DESTINAZIONE!
- Questo sistema fa una copia sola, non tiene alcuno storico. Quindi se si fa un errore e poi un backup, non ci sono piu` copie "buone" (prima dell'errore) da recuperare. Eventualmente se si vuole tenere uno storico, si puo` backuppare in locale la copia su un file tar o come si vuole. Ovviamente non bisogna alterare il contenuto della copia altrimenti poi Rsync rischia di dover trasferire piu` roba di quella necessaria per riallineare le directory
- La copia avviene SOLO IN UN VERSO, dalla sorgente alla destinazione. Non si tratta di una sincronizzazione bidirezionale. Per fare sincro bidirezionali si puo` usare "Unison".
Principio di funzionamento
Si installa rsync su tutte e due le macchine, e da una delle due lo si lancia facendo in modo che esso stesso lanci, attraverso ssh, la sua "controparte" sull'altra macchina. Alla fine della sincronizzazione rsync termina su tutte due le macchine, e non resta in ascolto in alcun modo. Per usare questo sistema occorre ovviamente avere un account (dedicato, oppure il tuo utente, oppure root se devi sincronizzare roba che puo` essere letta solo da root) sulla macchina remota. Non e` necessario che l'account usato localmente sia lo stesso usato in remoto. Se si vuole usare questo sistema da cron, occorre per forza usare l'autenticazione a chiavi asimmetriche in ssh, per non dover usare delle password. Se lo si usa a mano, si puo` anche usare una normale autenticazione a password.
Creazione chiavi asimmetriche
Questa parte e` necessaria solo se si vuole lanciare rsync in modo automatico senza dover dare una password per la connessione.
Creare le chiavi asimmetriche con il comando ssh-keygen avendo cura di NON impostare una passphrase.
Copiare la chiave pubblica nel file .ssh/authorized_keys nella home dell'utente sulla macchina "remota" a cui poi ci si colleghera`.
- Copiare la chiave privata in un file che poi dovremo indicare nella linea di comando di rsync sulla macchina "locale". E` bene che solo l'utente che deve lanciare rsync possa leggere questo file, perche` si tratta di una chiave privata senza password.
Parametri di rsync
Qui di seguito il lancio di rsync usando chiavi asimmetriche per autenticare, per fare un backup da una macchina remota (10.1.1.1) usando l'utente remoto rsync (creato all'uopo, ma va bene qualsiasi utente) dal path remoto "/home/" al path locale "/backup/home". La sintassi dei path di partenza e destinazione e` praticamente identica a quella di scp. Non e` affatto necessario che la copia vada dalla macchina remota a quella locale, puo` anche andare al contrario. E` consigliabile leggere comuque il manuale, specie relativamente all'opzione "--delete". Per testare le cose senza fare danni, si puo` usare il parametro "n" e togliere il parametro "q".
# q = quiet, z=comprimi # il file chiave_dsa_rsync contiene la chiave privata # exclude funziona come in tar # gli ultimi due parametri sono username@host:path sorgente e path destinazione. rsync -qaAHXz --stats --delete -e "ssh -i chiave_dsa_rsync" --exclude ".ssh" --exclude ".bash_history" --exclude ".viminfo" rsync@10.1.1.1:/home/ /backup/home/
Operazioni manuali semplici
Supponendo di voler lanciare qualcosa a mano una tantum, senza uso delle chiavi ma con le semplici password, ecco alcuni esempi utili.
- Dalla macchina remota alla macchina locale, copia completa con cancellazione di quello che non c'e`. Attenzione perche` la cancellazione e` crudele e spesso fa danni. Ricordiamoci che la cancellazione spazza via tutto quello che c'e` sulla destinazione e che non c'e` nella sorgente, quindi se c'e` roba in piu`, la cancella. Se si sbaglia destionazione e per dire si fa sulla root della macchina remota, vi fotte tutto il file system!!! Occhio soprattutto a non finire per sbaglio una directory piu` indietro di dove si vorrebbe finire. E` sempre meglio fare prima una prova (con la "n" al posto della "v") in quanto dall'output della prova si vede subito che rsync vorrebbe cancellare un sacco di roba che voi non volevate cancellare.
rsync -vaAHXz --stats --delete rsync@10.1.1.1:/home/ /backup/home/
- Dalla macchina locale alla macchina remota, test (ovvero non fa nulla, mostra solo quello che farebbe) di copia completa con cancellazione.
rsync -naAHXz --stats --delete /ud0/ root@jorge:/ud0/
- Come sopra, ma non e` un test, lo fa davvero (cambia la "n" in "v"):
rsync -vaAHXz --stats --delete /ud0/ root@jorge:/ud0/
Usare Rsync per fare backup locali
Semplice copia con rsync fra due dischi locali, con cancellazione dalla destinazione dei files che non ci sono nella sorgente:
rsync -aAHX --del --stats /source /destination rsync -aAHX --del --stats /home /mnt
Attenzione agli slash in fondo ai path
Attenzione a come si mettono gli slash in fondo ai path di sorgente e destinazione, cambia la logica di creazione dei path di destinazione. Se si mette lo slash alla fine del path di partenza, si copia il contenuto del path di partenza dentro al path di destinazione. Se NON SI METTE lo slash alla fine del path di partenza, si copia l'ultima directory (compreso il contenuto, ovviamente) del path di partenza nel path di destinazione.
# copia il contenuto del source path (ovvero cio` che si trova DENTRO a /source/path/ senza "path/") dentro al /dest/path/ # se ad esempio abbiamo /source/path/file1.txt il risultato sara` /dest/path/file1.txt rsync /source/path/ /dest/path/ # copia il source path compresa l' ultima directory del source path dentro al /dest/path/ # se ad esempio abbiamo /source/path/file1.txt il risultato sara` /dest/path/path/file1.txt # se la directory dest/path/path non esiste, la crea, ma crea solo l' ultima. Ovvero /dest/path/ deve esistere da prima. rsync /source/path /dest/path/
Copiare files enormi a rischio interruzione
Se dobbiamo fare una copia di un file enorme, e siamo a rischi di interruzioni del processo di copia, possiamo provare a farla con rsync, riprendendo da dove eravamo rimasti. Il parametro "--partial" permette di riprendere una copia a meta`, in questo modo:
# se ho tanto spazio sul disco di destinazione: rsync --partial --progress /source /destination # se ho poco spazio sul disco di destinazione: rsync --partial --inplace --progress /source /destination
Chiaramente funziona in locale quanto in remoto (con destinazione del tipo root@host:/path) ed e` assai utile proprio in remoto, perche` e` difficile che una copia si interrompa in locale. Siccome non so quanto sia realmente affidabile il metodo, credo che sia meglio fare un md5sum dei files alla fine della copia. Il parametro "--inplace" sovrascrive il file di destinazione anziche` creare una copia e poi rinominarla alla fine. Utile se il disco di destinazione non e` in grado di contenere due copie del file enorme che stiamo trasferendo, ma una soltanto.
Parametri interessanti per le copie dei file system
Se si vuole copiare il root file system, oppure un file system che non contiene solo files tradizionali (qualcosa di piu` dei files utente di Samba, per dire, che sono solamente files) ma contine hardlinks, symlink, attributi estesi, ACL posix, eccetera, allora occorre usare i parametri giusti. Ce ne sono tanti nel man, ma questi sono i piu` comuni e comodi:
- Minimale, copia tutto (compresi i symlink) ma non gestisce gli hardlink, le ACL, gli attributi estesi: -a
- Copia gli hardlink come tali (cioe` crea gli hardlink e non copia 2 volte lo stesso file): -H
- Copia gli attributi estesi: -X
- Copia le ACL posix: -A
- Copia in maniera efficiente gli sparse files: -S
- Crea nella destinazione il path completo specificato nella sorgente e non solo l'ultimo pezzo: -R (leggi il man per questo, che la spiegazione e` lunga)
- Non tocca i files gia` esistenti nella destinazione: --ignore-existing. (utile per esempio se sincronizzo due maildir perche` aggiunge le mail che mancano ma non sovrascrive i files di indice di dovecot sulla destinazione. attenzione: le directory non sono files, le directory non vengono ignorate, ma questo ha assolutamente senso)
Un esempio di rsync che puo` copiare tutto il root file system e avere una macchina avviabile (previa ricreazione del boot loader) potrebbe essere:
rsync -aAXHv / /path/to/backup/folder --exclude="/dev/*" --exclude="/proc/*" --exclude="/sys/*" --exclude="/tmp/*" --exclude="/run/*" --exclude="/mnt/*" --exclude="/media/*"--exclude="/lost+found" --exclude="/root/VirtualBox VMs" --exclude="/home" --exclude="/ud0" --exclude="/var/vmail"
Notare che esclude il CONTENUTO delle directory dev, proc, eccetera ma non la directory stessa, che deve esistere altrimenti non va una sega. Esclude invece totalmente la lost+found, la quale esite gia` per definizione nel nuovo disco (posto che sia un disco e non una subdir).
ssh su porta non standard
Per usare rsync su ssh su una porta non standard:
rsync -e "ssh -p <numero porta>" eccetera
Uno script di backup orribile
Questo e` un semplice script i backup per fare una copia con rsync su un disco esterno usb. Attenzione all'uso del "--delete" che potrebbe cancellare il contenuto del disco di backup. Ovviamente dovrete adattarlo al vostro uso, questo contiene funzioni specifiche (soprattutto per i virtuali) per un mio server.
# #!/bin/bash # cd / echo echo ========================================= echo Backup con rsync su HDD esterno echo ========================================= echo # check se /mnt e gia in uso if ! [ -f /mnt/not_mounted ]; then echo "Backup fallito: /mnt e' gia' montata!"; exit 1 fi; # se non e` in uso, la monto mount -t ext3 -L $1 /mnt if [ -f /mnt/not_mounted ]; then echo Backup fallito: non riesco ad accedere al disco removibile ; else if ! [ -d /mnt/backup-rsync ]; then echo "Non esiste la directory backup-rsync sul disco usb: la creo."; mkdir /mnt/backup-rsync fi; echo `date` "Inizio il backup del sistema (esclusi ud0, home, mail e virtuali)" rsync -aAXH / /mnt/backup-rsync/ --one-file-system --stats --delete --exclude="/dev/*" --exclude="/proc/*" --exclude="/sys/*" --exclude="/tmp/*" --exclude="/run/*" --exclude="/mnt/*" --exclude="/media/*"--exclude="/lost+found" --exclude="/root/VirtualBox VMs" --exclude="/home" --exclude="/ud0" --exclude="/var/vmail" echo . echo `date` "Inizio il backup di ud0" rsync -aAXR /ud0/ /mnt/backup-rsync/ --stats --delete echo . echo `date` "Inizio il backup delle home" rsync -aAXR /home/ /mnt/backup-rsync/ --stats --delete echo . echo `date` "Inizio il backup della mail" rsync -aAXHR /var/vmail/ /mnt/backup-rsync/ --delete echo . echo `date` "Inizio il backup di MindTouch" VBoxManage controlvm "MindTouch" savestate tar cvzf /mnt/MindTouch.tgz /root/VirtualBox\ VMs/MindTouch/ /root/.VirtualBox/ --totals > /mnt/MindTouch.log VBoxManage startvm "MindTouch" -type vrdp echo echo echo `date` "Smonto il disco" sync sleep 1m echo . df -h echo . fi; umount /mnt date