#!/bin/bash # PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH" help() { less -M << EOF Press 'q' to Quit, Enter to scroll! ============================================================================= You can use this script to backup and restore the MBR. v1.7 (11-6-2007) The (M)aster (B)oot (R)ecord is the first 512 bytes of a hard drive, you should always have a current backup of the MBR! To hold the MBR, you can use any media with a filesystem on it, but the filesystem on the media must be supported by the kernel! In addition to backing up the MBR of the hard drive you specify, it also makes a backup of the boot sector from each partition on the hard drive. Backup MBR from /dev/sda to directory /mbr on usb device /dev/sdb. # backup-mbr -b -d /mbr sda sdb "If directory doesn't exist, will create." Restore MBR to /dev/sda from backup in directory /mbr on /dev/sdb. # backup-mbr -r -d /mbr sda sdb Restore boot sector to /dev/sda1 from backup in directory /mbr on /dev/sdb. # backup-mbr -r -d /mbr sda1 sdb If you want to backup the MBR to a multi-session CD-R/RW, do this. # backup-mbr -cd-multi -b -d /mbr sda scd0 You can specify the cd device the old (pre kernel v2.6) way, like this. # backup-mbr -cd-multi -b -d /mbr sda 0,0,0 You'll need 'cdrecord' and 'mkisofs' installed, and have a CD in the drive '/dev/scd0', or 0,0,0 etc. If it's not a multi-session CD-R/RW, do it this way. # backup-mbr -cd -b -d /mbr sda scd0 "CD will be written multi-session." The non multi-session CD-RW must be blank, blank it first if it's not. cdrecord blank=fast dev=/dev/scd0 "You'll loose anything on the CD!" Or, if you want this script to blank the CD-RW. # backup-mbr -cd-blank -b -d /mbr sda scd0 Restore MBR to /dev/sda from backup in directory /mbr on /dev/scd0. # backup-mbr -r -d /mbr sda scd0 ============================================================================= EOF exit } fdisk_mbr() { echo "You can restore the whole MBR (512 bytes) like this. dd if=$1.mbr of=/dev/$1 bs=512 count=1 If you just want to restore the MBR boot sector (first 446 bytes), do this. dd if=$1.mbr of=/dev/$1 bs=446 count=1 If you just want to restore the MBR partition table (last 64 bytes), do this. dd if=$1.mbr of=/dev/$1 bs=1 count=64 skip=446 seek=446" >/tmp/floppy/$2/mbr-$1.txt fdisk -l /dev/$1 >/tmp/floppy/$2/fdisk.$1 fdisk -ul /dev/$1 >>/tmp/floppy/$2/fdisk.$1 } sfdisk_mbr() { sfdisk -d /dev/$1 >/tmp/floppy/$2/sfdisk.$1 echo " You can also use sfdisk to restore the MBR partition table. sfdisk /dev/$1 < sfdisk.$1 Or, you can use the backup-mbr script. Read sfdisk.$1, but don't edit. Read fdisk.$1 for a listing of the partition table." >>/tmp/floppy/$2/mbr-$1.txt } mbr_cd() { error() { rm -rf /tmp/floppy rm -f /tmp/mbr.iso cat /tmp/error echo echo "ERROR! $1" rm -f /tmp/error exit } if ! grep -q -w $2 /proc/partitions ; then echo "ERROR! I can't find \`$2' listed in /proc/partitions." exit elif ! echo $2 | grep -q "[a-z]$" ; then echo "ERROR! The device \`$2' is not a whole disk." exit fi mkdir -p /tmp/floppy/$1 dd if=/dev/$2 of=/tmp/floppy/$1/$2.mbr bs=512 count=1 1>/dev/null 2>/tmp/error && \ if [ ! $? = 0 ]; then rm -rf /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem." rm -f /tmp/error exit else echo echo "Copied MBR from \`/dev/$2' for \`$1/$2.mbr' on $3." if [ -x "`type -path fdisk`" ]; then pt=`fdisk -l /dev/$2 | grep "^/dev/$2" | awk '{print $1}'` for p in $pt ; do dev=`echo $p | cut -b 6-10` dd if=/dev/$dev of=/tmp/floppy/$1/$dev.bs bs=512 count=1 1>/dev/null 2>/dev/null && \ echo "Copied boot sector from \`/dev/$dev' for \`$1/$dev.bs' on $3." done fdisk_mbr $2 $1 fi sfdisk_mbr $2 $1 fi echo "*** Creating mbr.iso..." if [ "$cd_multi" = "yes" ]; then multi="`cdrecord -msinfo dev=$3 2>/tmp/error | head -n 1`" echo $multi | grep "^[0-9]" | grep -q "[0-9]$" || error=yes if [ "$error" = "yes" ]; then echo "There's not a multi-session CD in $3." exit fi (cd /tmp/floppy && mkisofs -R -J -o ../mbr.iso -C $multi -M $3 . 1>/dev/null 2>/tmp/error) || error else (cd /tmp/floppy && mkisofs -R -J -o ../mbr.iso . 1>/dev/null 2>/tmp/error) || error fi if [ "$cd_blank" = "yes" ]; then echo "*** Blanking CD..." cdrecord blank=fast dev=$3 1>/dev/null 2>/tmp/error || error fi echo "*** Writing mbr.iso multi-session to $3..." cdrecord -multi -tao -data dev=$3 /tmp/mbr.iso 1>/dev/null 2>/tmp/error || error rm -rf /tmp/floppy rm -f /tmp/mbr.iso /tmp/error echo "*** Read $1/mbr-$2.txt on $3." echo "*** Done!" exit } if [ -z "$1" ]; then help elif [ "$1" = "-cd" -o "$1" = "-cd-multi" -o "$1" = "-cd-blank" ]; then if [ ! -x "`type -path cdrecord`" -o ! -x "`type -path mkisofs`" ]; then echo "ERROR! I can't find cdrecord and/or mkisofs." exit else if [ "$1" = "-cd-multi" ]; then cd_multi=yes elif [ "$1" = "-cd-blank" ]; then cd_blank=yes fi shift cd=yes if echo $5 | grep -q "," ; then cd_dev=$5 dev=$4 else cd_dev=/dev/$5 dev=$5 fi fi else dev=$5 fi if [ "$1" = "-b" -a "$2" = "-d" -a -n "$3" -a -n "$4" -a -n "$5" ]; then if [ -b "/dev/$4" -a -b "/dev/$dev" ]; then if [ -n "$cd" ]; then mbr_cd $3 $4 $cd_dev $cd_multi $cd_blank fi if ! grep -q -w $4 /proc/partitions ; then echo "ERROR! I can't find \`$4' listed in /proc/partitions." exit fi if ! echo $4 | grep -q "[a-z]$" ; then echo "ERROR! The device \`$4' is not a whole disk." exit fi umount /tmp/floppy 2>/dev/null umount /dev/$5 2>/dev/null mkdir -p /tmp/floppy if ! mount -o rw /dev/$5 /tmp/floppy 1>/dev/null 2>/dev/null ; then echo echo "ERROR! I can't mount device \`/dev/$5'!" exit fi if [ ! -d "/tmp/floppy/$3" ]; then mkdir -p /tmp/floppy/$3 || exit fi dd if=/dev/$4 of=/tmp/floppy/$3/$4.mbr bs=512 count=1 1>/dev/null 2>/tmp/error && \ if [ ! $? = 0 ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem!" rm -f /tmp/error exit else echo -e "\nCopied MBR from \`/dev/$4' to \`$3/$4.mbr' on /dev/$5." if [ -x "`type -path fdisk`" ]; then pt=`fdisk -l /dev/$4 | grep "^/dev/$4" | awk '{print $1}'` for p in $pt ; do dev=`echo $p | cut -b 6-10` dd if=/dev/$dev of=/tmp/floppy/$3/$dev.bs bs=512 count=1 1>/dev/null 2>/dev/null && \ echo "Copied boot sector from \`/dev/$dev' to \`$3/$dev.bs' on /dev/$5." done fdisk_mbr $4 $3 fi sfdisk_mbr $4 $3 fi umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy echo echo "Read $3/mbr-$4.txt on /dev/$5." echo "Done!" exit else echo echo "$0 $1 $2 $3 $4 $5" echo "ERROR! I can't find device \`/dev/$4' and/or \`/dev/$5'." exit fi elif [ "$1" = "-r" -a "$2" = "-d" -a -n "$3" -a -n "$4" -a -n "$5" ]; then if [ -b "/dev/$4" -a -b "/dev/$5" ]; then umount /tmp/floppy 2>/dev/null umount /dev/$5 2>/dev/null if echo $4 | cut -b 4 | grep -q "[1-9]" ; then mbr=$4.bs else mbr=$4.mbr fi mkdir -p /tmp/floppy 2>/dev/null if ! mount -o ro /dev/$5 /tmp/floppy 1>/dev/null 2>/dev/null ; then echo echo "ERROR! I can't mount device \`/dev/$5'." exit fi if [ ! -s /tmp/floppy/$3/$mbr ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy echo echo "ERROR! There's no \`$3/$mbr' on \`/dev/$5'." exit fi if [ "$mbr" = "$4.mbr" ]; then echo echo "Restoring \`/dev/$4' from MBR backup \`$4.mbr'." echo echo "Do you just want to restore the boot sector (first 446 bytes), or the" echo "partition table (last 64 bytes), or the whole MBR (512 bytes)?" echo echo "Answer 1 for boot sector (first 446 bytes)" echo "Answer 2 for the whole MBR (512 bytes)" echo "Answer 3 for just the partition table (last 64 bytes)" echo echo -n "Answer 1, 2, or 3 " read ans if [ "$ans" = "1" ]; then dd if=/tmp/floppy/$3/$mbr of=/dev/$4 bs=446 count=1 1>/dev/null 2>/tmp/error if [ ! $? = 0 ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem." rm -f /tmp/error exit fi MBR="MBR boot sector (first 446 bytes)" elif [ "$ans" = "2" ]; then dd if=/tmp/floppy/$3/$mbr of=/dev/$4 bs=512 count=1 1>/dev/null 2>/tmp/error if [ ! $? = 0 ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem." rm -f /tmp/error exit fi MBR="whole MBR (512 bytes)" elif [ "$ans" = "3" ]; then if [ -x "`type -path sfdisk`" -a -s "/tmp/floppy/$3/sfdisk.$4" ]; then sfdisk /dev/$4 < /tmp/floppy/$3/sfdisk.$4 1>/dev/null 2>/tmp/error else dd if=/tmp/floppy/$3/$mbr of=/dev/$4 bs=1 count=64 skip=446 seek=446 1>/dev/null 2>/tmp/error fi if [ ! $? = 0 ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem!" rm -f /tmp/error exit fi MBR="MBR partition table (last 64 bytes)" else umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy echo echo "Cancelled!" exit fi else dd if=/tmp/floppy/$3/$mbr of=/dev/$4 bs=512 count=1 1>/dev/null 2>/tmp/error if [ ! $? = 0 ]; then umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy cat /tmp/error echo echo "ERROR! There was a problem." rm -f /tmp/error exit fi MBR="boot sector ($mbr)" fi umount /tmp/floppy 2>/dev/null && rmdir /tmp/floppy blockdev --rereadpt /dev/$4 2>/dev/null echo echo "Copied $MBR to \`/dev/$4'." echo "Done!" exit else echo echo "$0 $1 $2 $3 $4 $5" echo "ERROR! I can't find device \`/dev/$4' and/or \`/dev/$5'." exit fi else help fi