Backup of persistent memory

Script Download

#! /bin/bash
#----------------------------------------------------------------------
# kn-backup.sh (V0.1-6)
# Description: Backup persistent memory from flash disk
# installation and exchange persistent memory with old one
# Author: Werner P. Schulz <Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein!>
# Created at: Sa Jun 23 19:06 CEST 2012
# License: This file is licensed under the GPL v3.
#----------------------------------------------------------------------
# Last change: Fr 07 Mär 2014 10:43:01 CET [wps]

partselect() {
# look for suitable partitions
sfdisk -l | sed -n '/sd.[0-9]/p'| sed 's/\/dev\///' | \
  sed '/Empty\|Extend\|Hidden\|swap/d' \
  | awk '{print $1}'| sed -e '/'$INST_PART'/'d -e '/'$OVL_PART'/'d \
  > /tmp/partition.lst
display_part
}
i_partselect() {
# look for suitable partitions
sfdisk -l | sed -n '/sd.[0-9]/p'| sed 's/\/dev\///' | \
  sed '/FAT\|NTFS\|Empty\|Extend\|Hidden\|swap/d' \
  | awk '{print $1}'| sed -e '/'$INST_PART'/'d -e '/'$OVL_PART'/'d \
  > /tmp/partition.lst
display_part
}

display_part() {
# show if suitable partitions found
for i in $(cat /tmp/partition.lst | awk '{print $1}'); do
  part="${i##}"
  PARTLIST[$((count++))]="$part"
  PARTLIST[$((count++))]="$(awk '{printf("%8d",($1 / 2048) "MB")}' \
    /sys/block/$(expr substr $i 1 3)/$i/size 2>/dev/null) \
    $(blkid -o list /dev/$i | sed -n '3p' | awk '{print $2}')"
done
if [ ${#PARTLIST[*]} -eq 0 ]; then
  dialog --title "$TL" --infobox \
  "\nCannot find any partition to use!" 0 0
  exit 1 # backups impossible
else
  SEL=`dialog --title "$TL" --aspect 12 --colors --menu \
    "$TM" 0 0 0 "${PARTLIST[@]}" 3>&1 1>&2 2>&3`
  [ $? -eq 1 ] && return 1
  mount | grep -q "media/$SEL" || mount /media/$SEL
fi
}

listdatei() {
# list your comment-files
for i in $(ls -1c /media/$SEL/knx/bufi/C | sed -n '/'$BU_COM'/p' \
  | awk '{print $1}'); do
  datei="${i##}"
  DATEILIST[$((count++))]="$datei"
  DATEILIST[$((count++))]="$(cat /media/$SEL/knx/bufi/C/$i \
    | awk '{print $1,$2,$3," .."}')"
done
if [ ${#DATEILIST[*]} -eq 0 ]; then
  dialog --title "$TL" --msgbox \
    "\nCannot find any backup within this partition!" 0 0
  return 1 # empty comment-folder
else
  DATEI=`dialog --title "$TL" --colors --menu \
    "$TM1" 20 60 13 "${DATEILIST[@]}" 3>&1 1>&2 2>&3`
  [ $? -eq 1 ] && return 2 # no comment selected
  dialog --title "$TL" --aspect 12 --colors --defaultno \
  --yes-label "$YES_LABEL" --no-label "$NO_LABEL" --yesno \
    "\n\Z1Your comment for this backup:\Zn \
\n\n`cat /media/$SEL/knx/bufi/C/$DATEI` \
\n\n\n$TQUEST" 0 0
  if [ $? -eq 0 ]; then
    USEDATEI=$DATEI
  else
    return 2 # comment-text refused
  fi
fi
}

i_listdatei() {
# list incremental backup folder
for i in $(ls -1c /media/$SEL/knx/bufi/incr | awk '{print $1}'); do
  datei="${i##}"
  DATEILIST[$((count++))]="$datei"
  DATEILIST[$((count++))]="$(ls -ld /media/$SEL/knx/bufi/incr/$datei \
     | awk '{print $6,$7,$8}')"
done
if [ ${#DATEILIST[*]} -eq 0 ]; then
  dialog --title "$TL" --msgbox \
    "\nCannot find any backup within this partition!" 0 0
  return 1
else
  FOLDER=`dialog --title "$TL" --colors --menu \
    "\n$TQUEST" 18 60 11 "${DATEILIST[@]}" 3>&1 1>&2 2>&3`
  [ $? -eq 1 ] && return 2 # no folder selected
  dialog --title "$TL" --aspect 12 --colors --defaultno \
  --yes-label "Repair & reboot" --no-label "Not repair" --yesno \
    "$TWARN\nReally use '/media/$SEL/knx/bufi/incr/$FOLDER?" 0 0
  if [ $? -eq 0 ]; then
    USEFOLDER=$FOLDER
  else
    return 2 # incremental backup-folder refused
  fi
fi
}

filefolder() {
# name of file and folder
PARTLIST=()
count=0
partselect
[ $? -eq 1 ] && return 1
BU_VERSION=$(date "+%d%m%y-%H%M")
BU_FI=${BU_ART}_${BU_VERSION}.tar.gz
if ! [ -d /media/$SEL/knx/bufi/C ]; then
  mkdir -p /media/$SEL/knx/bufi/C/
fi
cd /
}

i_filefolder() {
# name of incremental folder	
PARTLIST=()
count=0
i_partselect
[ $? -eq 1 ] && return 1
cd /
}

writecomment() {
COMMENT=`dialog --title "$TL" --nocancel --colors --inputbox \
  "\nWrite a \Z1comment for this backup\Zn. You can \n
input strings of length longer than the \n
width of the input box, in that case, the \n
input field will be automatically scrolled. \n
You can use BACKSPACE to correct errors. \n\n" 13 51 3>&1 1>&2 2>&3`
echo "$COMMENT" > /media/$SEL/knx/bufi/C/${BU_COM}_${BU_VERSION}
}

seekpartition() {
PARTLIST=()
count=0
partselect
[ $? -eq 1 ] && return 1
if ! [ -d /media/$SEL/knx/bufi/C ]; then
  dialog --title "$TL" --aspect 12 --msgbox \
    "\nCannot find backups within this partition!" 0 0
  return 1 # no backup-folder
fi
}

i_seekpartition() {
PARTLIST=()
count=0
i_partselect
[ $? -eq 1 ] && return 1
if ! [ -d /media/$SEL/knx/bufi/incr ]; then
  dialog --title "$TL" --aspect 12 --msgbox \
    "\nCannot find backups within this partition!" 0 0
  return 1 # no backup-folder
fi
}

seekbackup() {
# look for right comment file
DATEILIST=()
USEDATEI=""
TM="\nWhich backup do you want to restore?"
count=0
listdatei
[ $? -ge 1 ] && return 1 # no comment found or selected
# look for right backup file
TIME_C=$(expr substr $USEDATEI 9 11)
count=0
for i in $(ls -1c -I "C" /media/$SEL/knx/bufi | sed -n '/'$BU_ART'/p' \
  | awk '{print $1}'); do
  BACKUP="${i##}"
  TIME_B="$(expr substr $BACKUP 6 11)"
  if [ "$TIME_B" = "$TIME_C" ]; then
    [ -e /mnt-system/bufi ] && rm /mnt-system/bufi
    return 0 # comment and backup with equal timestamp
  fi
done
return 2 # orphaned commentfile
}

i_seekbackup() {
# look for incremental backup folder
DATEILIST=()
USEFOLDER=""
TM="\nWhich backup do you want to restore?"
count=0
i_listdatei
return
}

orphancomment() {
# cannot find backup-file
dialog --title "$TL" --colors --aspect 12 --msgbox \
  "\nCannot find '$BACKUP'! Perhaps you \
\ndeleted it manually. Shall we also \
\ndelete the comment-file?" 0 0
if [ $? -eq 0 ]; then
  rm $USEDATEI
fi	
}

#----------------------------------------------------------------------
w_backup() {
TL="Backup whole persistent memory"
TM="\nWhich partition to use for backup?"
BU_ART="bufi"
BU_COM="comment"
filefolder
[ $? -eq 1 ] && return 0
clear
setterm -cursor off
tput cup  19 1
tar -C KNOPPIX-DATA/ --exclude=*/Cache/* \
  -vczf /media/$SEL/knx/bufi/$BU_FI ./ \
  | awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
writecomment
dialog --title "$TL" --aspect 12 --msgbox \
"\nYou can find your backup at /media/$SEL/knx/bufi/$BU_FI" 0 0
}

p_backup() {
TL="Backup only personal persistent memory"
TM="\nWhich partition to use for backup?"
BU_ART="pbuf"
BU_COM="pcommen"
filefolder
[ $? -eq 1 ] && return 0
clear
setterm -cursor off
tput cup  19 1
tar -C /KNOPPIX-DATA/ --exclude=*/Cache/* \
  -vczf /media/$SEL/knx/bufi/$BU_FI ./home/ ./etc/ \
  | awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
writecomment
dialog --title "$TL" --aspect 12 --msgbox \
"\nYou can find your backup at /media/$SEL/knx/bufi/$BU_FI" 0 0
}

restore_reboot() {
# rsync from backup
[ -d /media/$SEL/knx/bufi/tmp ] && rm -R /media/$SEL/knx/bufi/tmp
mkdir /media/$SEL/knx/bufi/tmp
clear
setterm -cursor off
tput cup  19 1
tar -vxzf /media/$SEL/knx/bufi/$BACKUP -C /media/$SEL/knx/bufi/tmp  \
| awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
cd /
clear
setterm -cursor off
tput cup  19 1
rsync -av --numeric-ids --delete --delete-after --exclude=*/Cache/*  \
  /media/$SEL/knx/bufi/tmp/ /KNOPPIX-DATA/ \
  | awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
rm -R /media/$SEL/knx/bufi/tmp
if ! [ $? = 24 -o $? = 0 ] ; then
  dialog --title "$TL" --aspect 12 --msgbox \
  "\nFatal: rsync 'persistent memory' \nfinished with errors!" 0 0
fi
/sbin/reboot
}

#----------------------------------------------------------------------
w_restore() {
TL="Restore elder whole backup"
TM="\nWhere are the backups?"
BU_ART="bufi"
BU_COM="comment"
seekpartition
[ $? -eq 1 ] && return 0
YES_LABEL="Restore & reboot"; NO_LABEL="Not restore"
TQUEST="Really restore with it?"
seekbackup
R_SB=$?
[ $R_SB -eq 1 ] && return 0
if [ $R_SB -eq 0 ]; then
  restore_reboot
elif [ $R_SB -eq 2 ]; then
  orphancomment
fi
return 0
}

p_restore() {
TL="Restore elder personal backup"
TM="\nWhere are the backups?"
BU_ART="pbuf"
BU_COM="pcommen"
seekpartition
[ $? -eq 1 ] && return
YES_LABEL="Restore & reboot"; NO_LABEL="Not restore"
TQUEST="Really restore with it?"
seekbackup
R_SB=$?
[ $R_SB -eq 1 ] && return 0
if [ $R_SB -eq 0 ]; then
  restore_reboot
elif [ $R_SB -eq 2 ]; then
  orphancomment
fi
return 0
}

#----------------------------------------------------------------------
fkdelete() {
TL="Delete useless backups"
TM="\nWhere are the backups?"
TM1="\nWhich backup to delete?"
BU_ART="buf"
BU_COM="commen"
TQUEST="Really delete it?"
seekpartition
[ $? -eq 1 ] && return 0
YES_LABEL="Delete"; NO_LABEL="Not delete"
seekbackup
R_SB=$?
[ $R_SB -eq 1 ] && return 0
if [ $R_SB -eq 0 ]; then
  rm /media/$SEL/knx/bufi/$BACKUP
  rm /media/$SEL/knx/bufi/C/$USEDATEI
  return 0
elif [ $R_SB -eq 2 ]; then
  orphancomment
fi
return 0
}

#----------------------------------------------------------------------
i_create() {
TL="Create incremental backup"
TM="\nWhich partition to use for backup?"
i_filefolder
[ $? -eq 1 ] && return 0
if ! [ -d /media/$SEL/knx/bufi/incr/daily.0 ] ; then
  mkdir -p /media/$SEL/knx/bufi/incr/daily.0
fi
clear
setterm -cursor off
tput cup  19 1
rsync -av --numeric-ids --delete --delete-after --exclude=*/Cache/*  \
  /KNOPPIX-DATA/ /media/$SEL/knx/bufi/incr/daily.0 \
  | awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
if ! [ $? = 24 -o $? = 0 ] ; then
  dialog --title "$TL" --aspect 12 --msgbox \
  "\nFatal: rsync 'persistent memory' \nfinished with errors!" 0 0
fi
touch /media/$SEL/knx/bufi/incr/daily.0
if [ -d /media/$SEL/knx/bufi/incr/daily.9 ] ; then
  rm -rf /media/$SEL/knx/bufi/incr/daily.9
fi
# rotate snapshots
for OLD in 9 8 7 6 5 4 3 2 1  ; do
  if [ -d /media/$SEL/knx/bufi/incr/daily.$OLD ] ; then
    NEW=$[ $OLD + 1 ]
    touch /media/$SEL/knx/bufi/.timestamp -r /media/$SEL/knx/bufi/incr/daily.$OLD
    mv /media/$SEL/knx/bufi/incr/daily.$OLD /media/$SEL/knx/bufi/incr/daily.$NEW
    touch /media/$SEL/knx/bufi/incr/daily.$NEW -r /media/$SEL/knx/bufi/.timestamp
  fi
done
if [ -d /media/$SEL/knx/bufi/incr/daily.0 ] ; then
  cp -al /media/$SEL/knx/bufi/incr/daily.0 /media/$SEL/knx/bufi/incr/daily.1
fi
sync
dialog --title "$TL" --aspect 12 --msgbox \
"\nYou can find your incremental backup \nat /media/$SEL/knx/bufi/incr/" 0 0
}

i_repair() {
echo "Repair incremental"
TL="Repair persistent memory with incremental backup"
TM="\nWhere are the incremental backups?"
i_seekpartition
[ $? -eq 1 ] && return 0
TQUEST="Which backup to use?"
i_seekbackup
[ "$USEFOLDER" = "" ] && return 2
cd /
clear
setterm -cursor off
tput cup  19 1
rsync -av --numeric-ids --delete --delete-after --exclude=*/Cache/*  \
  /media/$SEL/knx/bufi/incr/$USEFOLDER/ /KNOPPIX-DATA/ \
  | awk '{printf "%-78s\r", substr($1, 1, 78)}'
setterm -cursor on
if ! [ $? = 24 -o $? = 0 ] ; then
  dialog --title "$TL" --aspect 12 --msgbox \
  "\nFatal: rsync 'persistent memory' \nfinished with errors!" 0 0
fi
/sbin/reboot
}

# ------------------------------- main  -------------------------------
TL="Test prerequisites"
if [ "$(id -u)" -ne 0 ] ; then
  dialog --title "$TL" --infobox \
    "\nYou must be root to use this script!" 5 40
  exit 1
fi
# are we within a flash disk installation
if ! [ -e /mnt-system/ldlinux.sys ]; then
  dialog --title "$TL" --infobox \
    "\nYou have no flash disk installation!" 5 40
  exit 1
fi
TWARN="\nTo prevent loss of data \nclose \Z1\Zball running applications\Zn!\n"
# which partition contains flash install
INST_PART="$(df -h | sed -n '/mnt-system/p'| sed 's/\/dev\///' | \
  awk '{print $1}')"
# if persistent memory in overlay partition
OVL_PART=""
if [ -e /mnt-system/KNOPPIX/knoppix-data.inf ]; then
  OVL_PART=`echo ${INST_PART/1/2}`
fi  
# what can we do  
W1="1) Backup whole persistent memory"
W2="2) Restore elder whole backup"
W3="3) Backup personal persistent memory"
W4="4) Restore elder personal backup"
W5="5) Delete useless old backups"
W6="6) Create incremental backup of persistent memory"
W7="7) Repair persistent memory with incremental backup"
while true; do
  TL="Manage persistent memory of flash disk installation"
  WAHL=`dialog --title "$TL" --aspect 12 --menu \
"\nWhat do you want to do?" 0 0 0 \
  "$W1" "" "$W2" "" "$W3" "" "$W4" "" "$W5" "" \
  "$W6" "" "$W7" "" 3>&1 1>&2 2>&3`
  case "$WAHL" in
    $W1) w_backup;;
    $W2) w_restore;;
    $W3) p_backup;;
    $W4) p_restore;;
    $W5) fkdelete;;
    $W6) i_create;;
    $W7) i_repair;;
    *) break
  esac
done

Top