backupninja/handlers/wget
Gabriel Filion 5c6c583181 Enable use of ionice for all handlers to alleviate IO load
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.
2020-12-31 02:08:50 -05:00

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