Het maken van een backup met rsync. Ik heb verschillende scripts lopen die met rsync een backup maken. Sommige scripts maken een backup van een andere computer naar de backup server. Sommige scripts copieren data van de ene partitie van de backup-server naar de andere. Op de backup server zelf worden een aantal directories naar een andere partitie gecopieerd. Dit gebeurt dagelijks. Ik heb gekozen voor de directory structuur: /BackupPartitie |--systeem1 | |--daily | | |--0 | | |--1 ....... | | `--6 | |--weekly | | |--51 | | |--52 | | |--1 | | `--2 | `--montly | |--12 | |--16 | |--20 ....... | `--8 |--systeem2 | Elke dag wordt die van een week geleden gewist. Elke zaterdag wordt nummer 5 gecopieerd naar de weekomgeving. Die van een maand geleden wordt dan gewist. Elke 4 weken wordt die van zaterdag bovendien naar de maandomgeving gecopieerd. Die van een jaar geleden wordt dan gewist. rsync_mail copieert /var/spool/mail om die directory te mogen lezen, zit de rsync-gebruiker in de groep mail $ grep rsync /etc/group mail::12:mail,rsync rsync:x:104: $ rsync_fotos copieert /home/johan/fotos Het is een klassiek Unix systeem met een umask van 022 Dat wil zeggen dat alle gebruikers, en dus met name rsync de foto's mag lezen. Ook de windows (FAT) partitie op deze machine mag iedereen lezen. backup_linux copieert de hele / van de bewuste linux machine. Omdat echt alles gelezen moet worden, moet rsync root rechten hebben. Dat is te realiseren met uid=0. Om rsync te beperken, staar in /home/rsync/.ssh/authorised_keys dat alleen het backup script uitgevoerd mag worden. #!/bin/bash if [ "$SSH_ORIGINAL_COMMAND" == \ "rsync --server --sender -vlogDtpr --modify-window=3601 . /" ] then rsync --server --sender -vlogDtpr --modify-window=3601 . / else if [ "$SSH_ORIGINAL_COMMAND" == "date" ] then date else datum=`date +"%Y%m%d-%k%M%S"` ( date ; set ) > "/home/rsync/ERROR/$datum" rsync --server --sender -vlogDtpr . /home/rsync/ERROR fi fi Dus: - of het oorspronkelijke rsync-commando wordt uitgevoerd - of het date commando wordt uitgevoerd (dit wordt gebruikt om te controleren wat er online is en met name of SSH draait ) - of je krijgt een copy van een ERROR directory backup_windows mount de windows machine met smbfs. Het rsync commando hoeft dan geen authenticatie meer te doen. Er kan gewoon gecopieerd worden van het mountpoint naar de backup directory: rsync -av --exclude=win386.swp \ --delete --link-dest=$LINKDIR \ --modify-window=3601 \ /mnt/smb/ /WindowsBackup/TMP > $TMP_FILE als de rsync mislukt, (netwerk verbreken) wordt die enige tijd later gewoon herhaald. als de rsync slaagt, dan wordt TMP gemoved naar PC1/`date +%Y%m%d-%H%M%S` en er wordt voor gezorgd dat $LINKDIR de volgende keer netjes verwijst naar de directory PC1/yyyymmdd-hhmmss, met de juiste datum en tijd. De optie --modify-window=3601 Deze optie zorgt er voor dat de klokken 1 uur (en 1 sec) verkeerd mogen staan. Dit is nodig als je FAT-partities hebt en soms overschakelt naar zomer/wintertijd. Dan zijn de bestanden plots een uur ouder/jonger, met tot gevolg dat alles opnieuw gecopieerd wordt. # Bij de overgang van/naar DST worden alle files plotseling een uur # nieuwer of ouder. Dit ontstaat door de code # secs += sys_tz.tz_minuteswest*60; # in de functie date_dos2unix van /usr/src/linux/fs/fat/misc.c # Deze code is nodig omdat het FAT-filesysteem de tijd in localtime # opslaat. Bij het terugrekenen naar unixtime, zou je rekening moeten # houden met de tijdzone van het moment waarop de file aangemaakt was. # Voor een deel kan dat niet (er zijn namelijk 2 tijden 2:30) en voor # een deel is dat te moeijlijk (Olson bibliotheek wil je niet in de # kernel gebruiken). Daarom heel lomp die regel vervangen door # secs -= 3600; en de bijpassende regel in fat_date_unix2dos # vervangen door unix_date += 3600; # Nu gaat de tijd in ieder geval niet meer bij elke overgang zwabberen. # (Maar is de tijd helaas inconsistent tussen Linux en Windows.) De basis structuur van de scripts is de volgende : - een bestand aanmaken met een timestamp van 23 uur geleden. Die gebruik ik om te controleren of de vorige backup ouder was dan 23 uur. (Ik had het ooit op 24 uur staan; dan wordt er elke 25 uur een backup gemaakt). - controleren of ik het date commando kan uitvoeren. Zo ja, dan staat mijn laptop aan. - mounten en unmounten van de backup partitie. Dit voorkomt dat een rm -rf de boel wist. - een lockfile, zodat maximaal een proces tegelijk met de partitite /LinuxBackup bezig is. Ga maar eens na wat er gebeurt als een ander proces op een onhandig moment de umount doet. - de optie --link-dest, daar hebben we het al over gehad - de optie --modify-window=3601 zorgt er voor dat de klokken 1 uur (en 1 sec) verkeerd mogen staan. Dit is nodig als je FAT-partities hebt en soms overschakelt naar zomer/wintertijd. Dan zijn de bestanden plots een uur ouder/jonger, met tot gevolg dat alles opnieuw gecopieerd wordt. - de TMP directory die zorgt ervoor dat ik de laptop halverwege een backup mag loskoppelen. Als de laptop weer aangekoppeld wordt zal de backup afgemaakt worden zodra het backup script weer draait. - een ssh-key die specifiek voor de gebruiker rsync op mano gemaakt is #!/bin/bash STATUS_DIR=/usr/local/var/lib/backup mkdir -p $STATUS_DIR RDIR=MANO touch -d 'now -23 hour' $STATUS_DIR/timestamp # Als er geen copy is, of als de laatste complete copy ouder is dan 24 uur, # probeer dan een nieuwe copy te maken # Het tijdstip van ${STATUS_DIR}/${RDIR} is het tijdstip van de # laatste complete copy # De inhoud van ${STATUS_DIR}/${RDIR} is de directory van de laatste # compete copy if [ ! -e ${STATUS_DIR}/${RDIR} ] || [ ${STATUS_DIR}/${RDIR} -ot $STATUS_DIR/timestamp ] then if ssh -i /root/.ssh/id_rsa_rsync rsync@mano date 2> /dev/null > /dev/null then TMP_FILE=`mktemp -t` lockfile /var/lock/LinuxBackup mount /LinuxBackup if [ -e ${STATUS_DIR}/${RDIR} ] then LINKDIR=`cat ${STATUS_DIR}/${RDIR}` else LINKDIR=/dev/null fi if rsync -av --rsh="ssh -i /root/.ssh/id_rsa_rsync" \ --modify-window=3601 \ --delete --exclude=/proc/ \ --exclude=/mnt/windows/windows/win386.swp \ --modify-window=3601 --link-dest=$LINKDIR \ rsync@mano:/ /LinuxBackup/MANO/TMP > $TMP_FILE then mv $TMP_FILE ${STATUS_DIR}/${RDIR}.list BACKUPDIR=/LinuxBackup/MANO/`date +%Y%m%d-%H%M%S` mv /LinuxBackup/MANO/TMP $BACKUPDIR echo $BACKUPDIR > ${STATUS_DIR}/${RDIR} else mv --backup=t $TMP_FILE ${STATUS_DIR}/${RDIR}half fi umount /LinuxBackup rm -f /var/lock/LinuxBackup fi fi exit