#!/bin/bash . /usr/share/fog/lib/partition-funcs.sh REG_LOCAL_MACHINE_XP="/ntfs/WINDOWS/system32/config/system" REG_LOCAL_MACHINE_7="/ntfs/Windows/System32/config/SYSTEM" # 1 to turn on massive debugging of partition table restoration ismajordebug=0 #If a sub shell gets invoked and we lose kernel vars this will reimport them oIFS=$IFS for var in $(cat /proc/cmdline); do IFS=$oIFS read name value <<< $(echo "$var" | grep =.* | awk -F= '{name=$1;$1="";gsub(/[ \t]+$/,"",$0);gsub(/^[ \t]+/,"",$0); gsub(/[+][_][+]/," ",$0); value=$0; print name; print value;}') IFS=$'\n' [[ -z $value ]] && continue value=$(echo $value | sed 's/\"//g') printf -v "$name" -- "$value" done IFS=$oIFS ### If USB Boot device we need a way to get the kernel args properly [[ $boottype == usb && -f /tmp/hinfo.txt ]] && . /tmp/hinfo.txt # Below Are non parameterized functions # These functions will run without any arguments # # Clears thes creen unless its a debug task clearScreen() { case $isdebug in [Yy][Ee][Ss]|[Yy]) clear ;; esac } # Displays the nice banner along with the running version displayBanner() { version=$(wget -qO - http://${web}service/getversion.php 2>/dev/null) echo " +------------------------------------------+" echo " | ..#######:. ..,#,.. .::##::. |" echo " |.:###### .:;####:......;#;.. |" echo " |...##... ...##;,;##::::.##... |" echo " | ,# ...##.....##:::## ..:: |" echo " | ## .::###,,##. . ##.::#.:######::.|" echo " |...##:::###::....#. .. .#...#. #...#:::. |" echo " |..:####:.. ..##......##::## .. # |" echo " | # . ...##:,;##;:::#: ... ##.. |" echo " | .# . .:;####;::::.##:::;#:.. |" echo " | # ..:;###.. |" echo " | |" echo " +------------------------------------------+" echo " | Free Computer Imaging Solution |" echo " +------------------------------------------+" echo " | Credits: http://fogproject.org/Credits |" echo " | http://fogproject.org/Credits |" echo " | Released under GPL Version 3 |" echo " +------------------------------------------+" echo " Version: $version" } # Gets all system mac addresses except for loopback getMACAddresses() { read ifaces <<< $(/sbin/ip -4 -o addr | awk -F'([ /])+' '/global/ {print $2}' | tr '[:space:]' '|' | sed -e 's/^[|]//g' -e 's/[|]$//g') read mac_addresses <<< $(/sbin/ip -0 -o addr | awk "/$ifaces/ {print \$11}" | tr '[:space:]' '|' | sed -e 's/^[|]//g' -e 's/[|]$//g') echo $mac_addresses } # Verifies that there is a network interface verifyNetworkConnection() { dots "Verifying network interface configuration" local count=$(/sbin/ip addr | awk -F'[ /]+' '/global/{print $3}' | wc -l) if [[ -z $count || $count -lt 1 ]]; then echo "Failed" debugPause handleError "No network interfaces found (${FUNCNAME[0]})\n Args Passed: $*" fi echo "Done" debugPause } # Verifies that the OS is valid for resizing validResizeOS() { [[ $osid != @([1-2]|4|[5-7]|9|50|51) ]] && handleError " * Invalid operating system id: $osname ($osid) (${FUNCNAME[0]})\n Args Passed: $*" } # Gets the information from the system for inventory doInventory() { sysman=$(dmidecode -s system-manufacturer) sysproduct=$(dmidecode -s system-product-name) sysversion=$(dmidecode -s system-version) sysserial=$(dmidecode -s system-serial-number) systype=$(dmidecode -t 3 | grep Type:) biosversion=$(dmidecode -s bios-version) biosvendor=$(dmidecode -s bios-vendor) biosdate=$(dmidecode -s bios-release-date) mbman=$(dmidecode -s baseboard-manufacturer) mbproductname=$(dmidecode -s baseboard-product-name) mbversion=$(dmidecode -s baseboard-version) mbserial=$(dmidecode -s baseboard-serial-number) mbasset=$(dmidecode -s baseboard-asset-tag) cpuman=$(dmidecode -s processor-manufacturer) cpuversion=$(dmidecode -s processor-version) cpucurrent=$(dmidecode -t 4 | grep 'Current Speed:' | head -n1) cpumax=$(dmidecode -t 4 | grep 'Max Speed:' | head -n1) mem=$(cat /proc/meminfo | grep MemTotal) hdinfo=$(hdparm -i $hd 2>/dev/null | grep Model=) caseman=$(dmidecode -s chassis-manufacturer) casever=$(dmidecode -s chassis-version) caseserial=$(dmidecode -s chassis-serial-number) casesasset=$(dmidecode -s chassis-asset-tag) sysman64=$(echo $sysman | base64) sysproduct64=$(echo $sysproduct | base64) sysversion64=$(echo $sysversion | base64) sysserial64=$(echo $sysserial | base64) systype64=$(echo $systype | base64) biosversion64=$(echo $biosversion | base64) biosvendor64=$(echo $biosvendor | base64) biosdate64=$(echo $biosdate | base64) mbman64=$(echo $mbman | base64) mbproductname64=$(echo $mbproductname | base64) mbversion64=$(echo $mbversion | base64) mbserial64=$(echo $mbserial | base64) mbasset64=$(echo $mbasset | base64) cpuman64=$(echo $cpuman | base64) cpuversion64=$(echo $cpuversion | base64) cpucurrent64=$(echo $cpucurrent | base64) cpumax64=$(echo $cpumax | base64) mem64=$(echo $mem | base64) hdinfo64=$(echo $hdinfo | base64) caseman64=$(echo $caseman | base64) casever64=$(echo $casever | base64) caseserial64=$(echo $caseserial | base64) casesasset64=$(echo $casesasset | base64) } # Gets the location of the SAM registry if found getSAMLoc() { local path="" local paths="/ntfs/WINDOWS/system32/config/SAM /ntfs/Windows/System32/config/SAM" for path in $paths; do [[ ! -f $path ]] && continue sam="$path" && break done } # Appends dots to the end of string up to 50 characters. # Makes the output more aligned and organized. # # $1 String to append dots to dots() { local str="$*" [[ -z $str ]] && handleError "No string passed (${FUNCNAME[0]})\n Args Passed: $*" local pad=$(printf "%0.1s" "."{1..50}) printf " * %s%*.*s" "$str" 0 $((50-${#str})) "$pad" } # Enables write caching on the disk passed # If the disk does not support write caching this does nothing # # $1 is the drive enableWriteCache() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" wcache=$(hdparm -W $disk 2>/dev/null | tr -d '[[:space:]]' | awk -F= '/.*write-caching=/{print $2}') if [[ -z $wcache || $wcache == notsupported ]]; then echo " * Write caching not supported" debugPause return fi dots "Enabling write cache" hdparm -W1 $disk >/dev/null 2>&1 case $? in 0) echo "Enabled" ;; *) echo "Failed" debugPause handleWarning "Could not set caching status (${FUNCNAME[0]})" return ;; esac debugPause } # Expands partitions, as needed/capable # # $1 is the partition # $2 is the fixed size partitions (can be empty) expandPartition() { local part="$1" local fixed="$2" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" local disk="" local part_number=0 getDiskFromPartition "$part" getPartitionNumber "$part" local is_fixed=$(echo $fixed | awk "/(^$part_number:|:$part_number:|:$part_number$|^$part_number$)/{print 1}") if [[ $is_fixed -eq 1 ]]; then echo " * Not expanding ($part) fixed size" debugPause return fi local fstype="" fsTypeSetting $part case $fstype in ntfs) dots "Resizing $fstype volume ($part)" ntfsresize $part -f -b -P /dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not resize $part (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause resetFlag "$part" ;; extfs) dots "Resizing $fstype volume ($part)" e2fsck -fp $part >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not check before resize (${FUNCNAME[0]})\n Args Passed: $*" ;; esac resize2fs $part >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not resize $part (${FUNCNAME[0]})\n Args Passed: $*" ;; esac e2fsck -fp $part >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not check after resize (${FUNCNAME[0]})\n Args Passed: $*" ;; esac ;; *) echo " * Not expanding ($part -- $fstype)" debugPause ;; esac debugPause runPartprobe "$disk" } # Gets the filesystem type of the partition passed # # $1 is the partition fsTypeSetting() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" local blk_fs=$(blkid -po udev $part | awk -F= /FS_TYPE=/'{print $2}') case $blk_fs in btrfs) fstype="btrfs" ;; ext[2-4]) fstype="extfs" ;; hfsplus) fstype="hfsp" ;; ntfs) fstype="ntfs" ;; swap) fstype="swap" ;; vfat) fstype="fat" ;; xfs) fstype="xfs" ;; *) fstype="imager" ;; esac } # Gets the disk part table UUID # # $1 is the disk getDiskUUID() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" diskuuid=$(blkid -po udev $disk | awk -F= '/PART_TABLE_UUID=/{print $2}') } # Gets the partition entry name # # $1 is the partition getPartName() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" partname=$(blkid -po udev $part | awk -F= '/PART_ENTRY_NAME=/{print $2}') } # Gets the partition entry type # # $1 is the partition getPartType() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" parttype=$(blkid -po udev $part | awk -F= '/PART_ENTRY_TYPE=/{print $2}') } # Gets the partition fs UUID # # $1 is the partition getPartFSUUID() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" partfsuuid=$(blkid -po udev $part | awk -F= '/FS_UUID=/{print $2}') } # Gets the partition entry UUID # # $1 is the partition getPartUUID() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" partuuid=$(blkid -po udev $part | awk -F= '/PART_ENTRY_UUID=/{print $2}') } # Gets the entry schemed (dos, gpt, etc...) # # $1 is the partition getPartitionEntryScheme() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" scheme=$(blkid -po udev $part | awk -F= '/PART_ENTRY_SCHEME=/{print $2}') } # Checks if the partition is dos extended (mbr with logical parts) # # $1 is the partition partitionIsDosExtended() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" local scheme="" getPartitionEntryScheme "$part" debugEcho "scheme = $scheme" 1>&2 case $scheme in dos) echo "no" ;; *) local parttype="" getPartType "$part" debugEcho "parttype = $parttype" 1>&2 [[ $parttype == +(0x5|0xf) ]] && echo "yes" || echo "no" ;; esac debugPause } # Returns the block size of a partition # # $1 is the partition # $2 is the variable to set getPartBlockSize() { local part="$1" local varVar="$2" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $varVar ]] && handleError "No variable to set passed (${FUNCNAME[0]})\n Args Passed: $*" printf -v "$varVar" $(blockdev --getpbsz $part) } # Prepares location info for uploads # # $1 is the image path prepareUploadLocation() { local imagePath="$1" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" dots "Preparing backup location" if [[ ! -d $imagePath ]]; then mkdir -p $imagePath >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Failed to create image capture path (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fi echo "Done" debugPause dots "Setting permission on $imagePath" chmod -R 777 $imagePath >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Failed to set permissions (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause dots "Removing any pre-existing files" rm -Rf $imagePath/* >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not clean files (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause } # Shrinks partitions for upload (resizable images only) # # $1 is the partition # $2 is the fstypes file location # $3 is the fixed partition numbers empty ok shrinkPartition() { local part="$1" local fstypefile="$2" local fixed="$3" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $fstypefile ]] && handleError "No type file passed (${FUNCNAME[0]})\n Args Passed: $*" local disk="" local part_number=0 getDiskFromPartition "$part" getPartitionNumber "$part" local is_fixed=$(echo $fixed | awk "/(^$part_number:|:$part_number:|:$part_number$|^$part_number$)/{print 1}") if [[ $is_fixed -eq 1 ]]; then echo " * Not shrinking ($part) fixed size" debugPause return fi local fstype="" fsTypeSetting "$part" echo "$part $fstype" >> $fstypefile local size=0 local tmpoutput="" local sizentfsresize=0 local sizeextresize=0 local sizefd=0 local tmp_success="" local test_string="" local do_resizefs=0 local do_resizepart=0 local extminsize=0 local block_size=0 local sizeextresize=0 local adjustedfdsize=0 local part_block_size=0 case $fstype in ntfs) ntfsresize -f -i -v -P $part >/tmp/tmpoutput.txt 2>&1 if [[ ! $? -eq 0 ]]; then handleError " * (${FUNCNAME[0]})\n Args Passed: $*\n\nFatal Error, unable to find size data out on $part. Cmd: ntfsresize -f -i -v -P $part" fi tmpoutput=$(cat /tmp/tmpoutput.txt) size=$(cat /tmp/tmpoutput.txt | grep "You might resize" | cut -d" " -f5) [[ -z $size ]] && handleError " * (${FUNCNAME[0]})\n Args Passed: $*\n\nFatal Error, Unable to determine possible ntfs size\n * To better help you debug we will run the ntfs resize\n\t but this time with full output, please wait!\n\t $(cat /tmp/tmpoutput.txt)" rm /tmp/tmpoutput.txt >/dev/null 2>&1 sizentfsresize=$((size / 1000)) let sizentfsresize+=300000 sizentfsresize=$((sizentfsresize * 1${percent} / 100)) sizefd=$((sizentfsresize * 103 / 100)) echo " * Possible resize partition size: $sizentfsresize k" dots "Running resize test $part" ntfsresize -f -n -s ${sizentfsresize}k $part /tmp/tmpoutput.txt 2>&1 local ntfsstatus="$?" tmpoutput=$(cat /tmp/tmpoutput.txt) test_string=$(cat /tmp/tmpoutput.txt | egrep -io "(ended successfully|bigger than the device size|volume size is already OK)" | tr -d '[[:space:]]') echo "Done" debugPause rm /tmp/tmpoutput.txt >/dev/null 2>&1 case $test_string in endedsuccessfully) echo " * Resize test was successful" do_resizefs=1 do_resizepart=1 ntfsstatus=0 ;; biggerthanthedevicesize) echo " * Not resizing filesystem $part (part too small)" ntfsstatus=0 ;; volumesizeisalreadyOK) echo " * Not resizing filesystem $part (already OK)" do_resizepart=1 ntfsstatus=0 ;; esac [[ ! $ntfsstatus -eq 0 ]] && handleError "Resize test failed!\n $tmpoutput\n (${FUNCNAME[0]})\n Args Passed: $*" if [[ $do_resizefs -eq 1 ]]; then debugPause dots "Resizing filesystem" ntfsresize -f -s ${sizentfsresize}k $part < /usr/share/fog/lib/EOFNTFS >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not resize disk (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fi if [[ $do_resizepart -eq 1 ]]; then debugPause dots "Resizing partition $part" getPartBlockSize "$part" "part_block_size" case $osid in [1-2]|4) resizePartition "$part" "$sizentfsresize" "$imagePath" [[ $osid -eq 2 ]] && correctVistaMBR "$disk" ;; [5-7]|9) [[ $part_number -eq $win7partcnt ]] && part_start=$(blkid -po udev $part 2>/dev/null | awk -F= '/PART_ENTRY_OFFSET=/{printf("%.0f\n",$2*'$part_block_size'/1000)}') || part_start=1048576 if [[ -z $part_start || $part_start -lt 1 ]]; then echo "Failed" debugPause handleError "Unable to determine disk start location (${FUNCNAME[0]})\n Args Passed: $*" fi adjustedfdsize=$((sizefd + part_start)) resizePartition "$part" "$adjustedfdsize" "$imagePath" ;; esac echo "Done" fi resetFlag "$part" ;; extfs) dots "Checking $fstype volume ($part)" e2fsck -fp $part >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "e2fsck failed to check $part (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause extminsize=$(resize2fs -P $part 2>/dev/null | awk -F': ' '{print $2}') block_size=$(dumpe2fs -h $part 2>/dev/null | awk /^Block\ size:/'{print $3}') size=$((extminsize * block_size)) sizeextresize=$((size * 103 / 100 / 1024)) [[ -z $sizeextresize || $sizeextresize -lt 1 ]] && handleError "Error calculating the new size of extfs ($part) (${FUNCNAME[0]})\n Args Passed: $*" dots "Shrinking $fstype volume ($part)" resize2fs $part -M >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not shrink $fstype volume ($part) (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause dots "Shrinking $part partition" resizePartition "$part" "$sizeextresize" "$imagePath" echo "Done" debugPause dots "Resizing $fstype volume ($part)" resize2fs $part >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could resize $fstype volume ($part) (${FUNCNAME[0]})\n Args Passed: $*" ;; esac e2fsck -fp $part >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not check expanded volume ($part) (${FUNCNAME[0]})\n Args Passed: $*" ;; esac ;; *) echo " * Not shrinking ($part $fstype)" ;; esac debugPause } # Resets the dirty bits on a partition # # $1 is the part resetFlag() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" local fstype="" fsTypeSetting "$part" case $fstype in ntfs) dots "Clearing ntfs flag" ntfsfix -b -d $part >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" ;; esac ;; esac } # Counts the partitions containing the fs type as passed # # $1 is the disk # $2 is the part type to look for # $3 is the variable to store the count into. This is # a variable variable countPartTypes() { local disk="$1" local parttype="$2" local varVar="$3" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $parttype ]] && handleError "No partition type passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $varVar ]] && handleError "No variable to set passed (${FUNCNAME[0]})\n Args Passed: $*" local count=0 local fstype="" local parts="" local part="" getPartitions "$disk" for part in $parts; do fsTypeSetting "$part" case $fstype in $parttype) let count+=1 ;; esac done printf -v "$varVar" "$count" } # Writes the image to the disk # # $1 = Source File # $2 = Target # $3 = mc task or not (not required) writeImage() { local file="$1" local target="$2" local mc="$3" [[ -z $target ]] && handleError "No target to place image passed (${FUNCNAME[0]})\n Args Passed: $*" mkfifo /tmp/pigz1 case $mc in yes) udp-receiver --nokbd --portbase $port --ttl 32 --mcast-rdv-address $storageip 2>/dev/null >/tmp/pigz1 & ;; *) [[ -z $file ]] && handleError "No source file passed (${FUNCNAME[0]})\n Args Passed: $*" cat $file >/tmp/pigz1 & ;; esac if [[ $imgFormat -eq 1 || $imgLegacy -eq 1 ]]; then echo " * Imaging using Partimage" pigz -d -c /tmp/status.fog else echo " * Imaging using Partclone" pigz -d -c /dev/null 2>&1 } # Gets the valid restore parts. They're only # valid if the partition data exists for # the partitions on the server # # $1 = Disk (e.g. /dev/sdb) # $2 = Disk number (e.g. 1) # $3 = ImagePath (e.g. /net/foo) getValidRestorePartitions() { local disk="$1" local disk_number="$2" local imagePath="$3" local setrestoreparts="$4" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" local valid_parts="" local parts="" local part="" local imgpart="" local part_number=0 getPartitions "$disk" for part in $parts; do getPartitionNumber "$part" [[ $imgPartitionType != all && $imgPartitionType != $part_number ]] && continue case $osid in [1-2]) [[ ! -f $imagePath ]] && imgpart="$imagePath/d${disk_number}p${part_number}.img*" || imgpart="$imagePath" ;; 4|[5-7]|9) [[ ! -f $imagePath/sys.img.000 ]] && imgpart="$imagePath/d${disk_number}p${part_number}.img*" if [[ -z $imgpart ]]; then case $win7partcnt in 1) [[ $part_number -eq 1 ]] && imgpart="$imagePath/sys.img.*" ;; 2) [[ $part_number -eq 1 ]] && imgpart="$imagePath/rec.img.000" [[ $part_number -eq 2 ]] && imgpart="$imagePath/sys.img.*" ;; 3) [[ $part_number -eq 1 ]] && imgpart="$imagePath/rec.img.000" [[ $part_number -eq 2 ]] && imgpart="$imagePath/rec.img.001" [[ $part_number -eq 3 ]] && imgpart="$imagePath/sys.img.*" ;; esac fi ;; *) imgpart="$imagePath/d${disk_number}p${part_number}.img*" ;; esac ls $imgpart >/dev/null 2>&1 [[ $? -eq 0 ]] && valid_parts="$valid_parts $part" done [[ -z $setrestoreparts ]] && restoreparts=$(echo $valid_parts | uniq | sort -V) || restoreparts="$(echo $setrestoreparts | uniq | sort -V)" } # Makes all swap partitions and sets uuid's in linux setups # # $1 = Disk (e.g. /dev/sdb) # $2 = Disk number (e.g. 1) # $3 = ImagePath (e.g. /net/foo) # $4 = ImagePartitionType (e.g. all, mbr, 1, 2, 3, etc.) makeAllSwapSystems() { local disk="$1" local disk_number="$2" local imagePath="$3" local imgPartitionType="$4" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imgPartitionType ]] && handleError "No image partition type passed (${FUNCNAME[0]})\n Args Passed: $*" local swapuuidfilename="" swapUUIDFileName "$imagePath" "$disk_number" local parts="" local part="" local part_number=0 getPartitions "$disk" for part in $parts; do getPartitionNumber "$part" [[ $imgPartitionType == all || $imgPartitionType -eq $part_number ]] && makeSwapSystem "$swapuuidfilename" "$part" done runPartprobe "$disk" } # Changes the hostname on windows systems # # $1 = Partition changeHostname() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $hostname || $hostearly -eq 0 ]] && return REG_HOSTNAME_KEY1="\ControlSet001\Services\Tcpip\Parameters\NV Hostname" REG_HOSTNAME_KEY2="\ControlSet001\Services\Tcpip\Parameters\Hostname" REG_HOSTNAME_KEY3="\ControlSet001\Services\Tcpip\Parameters\NV HostName" REG_HOSTNAME_KEY4="\ControlSet001\Services\Tcpip\Parameters\HostName" REG_HOSTNAME_KEY5="\ControlSet001\Control\ComputerName\ActiveComputerName\ComputerName" REG_HOSTNAME_KEY6="\ControlSet001\Control\ComputerName\ComputerName\ComputerName" REG_HOSTNAME_KEY7="\ControlSet001\services\Tcpip\Parameters\NV Hostname" REG_HOSTNAME_KEY8="\ControlSet001\services\Tcpip\Parameters\Hostname" REG_HOSTNAME_KEY9="\ControlSet001\services\Tcpip\Parameters\NV HostName" REG_HOSTNAME_KEY10="\ControlSet001\services\Tcpip\Parameters\HostName" REG_HOSTNAME_KEY11="\CurrentControlSet\Services\Tcpip\Parameters\NV Hostname" REG_HOSTNAME_KEY12="\CurrentControlSet\Services\Tcpip\Parameters\Hostname" REG_HOSTNAME_KEY13="\CurrentControlSet\Services\Tcpip\Parameters\NV HostName" REG_HOSTNAME_KEY14="\CurrentControlSet\Services\Tcpip\Parameters\HostName" REG_HOSTNAME_KEY15="\CurrentControlSet\Control\ComputerName\ActiveComputerName\ComputerName" REG_HOSTNAME_KEY16="\CurrentControlSet\Control\ComputerName\ComputerName\ComputerName" REG_HOSTNAME_KEY17="\CurrentControlSet\services\Tcpip\Parameters\NV Hostname" REG_HOSTNAME_KEY18="\CurrentControlSet\services\Tcpip\Parameters\Hostname" REG_HOSTNAME_KEY19="\CurrentControlSet\services\Tcpip\Parameters\NV HostName" REG_HOSTNAME_KEY20="\CurrentControlSet\services\Tcpip\Parameters\HostName" dots "Mounting directory" if [[ ! -d /ntfs ]]; then mkdir -p /ntfs >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo "Failed" debugPause handleError " * Could not create mount location (${FUNCNAME[0]})\n Args Passed: $*" fi fi umount /ntfs >/dev/null 2>&1 ntfs-3g -o remove_hiberfile,rw $part /ntfs >/tmp/ntfs-mount-output 2>&1 case $? in 0) echo "Done" debugPause ;; *) echo "Failed" debugPause handleError " * Could not mount $part (${FUNCNAME[0]})\n Args Passed: $*\n Reason: $(cat /tmp/ntfs-mount-output)" ;; esac if [[ ! -f /usr/share/fog/lib/EOFREG ]]; then key1="$REG_HOSTNAME_KEY1" key2="$REG_HOSTNAME_KEY2" key3="$REG_HOSTNAME_KEY3" key4="$REG_HOSTNAME_KEY4" key5="$REG_HOSTNAME_KEY5" key6="$REG_HOSTNAME_KEY6" key7="$REG_HOSTNAME_KEY7" key8="$REG_HOSTNAME_KEY8" key9="$REG_HOSTNAME_KEY9" key10="$REG_HOSTNAME_KEY10" key11="$REG_HOSTNAME_KEY11" key12="$REG_HOSTNAME_KEY12" key13="$REG_HOSTNAME_KEY13" key14="$REG_HOSTNAME_KEY14" key15="$REG_HOSTNAME_KEY15" key16="$REG_HOSTNAME_KEY16" key17="$REG_HOSTNAME_KEY17" key18="$REG_HOSTNAME_KEY18" key19="$REG_HOSTNAME_KEY19" key20="$REG_HOSTNAME_KEY20" case $osid in 1) regfile="$REG_LOCAL_MACHINE_XP" ;; 2|4|[5-7]|9) regfile="$REG_LOCAL_MACHINE_7" ;; esac echo "ed $key1" >/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key2" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key3" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key4" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key5" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key6" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key7" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key8" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key9" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key10" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key11" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key12" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key13" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key14" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key15" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key16" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key17" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key18" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key19" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "ed $key20" >>/usr/share/fog/lib/EOFREG echo "$hostname" >>/usr/share/fog/lib/EOFREG echo "q" >> /usr/share/fog/lib/EOFREG echo "y" >> /usr/share/fog/lib/EOFREG echo >> /usr/share/fog/lib/EOFREG fi if [[ -e $regfile ]]; then dots "Changing hostname" reged -e $regfile < /usr/share/fog/lib/EOFREG >/dev/null 2>&1 case $? in [0-2]) echo "Done" debugPause ;; *) echo "Failed" debugPause umount /ntfs >/dev/null 2>&1 echo " * Failed to change hostname" return ;; esac fi rm -rf /usr/share/fog/lib/EOFREG umount /ntfs >/dev/null 2>&1 } # Fixes windows 7/8 boot, though may need # to be updated to only impact windows 7 # in which case we need a more dynamic method # # $1 is the partition fixWin7boot() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ $osid != [5-7] ]] && return local fstype="" fsTypeSetting "$part" [[ $fstype != ntfs ]] && return dots "Mounting partition" if [[ ! -d /bcdstore ]]; then mkdir -p /bcdstore >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError " * Could not create mount location (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fi ntfs-3g -o remove_hiberfile,rw $part /bcdstore >/tmp/ntfs-mount-output 2>&1 case $? in 0) echo "Done" debugPause ;; *) echo "Failed" debugPause handleError " * Could not mount $part (${FUNCNAME[0]})\n Args Passed: $*\n Reason: $(cat /tmp/ntfs-mount-output)" ;; esac if [[ ! -f /bcdstore/Boot/BCD ]]; then umount /bcdstore >/dev/null 2>&1 return fi dots "Backing up and replacing BCD" mv /bcdstore/Boot/BCD{,.bak} >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause umount /bcdstore >/dev/null 2>&1 echo " * Could not create backup" return ;; esac cp /usr/share/fog/BCD /bcdstore/Boot/BCD >/dev/null 2>&1 case $? in 0) echo "Done" debugPause umount /bcdstore >/dev/null 2>&1 ;; *) echo "Failed" debugPause umount /bcdstore >/dev/null 2>&1 echo " * Could not copy our bcd file" return ;; esac umount /bcdstore >/dev/null 2>&1 } # Clears out windows hiber and page files # # $1 is the partition clearMountedDevices() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" if [[ ! -d /ntfs ]]; then mkdir -p /ntfs >/dev/null 2>&1 case $? in 0) umount /ntfs >/dev/null 2>&1 ;; *) handleError "Could not create mount point /ntfs (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fi case $osid in 4|[5-7]|9) local fstype="" fsTypeSetting "$part" REG_HOSTNAME_MOUNTED_DEVICES_7="\MountedDevices" if [[ ! -f /usr/share/fog/lib/EOFMOUNT ]]; then echo "cd $REG_HOSTNAME_MOUNTED_DEVICES_7" >/usr/share/fog/lib/EOFMOUNT echo "dellallv" >>/usr/share/fog/lib/EOFMOUNT echo "q" >>/usr/share/fog/lib/EOFMOUNT echo "y" >>/usr/share/fog/lib/EOFMOUNT echo >> /usr/share/fog/lib/EOFMOUNT fi case $fstype in ntfs) dots "Clearing part ($part)" ntfs-3g -o remove_hiberfile,rw $part /ntfs >/tmp/ntfs-mount-output 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError " * Could not mount $part (${FUNCNAME[0]})\n Args Passed: $*\n Reason: $(cat /tmp/ntfs-mount-output)" ;; esac if [[ ! -f $REG_LOCAL_MACHINE_7 ]]; then echo "Reg file not found" debugPause umount /ntfs >/dev/null 2>&1 return fi reged -e $REG_LOCAL_MACHINE_7 /dev/null 2>&1 case $? in [0-2]) echo "Done" debugPause umount /ntfs >/dev/null 2>&1 ;; *) echo "Failed" debugPause /umount /ntfs >/dev/null 2>&1 echo " * Could not clear partition $part" return ;; esac ;; esac ;; esac } # Only removes the page file # # $1 is the device name of the windows system partition removePageFile() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" local fstype="" fsTypeSetting "$part" [[ ! $ignorepg -eq 1 ]] && return case $osid in [1-2]|4|[5-7]|[9]|50|51) case $fstype in ntfs) dots "Mounting partition ($part)" if [[ ! -d /ntfs ]]; then mkdir -p /ntfs >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError " * Could not create mount location (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fi umount /ntfs >/dev/null 2>&1 ntfs-3g -o remove_hiberfile,rw $part /ntfs >/tmp/ntfs-mount-output 2>&1 case $? in 0) echo "Done" debugPause ;; *) echo "Failed" debugPause handleError " * Could not mount $part (${FUNCNAME[0]})\n Args Passed: $*\n Reason: $(cat /tmp/ntfs-mount-output)" ;; esac if [[ -f /ntfs/pagefile.sys ]]; then dots "Removing page file" rm -rf /ntfs/pagefile.sys >/dev/null 2>&1 case $? in 0) echo "Done" debugPause ;; *) echo "Failed" debugPause echo " * Could not delete the page file" ;; esac fi if [[ -f /ntfs/hiberfil.sys ]]; then dots "Removing hibernate file" rm -rf /ntfs/hiberfil.sys >/dev/null 2>&1 case $? in 0) echo "Done" debugPause ;; *) echo "Failed" debugPause umount /ntfs >/dev/null 2>&1 echo " * Could not delete the hibernate file" ;; esac fi umount /ntfs >/dev/null 2>&1 ;; esac ;; esac } # Sets OS mbr, as needed, and returns the Name # based on the OS id passed. # # $1 the osid to determine the os and mbr determineOS() { local osid="$1" [[ -z $osid ]] && handleError "No os id passed (${FUNCNAME[0]})\n Args Passed: $*" case $osid in 1) osname="Windows XP" mbrfile="/usr/share/fog/mbr/xp.mbr" ;; 2) osname="Windows Vista" mbrfile="/usr/share/fog/mbr/vista.mbr" ;; 3) osname="Windows 98" mbrfile="" ;; 4) osname="Windows (Other)" mbrfile="" ;; 5) osname="Windows 7" mbrfile="/usr/share/fog/mbr/win7.mbr" defaultpart2start="105906176B" ;; 6) osname="Windows 8" mbrfile="/usr/share/fog/mbr/win8.mbr" defaultpart2start="368050176B" ;; 7) osname="Windows 8.1" mbrfile="/usr/share/fog/mbr/win8.mbr" defaultpart2start="368050176B" ;; 8) osname="Apple Mac OS" mbrfile="" ;; 9) osname="Windows 10" mbrfile="" ;; 50) osname="Linux" mbrfile="" ;; 51) osname="Chromium OS" mbrfile="" ;; 99) osname="Other OS" mbrfile="" ;; *) handleError " * Invalid OS ID ($osid) (${FUNCNAME[0]})\n Args Passed: $*" ;; esac } # Converts the string (seconds) passed to human understanding # # $1 the seconds to convert sec2string() { local T="$1" [[ -z $T ]] && handleError "No string passed (${FUNCNAME[0]})\n Args Passed: $*" local d=$((T/60/60/24)) local H=$((T/60/60%24)) local i=$((T/60%60)) local s=$((T%60)) local dayspace='' local hourspace='' local minspace='' [[ $H > 0 ]] && dayspace=' ' [[ $i > 0 ]] && hourspace=':' [[ $s > 0 ]] && minspace=':' (($d > 0)) && printf '%d day%s' "$d" "$dayspace" (($H > 0)) && printf '%d%s' "$H" "$hourspace" (($i > 0)) && printf '%d%s' "$i" "$minspace" (($s > 0)) && printf '%d' "$s" } # Returns the disk based off the partition passed # # $1 is the partition to grab the disk from getDiskFromPartition() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" disk=$(echo $part | sed 's/p\?[0-9]\+$//g') } # Returns the number of the partition passed # # $1 is the partition to get the partition number for getPartitionNumber() { local part="$1" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" part_number=$(echo $part | grep -o '[0-9]*$') } # $1 is the partition to search for. getPartitions() { local disk="$1" [[ -z $disk ]] && disk="$hd" [[ -z $disk ]] && handleError "No disk found (${FUNCNAME[0]})\n Args Passed: $*" parts=$(lsblk -I 3,8,9,179,259 -lpno KNAME,TYPE $disk | awk '{if ($2 ~ /part/ || $2 ~ /md/) print $1}' | sort -V | uniq) } # Gets the hard drive on the host # Note: This function makes a best guess getHardDisk() { [[ -n $fdrive ]] && hd=$(echo $fdrive) [[ -n $hd ]] && return local devs=$(lsblk -dpno KNAME -I 3,8,9,179,259 | uniq | sort -V) disks=$(echo $devs) [[ -z $disks ]] && handleError "Cannot find disk on system (${FUNCNAME[0]})\n Args Passed: $*" [[ $1 == true ]] && return for hd in $disks; do break done } # Finds the hard drive info and set's up the type findHDDInfo() { case $imgType in [Nn]|mps|dd) dots "Looking for Hard Disk" getHardDisk if [[ -z $hd ]]; then echo "Failed" debugPause handleError "Could not find hard disk ($0)\n Args Passed: $*" fi echo "Done" debugPause case $type in down) diskSize=$(lsblk --bytes -dplno SIZE -I 3,8,9,179,259 $hd) [[ $diskSize -gt 2199023255552 ]] && layPartSize="2tB" echo " * Using Disk: $hd" [[ $imgType == +([nN]) ]] && validResizeOS enableWriteCache "$hd" ;; up) dots "Reading Partition Tables" runPartprobe "$hd" getPartitions "$hd" if [[ -z $parts ]]; then echo "Failed" debugPause handleError "Could not find partitions ($0)\n Args Passed: $*" fi echo "Done" debugPause ;; esac echo " * Using Hard Disk: $hd" ;; mpa) dots "Looking for Hard Disks" getHardDisk "true" if [[ -z $disks ]]; then echo "Failed" debugPause handleError "Could not find any disks ($0)\n Args Passed: $*" fi echo "Done" debugPause case $type in up) for disk in $disks; do dots "Reading Partition Tables on $disk" getPartitions "$disk" if [[ -z $parts ]]; then echo "Failed" debugPause echo " * No partitions for disk $disk" debugPause continue fi echo "Done" debugPause done ;; esac echo " * Using Disks: $disks" ;; esac } # Imaging complete completeTasking() { case $type in up) chmod -R 777 "$imagePath" >/dev/null 2>&1 killStatusReporter . /bin/fog.imgcomplete ;; down) killStatusReporter if [[ -f /images/postdownloadscripts/fog.postdownload ]]; then postdownpath="/images/postdownloadscripts/" . ${postdownpath}fog.postdownload fi [[ $capone -eq 1 ]] && exit 0 if [[ $osid == +([1-2]|4|[5-7]|9) ]]; then for disk in $disks; do getPartitions "$disk" for part in $parts; do fsTypeSetting "$part" [[ $fstype == ntfs ]] && changeHostname "$part" done done fi . /bin/fog.imgcomplete ;; esac } # Corrects mbr layout for Vista OS # # $1 is the disk to correct for correctVistaMBR() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" dots "Correcting Vista MBR" dd if=$disk of=/tmp.mbr count=1 bs=512 >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not create backup (${FUNCNAME[0]})\n Args Passed: $*" ;; esac xxd /tmp.mbr /tmp.mbr.txt >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "xxd command failed (${FUNCNAME[0]})\n Args Passed: $*" ;; esac rm /tmp.mbr >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Couldn't remove /tmp.mbr file (${FUNCNAME[0]})\n Args Passed: $*" ;; esac fogmbrfix /tmp.mbr.txt /tmp.mbr.fix.txt >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "fogmbrfix failed to operate (${FUNCNAME[0]})\n Args Passed: $*" ;; esac rm /tmp.mbr.txt >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not remove the text file (${FUNCNAME[0]})\n Args Passed: $*" ;; esac xxd -r /tmp.mbr.fix.txt /mbr.mbr >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not run second xxd command (${FUNCNAME[0]})\n Args Passed: $*" ;; esac rm /tmp.mbr.fix.txt >/dev/null 2>&1 case $? in 0) ;; *) echo "Failed" debugPause handleError "Could not remove the fix file (${FUNCNAME[0]})\n Args Passed: $*" ;; esac dd if=/mbr.mbr of="$disk" count=1 bs=512 >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not apply fixed MBR (${FUNCNAME[0]})\n Args Passed: $*" ;; esac debugPause } # Prints an error with visible information # # $1 is the string to inform what went wrong handleError() { local str="$1" local parts="" local part="" echo "##############################################################################" echo "# #" echo "# An error has been detected! #" echo "# #" echo "##############################################################################" echo -e "$str" # # expand the file systems in the restored partitions # # Windows 7, 8, 8.1: # Windows 2000/XP, Vista: # Linux: if [[ -n $2 ]]; then case $osid in [1-2]|4|[5-7]|9|50|51) if [[ -n "$hd" ]]; then getPartitions "$hd" for part in $parts; do expandPartition "$part" done fi ;; esac fi if [[ -z $isdebug ]]; then echo "##############################################################################" echo "# #" echo "# Computer will reboot in 1 minute #" echo "# #" echo "##############################################################################" usleep 60000000 else debugPause fi exit 1 } # Prints a visible banner describing an issue but not breaking # # $1 The string to inform the user what the problem is handleWarning() { local str="$1" echo "##############################################################################" echo "# #" echo "# A warning has been detected! #" echo "# #" echo "##############################################################################" echo -e "$str" echo "##############################################################################" echo "# #" echo "# Will continue in 1 minute #" echo "# #" echo "##############################################################################" usleep 60000000 debugPause } # Re-reads the partition table of the disk passed # # $1 is the disk runPartprobe() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" umount /ntfs /bcdstore >/dev/null 2>&1 udevadm settle blockdev --rereadpt $disk >/dev/null 2>&1 [[ ! $? -eq 0 ]] && handleError "Failed to read back partitions (${FUNCNAME[0]})\n Args Passed: $*" } # Sends a command list to a file for use when debugging # # $1 The string of the command needed to run. debugCommand() { local str="$1" case $isdebug in [Yy][Ee][Ss]|[Yy]) echo -e "$str" >> /tmp/cmdlist ;; esac } # Escapes the passed item where needed # # $1 the item that needs to be escaped escapeItem() { local item="$1" echo $item | sed -r 's%/%\\/%g' } # uploadFormat # Description: # Tells the system what format to upload in, whether split or not. # Expects first argument to be the fifo to send to. # Expects part of the filename in the case of resizable # will append 000 001 002 automatically # # $1 The fifo name (file in file out) # $2 The file to upload into on the server uploadFormat() { local fifo="$1" local file="$2" [[ -z $fifo ]] && handleError "Missing file in file out (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $file ]] && handleError "Missing file name to store (${FUNCNAME[0]})\n Args Passed: $*" [[ ! -e $fifo ]] && mkfifo $fifo >/dev/null 2>&1 case $imgFormat in 2) pigz $PIGZ_COMP < $fifo | split -a 3 -d -b 200m - ${file}. & ;; *) pigz $PIGZ_COMP < $fifo > ${file}.000 & ;; esac } # Thank you, fractal13 Code Base # # Save enough MBR and embedding area to capture all of GRUB # Strategy is to capture EVERYTHING before the first partition. # Then, leave a marker that this is a GRUB MBR for restoration. # We could get away with less storage, but more details are required # to parse the information correctly. It would make the process # more complicated. # # See the discussion about the diskboot.img and the sector list # here: http://banane-krumm.de/bootloader/grub2.html # # Expects: # the device name (e.g. /dev/sda) as the first parameter, # the disk number (e.g. 1) as the second parameter # the directory to store images in (e.g. /image/dev/xyz) as the third parameter # # $1 is the disk # $2 is the disk number # $3 is the image path to save the file to. # $4 is the determinator of sgdisk use or not saveGRUB() { local disk="$1" local disk_number="$2" local imagePath="$3" local sgdisk="$4" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" # Determine the number of sectors to copy # Hack Note: print $4+0 causes the column to be interpretted as a number # so the comma is tossed local count=$(sfdisk -d $disk 2>/dev/null | awk /start=\ *[1-9]/'{print $4+0}' | sort -n | head -n1) local has_grub=$(dd if=$disk bs=512 count=1 2>&1 | grep -i 'grub') local hasgrubfilename="" if [[ -n $has_grub ]]; then hasGrubFileName "$imagePath" "$disk_number" "$sgdisk" touch $hasgrubfilename fi # Ensure that no more than 1MiB of data is copied (already have this size used elsewhere) [[ $count -gt 2048 ]] && count=2048 local mbrfilename="" MBRFileName "$imagePath" "$disk_number" "mbrfilename" "$sgdisk" dd if=$disk of=$mbrfilename count=$count bs=512 >/dev/null 2>&1 } # Checks for the existence of the grub embedding area in the image directory. # Echos 1 for true, and 0 for false. # # Expects: # the device name (e.g. /dev/sda) as the first parameter, # the disk number (e.g. 1) as the second parameter # the directory images stored in (e.g. /image/xyz) as the third parameter # $1 is the disk # $2 is the disk number # $3 is the image path # $4 is the sgdisk determinator hasGRUB() { local disk_number="$1" local imagePath="$2" local sgdisk="$3" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" local hasgrubfilename="" hasGrubFileName "$imagePath" "$disk_number" "$sgdisk" hasGRUB=0 [[ -e $hasgrubfilename ]] && hasGRUB=1 } # Restore the grub boot record and all of the embedding area data # necessary for grub2. # # Expects: # the device name (e.g. /dev/sda) as the first parameter, # the disk number (e.g. 1) as the second parameter # the directory images stored in (e.g. /image/xyz) as the third parameter # $1 is the disk # $2 is the disk number # $3 is the image path # $4 is the sgdisk determinator restoreGRUB() { local disk="$1" local disk_number="$2" local imagePath="$3" local sgdisk="$4" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" local tmpMBR="" MBRFileName "$imagePath" "$disk_number" "tmpMBR" "$sgdisk" local count=$(du -B 512 $tmpMBR | awk '{print $1}') [[ $count -eq 8 ]] && count=1 dd if=$tmpMBR of=$disk bs=512 count=$count >/dev/null 2>&1 runPartprobe "$disk" } # Waits for enter if system is debug type debugPause() { case $isdebug in [Yy][Ee][Ss]|[Yy]) echo " * Press [Enter] key to continue" read -p "$*" ;; *) return ;; esac } debugEcho() { local str="$*" case $isdebug in [Yy][Ee][Ss]|[Yy]) echo "$str" ;; *) return ;; esac } majorDebugEcho() { [[ $ismajordebug -gt 1 ]] && echo "$*" } majorDebugPause() { [[ ! $ismajordebug -gt 0 ]] && return echo " * Press [Enter] key to continue" read -p "$*" } swapUUIDFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" swapuuidfilename="$imagePath/d${disk_number}.original.swapuuids" } mainUUIDFileName() { local imagePath="$1" local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" mainuuidfilename="$imagePath/d${disk_number}.original.uuids" } sfdiskPartitionFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" sfdiskoriginalpartitionfilename="$imagePath/d${disk_number}.partitions" } sfdiskLegacyOriginalPartitionFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" sfdisklegacyoriginalpartitionfilename="$imagePath/d${disk_number}.original.partitions" } sfdiskMinimumPartitionFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" sfdiskminimumpartitionfilename="$imagePath/d${disk_number}.minimum.partitions" } sfdiskOriginalPartitionFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" sfdiskPartitionFileName "$imagePath" "$disk_number" } sgdiskOriginalPartitionFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" sgdiskoriginalpartitionfilename="$imagePath/d${disk_number}.sgdisk.original.partitions" } fixedSizePartitionsFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" fixed_size_file="$imagePath/d${disk_number}.fixed_size_partitions" } hasGrubFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 local sgdisk="$3" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" hasgrubfilename="$imagePath/d${disk_number}.has_grub" [[ -n $sgdisk ]] && hasgrubfilename="$imagePath/d${disk_number}.grub.mbr" } MBRFileName() { local imagePath="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 local varVar="$3" local sgdisk="$4" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $varVar ]] && handleError "No variable to set passed (${FUNCNAME[0]})\n Args Passed: $*" local mbr="" local hasGRUB=0 hasGRUB "$disk_number" "$imagePath" "$sgdisk" [[ -n $sgdisk && $hasGRUB -eq 1 ]] && mbr="$imagePath/d${disk_number}.grub.mbr" || mbr="$imagePath/d${disk_number}.mbr" case $type in down) [[ ! -f $mbr && -n $mbrfile ]] && mbr="$mbrfile" printf -v "$varVar" "$mbr" [[ -z $mbr ]] && handleError "Image store corrupt, unable to locate MBR, no default file specified (${FUNCNAME[0]})\n Args Passed: $*\n $varVar Variable set to: ${!varVar}" [[ ! -f $mbr ]] && handleError "Image store corrupt, unable to locate MBR, no file found (${FUNCNAME[0]})\n Args Passed: $*\n Variable set to: ${!varVar}\n $varVar Variable set to: ${!varVar}" ;; up) printf -v "$varVar" "$mbr" ;; esac } EBRFileName() { local path="$1" # e.g. /net/dev/foo local disk_number="$2" # e.g. 1 local part_number="$3" # e.g. 5 [[ -z $path ]] && handleError "No path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $part_number ]] && handleError "No partition number passed (${FUNCNAME[0]})\n Args Passed: $*" ebrfilename="$path/d${disk_number}p${part_number}.ebr" } tmpEBRFileName() { local disk_number="$1" local part_number="$2" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $part_number ]] && handleError "No partition number passed (${FUNCNAME[0]})\n Args Passed: $*" local ebrfilename="" EBRFileName "/tmp" "$disk_number" "$disk_number" tmpebrfilename="$ebrfilename" } # # Works for MBR/DOS or GPT style partition tables # Only saves PT information if the type is "all" or "mbr" # # For MBR/DOS style PT # Saves the MBR as everything before the start of the first partition (512+ bytes) # This includes the DOS MBR or GRUB. Don't know about other bootloaders # This includes the 4 primary partitions # The EBR of extended and logical partitions is actually the first 512 bytes of # the partition, so we don't need to save/restore them here. # # savePartitionTablesAndBootLoaders() { local disk="$1" # e.g. /dev/sda local disk_number="$2" # e.g. 1 local imagePath="$3" # e.g. /net/dev/foo local osid="$4" # e.g. 50 local imgPartitionType="$5" local sfdiskfilename="$6" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $osid ]] && handleError "No osid passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imgPartitionType ]] && handleError "No img part type passed (${FUNCNAME[0]})\n Args Passed: $*" if [[ -z $sfdiskfilename ]]; then sfdiskPartitionFileName "$imagePath" "$disk_number" sfdiskfilename="$sfdiskoriginalpartitionfilename" fi local hasgpt=0 hasGPT "$disk" local have_extended_partition=0 # e.g. 0 or 1-n (extended partition count) local strdots="" [[ $hasgpt -eq 0 ]] && have_extended_partition=$(sfdisk -l $disk 2>/dev/null | egrep "^${disk}.* (Extended|W95 Ext'd \(LBA\))$" | wc -l) runPartprobe "$disk" case $hasgpt in 0) strdots="Saving Partition Tables (MBR)" case $osid in 4|50|51) [[ $disk_number -eq 1 ]] && strdots="Saving Partition Tables and GRUB (MBR)" ;; esac dots "$strdots" saveGRUB "$disk" "$disk_number" "$imagePath" sfdisk -d $disk 2>/dev/null > $sfdiskfilename [[ $have_extended_partition -ge 1 ]] && saveAllEBRs "$disk" "$disk_number" "$imagePath" echo "Done" ;; 1) dots "Saving Partition Tables (GPT)" saveGRUB "$disk" "$disk_number" "$imagePath" "true" sgdisk -b "$imagePath/d${disk_number}.mbr" $disk >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then echo "Failed" debugPause handleError "Error trying to save GPT partition tables (${FUNCNAME[0]})\n Args Passed: $*" fi sfdisk -d $disk 2>/dev/null > $sfdiskfilename echo "Done" ;; esac runPartprobe "$disk" debugPause } clearPartitionTables() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ $nombr -eq 1 ]] && return dots "Erasing current MBR/GPT Tables" sgdisk -Z $disk >/dev/null 2>&1 case $? in 0) echo "Done" ;; 2) echo "Done, but cleared corrupted partition." ;; *) echo "Failed" debugPause handleError "Error trying to erase partition tables (${FUNCNAME[0]})\n Args Passed: $*" ;; esac runPartprobe "$disk" debugPause } # Restores the partition tables and boot loaders # # $1 is the disk # $2 is the disk number # $3 is the image path # $4 is the osid # $5 is the image partition type restorePartitionTablesAndBootLoaders() { local disk="$1" local disk_number="$2" local imagePath="$3" local osid="$4" local imgPartitionType="$5" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $osid ]] && handleError "No osid passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imgPartitionType ]] && handleError "No image part type passed (${FUNCNAME[0]})\n Args Passed: $*" local tmpMBR="" local strdots="" if [[ $nombr -eq 1 ]]; then echo " * Skipping partition tables and MBR" debugPause return fi clearPartitionTables "$disk" majorDebugEcho "Partition table should be empty now." majorDebugShowCurrentPartitionTable "$disk" "$disk_number" majorDebugPause MBRFileName "$imagePath" "$disk_number" "tmpMBR" [[ ! -f $tmpMBR ]] && handleError "Image Store Corrupt: Unable to locate MBR (${FUNCNAME[0]})\n Args Passed: $*" local table_type="" getDesiredPartitionTableType "$imagePath" "$disk_number" majorDebugEcho "Trying to restore to $table_type partition table." if [[ $table_type == GPT ]]; then dots "Restoring Partition Tables (GPT)" restoreGRUB "$disk" "$disk_number" "$imagePath" "true" sgdisk -gel $tmpMBR $disk >/dev/null 2>&1 [[ ! $? -eq 0 ]] && handleError "Error trying to restore GPT partition tables (${FUNCNAME[0]})\n Args Passed: $*" global_gptcheck="yes" echo "Done" else case $osid in 50|51) strdots="Restoring Partition Tables and GRUB (MBR)" ;; *) strdots="Restoring Partition Tables (MBR)" ;; esac dots "$strdots" restoreGRUB "$disk" "$disk_number" "$imagePath" echo "Done" debugPause majorDebugShowCurrentPartitionTable "$disk" "$disk_number" majorDebugPause ebrcount=$(ls -1 $imagePath/*.ebr 2>/dev/null | wc -l) [[ $ebrcount -gt 0 ]] && restoreAllEBRs "$disk" "$disk_number" "$imagePath" "$imgPartitionType" local sfdiskoriginalpartitionfilename="" local sfdisklegacyoriginalpartitionfilename="" sfdiskPartitionFileName "$imagePath" "$disk_number" sfdiskLegacyOriginalPartitionFileName "$imagePath" "$disk_number" if [[ -r $sfdiskoriginalpartitionfilename ]]; then dots "Inserting Extended partitions" sfdisk $disk < $sfdiskoriginalpartitionfilename >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" ;; esac elif [[ -e $sfdisklegacyoriginalpartitionfilename ]]; then dots "Extended partitions (legacy)" sfdisk $disk < $sfdisklegacyoriginalpartitionfilename >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" ;; esac else echo " * No extended partitions" fi fi debugPause runPartprobe "$disk" majorDebugShowCurrentPartitionTable "$disk" "$disk_number" majorDebugPause } savePartition() { local part="$1" local disk_number="$2" local imagePath="$3" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No drive number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" local part_number=0 getPartitionNumber "$part" local fstype="" local parttype="" local imgpart="" local fifoname="/tmp/pigz1" if [[ $imgPartitionType != all && $imgPartitionType != $part_number ]]; then echo " * Skipping partition $part ($part_number)" debugPause return fi echo " * Processing Partition: $part ($part_number)" debugPause fsTypeSetting "$part" getPartType "$part" local ebrfilename="" local swapuuidfilename="" case $fstype in swap) echo " * Saving swap partition UUID" swapUUIDFileName "$imagePath" "$disk_number" saveSwapUUID "$swapuuidfilename" "$part" ;; *) case $parttype in 0x5|0xf) echo " * Not capturing content of extended partition" debugPause EBRFileName "$imagePath" "$disk_number" "$part_number" touch "$ebrfilename" ;; *) echo " * Using partclone.$fstype" debugPause imgpart="$imagePath/d${disk_number}p${part_number}.img" uploadFormat "$fifoname" "$imgpart" partclone.$fstype -fsck-src-part -c -s $part -O $fifoname -N -f 1 case $? in 0) mv ${imgpart}.000 $imgpart >/dev/null 2>&1 echo " * Image Captured" ;; *) handleError "Failed to complete capture (${FUNCNAME[0]})\n Args Passed: $*" ;; esac ;; esac ;; esac rm -rf $fifoname >/dev/null 2>&1 debugPause } restorePartition() { local part="$1" local disk_number="$2" local imagePath="$3" local mc="$4" [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" if [[ $imgPartitionType != all && $imgPartitionType != $part_number ]]; then echo " * Skipping partition: $part ($part_number)" debugPause return fi local imgpart="" local ebrfilename="" local disk="" local part_number=0 getDiskFromPartition "$part" getPartitionNumber "$part" echo " * Processing Partition: $part ($part_number)" debugPause case $imgType in dd) imgpart="$imagePath" ;; n|mps|mpa) case $osid in [1-2]) [[ -f $imagePath ]] && imgpart="$imagePath" || imgpart="$imagePath/d${disk_number}p${part_number}.img*" ;; 4|8|50|51) imgpart="$imagePath/d${disk_number}p${part_number}.img*" ;; [5-7]|9) [[ ! -f $imagePath/sys.img.000 ]] && imgpart="$imagePath/d${disk_number}p${part_number}.img*" if [[ -z $imgpart ]] ;then case $win7partcnt in 1) imgpart="$imagePath/sys.img.*" ;; 2) case $part_number in 1) imgpart="$imagePath/rec.img.000" ;; 2) imgpart="$imagePath/sys.img.*" ;; esac ;; 3) case $part_number in 1) imgpart="$imagePath/rec.img.000" ;; 2) imgpart="$imagePath/rec.img.001" ;; 3) imgpart="$imagePath/sys.img.*" ;; esac ;; esac fi ;; esac ;; *) handleError "Invalid Image Type $imgType (${FUNCNAME[0]})\n Args Passed: $*" ;; esac ls $imgpart >/dev/null 2>&1 if [[ ! $? -eq 0 ]]; then EBRFileName "$imagePath" "$disk_number" "$part_number" [[ -e $ebrfilename ]] && echo " * Not deploying content of extended partition" || echo " * Partition File Missing: $imgpart" runPartprobe "$disk" return fi writeImage "$imgpart" "$part" "$mc" runPartprobe "$disk" resetFlag "$part" } runFixparts() { local disk="$1" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" dots "Attempting fixparts" fixparts $disk /dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" debugPause handleError "Could not fix partition layout (${FUNCNAME[0]})\n Args Passed: $*" "yes" ;; esac debugPause runPartprobe "$disk" } killStatusReporter() { dots "Stopping FOG Status Reporter" kill -9 $statusReporter >/dev/null 2>&1 case $? in 0) echo "Done" ;; *) echo "Failed" ;; esac debugPause } prepareResizeDownloadPartitions() { local disk="$1" local disk_number="$2" local imagePath="$3" local osid="$4" local imgPartitionType="$5" [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $osid ]] && handleError "No osid passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imgPartitionType ]] && handleError "No image partition type passed (${FUNCNAME[0]})\n Args Passed: $*" if [[ $nombr -eq 1 ]]; then echo -e " * Skipping partition preperation\n" debugPause return fi restorePartitionTablesAndBootLoaders "$disk" "$disk_number" "$imagePath" "$osid" "$imgPartitionType" local do_fill=0 fillDiskWithPartitionsIsOK "$disk" "$imagePath" "$disk_number" majorDebugEcho "Filling disk = $do_fill" dots "Attempting to expand/fill partitions" if [[ $do_fill -eq 0 ]]; then echo "Failed" debugPause handleError "Fatal Error: Could not resize partitions (${FUNCNAME[0]})\n Args Passed: $*" fi fillDiskWithPartitions "$disk" "$imagePath" "$disk_number" echo "Done" debugPause runPartprobe "$disk" } # $1 is the disks # $2 is the image path # $3 is the image partition type (either all or partition number) # $4 is the flag to say whether this is multicast or not performRestore() { local disks="$1" local disk="" local imagePath="$2" local imgPartitionType="$3" local mc="$4" [[ -z $disks ]] && handleError "No disks passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*" [[ -z $imgPartitionType ]] && handleError "No partition type passed (${FUNCNAME[0]})\n Args Passed: $*" local disk_number=1 local part_number=0 local restoreparts="" local mainuuidfilename="" [[ $imgType =~ [Nn] ]] && local tmpebrfilename="" for disk in $disks; do mainuuidfilename="" mainUUIDFileName "$imagePath" "$disk_number" getValidRestorePartitions "$disk" "$disk_number" "$imagePath" "$restoreparts" [[ -z $restoreparts ]] && handleError "No image file(s) found that would match the partition(s) to be restored (${FUNCNAME[0]})\n Args Passed: $*" for restorepart in $restoreparts; do getPartitionNumber "$restorepart" [[ $imgType =~ [Nn] ]] && tmpEBRFileName "$disk_number" "$part_number" restorePartition "$restorepart" "$disk_number" "$imagePath" "$mc" [[ $imgType =~ [Nn] ]] && restoreEBR "$restorepart" "$tmpebrfilename" [[ $imgType =~ [Nn] ]] && expandPartition "$restorepart" "$fixed_size_partitions" [[ $osid == +([5-7]) && $imgType =~ [Nn] ]] && fixWin7boot "$restorepart" done restoreparts="" echo " * Resetting UUIDs for $disk" debugPause restoreUUIDInformation "$disk" "$mainuuidfilename" echo " * Resettings swap systems" debugPause makeAllSwapSystems "$disk" "$disk_number" "$imagePath" "$imgPartitionType" let disk_number+=1 done }