mirror of
https://0xacab.org/liberate/backupninja.git
synced 2024-11-23 11:13:18 +01:00
5c6c583181
On some workloads, a process creating backups should not become so aggressive on resources that it prevents normal activity of a machine from running. It is especially important when writing to disk. One way to make backups have less impact on the main workload is to force backups to a lower ionice level. With the new ionicelevel configuration, it becomes possible for users to activate the use of ionice and to define the level within the best-effort class to better suit their needs.
227 lines
4.8 KiB
Bash
227 lines
4.8 KiB
Bash
# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
|
|
# vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
|
|
#
|
|
# backupninja handler to do incremental backups using
|
|
# wget and hardlinks, based on rsync handler
|
|
#
|
|
# feedback: rhatto at riseup.net | gpl
|
|
#
|
|
# Config file options
|
|
# -------------------
|
|
#
|
|
# [general]
|
|
# log = wget log file
|
|
# partition = partition where the backup lives
|
|
# fscheck = set to 1 if fsck should run on $partition after the backup is made
|
|
# read_only = set to 1 if $partition is mounted read-only
|
|
# mountpoint = backup partition mountpoint or backup main folder
|
|
# backupdir = folder relative do $mountpoint where the backup should be stored
|
|
# days = number of backup increments (min = 5)
|
|
# lockfile = lockfile to be kept during backup execution
|
|
# nicelevel = wget command nice level
|
|
# ionicelevel = ionice best-effort level applied to wget command
|
|
# enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly
|
|
# tmp = temp folder
|
|
#
|
|
# [source]
|
|
# wget = wget program
|
|
# wget_options = wget command options
|
|
# url = remote data url
|
|
# bandwidthlimit = set a bandwidth limit in kbps (remote source only)
|
|
#
|
|
# [destination]
|
|
# folder = local folder
|
|
#
|
|
# You can also specify some system comands if you don't want the default system values:
|
|
#
|
|
# [system]
|
|
# rm = rm command
|
|
# cp = cp command
|
|
# touch = touch command
|
|
# mv = mv command
|
|
# fsck = fsck command
|
|
#
|
|
# TODO: Daily, weekly and monthly snapshot rotation (like the one present on maildir handler).
|
|
#
|
|
|
|
# config file evaluation
|
|
|
|
setsection system
|
|
getconf rm rm
|
|
getconf cp cp
|
|
getconf touch touch
|
|
getconf mv mv
|
|
getconf fsck fsck
|
|
|
|
setsection general
|
|
getconf log /var/log/backup/wget.log
|
|
getconf partition
|
|
getconf fscheck
|
|
getconf read_only
|
|
getconf mountpoint
|
|
getconf backupdir
|
|
getconf rotate
|
|
getconf days
|
|
getconf lockfile
|
|
getconf nicelevel 0
|
|
getconf ionicelevel
|
|
getconf enable_mv_timestamp_bug no
|
|
getconf tmp /tmp
|
|
|
|
setsection source
|
|
getconf wget wget
|
|
getconf wget_options
|
|
getconf url
|
|
getconf bandwidthlimit
|
|
|
|
setsection destination
|
|
getconf folder
|
|
|
|
# function definitions
|
|
|
|
function rotate {
|
|
|
|
if [[ "$2" < 4 ]]; then
|
|
error "Rotate: minimum of 4 rotations"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -d $1.$2 ]; then
|
|
$nice $mv /$1.$2 /$1.tmp
|
|
fi
|
|
|
|
for ((n=$[$2 - 1]; n >= 0; n--)); do
|
|
if [ -d $1.$n ]; then
|
|
dest=$[$n + 1]
|
|
$nice $mv /$1.$n /$1.$dest
|
|
$touch /$1.$dest
|
|
fi
|
|
done
|
|
|
|
if [ -d $1.tmp ]; then
|
|
$nice $mv /$1.tmp /$1.0
|
|
fi
|
|
|
|
if [ -d $1.1 ]; then
|
|
$nice $cp -alf /$1.1/. /$1.0
|
|
fi
|
|
|
|
}
|
|
|
|
function move_files {
|
|
ref=$tmp/makesnapshot-mymv-$$;
|
|
$touch -r $1 $ref;
|
|
$mv $1 $2;
|
|
$touch -r $ref $2;
|
|
$rm $ref;
|
|
}
|
|
|
|
backupdir="$mountpoint/$backupdir"
|
|
|
|
# does $backupdir exists?
|
|
|
|
if [ ! -d "$backupdir" ]; then
|
|
error "Backupdir $backupdir does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
# setup number of increments
|
|
|
|
if [ -z "$days" ]; then
|
|
keep="4"
|
|
else
|
|
keep=$[$days - 1]
|
|
fi
|
|
|
|
# lockfile setup
|
|
|
|
if [ ! -z "$lockfile" ]; then
|
|
$touch $lockfile || warning "Could not create lockfile $lockfile"
|
|
fi
|
|
|
|
# nicelevel setup
|
|
|
|
if [ ! -z "$nicelevel" ]; then
|
|
nice="nice -n $nicelevel"
|
|
else
|
|
nice=""
|
|
fi
|
|
|
|
if [ -n "$ionicelevel" ]; then
|
|
nice="ionice -c2 -n $ionicelevel $nice"
|
|
fi
|
|
|
|
# set mv procedure
|
|
|
|
if [ $enable_mv_timestamp_bug == "yes" ]; then
|
|
mv=move_files
|
|
fi
|
|
|
|
# set excludes
|
|
|
|
for path in $exclude; do
|
|
EXCLUDES="$EXCLUDES --exclude=$path"
|
|
done
|
|
|
|
echo "Starting backup at `date`" >> $log
|
|
|
|
# mount backup destination folder as read-write
|
|
|
|
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
|
if [ -d "$mountpoint" ]; then
|
|
mount -o remount,rw $mountpoint
|
|
if (($?)); then
|
|
error "Could not mount $mountpoint"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# the backup procedure
|
|
|
|
if [ ! -d "$backupdir/$folder/$folder.0" ]; then
|
|
mkdir -p $backupdir/$folder/$folder.0
|
|
fi
|
|
|
|
info "Rotating $backupdir/$folder/$folder..."
|
|
echo "Rotating $backupdir/$folder/$folder..." >> $log
|
|
rotate $backupdir/$folder/$folder $keep
|
|
info "Wget'ing $SECTION on $backupdir/$folder/$folder.0..."
|
|
|
|
if [ ! -z "$bandwidth" ]; then
|
|
limit_rate="--limit-rate=$bandwidth""k"
|
|
fi
|
|
|
|
cd $backupdir/$folder/$folder.0
|
|
wget $wget_options $limit-rate -r -c -N -e robots=off $url
|
|
cd -
|
|
|
|
$touch $backupdir/$folder/$folder.0
|
|
|
|
# remount backup destination as read-only
|
|
|
|
if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then
|
|
mount -o remount,ro $mountpoint
|
|
fi
|
|
|
|
# check partition for errors
|
|
|
|
if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then
|
|
umount $mountpoint
|
|
if (($?)); then
|
|
warning "Could not umount $mountpoint to run fsck"
|
|
else
|
|
$nice $fsck -v -y $partition >> $log
|
|
mount $mountpoint
|
|
fi
|
|
fi
|
|
|
|
# removes the lockfile
|
|
|
|
if [ ! -z "$lockfile" ]; then
|
|
$rm $lockfile || warning "Could not remove lockfile $lockfile"
|
|
fi
|
|
|
|
echo "Finnishing backup at `date`" >> $log
|
|
|