#!/bin/bash
#
# Skript zum Testen der optimalen Blocksize für dd-Backup.
# ddtest.sh
# ver=0.5
#
# Aufruf mit sudo bzw. als root erforderlich für Feature "Caches leeren"
#
# Features:
# - für RPi oder beliebige andere Linux-Systeme
# - Lesetest und wahlweise auch Schreibtest in beliebigen Pfaden
# - Auch Test der Auswirkung durch gzip-Kompression
# - Gültigkeit der Pfade und Schreibrechte werden geprüft
# - Blockgrößen von 256 Bytes bis 8 MBytes werden getestet.
# - Cache-flush zur Vermeidung von Caching
# - Testdatei mir Random-Werten oder 0-Werten wählbar
# Hinweise:
# - Lesedatei auf Pi bzw. Linux-System wird immer erzeugt
# - Schreibdatei auf Backuplaufwerk wird nur beim Schreibtest generiert
# - Schreibpfad sollte auf externem Datenträger oder Server/NAS liegen!
# - Testdateien werden am Ende wieder gelöscht.
# - Erzeugung der Testdatei mir Random-Werten dauert viel(!) länger als mit
#   0-Werten (beim RPi ca 1,5MB/s gegenüber 14MB/s mit 0-Werten), sollte aber
#   realistischere Ergebnisse liefern bei Verwendung der gzip-Kompression
#   und ist daher wohl nur bei Test mit gzip-Kompression auch erforderlich.
# - Lesedatei_in_MB sollte ein ganzzahliges Vielfaches jeder einzelnen, zu
#   testenden Blockgrößen sein (da jeweils Verdopplung also Vielfaches von 8)
# - Bei Einsatz unter OS X müssen im Code zumindest die bs angepasst werden
#   z.B. 1M 2M ... ändern in 1m 2m ... (habe ich irgendwo gelesen)
#   Ob der Rest bei OS X funktioniert? Keine Ahnung ... ;)
# (c) 2014 deMattin - free for all!
#     http://www.k64.eu/linux-tools/
# inspired by framp with his raspiBackup-Skript
# on http://www.linux-tips-and-tricks.de/raspiBackup 
#
# Einstellungen/Settings:
# -----------
Lesepfad="/tmp"
Lesedatei_in_MB=120
Auch_Schreibtest=0
Schreibpfad="/backup"
gzip_test=0
Zufallsdaten=0
# ===========
#
# Ab hier muss nichts geändert werden!
Lesedatei="$Lesepfad/intestfile.dat"
Schreibdatei="$Schreibpfad/outtestfile.dat"
clear
echo "Konfiguration:"
echo "--------------"
echo "Lesepfad: $Lesepfad"
echo "Testdateigröße: $Lesedatei_in_MB MiB"
if test $Auch_Schreibtest == 0
 then
  echo "Nur Lesetest wird durchgeführt"
 else
  echo "Schreibtest wird durchgeführt"
  echo "Schreibpfad: $Schreibpfad"
fi
test $gzip_test -ne 0 && echo "Schreibtest mit gzip-Kompression" || echo "Schreibtest ohne gzip-Kompression"
test $Zufallsdaten -ne 0 && echo "Zufallsdaten in Testdatei" || echo "0-Werte in Testdatei"
echo "*** Taste \"q\" für Abbruch - weiter mit beliebiger, anderer Taste. ***"
stty raw -echo
char=`dd bs=1 count=1 2>/dev/null`
stty -raw echo
if [ "$char" == "q" ]
 then
  exit
fi
# Schreibrechte prüfen
f=0
if [ -w $Lesepfad ]
 then
  echo "Schreibrechte auf $Lesepfad - ok!"
 else
  echo "Fehler: Keine Schreibrechte auf $Lesepfad!"
  f=1
fi
if test $Auch_Schreibtest != 0
 then
  if [ -w $Schreibpfad ] 
   then
    echo "Schreibrechte auf $Schreibpfad - ok!"
   else
    echo "Fehler: Keine Schreibrechte auf $Schreibpfad!"
    f=1
  fi
fi
# Wenn benötigten Rechte fehlen, dann Abbruch!
test $f -eq 0 || exit

#
# Hier geht's endlich los!
#
echo ""
echo "Testdatei $Lesedatei mit $Lesedatei_in_MB MiB wird erzeugt."

# Testfile mit Zufallswerten statt 0-Werten dauert ewig bei der Erzeugung!
if test $Zufallsdaten == 0
 then
  dd if=/dev/zero of=$Lesedatei bs=1M count=$Lesedatei_in_MB
 else
  dd if=/dev/urandom of=$Lesedatei bs=1M count=$Lesedatei_in_MB
fi

echo ""
# zu testende Blockgrößen
for bs in 256 512 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1M 2M 4M 8M 

do
 # alles Caches leeren
 sync
 echo 3 > /proc/sys/vm/drop_caches
 echo "Teste block size  = $bs"
 if test "$Auch_Schreibtest" == "0"
  then
   # Nur Lesetest
    if test "$gzip_test" == "0"
     then
      dd if=$Lesedatei of=/dev/null bs=$bs
     else
      # Testen mit Kompression
      dd if=$Lesedatei bs=$bs | gzip > /dev/null
    fi
  else
   # Auch Schreibtest
    if test "$gzip_test" == "0"
     then
      dd if=$Lesedatei of=$Schreibdatei bs=$bs
     else
      # Testen mit Kompression
      dd if=$Lesedatei bs=$bs | gzip > $Schreibdatei
    fi
    rm $Schreibdatei
    echo "Lösche Schreibdatei..."
  fi
  echo ""
done
echo "Lösche Lesedatei..."
rm $Lesedatei
echo ""
echo "Fertig!"