Backup: Unterschied zwischen den Versionen
Aus MeinWiki
(→LVM Shadowcopy[https://wiki.samba.org/index.php/Rotating_LVM_snapshots_for_shadow_copy]) |
|||
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 50: | Zeile 50: | ||
umount /mnt/backup | umount /mnt/backup | ||
− | == LVM Shadowcopy == | + | == LVM Shadowcopy[https://wiki.samba.org/index.php/Rotating_LVM_snapshots_for_shadow_copy] == |
+ | * Script smbsnap | ||
+ | #!/bin/bash | ||
+ | # | ||
+ | # written by Christian Schwamborn | ||
+ | # bugs and suggestions to: | ||
+ | # christian.schwamborn[you-know-what-comes-here]nswit.de | ||
+ | # | ||
+ | # published under GNU General Public License v.2 | ||
+ | # version 1.0.3 (2007-12-13) | ||
+ | # | ||
+ | # Authors: Christian Schwamborn [CS] | ||
+ | # Schlomo Schapiro [GSS] sschapiro[you-know-what-comes-here]probusiness.de | ||
+ | # | ||
+ | # History: | ||
+ | # 1.0.1 (2006-11-21) CS initial release | ||
+ | # 1.0.2 (2007-01-08) CS snapshottime now in GMT | ||
+ | # 1.0.3 (2007-12-13) GSS added support for extra mount options (for XFS) | ||
+ | # | ||
+ | # You are using this scrip at your own risk, the author is not responsible | ||
+ | # for data damage or losses in any way. | ||
+ | # | ||
+ | # What this is: | ||
+ | # You can use this script to create and manage snapshots for the Samba | ||
+ | # VFS module shadow_copy. | ||
+ | # | ||
+ | # How to use: | ||
+ | # The script provides some commanline parameters which are usefull for | ||
+ | # start/stop scrips (i.e. mount and unmount). Other parameters are usefull | ||
+ | # for cronjobs - add this, for a usual snapshot scenario (without trailing #) | ||
+ | # to your crontab: | ||
+ | # | ||
+ | # 0 12 * * 1-5 root /usr/local/sbin/smbsnap autosnap 0 0 | ||
+ | # 0 7 * * 2-5 root /usr/local/sbin/smbsnap autosnap 0 1 | ||
+ | # 0 7 * * 1 root /usr/local/sbin/smbsnap autosnap 0 2 | ||
+ | # 3,33 * * * * root /usr/local/sbin/smbsnap autoresize all | ||
+ | # | ||
+ | # This takes snapshots at 7:00 and 12:00 every workday and checks every hour | ||
+ | # if a snapshot needs to be resized. | ||
+ | # | ||
+ | # The script has some flaws: | ||
+ | # -This script currently works only with LVM2, no EVMS support yet | ||
+ | # -XFS should be easy to implement, but it isn't yet | ||
+ | # -You must not use dashes in your volumegroups or logical volumes | ||
+ | # -Be carefull with the configuration, the parameters are not completely | ||
+ | # checked right now, as the same for the command line parameters | ||
+ | # -You have to keep track of the freespace of your volumegroups | ||
+ | # -Be aware, that if your snapshots grow faster than you assumed, they will | ||
+ | # become unusable. With the configuration shown above, this script checks | ||
+ | # every 30 minutes if the snapshots are in the need of a resize. If | ||
+ | # someone has a better idea how to check the snapshots than periodical, | ||
+ | # let me know plaese. | ||
+ | # | ||
+ | # This script is written for the bash, other shells might work, it also uses | ||
+ | # some external commands: mount, umount, grep, date, bc, logger, lvcreate, | ||
+ | # lvremove, lvresize | ||
+ | # | ||
+ | # There are currently three variables that have to be configured: | ||
+ | # -SnapVolumes is an array, every element of that array represents a logical | ||
+ | # volume that is configured for snapshots. Each element is a comma seperated | ||
+ | # list, which consists of the logical volume itself (i.e. /dev/GROUP1/foo), | ||
+ | # the start size of the snapshot (in megabytes), the freespace which should | ||
+ | # be maintained (in megabytes), the space added, when a snapshot is | ||
+ | # resized (also in megabytes) and optionally additional mount options required | ||
+ | # for mounting the snapshot, like ",nouuid" for XFS. Please add the leading "," | ||
+ | # because this parameter will be appended to "mount -o ro" *verbatim*. | ||
+ | # The number of an element is used as a reference when calling the script | ||
+ | # -SnapSets is also an array, currently every element just represents the | ||
+ | # age (in days) of a snapshot of the specific snapshot-set. | ||
+ | # -OffDays is a simple string with the none work days. | ||
+ | # | ||
+ | # The script will figure out by itself where to mount the snapshots, but the | ||
+ | # original logical volumes has to be mounted fist. | ||
+ | # | ||
+ | # Copy and adjust the following three variables (without #) to a blank file in | ||
+ | # /etc/samba and name it smbsnap.conf. If you place the configuration file | ||
+ | # elsewhere, make sure to adjust the path below. | ||
+ | # | ||
+ | # SnapVolumes=('/dev/GROUP/foo;2000;500;1000;,nouuid' '/dev/GROUP/bar;3000;1000;2000') | ||
+ | # SnapSets=(2 5 20) | ||
+ | # OffDays="Sat Sun" | ||
+ | # | ||
+ | # NOTE TO USERS OF PREVIOUS VERSION !! | ||
+ | # | ||
+ | # The delimiter changed from , to ; to support adding multiple mount options | ||
+ | # | ||
+ | # please convert your smbsnap.conf with sed -e 's/,/;/g' -i /etc/samba/smbsnap.conf | ||
+ | # | ||
+ | # Sorry for the invonvenience ... | ||
+ | # | ||
+ | ############################################################################### | ||
+ | |||
+ | . /etc/samba/smbsnap.conf | ||
+ | |||
+ | export LANG=en_US.UTF-8 | ||
+ | export LANGUAGE=en_US:en | ||
+ | SnapDate=$(date -u +%Y.%m.%d-%H.%M).00 | ||
+ | logFile=/var/log/backup.log | ||
+ | [ -z "${1}" ] || Command=${1} | ||
+ | [ -z "${2}" ] || LVolume=${2} | ||
+ | [ -z "${3}" ] || SnapSet=${3} | ||
+ | |||
+ | |||
+ | ExtraMountOptions= | ||
+ | |||
+ | # process a single snapshot | ||
+ | # arguments: Command | ||
+ | # needs: SnapShot, VolumePath, SnapSets, OffDays, FreeSize, ReSize | ||
+ | # provides: na. | ||
+ | # local: cmd, SnapShotPath, CurrSnapSets, Count, Expire, Parameters, SnapState, CurrSize, FillPercet, CurrFreeSize | ||
+ | function DoSnap() | ||
+ | { | ||
+ | cmd=${1} | ||
+ | SnapShotPath=${VolumePath}/@GMT-$(echo ${SnapShot##*/} | cut -f3-4 -d\-) | ||
+ | |||
+ | case ${cmd} in | ||
+ | # to mount snapshots | ||
+ | mount) | ||
+ | [ -d ${SnapShotPath} ] || mkdir ${SnapShotPath} || \ | ||
+ | logger "${0}: ***error*** - unable to create mountpoint for ${SnapShot}" | ||
+ | if mount | grep -q ${SnapShotPath}; then | ||
+ | logger "${0}: ***error*** - snapshot ${SnapShot} is allready mounted to ${SnapShotPath}" | ||
+ | else | ||
+ | mount ${SnapShot} ${SnapShotPath} -o ro$ExtraMountOptions >> $logFile 2>&1 || \ | ||
+ | logger "${0}: ***error*** - can not mount ${SnapShot} to ${SnapShotPath}" | ||
+ | fi | ||
+ | ;; | ||
+ | |||
+ | # to unmount a snapshots | ||
+ | umount) | ||
+ | if mount | grep -q ${SnapShotPath}; then | ||
+ | umount -f -l ${SnapShotPath} >> $logFile 2>&1 || \ | ||
+ | logger "${0}: ***error*** - can not unmount ${SnapShot} mounted to ${SnapShotPath}" | ||
+ | else | ||
+ | logger "${0}: ***error*** - snapshot ${SnapShot} is not mounted to ${SnapShotPath}" | ||
+ | fi | ||
+ | ;; | ||
+ | |||
+ | # to remove expired snapshots | ||
+ | clean) | ||
+ | CurrSnapSet=$(echo ${SnapShot##*/} | cut -f2 -d\-) | ||
+ | if [ ${CurrSnapSet} -ge 0 ] && [ ${CurrSnapSet} -lt ${#SnapSets[@]} ]; then | ||
+ | Expire=$(echo ${SnapSets[${CurrSnapSet}]} | cut -f1 -d,) | ||
+ | |||
+ | # add off-days, if any, to the expire time; we just count work-days | ||
+ | declare -i Count=1 | ||
+ | while [ ${Expire} -ge ${Count} ];do | ||
+ | echo ${OffDays} | grep -q $(date -d "-${Count} day" +%a) && Expire=$((${Expire} + 1)) | ||
+ | Count=$((${Count} + 1)) | ||
+ | done | ||
+ | |||
+ | # compare date now minus expire-time with the snapshot-date | ||
+ | if [ $(( $(date +%s) - ${Expire}*24*60*60 - 12*60*60)) -gt \ | ||
+ | $(date -d "$(echo ${SnapShot##*/} | cut -f3 -d\- | tr \. \-) \ | ||
+ | $(echo ${SnapShot##*/} | cut -f4 -d\- | tr \. \:)" +%s) ]; then | ||
+ | # unmount snapshot | ||
+ | if mount | grep -q ${SnapShotPath}; then | ||
+ | umount -f ${SnapShotPath} >> $logFile 2>&1 || \ | ||
+ | logger "${0}: ***error*** - can not unmount ${SnapShot} mounted to ${SnapShotPath}" | ||
+ | fi | ||
+ | if ! mount | grep -q ${SnapShotPath}; then | ||
+ | # remove mount-directory | ||
+ | if [ -d ${SnapShotPath} ]; then | ||
+ | rmdir ${SnapShotPath} || \ | ||
+ | logger "${0}: ***error*** - unable to remove mountpoint for ${SnapShot}" | ||
+ | fi | ||
+ | # finally remove snapshot | ||
+ | if /sbin/lvremove -f ${SnapShot} >> $logFile 2>&1;then | ||
+ | logger "${0}: successfully removed outdated snapshot ${SnapShot}" | ||
+ | else | ||
+ | logger "${0}: ***error*** - can not remove logical volume ${SnapShot}" | ||
+ | fi | ||
+ | fi | ||
+ | fi | ||
+ | else | ||
+ | logger "${0}: ***error*** - snapshot-set #${CurrSnapSet} of snaphot ${SnapShot} is not configured" | ||
+ | fi | ||
+ | ;; | ||
+ | |||
+ | # to check periodical if the snapshots have to be resized | ||
+ | autoresize) | ||
+ | Parameters="--options lv_size,snap_percent --noheadings --nosuffix --separator , --unbuffered --units m" | ||
+ | SnapState=$(lvs ${Parameters} ${SnapShot}) | ||
+ | CurrSize=$(echo ${SnapState} | cut -f1 -d,) | ||
+ | FillPercet=$(echo ${SnapState} | cut -f2 -d,) | ||
+ | CurrFreeSize=$(echo "${CurrSize}-${CurrSize}/100*${FillPercet}" | bc) | ||
+ | |||
+ | if ! [ $(echo "${CurrFreeSize} > ${FreeSize}" | bc) -eq 1 ]; then | ||
+ | if /sbin/lvresize -L +${ReSize}M ${SnapShot} >> $logFile 2>&1; then | ||
+ | logger "${0}: successfully resized snapshot ${SnapShot}" | ||
+ | else | ||
+ | logger "${0}: ***error*** - an error occurred while resizing ${SnapShot}" | ||
+ | fi | ||
+ | fi | ||
+ | ;; | ||
+ | esac | ||
+ | } | ||
+ | |||
+ | |||
+ | # invoked if all snapshots of a volume are processed | ||
+ | # arguments: Command | ||
+ | # needs: VolumeDevice, VolumePath, SnapSet & functions: DoSnap | ||
+ | # provides: SnapShot | ||
+ | # local: snapset_tmp, cmd | ||
+ | function DoAllSnaps() | ||
+ | { | ||
+ | cmd=${1} | ||
+ | [ -z "${SnapSet}" ] || snapset_tmp="${SnapSet}-" | ||
+ | # checkout if the configured volume exists and is mounted | ||
+ | if [ -b ${VolumeDevice} ]; then | ||
+ | if mount | grep -q "${VolumePath} "; then | ||
+ | # process all snapshots of the volume and, if given, of a specific snapshot-set | ||
+ | for SnapShot in ${VolumeDevice}-${snapset_tmp}*; do | ||
+ | if [ ${SnapShot} = "${VolumeDevice}-${snapset_tmp}*" ]; then | ||
+ | logger "${0}: ***error*** - no backupset #${SnapSet} found for ${VolumeDevice}" | ||
+ | else | ||
+ | DoSnap ${cmd} | ||
+ | fi | ||
+ | done | ||
+ | else | ||
+ | logger "${0}: ***error*** - logical volume ${VolumeDevice} not mounted to ${VolumePath}" | ||
+ | fi | ||
+ | else | ||
+ | logger "${0}: ***error*** - logical volume ${VolumeDevice} does not exist" | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | |||
+ | # creates a new snapshot and mounts it | ||
+ | # arguments: na. | ||
+ | # needs: VolumeDevice, VolumePath, SnapSet, SnapSize, SnapDate & functions: DoAllSnaps, DoSnap | ||
+ | # provides: SnapShot | ||
+ | # local: na. | ||
+ | function MakeSnap () | ||
+ | { | ||
+ | case ${SnapSet} in | ||
+ | |||
+ | [0-9]) | ||
+ | if [ "${Command}" = "autosnap" ]; then DoAllSnaps "clean"; fi | ||
+ | SnapShot=${VolumeDevice}-${SnapSet}-${SnapDate} | ||
+ | if /sbin/lvcreate -L${SnapSize}M -s -n ${SnapShot##*/} ${VolumeDevice} >> $logFile 2>&1; then | ||
+ | logger "${0}: successfully created new snapshot ${SnapShot}" | ||
+ | else | ||
+ | logger "${0}: ***error*** - an error occurred while creating snapshot ${SnapShot}" | ||
+ | fi | ||
+ | DoSnap "mount" | ||
+ | ;; | ||
+ | |||
+ | *) | ||
+ | echo "usage: ${0} snap|autosnap <LV number | all> <Snap-Set Number>" | ||
+ | ;; | ||
+ | esac | ||
+ | } | ||
+ | |||
+ | |||
+ | # sets some variables and splits the way for certain commands | ||
+ | # arguments: one object of the array SnapVolumes | ||
+ | # needs: Command, & functions: DoAllSnaps MakeSnap | ||
+ | # provides: SnapVolume, VolumeDevice, PVGroupName, LVolumeName, VolumePath, SnapSize, FreeSize, ReSize | ||
+ | # local: na. | ||
+ | function SecondChoice () | ||
+ | { | ||
+ | SnapVolume=${1} | ||
+ | VolumeDevice=$(echo ${SnapVolume} | cut -f1 -d\;) | ||
+ | PVGroupName=$(echo ${VolumeDevice} | cut -f3 -d/) | ||
+ | LVolumeName=$(echo ${VolumeDevice} | cut -f4 -d/) | ||
+ | VolumePath=$(mount | grep ^/dev[[:alnum:]/]*${PVGroupName}.${LVolumeName}[\ ] | cut -f3 -d' ') | ||
+ | SnapSize=$(echo ${SnapVolume} | cut -f2 -d\;) | ||
+ | FreeSize=$(echo ${SnapVolume} | cut -f3 -d\;) | ||
+ | ReSize=$(echo ${SnapVolume} | cut -f4 -d\;) | ||
+ | ExtraMountOptions=$(echo ${SnapVolume} | cut -f5 -d\;) | ||
+ | |||
+ | case ${Command} in | ||
+ | |||
+ | mount|umount|clean|autoresize) | ||
+ | DoAllSnaps ${Command} | ||
+ | ;; | ||
+ | |||
+ | snap|autosnap) | ||
+ | MakeSnap | ||
+ | ;; | ||
+ | esac | ||
+ | } | ||
+ | |||
+ | |||
+ | # decides if all configured volumes are processed or just a specific one | ||
+ | # arguments: na. | ||
+ | # needs: Command, LVolume, SnapVolumes & functions: SecondChoice | ||
+ | # provides: na. | ||
+ | # local: snp | ||
+ | case ${Command} in | ||
+ | |||
+ | mount|umount|snap|clean|autosnap|autoresize) | ||
+ | case ${LVolume} in | ||
+ | |||
+ | all) | ||
+ | for snp in ${SnapVolumes[@]}; do | ||
+ | SecondChoice ${snp} | ||
+ | done | ||
+ | ;; | ||
+ | |||
+ | [0-9]) | ||
+ | if [ ${LVolume} -ge 0 ] && [ ${LVolume} -lt ${#SnapVolumes[@]} ]; then | ||
+ | SecondChoice ${SnapVolumes[LVolume]} | ||
+ | else | ||
+ | logger "${0}: ***error*** - there is no configured logical volume #${LVolume} for snapshots" | ||
+ | fi | ||
+ | ;; | ||
+ | |||
+ | *) | ||
+ | echo "usage: ${0} <command> <LV number | all> [<Snap-Set Number>]" | ||
+ | ;; | ||
+ | esac | ||
+ | ;; | ||
+ | |||
+ | *) | ||
+ | echo "usage: ${0} <command> <LV number | all> [<Snap-Set Number>]" | ||
+ | echo | ||
+ | echo " valid commands are:" | ||
+ | echo " mount - to mount snapshots" | ||
+ | echo " umount - to unmount snapshots" | ||
+ | echo " snap - to make a new snapshot" | ||
+ | echo " clean - to cleanup outdated snapshots" | ||
+ | echo " autosnap - normally used for cronjobs to cleanup" | ||
+ | echo " outdates snapshots an create a new one" | ||
+ | echo " autoresize - for a periodical check if snapshots" | ||
+ | echo " needs to be resized" | ||
+ | echo | ||
+ | echo " <LV number> is the number of a logical volume, configured for" | ||
+ | echo " snapshots in SnapVolumes, or simply 'all' for all volumes" | ||
+ | echo " <Snap-Set Number> is the number of the snapshot-set, configured" | ||
+ | echo " in SnapSet. It is optional, except for the commands 'snap' and" | ||
+ | echo " 'autosnap'" | ||
+ | echo | ||
+ | ;; | ||
+ | esac | ||
+ | *Konfiguration /etc/samba/smbsnap.conf | ||
+ | SnapVolumes=('/dev/volg1/lvdaten1;200;50;1000;,nouuid') | ||
+ | SnapSets=(2 5 20) | ||
+ | OffDays="Sat Sun" | ||
+ | |||
+ | *Scheduler | ||
+ | 0 12 * * 1-5 /root/bin/smbsnap autosnap all 0 | ||
+ | 0 19 * * 2-5 /root/bin/smbsnap autosnap all 1 | ||
+ | 0 19 * * 1 /root/bin/smbsnap autosnap all 2 | ||
+ | 0 20 * * * /root/bin/smbsnap clean all | ||
+ | # 3,33 * * * * /root/bin/smbsnap autoresize all |
Aktuelle Version vom 25. September 2015, 14:13 Uhr
Inhaltsverzeichnis
tar Backup
Backup erstellen
tar -zcvf name.tar.gz /source
Backup wiederherstellen
tar -C /destination -xzvf name.tar.gz
Rdiff Backup
Backup erstellen
rdiff-backup /source /destination
- Backup ohne symbolische Links
rdiff-backup --exclude-symbolic-links /source /destination
Backups anzeigen
rdiff-backup -l /destination
Backup Statistik anzeigen
rdiff-backup-statistics /destination rdiff-backup --list-increment-sizes /destination
Restore
- letzte Sicherung
cp /destination / source
- ältere Sicherungen
rdiff-backup -l /destination rdiff-backup /destination/rdiff-backup-data/increments/... /source
- Wiederhrstellung mittels rdiff-backup-fs
rdiff-backup-fs /mnt/ /destination/rdiff-backup-data/
Entfernen ältere Backups
rdiff-backup --remove-older-than "Datum/Tage(5D)" /destination
Script
#!/bin/bash logPath1=/var/log/backup/ logFile1=backup$(date "+%y%m%d").log fileWrite1=$logPath1$logFile1 mount -t cifs -o username="USERNAME",password="PAASWORT" //172.30.4.12/backup /mnt/backup if [ -f /mnt/backup/mount ]; then echo $(date "+%y%m%d-%H%M%S")' Start Backup' >> $fileWrite1 rdiff-backup --exclude-symbolic-links /mnt/daten1/bereich/ /mnt/backup/daten1/bereich/ >> $fileWrite1 rdiff-backup --exclude-symbolic-links /mnt/daten1/home/ /mnt/backup/daten1/home >> $fileWrite1 rdiff-backup --exclude-symbolic-links /mnt/daten1/profile /mnt/backup/daten1/profile >> $fileWrite1 rdiff-backup --exclude-symbolic-links /mnt/daten1/exchange /mnt/backup/daten1/exchange >> $fileWrite1 /etc/init.d/postgresql stop rdiff-backup --exclude-symbolic-links /var/lib/postgresql/9.3/main /mnt/backup/var >> $fileWrite1 /etc/init.d/postgresql start logger "Externes Backup Erfolgreich" echo $(date "+%y%m%d-%H%M%S")' Stop Backup' >> $fileWrite1 else echo $(date "+%y%m%d-%H%M%S")' Error Backup' >> $fileWrite1 logger "Fehler externes Backup" fi umount /mnt/backup
LVM Shadowcopy[1]
- Script smbsnap
#!/bin/bash # # written by Christian Schwamborn # bugs and suggestions to: # christian.schwamborn[you-know-what-comes-here]nswit.de # # published under GNU General Public License v.2 # version 1.0.3 (2007-12-13) # # Authors: Christian Schwamborn [CS] # Schlomo Schapiro [GSS] sschapiro[you-know-what-comes-here]probusiness.de # # History: # 1.0.1 (2006-11-21) CS initial release # 1.0.2 (2007-01-08) CS snapshottime now in GMT # 1.0.3 (2007-12-13) GSS added support for extra mount options (for XFS) # # You are using this scrip at your own risk, the author is not responsible # for data damage or losses in any way. # # What this is: # You can use this script to create and manage snapshots for the Samba # VFS module shadow_copy. # # How to use: # The script provides some commanline parameters which are usefull for # start/stop scrips (i.e. mount and unmount). Other parameters are usefull # for cronjobs - add this, for a usual snapshot scenario (without trailing #) # to your crontab: # # 0 12 * * 1-5 root /usr/local/sbin/smbsnap autosnap 0 0 # 0 7 * * 2-5 root /usr/local/sbin/smbsnap autosnap 0 1 # 0 7 * * 1 root /usr/local/sbin/smbsnap autosnap 0 2 # 3,33 * * * * root /usr/local/sbin/smbsnap autoresize all # # This takes snapshots at 7:00 and 12:00 every workday and checks every hour # if a snapshot needs to be resized. # # The script has some flaws: # -This script currently works only with LVM2, no EVMS support yet # -XFS should be easy to implement, but it isn't yet # -You must not use dashes in your volumegroups or logical volumes # -Be carefull with the configuration, the parameters are not completely # checked right now, as the same for the command line parameters # -You have to keep track of the freespace of your volumegroups # -Be aware, that if your snapshots grow faster than you assumed, they will # become unusable. With the configuration shown above, this script checks # every 30 minutes if the snapshots are in the need of a resize. If # someone has a better idea how to check the snapshots than periodical, # let me know plaese. # # This script is written for the bash, other shells might work, it also uses # some external commands: mount, umount, grep, date, bc, logger, lvcreate, # lvremove, lvresize # # There are currently three variables that have to be configured: # -SnapVolumes is an array, every element of that array represents a logical # volume that is configured for snapshots. Each element is a comma seperated # list, which consists of the logical volume itself (i.e. /dev/GROUP1/foo), # the start size of the snapshot (in megabytes), the freespace which should # be maintained (in megabytes), the space added, when a snapshot is # resized (also in megabytes) and optionally additional mount options required # for mounting the snapshot, like ",nouuid" for XFS. Please add the leading "," # because this parameter will be appended to "mount -o ro" *verbatim*. # The number of an element is used as a reference when calling the script # -SnapSets is also an array, currently every element just represents the # age (in days) of a snapshot of the specific snapshot-set. # -OffDays is a simple string with the none work days. # # The script will figure out by itself where to mount the snapshots, but the # original logical volumes has to be mounted fist. # # Copy and adjust the following three variables (without #) to a blank file in # /etc/samba and name it smbsnap.conf. If you place the configuration file # elsewhere, make sure to adjust the path below. # # SnapVolumes=('/dev/GROUP/foo;2000;500;1000;,nouuid' '/dev/GROUP/bar;3000;1000;2000') # SnapSets=(2 5 20) # OffDays="Sat Sun" # # NOTE TO USERS OF PREVIOUS VERSION !! # # The delimiter changed from , to ; to support adding multiple mount options # # please convert your smbsnap.conf with sed -e 's/,/;/g' -i /etc/samba/smbsnap.conf # # Sorry for the invonvenience ... # ############################################################################### . /etc/samba/smbsnap.conf export LANG=en_US.UTF-8 export LANGUAGE=en_US:en SnapDate=$(date -u +%Y.%m.%d-%H.%M).00 logFile=/var/log/backup.log [ -z "${1}" ] || Command=${1} [ -z "${2}" ] || LVolume=${2} [ -z "${3}" ] || SnapSet=${3} ExtraMountOptions= # process a single snapshot # arguments: Command # needs: SnapShot, VolumePath, SnapSets, OffDays, FreeSize, ReSize # provides: na. # local: cmd, SnapShotPath, CurrSnapSets, Count, Expire, Parameters, SnapState, CurrSize, FillPercet, CurrFreeSize function DoSnap() { cmd=${1} SnapShotPath=${VolumePath}/@GMT-$(echo ${SnapShot##*/} | cut -f3-4 -d\-) case ${cmd} in # to mount snapshots mount) [ -d ${SnapShotPath} ] || mkdir ${SnapShotPath} || \ logger "${0}: ***error*** - unable to create mountpoint for ${SnapShot}" if mount | grep -q ${SnapShotPath}; then logger "${0}: ***error*** - snapshot ${SnapShot} is allready mounted to ${SnapShotPath}" else mount ${SnapShot} ${SnapShotPath} -o ro$ExtraMountOptions >> $logFile 2>&1 || \ logger "${0}: ***error*** - can not mount ${SnapShot} to ${SnapShotPath}" fi ;; # to unmount a snapshots umount) if mount | grep -q ${SnapShotPath}; then umount -f -l ${SnapShotPath} >> $logFile 2>&1 || \ logger "${0}: ***error*** - can not unmount ${SnapShot} mounted to ${SnapShotPath}" else logger "${0}: ***error*** - snapshot ${SnapShot} is not mounted to ${SnapShotPath}" fi ;; # to remove expired snapshots clean) CurrSnapSet=$(echo ${SnapShot##*/} | cut -f2 -d\-) if [ ${CurrSnapSet} -ge 0 ] && [ ${CurrSnapSet} -lt ${#SnapSets[@]} ]; then Expire=$(echo ${SnapSets[${CurrSnapSet}]} | cut -f1 -d,) # add off-days, if any, to the expire time; we just count work-days declare -i Count=1 while [ ${Expire} -ge ${Count} ];do echo ${OffDays} | grep -q $(date -d "-${Count} day" +%a) && Expire=$((${Expire} + 1)) Count=$((${Count} + 1)) done # compare date now minus expire-time with the snapshot-date if [ $(( $(date +%s) - ${Expire}*24*60*60 - 12*60*60)) -gt \ $(date -d "$(echo ${SnapShot##*/} | cut -f3 -d\- | tr \. \-) \ $(echo ${SnapShot##*/} | cut -f4 -d\- | tr \. \:)" +%s) ]; then # unmount snapshot if mount | grep -q ${SnapShotPath}; then umount -f ${SnapShotPath} >> $logFile 2>&1 || \ logger "${0}: ***error*** - can not unmount ${SnapShot} mounted to ${SnapShotPath}" fi if ! mount | grep -q ${SnapShotPath}; then # remove mount-directory if [ -d ${SnapShotPath} ]; then rmdir ${SnapShotPath} || \ logger "${0}: ***error*** - unable to remove mountpoint for ${SnapShot}" fi # finally remove snapshot if /sbin/lvremove -f ${SnapShot} >> $logFile 2>&1;then logger "${0}: successfully removed outdated snapshot ${SnapShot}" else logger "${0}: ***error*** - can not remove logical volume ${SnapShot}" fi fi fi else logger "${0}: ***error*** - snapshot-set #${CurrSnapSet} of snaphot ${SnapShot} is not configured" fi ;; # to check periodical if the snapshots have to be resized autoresize) Parameters="--options lv_size,snap_percent --noheadings --nosuffix --separator , --unbuffered --units m" SnapState=$(lvs ${Parameters} ${SnapShot}) CurrSize=$(echo ${SnapState} | cut -f1 -d,) FillPercet=$(echo ${SnapState} | cut -f2 -d,) CurrFreeSize=$(echo "${CurrSize}-${CurrSize}/100*${FillPercet}" | bc) if ! [ $(echo "${CurrFreeSize} > ${FreeSize}" | bc) -eq 1 ]; then if /sbin/lvresize -L +${ReSize}M ${SnapShot} >> $logFile 2>&1; then logger "${0}: successfully resized snapshot ${SnapShot}" else logger "${0}: ***error*** - an error occurred while resizing ${SnapShot}" fi fi ;; esac } # invoked if all snapshots of a volume are processed # arguments: Command # needs: VolumeDevice, VolumePath, SnapSet & functions: DoSnap # provides: SnapShot # local: snapset_tmp, cmd function DoAllSnaps() { cmd=${1} [ -z "${SnapSet}" ] || snapset_tmp="${SnapSet}-" # checkout if the configured volume exists and is mounted if [ -b ${VolumeDevice} ]; then if mount | grep -q "${VolumePath} "; then # process all snapshots of the volume and, if given, of a specific snapshot-set for SnapShot in ${VolumeDevice}-${snapset_tmp}*; do if [ ${SnapShot} = "${VolumeDevice}-${snapset_tmp}*" ]; then logger "${0}: ***error*** - no backupset #${SnapSet} found for ${VolumeDevice}" else DoSnap ${cmd} fi done else logger "${0}: ***error*** - logical volume ${VolumeDevice} not mounted to ${VolumePath}" fi else logger "${0}: ***error*** - logical volume ${VolumeDevice} does not exist" fi } # creates a new snapshot and mounts it # arguments: na. # needs: VolumeDevice, VolumePath, SnapSet, SnapSize, SnapDate & functions: DoAllSnaps, DoSnap # provides: SnapShot # local: na. function MakeSnap () { case ${SnapSet} in [0-9]) if [ "${Command}" = "autosnap" ]; then DoAllSnaps "clean"; fi SnapShot=${VolumeDevice}-${SnapSet}-${SnapDate} if /sbin/lvcreate -L${SnapSize}M -s -n ${SnapShot##*/} ${VolumeDevice} >> $logFile 2>&1; then logger "${0}: successfully created new snapshot ${SnapShot}" else logger "${0}: ***error*** - an error occurred while creating snapshot ${SnapShot}" fi DoSnap "mount" ;; *) echo "usage: ${0} snap|autosnap <LV number | all> <Snap-Set Number>" ;; esac } # sets some variables and splits the way for certain commands # arguments: one object of the array SnapVolumes # needs: Command, & functions: DoAllSnaps MakeSnap # provides: SnapVolume, VolumeDevice, PVGroupName, LVolumeName, VolumePath, SnapSize, FreeSize, ReSize # local: na. function SecondChoice () { SnapVolume=${1} VolumeDevice=$(echo ${SnapVolume} | cut -f1 -d\;) PVGroupName=$(echo ${VolumeDevice} | cut -f3 -d/) LVolumeName=$(echo ${VolumeDevice} | cut -f4 -d/) VolumePath=$(mount | grep ^/dev[[:alnum:]/]*${PVGroupName}.${LVolumeName}[\ ] | cut -f3 -d' ') SnapSize=$(echo ${SnapVolume} | cut -f2 -d\;) FreeSize=$(echo ${SnapVolume} | cut -f3 -d\;) ReSize=$(echo ${SnapVolume} | cut -f4 -d\;) ExtraMountOptions=$(echo ${SnapVolume} | cut -f5 -d\;) case ${Command} in mount|umount|clean|autoresize) DoAllSnaps ${Command} ;; snap|autosnap) MakeSnap ;; esac } # decides if all configured volumes are processed or just a specific one # arguments: na. # needs: Command, LVolume, SnapVolumes & functions: SecondChoice # provides: na. # local: snp case ${Command} in mount|umount|snap|clean|autosnap|autoresize) case ${LVolume} in all) for snp in ${SnapVolumes[@]}; do SecondChoice ${snp} done ;; [0-9]) if [ ${LVolume} -ge 0 ] && [ ${LVolume} -lt ${#SnapVolumes[@]} ]; then SecondChoice ${SnapVolumes[LVolume]} else logger "${0}: ***error*** - there is no configured logical volume #${LVolume} for snapshots" fi ;; *) echo "usage: ${0} <command> <LV number | all> [<Snap-Set Number>]" ;; esac ;; *) echo "usage: ${0} <command> <LV number | all> [<Snap-Set Number>]" echo echo " valid commands are:" echo " mount - to mount snapshots" echo " umount - to unmount snapshots" echo " snap - to make a new snapshot" echo " clean - to cleanup outdated snapshots" echo " autosnap - normally used for cronjobs to cleanup" echo " outdates snapshots an create a new one" echo " autoresize - for a periodical check if snapshots" echo " needs to be resized" echo echo " <LV number> is the number of a logical volume, configured for" echo " snapshots in SnapVolumes, or simply 'all' for all volumes" echo " <Snap-Set Number> is the number of the snapshot-set, configured" echo " in SnapSet. It is optional, except for the commands 'snap' and" echo " 'autosnap'" echo ;; esac
- Konfiguration /etc/samba/smbsnap.conf
SnapVolumes=('/dev/volg1/lvdaten1;200;50;1000;,nouuid') SnapSets=(2 5 20) OffDays="Sat Sun"
- Scheduler
0 12 * * 1-5 /root/bin/smbsnap autosnap all 0 0 19 * * 2-5 /root/bin/smbsnap autosnap all 1 0 19 * * 1 /root/bin/smbsnap autosnap all 2 0 20 * * * /root/bin/smbsnap clean all # 3,33 * * * * /root/bin/smbsnap autoresize all