#!/bin/bash export PATH='/sbin:/usr/sbin:/bin:/usr/bin' typeset -r usbstick_mountpoint='/media/usb0' typeset -r backupscript_version='V2.0.6' printf '#\n' printf '# Quantron backup script STARTING...\n' # stop codesys application # we assume this returns only after codesys is no longer running systemctl stop 'codesys3-rt.service' # send all output to the quantron framebuffer console export TERM='linux' exec 0<>'/dev/tty0' 1>&0 2>&0 clear # NASTY HACK: # systemd/udev has a timeout running which will send SIGKILL to # all processes in a cggroup. Since this backup script is interactive # the only way to avoid getting killed by that timeout is to move # the current shell process into another cggroup. # This hack is WRONG on so many levels that it hurts, but given # the time constraints and the stupidity how our system is currently # designed there was to other way. # We do this here, after redirecting output to the framebuffer terminal, # so that we can see whether this fails or not. printf '%d' $$ >'/sys/fs/cgroup/systemd/system/cgroup.procs' color_printf() { typeset color=$1 shift typeset ttycmd='' case "$color" in 'black') ttycmd=$'\E[30m' ;; 'red') ttycmd=$'\E[31m' ;; 'green') ttycmd=$'\E[32m' ;; 'yellow') ttycmd=$'\E[33m' ;; 'blue') ttycmd=$'\E[34m' ;; 'magenta') ttycmd=$'\E[35m' ;; 'cyan') ttycmd=$'\E[36m' ;; 'white') ttycmd=$'\E[37m' ;; esac printf '%s' "$ttycmd" printf "$@" printf '%s' $'\E[0m' } is_usbstick_mounted() { grep -q -E \ "[[:space:]]+${usbstick_mountpoint}[[:space:]]+(fat|vfat|ntfs|ext4)[[:space:]]+(rw|ro)," \ '/proc/self/mounts' return $? } disable_console_screensaver() { # make sure the framebuffer console screenblanker is NOT active printf '0\n' >'/sys/devices/platform/imx21-fb.0/graphics/fb0/blank' # disable screen blanking (we have to do this via terminal codes # since /sys/module/kernel/parameters/consoleblank is read-only) printf '\E[9;0]' return 0 } do_menu() { typeset key # # main menu # printf '\n#\n' printf '# Welcome to the ' color_printf 'red' 'QUANTRON' printf ' /var/dyn\n# backup tool (version %s)!\n' "${backupscript_version}" printf '#\n\n' color_printf 'yellow' ' * Menu:\n' color_printf 'yellow' ' - Press key for abort\n\t(system shutdown)\n' # key="A" color_printf 'yellow' ' - Press key for backup\n' # key="C" color_printf 'yellow' ' - Press key for restore\n' # key="D" for ((;;)) ; do disable_console_screensaver key='' # # wait for a key press... # # (warning: Quantron V3.1.9 has bash3.2.48 which does # NOT support -N, only -n is supported!) # IFS='' read -e -r -u0 -n1 key case "$key" in 'A') color_printf 'cyan' '#### Aborting, system shutting down...\n' sleep 3 reboot -p exit 0 ;; 'C') color_printf 'cyan' '#### Starting backup...\n' sleep 3 do_backup exit 0 ;; 'D') color_printf 'cyan' '#### Starting restore...\n' sleep 3 do_restore exit 0 ;; *) # beep ? ;; esac done # notreached } do_backup() { typeset -i backuperr=0 if ! is_usbstick_mounted ; then color_printf 'red' '# ERROR: No USB stick mounted, aborting\n' return 1 fi if ! /sbin/eag_usbstick mount_writeable ; then color_printf 'red' '# ERROR: Cannot mount stick writeable, aborting\n' return 1 fi mkdir -p "${usbstick_mountpoint}/quantron_backup" rm -f "${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2.md5sum" color_printf 'cyan' '\n# Saving files...\n' set -o pipefail (cd / && tar -cvf - var/dyn/* ) | \ bzip2 -9 | \ tee \ >(md5sum '/dev/stdin' | sed 's/\/dev\/stdin/quantron_var_dyn_backup.tar.bz2/' >"${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2.md5sum") \ >"${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2" (( backuperr+=$? )) sync ; sync # UNIX tradition! /sbin/eag_usbstick mount_readonly (( backuperr+=$? )) # verifying backup color_printf 'cyan' '\n# Verifying backup data...\n' (cd "${usbstick_mountpoint}/quantron_backup" && md5sum -c 'quantron_var_dyn_backup.tar.bz2.md5sum') if (( $? != 0 )) ; then (( backuperr++ )) color_printf 'red' '# ERROR: Wrong MD5 hash sum of written data\n' # remove backup archive so the user cannot restore broken data /sbin/eag_usbstick mount_writeable >'/dev/null' 2>&1 rm -f \ "${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2" \ "${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2.md5sum" /sbin/eag_usbstick mount_readonly >'/dev/null' 2>&1 fi if (( backuperr == 0 )) ; then color_printf 'green' '\n#\n# Backup success.\n#\n' else color_printf 'red' '\n#\n# Backup FAILED!!\n#\n' fi disable_console_screensaver color_printf 'yellow' '\n\nPlease remove USB stick and reboot...\n' return $(( backuperr?1:0 )) } do_restore() { typeset -i restoreerr=0 if [[ ! -r "${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2" ]] ; then color_printf 'red' '# ERROR: Cannot read backup file %s\n' "${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2" return 1 fi color_printf 'cyan' '\n# Verifying backup data...\n' (cd "${usbstick_mountpoint}/quantron_backup" && md5sum -c 'quantron_var_dyn_backup.tar.bz2.md5sum') if (( $? != 0 )) ; then color_printf 'red' '# ERROR: Backup archive does not have the correct hash sum.\n' color_printf 'red' '\n#\n# Restore FAILED!!\n#\n' return 1 fi color_printf 'cyan' '\n# Restoring files...\n' set -o pipefail bunzip2 -c <"${usbstick_mountpoint}/quantron_backup/quantron_var_dyn_backup.tar.bz2" | (cd / && tar -xvf -) (( restoreerr+=$? )) sync ; sync # UNIX tradition! if (( restoreerr == 0 )) ; then color_printf 'green' '\n#\n# Restore success.\n#\n' else color_printf 'red' '\n#\n# Restore FAILED!!\n#\n' fi disable_console_screensaver color_printf 'yellow' '\n\nPlease remove USB stick and reboot...\n' return $(( restoreerr?1:0 )) } # main do_menu # EOF.