diff options
author | Micah Anderson <micah@riseup.net> | 2010-01-17 23:54:09 +1300 |
---|---|---|
committer | Micah Anderson <micah@riseup.net> | 2010-01-17 23:54:09 +1300 |
commit | fe3620c6529cc449cd152ed58667e39d4a80257e (patch) | |
tree | ec83be42237855979a31f38cdce51f45cdbd7312 /handlers/sys.in | |
parent | 18f28c2cb00286cc0ff790ef6b6914f3f22ec4ac (diff) | |
parent | 46eccf2fd0c894790405b2e3aae8dfb99f5a5d98 (diff) | |
download | backupninja-fe3620c6529cc449cd152ed58667e39d4a80257e.tar.gz backupninja-fe3620c6529cc449cd152ed58667e39d4a80257e.tar.bz2 |
Merge branch 'master' into debian
Conflicts:
AUTHORS
ChangeLog
handlers/maildir.in
handlers/mysql.in
handlers/rsync.in
handlers/sys.helper.in
handlers/sys.in
src/backupninja.in
Diffstat (limited to 'handlers/sys.in')
-rwxr-xr-x | handlers/sys.in | 334 |
1 files changed, 237 insertions, 97 deletions
diff --git a/handlers/sys.in b/handlers/sys.in index f293840..69751ed 100755 --- a/handlers/sys.in +++ b/handlers/sys.in @@ -1,7 +1,8 @@ # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# vim: set filetype=sh sw=3 sts=3 expandtab autoindent: # # this handler will save various reports of vital system information. -# by default, all the reports are enabled and are saved in /var/backups. +# by default, all the reports are saved in /var/backups. # # (1) a capture of the debconf package selection states. This file # can be used to restore the answers to debconf questions for @@ -11,19 +12,27 @@ # (2) a list of all the packages installed and removed. # this file can be used to restore the state of installed packages # by running "dpkg --set-selections < dpkg-selections.txt and -# then run "apt-get -u dselect-upgrade". If you have the +# then run "apt-get -u dselect-upgrade". If you have the # debconf-set-selections file from (1), you should restore those first. -# -# (3) the partition table of all disks. +# +# (3) the partition table of all disks. # this partition table can be used to format another disk of -# the same size. this can be handy if using software raid and +# the same size. this can be handy if using software raid and # you have a disk go bad. just replace the disk and partition it # by running "sfdisk /dev/sdb < partitions.sdb.txt" # (MAKE SURE YOU PARTITION THE CORRECT DISK!!!) # -# (4) hardware information. +# (4) hardware information. # write to a text file the important things which hwinfo can gleen. # +# (5) the Luks header of every Luks block device, if option luksheaders +# is enabled. +# in case you (have to) scramble such a Luks header (for some time), +# and restore it later by running "dd if=luksheader.sda2.bin of=/dev/sda2" +# (MAKE SURE YOU PASS THE CORRECT DEVICE AS of= !!!) +# +# (6) LVM metadata for every detected volume group, if "lvm = yes" +# if [ -f /etc/debian_version ] then @@ -47,7 +56,7 @@ getconf dohwinfo yes if [ ! -d $parentdir ]; then mkdir -p $parentdir fi - + if [ $os = "debian" ] then getconf packagesfile $parentdir/dpkg-selections.txt @@ -57,9 +66,9 @@ then getconf debconfgetselections `which debconf-get-selections` elif [ $os = "redhat" ] then - getconf packagesfile $parentdir/rpmpackages.txt - getconf packagemgr `which rpm` - getconf packagemgroptions ' -qa ' + getconf packagesfile $parentdir/rpmpackages.txt + getconf packagemgr `which rpm` + getconf packagemgroptions ' -qa ' getconf SYSREPORT `which sysreport` getconf sysreport_options ' -norpm ' @@ -82,6 +91,15 @@ getconf HWINFO `which hwinfo` getconf sfdisk_options "" getconf hwinfo_options "" +getconf CRYPTSETUP `which cryptsetup` +getconf DD `which dd` +getconf luksheaders no +getconf luksheadersfile $parentdir/luksheader.__star__.bin + +getconf VGS `which vgs` +getconf VGCFGBACKUP `which vgcfgbackup` +getconf lvm no + getconf vsnames all # If vservers are configured, check that the ones listed in $vsnames are running. @@ -97,6 +115,30 @@ if [ $vservers_are_available = yes ]; then usevserver=yes fi +## SANITY CHECKS ######################### + +if [ "$luksheaders" == "yes" ]; then + if [ ! -x "$DD" ]; then + warning "can't find dd, skipping backup of Luks headers." + luksheaders="no" + fi + if [ ! -x "$CRYPTSETUP" ]; then + warning "can't find cryptsetup, skipping backup of Luks headers." + luksheaders="no" + fi +fi + +if [ "$lvm" == "yes" ]; then + if [ ! -x "$VGS" ]; then + warning "can't find vgs, skipping backup of LVM metadata" + lvm="no" + fi + if [ ! -x "$VGCFGBACKUP" ]; then + warning "can't find vgcfgbackup, skipping backup of LVM metadata" + lvm="no" + fi +fi + ## PACKAGES ############################## # @@ -122,7 +164,7 @@ if [ "$packages" == "yes" ]; then # don't expand * since it can be used in $packagemgroptions set -o noglob debug "$VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile" - $VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile" + $VSERVER $vserver exec $packagemgr $packagemgroptions > $VROOTDIR/$vserver$packagesfile || fatal "can not save $packagemgr info to $packagesfile" set +o noglob fi # is $debconfgetselections available inside $vserver ? @@ -143,9 +185,9 @@ if [ "$packages" == "yes" ]; then unset found done fi - + # We want to perform this on the host as well - if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then + if [ -z "$packagemgr" -o ! -x "$packagemgr" ]; then warning "can't find ${packagemgr}, skipping installed packages report." else # don't expand * since it can be used in $packagemgroptions @@ -194,7 +236,7 @@ catiffile () { done fi echo $DASHES >> $sysreportfile -} +} catifexec () { if [ -x $1 ]; then @@ -204,12 +246,12 @@ catifexec () { $* >> $sysreportfile 2>&1 || info "executing of $1 failed" fi } - + STATUS="Determining $os version:" catiffile $osversion -STATUS="Determinding your current hostname: " +STATUS="Determinding your current hostname: " catifexec "/bin/hostname" STATUS="Getting the date:" @@ -231,17 +273,17 @@ if [ $os = "redhat" ]; then catiffile "/bin/ls /etc/rc.d/rc*.d/" elif [ $os = "debian" ]; then - for level in 0 1 2 3 4 5 6 S; do - echo "Level: $level" >> $sysreportfile - for f in /etc/rc${level}.d/*; do - # Remove /etc/Knn or Snn from beginning - ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__') - if [ $f != $ff ]; then - echo $ff >> $sysreportfile - fi - done - echo "" >> $sysreportfile - done + for level in 0 1 2 3 4 5 6 S; do + echo "Level: $level" >> $sysreportfile + for f in /etc/rc${level}.d/*; do + # Remove /etc/Knn or Snn from beginning + ff=$(echo $f | @SED@ 's_/etc/rc..d/[KS][0-9][0-9]__') + if [ $f != $ff ]; then + echo $ff >> $sysreportfile + fi + done + echo "" >> $sysreportfile + done fi STATUS="Getting bootloader information:" @@ -250,34 +292,34 @@ catifexec "/bin/ls" "-alR /boot" # This covers sparc, alpha, and intel (respectively) # updated for grub -mpg if [ -f /etc/silo.conf ]; then - STATUS="Collecting information about the boot process (silo):" - catiffile "/etc/silo.conf" + STATUS="Collecting information about the boot process (silo):" + catiffile "/etc/silo.conf" fi if [ -f /etc/milo.conf ]; then - STATUS="Collecting information about the boot process (milo):" - catiffile "/etc/milo.conf" + STATUS="Collecting information about the boot process (milo):" + catiffile "/etc/milo.conf" fi if [ -f /etc/lilo.conf ]; then - STATUS="Collecting information about the boot process (lilo):" - catiffile "/etc/lilo.conf" - catifexec "/sbin/lilo" "-q" + STATUS="Collecting information about the boot process (lilo):" + catiffile "/etc/lilo.conf" + catifexec "/sbin/lilo" "-q" fi if [ -d /boot/grub -a -f /boot/grub/grub.conf -a -f /boot/grub/device.map ]; then - STATUS="Collecting information about the boot process (grub.conf):" - catiffile "/boot/grub/grub.conf" - STATUS="Collecting information about the boot process (grub.map):" - catiffile "/boot/grub/device.map" + STATUS="Collecting information about the boot process (grub.conf):" + catiffile "/boot/grub/grub.conf" + STATUS="Collecting information about the boot process (grub.map):" + catiffile "/boot/grub/device.map" fi if [ -f /etc/cluster.conf -o -f /etc/cluster.xml ] ; then - STATUS="Gathering information on cluster setup" - # 2.1 AS - if [ -f /etc/cluster.conf ] ; then - catiffile "/etc/cluster.conf" - fi - # Taroon - if [ -f /etc/cluster.xml ] ; then - catiffile "/etc/cluster.xml" - fi + STATUS="Gathering information on cluster setup" + # 2.1 AS + if [ -f /etc/cluster.conf ] ; then + catiffile "/etc/cluster.conf" + fi + # Taroon + if [ -f /etc/cluster.xml ] ; then + catiffile "/etc/cluster.xml" + fi fi STATUS="Gathering sysctl information (sysctl -a):" @@ -308,10 +350,10 @@ STATUS="Getting kernel version:" catifexec "/bin/uname" "-a" STATUS="Checking module information:" catifexec "/sbin/lsmod" -for x in $(/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null +for x in $(/sbin/lsmod | /bin/cut -f1 -d" " 2>/dev/null | /bin/grep -v Module 2>/dev/null ) ; do - STATUS="Checking module information $x:" - catifexec "/sbin/modinfo" "$x" + STATUS="Checking module information $x:" + catifexec "/sbin/modinfo" "$x" done STATUS="Gathering information about your filesystems:" @@ -334,27 +376,27 @@ STATUS="Collecting information regarding kernel modules" VER=`uname -r` catiffile "/lib/modules/$VER/modules.dep" if [ -f /etc/conf.modules ]; then - STATUS="Collecting information regarding kernel modules (conf.modules)" - catiffile "/etc/conf.modules" + STATUS="Collecting information regarding kernel modules (conf.modules)" + catiffile "/etc/conf.modules" fi if [ -f /etc/modules.conf ]; then - STATUS="Collecting information regarding kernel modules (modules.conf)" - catiffile "/etc/modules.conf" + STATUS="Collecting information regarding kernel modules (modules.conf)" + catiffile "/etc/modules.conf" fi if [ -f /etc/modprobe.conf ]; then - STATUS="Collecting information regarding kernel modules (modeprobe.conf)" - catiffile "/etc/modprobe.conf" + STATUS="Collecting information regarding kernel modules (modeprobe.conf)" + catiffile "/etc/modprobe.conf" fi # dkms status if [ -x /usr/sbin/dkms ] ; then STATUS="Gathering current status of modules, versions and kernels (dkms):" - catifexec "/usr/sbin/dkms" "status" + catifexec "/usr/sbin/dkms" "status" fi if [ -f /etc/sysconfig/isdncard ] ; then - STATUS="Gathering information about ISDN:" - catiffile "/etc/sysconfig/isdncard" + STATUS="Gathering information about ISDN:" + catiffile "/etc/sysconfig/isdncard" fi STATUS="Collecting information from the proc directory:" @@ -437,18 +479,21 @@ if [ $os = "redhat" ]; then elif [ $os = "debian" ]; then catifexec "/sbin/vgdisplay" "-vv" fi - + +STATUS="Collecting device-mapper (dm) information:" +catifexec '/sbin/dmsetup' 'info' + STATUS="Collecting SCSI Tape information (/etc/stinit.def)" catiffile "/etc/stinit.def" if [ -x /sbin/lsusb ] ; then - STATUS="Collecting USB devices list (lsusb):" - catifexec "/sbin/lsusb" + STATUS="Collecting USB devices list (lsusb):" + catifexec "/sbin/lsusb" fi if [ -x /usr/bin/lshal ] ; then - STATUS="Collecting global devices list (lshal):" - catifexec "/usr/bin/lshal" + STATUS="Collecting global devices list (lshal):" + catifexec "/usr/bin/lshal" fi @@ -467,24 +512,24 @@ fi if [ "$partitions" == "yes" ]; then if [ "$dosfdisk" == "yes" ]; then - if [ ! -x "$SFDISK" ]; then - warning "can't find sfdisk, skipping sfdisk report." - partitions="no" - fi + if [ ! -x "$SFDISK" ]; then + warning "can't find sfdisk, skipping sfdisk report." + partitions="no" + fi fi if [ "$dohwinfo" == "yes" ]; then - if [ ! -x "$HWINFO" ]; then - warning "can't find hwinfo, skipping partition report." - partitions="no" - fi + if [ ! -x "$HWINFO" ]; then + warning "can't find hwinfo, skipping partition report." + partitions="no" + fi fi fi if [ "$hardware" == "yes" ]; then - if [ ! -x "$HWINFO" ]; then - warning "can't find hwinfo, skipping hardware report." - hardware="no" - fi + if [ ! -x "$HWINFO" ]; then + warning "can't find hwinfo, skipping hardware report." + hardware="no" + fi fi ## HARDWARE ############################# @@ -492,48 +537,47 @@ fi # # here we use hwinfo to dump a table listing all the # information we can find on the hardware of this machine -# +# if [ "$hardware" == "yes" ]; then if [ "dohwinfo" == "yes" ]; then if [ -f $hardwarefile ]; then - rm $hardwarefile + rm $hardwarefile fi touch $hardwarefile echo -e "\n\n====================== summary ======================\n" >> $hardwarefile debug "$HWINFO --short --cpu --network --disk --pci >> $hardwarefile" $HWINFO --short --cpu --network --disk --pci >> $hardwarefile for flag in cpu network bios pci; do - echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile - $HWINFO --$flag >> $hardwarefile + echo -e "\n\n====================== $flag ======================\n" >> $hardwarefile + $HWINFO --$flag >> $hardwarefile done fi fi - ## PARTITIONS ############################# -# here we use sfdisk to dump a listing of all the partitions. +# here we use sfdisk to dump a listing of all the partitions. # these files can be used to directly partition a disk of the same size. if [ "$partitions" == "yes" ]; then if [ "$dosfdisk" == "yes" ]; then devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` - if [ "$devices" == "" ]; then - warning "No harddisks found" - fi - for dev in $devices; do - debug "$SFDISK will try to backup partition tables for device $dev" - [ -b $dev ] || continue - label=${dev#/dev/} - label=${label//\//-} - outputfile=${partitionsfile//__star__/$label} - debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null" - $SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null - if [ $? -ne 0 ]; then - warning "The partition table for $dev could not be saved." - fi - done + if [ "$devices" == "" ]; then + warning "No harddisks found" + fi + for dev in $devices; do + debug "$SFDISK will try to backup partition tables for device $dev" + [ -b $dev ] || continue + label=${dev#/dev/} + label=${label//\//-} + outputfile=${partitionsfile//__star__/$label} + debug "$SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null" + $SFDISK $sfdisk_options -d $dev > $outputfile 2>/dev/null + if [ $? -ne 0 ]; then + warning "The partition table for $dev could not be saved." + fi + done fi if [ "$dohwinfo" == "yes" ]; then debug "Using $HWINFO to get all available disk information" @@ -541,3 +585,99 @@ if [ "$partitions" == "yes" ]; then $HWINFO --disk >> $hardwarefile fi fi + +if [ "$luksheaders" == "yes" ]; then + devices=`LC_ALL=C $SFDISK -l 2>/dev/null | grep "^Disk /dev" | @AWK@ '{print $2}' | cut -d: -f1` + [ -n "$devices" ] || warning "No block device found" + targetdevices="" + for dev in $devices; do + [ -b $dev ] || continue + debug "$CRYPTSETUP isLuks $dev" + $CRYPTSETUP isLuks $dev + [ $? -eq 0 ] && targetdevices="$targetdevices $dev" + done + for dev in $targetdevices; do + label=${dev#/dev/} + label=${label//\//-} + outputfile=${luksheadersfile//__star__/$label} + # the following sizes are expressed in terms of 512-byte sectors + debug "Let us find out the Luks header size for $dev" + debug "$CRYPTSETUP luksDump \"$dev\" | grep '^Payload offset:' | @AWK@ '{print $3}'" + headersize=`$CRYPTSETUP luksDump "$dev" | grep '^Payload offset:' | @AWK@ '{print $3}'` + if [ $? -ne 0 ]; then + warning "Could not compute the size of Luks header, skipping device $dev" + continue + elif [ -z "$headersize" -o -n "`echo \"$headersize\" | sed 's/[0-9]*//g'`" ]; then + warning "The computed size of Luks header is not an integer, skipping device $dev" + continue + fi + debug "Let us backup the Luks header of device $dev" + debug "$DD if=\"${dev}\" of=\"${outputfile}\" bs=512 count=\"${headersize}\"" + output=`$DD if="${dev}" of="${outputfile}" bs=512 count="${headersize}" 2>&1` + exit_code=$? + if [ $exit_code -eq 0 ]; then + debug $output + info "The Luks header of $dev was saved to $outputfile." + else + debug $output + fatal "The Luks header of $dev could not be saved." + fi + done +fi + +## LVM #################################### + +# returns 0 on success, 1 on error, 2 if not tried +# outputs error message if error, reason if not tried +function doLvmBackup () { + local lvmdir="$1" + if [ ! -d "$lvmdir" ]; then + if ! mkdir "$lvmdir"; then + echo "could not create $lvmdir" + return 2 + else + info "successfully created $lvmdir" + fi + fi + if [ ! -w "$lvmdir" ]; then + echo "can not write to directory $lvmdir" + return 2 + fi + debug "Let's try to gather the list of LVM volume groups" + debug "$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '" + vgs=`$VGS --options vg_name --noheadings | @SED@ 's/^[ ]*//' | @SED@ 's/[ ]*$//' | tr '\n' ' '` + debug "Let's try to backup LVM metadata for detected volume groups: $vgs" + debug "$VGCFGBACKUP --file \"${lvmdir}\"/\'%s\' $vgs" + output=`$VGCFGBACKUP --file "${lvmdir}"/'%s' $vgs` + exit_code=$? + debug $output + case $exit_code in + 0) + info "LVM metadata was saved to $lvmdir for volume groups: $vgs" + return 0 + ;; + *) + echo "LVM metadata could not be saved for at least one of these volume groups: $vgs" + return 1 + ;; + esac +} + +if [ "$lvm" == "yes" ]; then + output=`doLvmBackup "${parentdir}/lvm"` + exit_code=$? + case $exit_code in + 0) # success. info message has already been displayed + true + ;; + 1) # error + fatal "$output" + ;; + 2) # could not even try + fatal "LVM metadata backup was not tried: $output" + ;; + *) # should never happen + fatal "Unhandled error ($exit_code) while trying to backup LVM metadata, please report a bug" + ;; + esac +fi |