Add backup scripts needed by OC-2G device remap

This commit is contained in:
Omar Ramadan 2018-11-06 12:51:01 -08:00 committed by Daniel Willmann
parent 3b9fd8c796
commit 6eea372883
9 changed files with 1221 additions and 0 deletions

View File

@ -0,0 +1,72 @@
SUMMARY = "Backup scripts"
LICENSE = "BSD"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/BSD;md5=3775480a712fc46a69647678acb234cb"
SRC_URI += "file://cbackup \
file://cbackup.sh \
file://mbackup \
file://mbackup.sh \
file://checkbk \
file://checkbk.service \
file://checkflashcfg \
file://checkflash.service \
"
S = "${WORKDIR}"
# set this variable to 0 to avoid blocking the boot process if flash configuration is not valid
# normally keep it to 1, in upper layers except if there is no way to know that a flash repair
# is needed from external server
export BLOCKOPTION = "0"
inherit gitver-repo
REPODIR = "${THISDIR}"
REPOFILE = "backup-scripts_1.0.bb"
PR := "r${REPOGITFN}"
REPODIR = "${THISDIR}/files"
REPOFILE = ""
PR := "${PR}.${REPOGITFN}"
RDEPENDS_${PN} += "busybox cronie util-linux coreutils base-files"
do_install() {
install -d ${D}${sysconfdir}
install -d ${D}${sysconfdir}/systemd
install -d ${D}${sysconfdir}/systemd/system
install -d ${D}${sysconfdir}/systemd/system/multi-user.target.wants
install -m 0755 -d ${D}${base_libdir}
install -m 0755 -d ${D}${systemd_unitdir}
install -m 0755 -d ${D}${systemd_unitdir}/system
install -m 0644 ${S}/checkbk.service ${D}${systemd_unitdir}/system/checkbk.service
ln -sf ${systemd_unitdir}/system/checkbk.service ${D}${sysconfdir}/systemd/system/multi-user.target.wants/checkbk.service
install -m 0644 ${S}/checkflash.service ${D}${systemd_unitdir}/system/checkflash.service
ln -sf ${systemd_unitdir}/system/checkflash.service ${D}${sysconfdir}/systemd/system/multi-user.target.wants/checkflash.service
install -d ${D}${bindir}
install -m 0755 ${S}/cbackup ${D}${bindir}/.cbackup
install -m 0755 ${S}/mbackup ${D}${bindir}/.mbackup
install -m 0755 ${S}/cbackup.sh ${D}${bindir}/cbackup
install -m 0755 ${S}/mbackup.sh ${D}${bindir}/mbackup
install -m 0755 ${S}/checkbk ${D}${bindir}/checkbk
install -m 0755 ${S}/checkflashcfg ${D}${bindir}/checkflashcfg
echo "BLOCKOPTION=${BLOCKOPTION}" > ${D}${sysconfdir}/bootoptions.conf
chmod 755 ${D}${sysconfdir}/bootoptions.conf
}
pkg_postinst_${PN}_append() {
echo "adding crontab"
test -d $D/var/spool/cron || mkdir -p $D/var/spool/cron
test -f /var/spool/cron/root && sed -i '/checkbk/d' $D/var/spool/cron/root
echo "15 3 * * * nice -n 15 ${bindir}/checkbk" >> $D/var/spool/cron/root
}
FILES_${PN} += "${bindir}/mbackup \
${bindir}/.mbackup \
${bindir}/cbackup \
${bindir}/.cbackup \
${bindir}/checkbk \
${bindir}/checkflashcfg \
${sysconfdir} \
${systemd_unitdir}/* \
"

View File

@ -0,0 +1,190 @@
#!/bin/sh
STAG=cbackup:
# lock wait time max 15mn * 60 = 900 secs (sufficient time to update)
LOCKWAIT=900
# this is a protection to make sure a backup is not currently created while checking
bname=mbackup
BAKPATH=""
_curr_dir=""
BAKEXT=".tar.gz"
BAKMD5EXT=".md5"
mybasename=""
readonly LOCKFILE_DIR=/var/lock
readonly LOCK_FD=980
lock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# still allow to run unlocked if the lock dir does not exist
if [ ! -d "${LOCKFILE_DIR}" ]; then
return 0
fi
# create lock file
eval "exec $fd>$lock_file"
# still allow to run unlocked if the lock file cannot be created
if [ $? -ne 0 ]; then
return 0
fi
# acquier the lock
flock -w ${LOCKWAIT} $fd \
&& return 0 \
|| return 1
}
unlock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# release the lock
flock -u $fd
sync
}
function my_exit()
{
cd "$_curr_dir"
unlock $bname
exit $*
}
function __sig_int {
log_write " "
log_write "$STAG WARNING: SIGINT caught"
my_exit 110
}
function __sig_quit {
log_write " "
log_write "$STAG WARNING: SIGQUIT caught"
my_exit 111
}
function __sig_term {
log_write " "
log_write "$STAG WARNING: SIGTERM caught"
my_exit 112
}
function __sig_hup {
log_write " "
log_write "$STAG WARNING: SIGHUP caught"
my_exit 113
}
function log_write()
{
echo "$*"
}
function log_write_nr()
{
echo -n "$*"
}
function show_help {
log_write "cbackup help information:"
log_write "checks integrity of backup created with mbackup, exit with 0 when valid"
log_write "Usage: cbackup [ --help ] <bfile>"
log_write " where: <bfile> # source backup base file name (without .tar.gz)"
log_write " # same base file name as provided with mbackup -f option"
log_write " --help # displays this help information"
log_write "example: cbackup /mnt/storage/.sysbackup/bk-mnt-rom-user # checks backup"
}
function check_path()
{
local retval=0
local slen=${#1}
local mystr
if ! [ -d $1 ] ; then
log_write "$STAG directory does not exist ($1)!"
retval=80
else
if [ "${1:$slen - 1:1}" == "/" ] ; then
mystr=${1:0:$slen - 1}
slen=$((slen-1))
else
mystr=$1
fi
BAKPATH=$mystr"/"
fi
return $retval
}
_curr_dir=`pwd`
# Lock to test a single instance is running, and exit if wait timeout
log_write "$STAG Checking if allowed to run..."
lock $bname || ( log_write "$STAG Checking if allowed to run... failed"; exit 100 )
log_write "$STAG Checking if allowed to run... done"
# Set TRAPs to release lock if forced to exit
trap __sig_int SIGINT
trap __sig_quit SIGQUIT
trap __sig_term SIGTERM
trap __sig_hup SIGHUP
TOTALARG=$#
while getopts :- FLAG; do
case $FLAG in
'-')
show_help
my_exit 0;;
\?)
log_write "Invalid option: -$OPTARG" && my_exit 1;;
\:)
log_write "Required argument not found for option: -$OPTARG" && my_exit 2;;
esac
done
# removes processed option(s) from the cmd line args
shift $((OPTIND-1))
if [ "$#" -ne 1 ]; then
show_help
my_exit 3
fi
check_path `dirname "$1"`
valret=$?
if [ $valret -ne 0 ]; then
my_exit $valret
fi
mybasename=`basename "$1"`
log_write "$STAG Checking backup: "$BAKPATH$mybasename
if ! [ -f $BAKPATH$mybasename$BAKEXT ] ; then
log_write "$STAG Source backup does not exist ($BAKPATH$mybasename$BAKEXT)!"
my_exit 4
fi
if ! [ -f $BAKPATH$mybasename$BAKMD5EXT ] ; then
log_write "$STAG Source backup MD5 does not exist ($BAKPATH$mybasename$BAKMD5EXT)!"
my_exit 5
fi
# verify if backup is valid
cd $BAKPATH
if [ $? != 0 ]; then
log_write "$STAG change dir to ($BAKPATH) failed."
my_exit 6
fi
# verifies if md5 is for the expected backup file
md5file=`cat $BAKPATH$mybasename$BAKMD5EXT | awk '{ print $2 }'`
if ! [ "./"$mybasename$BAKEXT == "$md5file" ]; then
log_write "$STAG MD5 ref file is not backup file ($md5file)!"
my_exit 7
fi
# verifies if md5 is correct
myresult=$(md5sum -c $BAKPATH$mybasename$BAKMD5EXT 2>&1)
myres=$?
if [ $myres != 0 ]; then
log_write "$STAG Checksum invalid"
my_exit 8
fi
log_write "$STAG Checksum Ok."
my_exit 0

View File

@ -0,0 +1,3 @@
#!/bin/sh
# Starts a lower priority version of cbackup
nice -n 5 /usr/bin/.cbackup "$@"

View File

@ -0,0 +1,193 @@
#!/bin/sh
# checks all flash partition backup integrity when the expected flash partition is mounted correctly
STAG=checkbk:
PENDINGCHK=/tmp/.boot_pending
# lock wait time max 15mn * 60 = 900 secs (sufficient time to update)
LOCKWAIT=900
bname=checkbk
TMPBK=""
DEFBAKPATH=/mnt/storage/.sysbackup
_curr_dir=""
configflashuser=/mnt/rom/user
configflashuserbk=$DEFBAKPATH/bk-mnt-rom-user
configflashfactory=/mnt/rom/factory
configflashfactorybk=$DEFBAKPATH/bk-mnt-rom-factory
__USESYSLOG=1
VERBOSE=''
__EXITCODE=0
readonly LOCKFILE_DIR=/var/lock
readonly LOCK_FD=978
lock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# still allow to run unlocked if the lock dir does not exist
if [ ! -d "${LOCKFILE_DIR}" ]; then
return 0
fi
# create lock file
eval "exec $fd>$lock_file"
# still allow to run unlocked if the lock file cannot be created
if [ $? -ne 0 ]; then
return 0
fi
# acquier the lock
flock -w ${LOCKWAIT} $fd \
&& return 0 \
|| return 1
}
unlock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# release the lock
flock -u $fd
sync
}
function my_exit()
{
cd "$_curr_dir"
unlock $bname
exit $*
}
function __sig_int {
log_write " "
log_write "$STAG WARNING: SIGINT caught"
my_exit 110
}
function __sig_quit {
log_write " "
log_write "$STAG WARNING: SIGQUIT caught"
my_exit 111
}
function __sig_term {
log_write " "
log_write "$STAG WARNING: SIGTERM caught"
my_exit 112
}
function __sig_hup {
log_write " "
log_write "$STAG WARNING: SIGHUP caught"
my_exit 113
}
checkflashpartro() {
if ! grep "$* jffs2 " /proc/mounts | grep -q " ro[,]"; then
return 13
fi
return 0
}
function log_write()
{
if [ ! -z ${VERBOSE} ] || [ ${__USESYSLOG} -eq 0 ]; then
echo "$*"
fi
if [ ${__USESYSLOG} -ne 0 ] ; then
logger -p local4.info "$*"
fi
}
function show_help {
echo "checkbk help information:"
echo "Usage: checkbk [ [ [-f file] [-n] ] | [--help] ] <spath>"
echo " -d # print debug verbose info"
echo " --help # displays this help information"
echo "example: checkbk; # checks and backup flash partitions silently"
echo "example: checkbk -d; # checks and backup flash partitions with verbose"
}
if [ -e "${PENDINGCHK}" ]; then
echo "$STAG Pending reboot, could not run!"
exit 97
fi
_curr_dir=`pwd`
# Lock to test a single instance is running, and exit if wait timeout
echo "$STAG Checking if allowed to run..."
lock $bname || ( echo "$STAG Checking if allowed to run... failed"; exit 100 )
echo "$STAG Checking if allowed to run... done"
# Set TRAPs to release lock if forced to exit
trap __sig_int SIGINT
trap __sig_quit SIGQUIT
trap __sig_term SIGTERM
trap __sig_hup SIGHUP
if [ -e "${PENDINGCHK}" ]; then
echo "$TAG Pending reboot, could not run!"
my_exit 97
fi
#keeps log file from getting big if run through a cron job
rm /var/log/$LOG_FILE >/dev/null 2>&1
TOTALARG=$#
while getopts :d- FLAG; do
case $FLAG in
d ) VERBOSE=1;;
'-')
show_help
my_exit 0;;
\?)
log_write "Invalid option: -$OPTARG" && my_exit 1;;
\:)
log_write "Required argument not found for option: -$OPTARG" && my_exit 2;;
esac
done
# removes processed option(s) from the cmd line args
shift $((OPTIND-1))
log_write "$STAG started"
# checks if factory partition needs a backup
if checkflashpartro $configflashfactory ; then
log_write "$STAG checking partition ($configflashfactory)"
__CBACKUP_RES=$(cbackup "$configflashfactorybk" 2>&1)
__CBACKUP_RET=$?
log_write "$__CBACKUP_RES"
if test ${__CBACKUP_RET} -ne 0; then
__MBACKUP_RES=$(mbackup "$configflashfactory" 2>&1)
__MBACKUP_RET=$?
log_write "$__MBACKUP_RES"
if test ${__MBACKUP_RET} -ne 0; then
__EXITCODE=$__MBACKUP_RET
fi
fi
else
log_write "$STAG partition ($configflashfactory) is not ready for backup"
__EXITCODE=70
fi
if checkflashpartro $configflashuser ; then
log_write "$STAG checking partition ($configflashuser)"
__CBACKUP_RES=$(cbackup "$configflashuserbk" 2>&1)
__CBACKUP_RET=$?
log_write "$__CBACKUP_RES"
if test ${__CBACKUP_RET} -ne 0; then
__MBACKUP_RES=$(mbackup "$configflashuser" 2>&1)
__MBACKUP_RET=$?
log_write "$__MBACKUP_RES"
if test ${__MBACKUP_RET} -ne 0; then
__EXITCODE=$__MBACKUP_RET
fi
fi
else
log_write "$STAG partition ($configflashuser) is not ready for backup"
__EXITCODE=71
fi
log_write "$STAG done!"
my_exit $__EXITCODE

View File

@ -0,0 +1,22 @@
[Unit]
Description=Check flash backups.
DefaultDependencies=no
Before=sysinit.target
After=mountuser.service checkroot.service checkstoragefs.service checkmonolithicupdate.service
Wants=mountuser.service checkroot.service checkstoragefs.service checkmonolithicupdate.service
RequiresMountsFor=/mnt/rom/user
RequiresMountsFor=/mnt/rom/factory
RequiresMountsFor=/tmp
RequiresMountsFor=/run
RequiresMountsFor=/mnt/storage
[Service]
Type=oneshot
Restart=no
RemainAfterExit=yes
ExecStart=/bin/sh -c 'export _NOSPINDLE=1 ; /usr/bin/checkbk -d ; export _NOSPINDLE= ; '
StandardOutput=syslog+console
StandardError=syslog+console
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,25 @@
[Unit]
Description=Check config flash state.
Before=multi-user.target
Before=shutdown.target
Before=watchdog.service
After=time-sync.target
After=checkbk.service
Wants=checkbk.service
Conflicts=shutdown.target
RequiresMountsFor=/mnt/rom/user
RequiresMountsFor=/tmp
RequiresMountsFor=/run
RequiresMountsFor=/var/volatile
[Service]
Type=oneshot
Restart=no
RemainAfterExit=yes
TimeoutStartSec=infinity
ExecStart=/usr/bin/checkflashcfg -d
StandardOutput=syslog+console
StandardError=syslog+console
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,269 @@
#!/bin/sh
# checks boot options to see what to do when the system has a flash configuration corruption
STAG=checkflashcfg:
PENDINGCHK=/tmp/.boot_pending
# lock wait time max 15mn * 60 = 900 secs (sufficient time to check it)
LOCKWAIT=900
bname=checkflashcfg
_curr_dir=""
__USESYSLOG=1
VERBOSE=''
__EXITCODE=0
CONFIGMOUNT=/mnt/rom/user
CONFIGMOUNTTYPE=jffs2
DEVCONFIG=/dev/mtdblock9
tempdir=""
TMPMOUNT=/tmp/.mnt_config
__NOHANG=0
_RECOVERY=1
readonly LOCKFILE_DIR=/var/lock
readonly LOCK_FD=977
# Get boot options configuration file
if [ -f "/etc/bootoptions.conf" ]; then
source "/etc/bootoptions.conf"
fi
lock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# still allow to run unlocked if the lock dir does not exist
if [ ! -d "${LOCKFILE_DIR}" ]; then
return 0
fi
# create lock file
eval "exec $fd>$lock_file"
# still allow to run unlocked if the lock file cannot be created
if [ $? -ne 0 ]; then
return 0
fi
# acquier the lock
flock -w ${LOCKWAIT} $fd \
&& return 0 \
|| return 1
}
unlock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# release the lock
flock -u $fd
sync
}
function my_exit()
{
trap - SIGINT
trap - SIGQUIT
trap - SIGTERM
trap - SIGHUP
sync
if [ -d "${tempdir}" ]; then
if mount | grep -q "${tempdir}"; then
umount "$tempdir"
fi
rmdir "$tempdir"
fi
cd "$_curr_dir"
unlock $bname
exit $*
}
checkrecovery() {
if mount | grep -q "on / type nfs" ; then
return 0
else
return 1
fi
}
function __sig_int {
log_write " "
log_write "$STAG WARNING: SIGINT caught"
my_exit 110
}
function __sig_quit {
log_write " "
log_write "$STAG WARNING: SIGQUIT caught"
my_exit 111
}
function __sig_term {
log_write " "
log_write "$STAG WARNING: SIGTERM caught"
my_exit 112
}
function __sig_hup {
log_write " "
log_write "$STAG WARNING: SIGHUP caught"
my_exit 113
}
checkflashconfig() {
if ! grep -q "$* " /proc/mounts; then
return 14
fi
return 0
}
function log_write()
{
if [ ! -z ${VERBOSE} ] || [ ${__USESYSLOG} -eq 0 ]; then
echo "$*"
fi
if [ ${__USESYSLOG} -ne 0 ] ; then
logger -p local4.info "$*"
fi
}
function show_help {
echo "checkflashcfg help information:"
echo "Usage: checkflashcfg [ [ [-d] [-n] ] | [--help] ]"
echo "Verify boot options and flash config state to learn what to do when corrupted"
echo "WARNING: this script may intentionnaly hang if -n is not provided and flash is corrupted"
echo " if not hanging, it may attempt to recreate an unmountable corrupted flash"
echo " config partition"
echo " -d # print debug verbose info"
echo " -n # no hang even if boot option specifies blocking in corruption"
echo " --help # displays this help information"
echo "example: checkflashcfg; # checks flash corruption and boot options silently"
echo "example: checkflashcfg -d -n;# checks flash corruption and boot options verbose, no hang"
}
if [ -e "${PENDINGCHK}" ]; then
echo "$STAG Pending reboot, could not run!"
exit 97
fi
_curr_dir=`pwd`
# Lock to test a single instance is running, and exit if wait timeout
echo "$STAG Checking if allowed to run..."
lock $bname || ( echo "$STAG Checking if allowed to run... failed"; exit 100 )
echo "$STAG Checking if allowed to run... done"
# Set TRAPs to release lock if forced to exit
trap __sig_int SIGINT
trap __sig_quit SIGQUIT
trap __sig_term SIGTERM
trap __sig_hup SIGHUP
if [ -e "${PENDINGCHK}" ]; then
echo "$STAG Pending reboot, could not run!"
my_exit 97
fi
#keeps log file from getting big
rm /var/log/$LOG_FILE >/dev/null 2>&1
TOTALARG=$#
while getopts :dn- FLAG; do
case $FLAG in
d ) VERBOSE=1;;
n ) __NOHANG=1;;
'-')
show_help
my_exit 0;;
\?)
log_write "Invalid option: -$OPTARG" && my_exit 1;;
\:)
log_write "Required argument not found for option: -$OPTARG" && my_exit 2;;
esac
done
# removes processed option(s) from the cmd line args
shift $((OPTIND-1))
log_write "$STAG checking..."
# checks if user flash is mounted correctly
if ! checkflashconfig "$CONFIGMOUNT" "$CONFIGMOUNTTYPE" ; then
# verifies if in recovery mode
checkrecovery
_RECOVERY=$?
# checks if the block boot option is active from bootoptions.conf
if [ ${BLOCKOPTION} -eq 1 ]; then
if [ ${__NOHANG} -ne 1 ]; then
if [ $_RECOVERY -eq 0 ]; then
log_write "$STAG script process is blocked as flash config is in recovery mode!"
else
log_write "$STAG script process is blocked as flash config needs to be repaired!"
fi
_MYCOUNTER=0
# makes sure the watchdog is manually started as systemd booting seq would be stuck to our process
/etc/init.d/watchdog.sh start
#loops forever to make sure any dependant service won't start when booting
while [ $_MYCOUNTER -eq 0 ]; do
sleep 1s
done
else
if [ $_RECOVERY -ne 0 ]; then
log_write "$STAG flash config needs to be repaired!"
__EXITCODE=3
fi
fi
else
if [ $_RECOVERY -ne 0 ]; then
# checks if flash could be mounted correctly
tempdir=`mktemp -d`
if [ $? -ne 0 ]; then
log_write "$STAG could not create tmp directory!"
my_exit 4
fi
if ! mount -t ${CONFIGMOUNTTYPE} -o ro,noatime,sync ${DEVCONFIG} ${tempdir}; then
# we need to recreate flash content cause the system could not self warns the problem
# and the flash is not mountable
log_write "$STAG recreating configuration flash partition..."
_C_RES=$(flash_erase -j /dev/mtd9 0 0 2>&1)
_C_RET=$?
if [ $_C_RET -ne 0 ]; then
log_write "Warning: cannot recreate flash partition!"
__EXITCODE=5
else
log_write "$STAG recreating configuration flash partition... Done"
# attempt to use mountuser tool to get flash access
_C_RES=$(/usr/bin/mountuser rw 2>&1)
_C_RET=$?
if [ $_C_RET -eq 0 ]; then
log_write "$STAG recreating config flash partition content..."
cp -rf $CONFIGMOUNT/* $TMPMOUNT
if [ $? -ne 0 ]; then
log_write "Warning: cannot copy current config to flash mount!"
__EXITCODE=6
else
echo "---------------------------" >> $TMPMOUNT/config/motd
echo "Attempted to recreate Flash" >> $TMPMOUNT/config/motd
echo "---------------------------" >> $TMPMOUNT/config/motd
_C_RES=$(/usr/bin/mountuser ro 2>&1)
_C_RET=$?
if [ $_C_RET -ne 0 ]; then
log_write "Warning: cannot remount flash mount to read only!"
__EXITCODE=7
else
log_write "$STAG recreating config flash partition content... Done"
fi
fi
else
log_write "$STAG cannot access flash for rw access!"
__EXITCODE=8
fi
fi
else
log_write "$STAG flash is mountable, won't be automatically repaired!"
__EXITCODE=9
fi
fi
fi
fi
log_write "$STAG checking... Done"
my_exit $__EXITCODE

View File

@ -0,0 +1,444 @@
#!/bin/sh
# Define this variable _NOSPINDLE before calling this script if this script run through a systemd service
# if this variable _SAFESYNC is also defined, it will do a wd safe sync instead (when watchdog daemon is not used)
STAG=mbackup:
ENDSIG=/tmp/mbackup_sig
ERRSIG=/tmp/mbackup_err
PENDINGCHK=/tmp/.boot_pending
# lock wait time max 15mn * 60 = 900 secs (sufficient time to update)
LOCKWAIT=900
bname=mbackup
TMPBK=""
DEFBAKPATH=/mnt/storage/.sysbackup/
BAKPATH=$DEFBAKPATH
_curr_dir=""
BAKEXT=".tar.gz"
PREVEXT=".tar.gz.bk1"
TMPEXT=".tar.gz.tmp"
BAKMD5EXT=".md5"
PREVMD5EXT=".md5.bk1"
TMPMD5EXT=".md5.tmp"
mybasename=""
CREATEPBACK=1
sp="/-\|"
sc=0
spin() {
if [ -z "$_NOSPINDLE" ]; then
printf "\r${STAG} ${sp:sc++:1}"
((sc==${#sp})) && sc=0
else
printf "${STAG} ${sp:sc++:1} \n"
((sc==${#sp})) && sc=0
if [ ! -z "$_SAFESYNC" ]; then
dmesg -D
echo 1 > /dev/watchdog
dmesg -E
fi
fi
}
endspin() {
if [ -z "$_NOSPINDLE" ]; then
printf "\r"
else
if [ ! -z "$_SAFESYNC" ]; then
dmesg -E
fi
fi
}
readonly LOCKFILE_DIR=/var/lock
readonly LOCK_FD=980
lock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# still allow to run unlocked if the lock dir does not exist
if [ ! -d "${LOCKFILE_DIR}" ]; then
return 0
fi
# create lock file
eval "exec $fd>$lock_file"
# still allow to run unlocked if the lock file cannot be created
if [ $? -ne 0 ]; then
return 0
fi
# acquier the lock
flock -w ${LOCKWAIT} $fd \
&& return 0 \
|| return 1
}
unlock() {
local prefix=$1
local fd=${2:-$LOCK_FD}
local lock_file=$LOCKFILE_DIR/$prefix.lock
# release the lock
flock -u $fd
sync
}
function my_exit()
{
sync
if [ -f "$BAKPATH$mybasename$TMPEXT" ]; then
rm -f $BAKPATH$mybasename$TMPEXT
fi
if [ -f "$BAKPATH$mybasename$TMPMD5EXT" ]; then
rm -f $BAKPATH$mybasename$TMPMD5EXT
fi
if [ -d "${TMPBK}" ]; then
TMPBKMNT_RES=$(mount | grep "${TMPBK}")
TMPBKMNT_RET=$?
if [ $TMPBKMNT_RET -eq 0 ]; then
umount ${TMPBK}
fi
rmdir "${TMPBK}"
fi
sync
cd "$_curr_dir"
unlock $bname
exit $*
}
function __sig_int {
endspin
log_write " "
log_write "$STAG WARNING: SIGINT caught"
my_exit 110
}
function __sig_quit {
endspin
log_write " "
log_write "$STAG WARNING: SIGQUIT caught"
my_exit 111
}
function __sig_term {
endspin
log_write " "
log_write "$STAG WARNING: SIGTERM caught"
my_exit 112
}
function __sig_hup {
endspin
log_write " "
log_write "$STAG WARNING: SIGHUP caught"
my_exit 113
}
function log_write()
{
echo "$*"
}
function log_write_nr()
{
echo -n "$*"
}
function show_help {
log_write "mbackup help information:"
log_write "Usage: mbackup [ [ [-f file] [-n] ] | [--help] ] <spath>"
log_write " where: <spath> # source directory path to backup recursively"
log_write " options: -f file # force output file name (will be appended with .tar.gz/.md5)"
log_write " # specified file destination directory must exist!"
log_write " # if -f not used, default dest. dir. is created: $BAKPATH"
log_write " # with auto generated filename according to <spath>"
log_write " -n # do not create a previous backup (*.bk1) if one already exist"
log_write " # default is to create one"
log_write " --help # displays this help information"
log_write "example: mbackup /mnt/rom/user; # backup user flash configuration to default dir"
log_write "example: mbackup -f /tmp/qq /mnt/rom/user; # backup user flash configuration to /tmp/qq"
}
function create_basename()
{
local retval
local retval2
local repchr=-
local srcchr=/
local slen=${#1}
local mystr
local mystr2
if [ "${1:$slen - 1:1}" == "/" ] ; then
mystr=${1:0:$slen - 1}
slen=$((slen-1))
else
mystr=$1
fi
if [ ${1:0:1} == "/" ] ; then
mystr2=${mystr:1:$slen - 1}
slen=$((slen-1))
else
mystr2=$mystr
fi
retval="bk-"${mystr2//$srcchr/$repchr}
retval2=${retval// /$repchr}
echo $retval2
}
# returns the file basename without directory and extension
function get_basename()
{
echo ${1//+(*\/|.*)}
return 0
}
function check_destpath()
{
local retval=0
local slen=${#1}
local mystr
if ! [ -d $1 ] ; then
log_write "$STAG Destination directory does not exist ($1)!"
retval=80
else
if [ "${1:$slen - 1:1}" == "/" ] ; then
mystr=${1:0:$slen - 1}
slen=$((slen-1))
else
mystr=$1
fi
BAKPATH=$mystr"/"
fi
return $retval
}
# corrects md5 associated source file
# param1=originalfilename
# param2=newfilename
# param3=md5 file to correct
function correct_md5_file()
{
local name1
local name2
name1=`basename $1`
if [ $? -ne 0 ]; then
log_write "$STAG Getting basename of ($1) fail!"
return 81
fi
name2=`basename $2`
if [ $? -ne 0 ]; then
log_write "$STAG Getting basename of ($2) fail!"
return 82
fi
sed -i "s/$name1/$name2/g" $3
if [ $? -ne 0 ]; then
log_write "$STAG Sed md5 file ($3) fail!"
return 83
fi
return 0
}
if [ -e "${PENDINGCHK}" ]; then
log_write "$STAG Pending reboot, could not run!"
exit 97
fi
_curr_dir=`pwd`
# Lock to test a single instance is running, and exit if wait timeout
log_write "$STAG Checking if allowed to run..."
lock $bname || ( log_write "$STAG Checking if allowed to run... failed"; exit 100 )
log_write "$STAG Checking if allowed to run... done"
# Set TRAPs to release lock if forced to exit
trap __sig_int SIGINT
trap __sig_quit SIGQUIT
trap __sig_term SIGTERM
trap __sig_hup SIGHUP
if [ -e "${PENDINGCHK}" ]; then
log_write "$TAG Pending reboot, could not run!"
my_exit 97
fi
TOTALARG=$#
while getopts :f:n- FLAG; do
case $FLAG in
f)
#log_write "#Filename (-f)"
check_destpath `dirname "$OPTARG"`
valret=$?
if [ $valret -ne 0 ]; then
my_exit $valret
fi
mybasename=`basename "$OPTARG"`;;
n)
log_write "$STAG No previous backup option specified (-n)"
CREATEPBACK=0;;
'-')
show_help
my_exit 0;;
\?)
log_write "Invalid option: -$OPTARG" && my_exit 1;;
\:)
log_write "Required argument not found for option: -$OPTARG" && my_exit 2;;
esac
done
# removes processed option(s) from the cmd line args
shift $((OPTIND-1))
if [ "$#" -ne 1 ]; then
show_help
my_exit 3
fi
if ! [ -d $1 ] ; then
log_write "$STAG Source directory does not exist ($1)!"
my_exit 4
fi
if [ "x$mybasename" == "x" ] ; then
mybasename=$(create_basename $1)
if ! [ -d "$BAKPATH" ]; then
mkdir -p $BAKPATH
if [ $? -ne 0 ]; then
log_write "$STAG create dir ($BAKPATH) fail!"
my_exit 5
fi
fi
fi
log_write "$STAG Creating backup to: "$BAKPATH$mybasename
TMPBK=$(mktemp -d)
if [ $? -ne 0 ]; then
log_write "$STAG mktemp fail!"
my_exit 6
fi
# temporarily bind mount dir to backup to TMPBK
mount --bind -o ro $1 ${TMPBK}
if [ $? -ne 0 ]; then
log_write "$STAG mount $1 to temp folder fail!"
my_exit 7
fi
rm -f $BAKPATH$mybasename$TMPEXT
if [ $? -ne 0 ]; then
log_write "$STAG cannot remove ($BAKPATH$mybasename$TMPEXT)!"
my_exit 8
fi
rm -f $BAKPATH$mybasename$TMPMD5EXT
if [ $? -ne 0 ]; then
log_write "$STAG cannot remove ($BAKPATH$mybasename$TMPMD5EXT)!"
my_exit 9
fi
rm -f ${ENDSIG}
rm -f ${ERRSIG}
log_write "$STAG Creating files backup..."
(
tar -zcf $BAKPATH$mybasename$TMPEXT -C ${TMPBK} .
if [ $? -ne 0 ]; then
log_write " $STAG tar ($BAKPATH$mybasename$TMPEXT) fail!"
touch ${ERRSIG}
exit 10
fi
touch ${ENDSIG}
) &
until [ -f ${ENDSIG} ]; do
spin
if [ -f ${ERRSIG} ]; then
my_exit 11
fi
if [ ! -f ${ENDSIG} ]; then
sleep 1s
fi
done
endspin
log_write "$STAG Creating files backup... done"
# create md5
cd $BAKPATH
if [ $? -ne 0 ]; then
log_write "$STAG cannot change dir to ($BAKPATH)!"
my_exit 12
fi
md5sum ./$mybasename$TMPEXT > ./$mybasename$TMPMD5EXT
if [ $? -ne 0 ]; then
log_write "$STAG cannot create md5 for ($BAKPATH$mybasename$TMPEXT)!"
my_exit 13
fi
# create a previous backup if one already exit
if [ $CREATEPBACK -eq 1 ]; then
if [ -f "$BAKPATH$mybasename$BAKEXT" ] && [ -f "$BAKPATH$mybasename$BAKMD5EXT" ]; then
log_write "$STAG Copy prev. backup to: "$BAKPATH$mybasename$PREVEXT
cp -f $BAKPATH$mybasename$BAKEXT $BAKPATH$mybasename$PREVEXT
if [ $? -ne 0 ]; then
log_write "$STAG Creating previous backup ($BAKPATH$mybasename$PREVEXT) fail!"
my_exit 14
fi
log_write "$STAG Copy prev. MD5 to: "$BAKPATH$mybasename$PREVMD5EXT
cp -f $BAKPATH$mybasename$BAKMD5EXT $BAKPATH$mybasename$PREVMD5EXT
if [ $? -ne 0 ]; then
log_write "$STAG Creating previous backup ($BAKPATH$mybasename$PREVMD5EXT) fail!"
my_exit 15
fi
correct_md5_file $BAKPATH$mybasename$BAKEXT $BAKPATH$mybasename$PREVEXT $BAKPATH$mybasename$PREVMD5EXT
if [ $? -ne 0 ]; then
my_exit $?
fi
fi
fi
# create current backup from temporary files
rm -f $BAKPATH$mybasename$BAKEXT
if [ $? -ne 0 ]; then
log_write " $STAG cannot remove ($BAKPATH$mybasename$BAKEXT) fail!"
my_exit 16
fi
rm -f $BAKPATH$mybasename$BAKMD5EXT
if [ $? -ne 0 ]; then
log_write " $STAG cannot remove ($BAKPATH$mybasename$BAKMD5EXT) fail!"
my_exit 17
fi
log_write "$STAG Move backup to: "$BAKPATH$mybasename$BAKEXT
mv $BAKPATH$mybasename$TMPEXT $BAKPATH$mybasename$BAKEXT
if [ $? -ne 0 ]; then
log_write " $STAG cannot move to ($BAKPATH$mybasename$BAKEXT) fail!"
my_exit 18
fi
log_write "$STAG Move MD5 to: "$BAKPATH$mybasename$BAKMD5EXT
mv $BAKPATH$mybasename$TMPMD5EXT $BAKPATH$mybasename$BAKMD5EXT
if [ $? -ne 0 ]; then
log_write " $STAG cannot move to ($BAKPATH$mybasename$BAKMD5EXT) fail!"
my_exit 19
fi
correct_md5_file $BAKPATH$mybasename$TMPEXT $BAKPATH$mybasename$BAKEXT $BAKPATH$mybasename$BAKMD5EXT
if [ $? -ne 0 ]; then
my_exit $?
fi
rm -f ${ENDSIG}
rm -f ${ERRSIG}
log_write "$STAG System sync..."
(
sync
if [ $? -ne 0 ]; then
log_write " $STAG sync fail!"
touch ${ERRSIG}
exit 20
fi
touch ${ENDSIG}
) &
until [ -f ${ENDSIG} ]; do
spin
if [ -f ${ERRSIG} ]; then
my_exit 21
fi
if [ ! -f ${ENDSIG} ]; then
sleep 1s
fi
done
endspin
log_write "$STAG System sync... done"
my_exit 0

View File

@ -0,0 +1,3 @@
#!/bin/sh
# Starts a lower priority version of mbackup
nice -n 5 /usr/bin/.mbackup "$@"