summaryrefslogtreecommitdiff
path: root/draft/other-tools/fog
diff options
context:
space:
mode:
Diffstat (limited to 'draft/other-tools/fog')
-rw-r--r--draft/other-tools/fog/fog-notes.txt148
-rwxr-xr-xdraft/other-tools/fog/fog.download261
-rwxr-xr-xdraft/other-tools/fog/fog.upload216
-rw-r--r--draft/other-tools/fog/funcs.sh2196
-rw-r--r--draft/other-tools/fog/partition-funcs.sh811
-rw-r--r--draft/other-tools/fog/procsfdisk.awk361
6 files changed, 3993 insertions, 0 deletions
diff --git a/draft/other-tools/fog/fog-notes.txt b/draft/other-tools/fog/fog-notes.txt
new file mode 100644
index 0000000..61a7d12
--- /dev/null
+++ b/draft/other-tools/fog/fog-notes.txt
@@ -0,0 +1,148 @@
+
+
+./src/buildroot/package/fog/scripts/usr/share/fog/lib/funcs.sh
+
+
+ pigz $PIGZ_COMP < $fifo | split -a 3 -d -b 200m - ${file}. &
+
+
+ mainuuidfilename="$imagePath/d${disk_number}.original.uuids"
+ swapuuidfilename="$imagePath/d${disk_number}.original.swapuuids"
+ sfdiskoriginalpartitionfilename="$imagePath/d${disk_number}.partitions"
+ sfdisklegacyoriginalpartitionfilename="$imagePath/d${disk_number}.original.partitions"
+ sfdiskminimumpartitionfilename="$imagePath/d${disk_number}.minimum.partitions"
+ sgdiskoriginalpartitionfilename="$imagePath/d${disk_number}.sgdisk.original.partitions"
+ fixed_size_file="$imagePath/d${disk_number}.fixed_size_partitions"
+ hasgrubfilename="$imagePath/d${disk_number}.has_grub"
+ [[ -n $sgdisk ]] && hasgrubfilename="$imagePath/d${disk_number}.grub.mbr"
+ [[ -n $sgdisk && $hasGRUB -eq 1 ]] && \
+ mbr="$imagePath/d${disk_number}.grub.mbr" || \
+ mbr="$imagePath/d${disk_number}.mbr"
+ ebrfilename="$path/d${disk_number}p${part_number}.ebr"
+
+# 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.
+
+# $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() {
+
+
+ # 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')
+
+ # 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
+
+}
+
+
+
+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"
+}
+
+savePartitionTablesAndBootLoaders() {
+
+ 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
+}o
+
+clearPartitionTables() {
+ sgdisk -Z $disk >/dev/null 2>&1
+}
+
+restorePartitionTablesAndBootLoaders() {
+ 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
+ [big cheat for MBR, dd, sfdisk for EBRs]
+ fi
+}
+
+
+savePartition() {
+ 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
+
diff --git a/draft/other-tools/fog/fog.download b/draft/other-tools/fog/fog.download
new file mode 100755
index 0000000..7190ebb
--- /dev/null
+++ b/draft/other-tools/fog/fog.download
@@ -0,0 +1,261 @@
+#!/bin/bash
+. /usr/share/fog/lib/funcs.sh
+. /bin/fog.donate
+. /bin/fog.checkin
+. /bin/fog.mount
+. /bin/fog.checkmount
+. /bin/fog.checkimgvar
+hd=""
+disks=""
+disk=""
+parts=""
+part=""
+imagePath="/images/$img"
+origmac=$mac
+mac=$(getMACAddresses | base64)
+. /bin/fog.inventory "true"
+mac="$origmac"
+origmac=""
+layPartSize="-1s"
+fog.statusreporter "$mac" "$web" & disown
+statusReporter="$!"
+fixed_size_partitions=""
+echo " * Using Image: $img"
+preparePartitions() {
+ echo " * Preparing Partition layout"
+ case $imgType in
+ [Nn])
+ case $osid in
+ 4|50|51)
+ [[ ! -d $imagePath ]] && handleError "Unable to locate image store ($0)\n Args Passed: $*"
+ prepareResizeDownloadPartitions "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ ;;
+ [1-2])
+ [[ ! -f $imagePath && ! -f $imagePath/$img && ! -d $imagePath ]] && handleError "Unable to locate image store ($0)\n Args Passed: $*"
+ [[ -d $imagePath && -f $imagePath/$img ]] && imagePath="$imagePath/$img"
+ if [[ -d $imagePath ]]; then
+ prepareResizeDownloadPartitions "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ else
+ startsector="63s"
+ restorePartitionTablesAndBootLoaders "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ dots "Removing partition"
+ parted -s $hd rm 1 >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not remove old partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ echo " * Attempting to expand/fill partitions"
+ dots "Recreating partition"
+ parted -s $hd mkpart primary ntfs 63s -- $layPartSize >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Could not create partition to fill disk ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Setting boot partition"
+ parted -s $hd set 1 boot on >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not make partition bootable ($0)\n Args Passed: $*"
+ fi
+ runPartprobe "$hd"
+ echo "Done"
+ debugPause
+ getPartitions "$hd"
+ for part in $parts; do
+ [[ -e $part ]] && break
+ done
+ fi
+ ;;
+ [5-7]|9)
+ [[ ! -d $imagePath && ! -f $imagePath/sys.img.000 ]] && handleError "Unable to locate image store ($0)\n Args Passed: $*"
+ if [[ ! -f $imagePath/sys.img.000 ]]; then
+ prepareResizeDownloadPartitions "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ else
+ echo " * Using legacy style partition setup"
+ win7partcnt=1
+ dots "Windows Boot Partition Exists"
+ if [[ ! -f $imagePath/gpt.bak && ! -f $imagePath/rec1.img.000 && ! -f $imagePath/rec.img.000 ]]; then
+ echo "No"
+ else
+ echo "Yes"
+ [[ -f $imagePath/rec.img.000 ]] && win7partcnt=2
+ [[ -f $imagePath/rec.img.001 || -f $imagePath/gpt.bak ]] && win7partcnt=3
+ fi
+ debugPause
+ echo " * Attempting to expand/fill partitions"
+ do_fill=0
+ fillDiskWithPartitionsIsOK "$hd" "$imagePath" 1
+ case $do_fill in
+ 1)
+ fillDiskWithPartitions "$hd" "$imagePath" 1
+ echo "Done"
+ ;;
+ *)
+ startsector="2048s"
+ restorePartitionTablesAndBootLoaders "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ case $win7partcnt in
+ 1)
+ dots "Removing partition"
+ parted -s $hd rm 1 >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not remove old partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Creating main partition"
+ parted -s $hd mkpart primary ntfs $startsector -- $layPartSize >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not recreate first partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Setting boot partition"
+ parted -s $hd set 1 boot on >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not make partition bootable ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ ;;
+ 2)
+ dots "Removing main partition"
+ parted -s $hd rm 1 >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not remove old main partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Recreating recovery partition"
+ parted -s $hd mkpart primary ntfs $startsector 206847s >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not create recovery partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Recreating main partition"
+ parted -s $hd mkpart primary ntfs $defaultpart2start -- $layPartSize >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not recreate main partition ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Setting boot partition"
+ parted -s $hd set 1 boot on >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not make partition bootable ($0)\nArgsPassed: $*"
+ fi
+ echo "Done"
+ ;;
+ 3)
+ dots "Removing partition data"
+ sgdisk -Z $hd >/dev/null 2>&1
+ sgdisk -gel $imagePath/gpt.bak $hd >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not recreate partitions ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ dots "Recreating sized out partitions"
+ sgdisk -x 3:$(sgdisk -E $hd) $hd >/dev/null 2>&1
+ if [[ ! $? -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "Fatal Error: Could not resize partitions ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ ;;
+ esac
+ ;;
+ esac
+ debugPause
+ runPartprobe "$hd"
+ dots "Setting up partition variables"
+ getPartitions "$hd"
+ restoreparts=""
+ part_number=0
+ for part in $parts; do
+ getPartitionNumber "$part"
+ [[ $part_number -le $win7partcnt ]] && restoreparts="$restoreparts $part"
+ done
+ echo "Done"
+ debugPause
+ fi
+ ;;
+ esac
+ ;;
+ mps)
+ [[ ! -d $imagePath ]] && handleError "Unable to locate image store ($0)\n Args Passed: $*"
+ restorePartitionTablesAndBootLoaders "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ runPartprobe "$hd"
+ gptcheck="$global_gptcheck"
+ ;;
+ mpa)
+ [[ ! -d $imagePath ]] && handleError "Unable to locate image store ($0)\n Args Passed: $*"
+ getHardDisk "true"
+ disk_number=1
+ for disk in $disks; do
+ restorePartitionTablesAndBootLoaders "$disk" "$disk_number" "$imagePath" "$osid" "$imgPartitionType"
+ runPartprobe "$disk"
+ gptcheck="$global_gptcheck"
+ let disk_number+=1
+ done
+ ;;
+ esac
+}
+putDataBack() {
+ runPartprobe "$hd"
+ getPartitions "$hd"
+ [[ -z $parts ]] && echo -e " * Seems like you are trying to restore to an empty disk. Be aware this will most probably cause trouble.\n"
+ echo " +--------------------------------+"
+ echo " | Attempting to deploy image |"
+ echo " +--------------------------------+"
+ [[ $imgFormat -eq 1 || $imgLegacy -eq 1 ]] && echo " | Using Partimage |" || echo " | Using Partclone |"
+ echo " +--------------------------------+"
+ [[ $mc == yes ]] && usleep 10000000 || usleep 3000000
+ case $imgType in
+ dd)
+ restorePartition "$hd" 1 "$imagePath/$img.*" "$mc"
+ ;;
+ n|mps|mpa)
+ [[ $imgType == +(n|mps) ]] && disks="$hd"
+ case $osid in
+ [1-2])
+ [[ ! -f $imagePath && ! -d $imagePath ]] && handleError "Fatal Error: Could not locate file ($0)\n Args Passed: $*"
+ ;;
+ [5-7]|9)
+ [[ ! -d $imagePath && ! -f $imagePath/sys.img.000 ]] && handleError "Fatal Error: Could not locate file ($0)\n Args Passed: $*"
+ ;;
+ 4|50|51)
+ [[ ! -d $imagePath ]] && handleError "Fatal Error: could not locate file ($0)\n Args Passed: $*"
+ ;;
+ esac
+ performRestore "$disks" "$imagePath" "$imgPartitionType" "$mc"
+ ;;
+ esac
+}
+findHDDInfo
+[[ $nombr -eq 1 ]] && echo " * Skipping partition layout (Single Partition restore)" || preparePartitions
+[[ $imgPartitionType != mbr ]] && putDataBack || echo " * Skipping partition restore (MBR Only)"
+completeTasking
diff --git a/draft/other-tools/fog/fog.upload b/draft/other-tools/fog/fog.upload
new file mode 100755
index 0000000..8a80ae8
--- /dev/null
+++ b/draft/other-tools/fog/fog.upload
@@ -0,0 +1,216 @@
+#!/bin/bash
+. /usr/share/fog/lib/funcs.sh
+. /bin/fog.checkin
+. /bin/fog.mount
+. /bin/fog.checkmount
+. /bin/fog.checkimgvar
+imagePath="/images/$macWinSafe"
+parts=""
+part=""
+disks=""
+disk=""
+hd=""
+echo " * Preparing to send image file to server"
+percent="$pct"
+[[ $pct -lt 5 || $pct -ge 100 ]] && percent=5
+[[ $pct -lt 10 ]] && percent="0$pct"
+fog.statusreporter "$mac" "$web" & disown
+statusReporter="$!"
+prepareUploadLocation "$imagePath"
+echo " * Using Image: $img"
+# resizable image type
+# discover windows partitions
+# remove pagefile and hibernate file
+# validate XP partition location
+# save original partition table
+# save MBR
+# shrink filesystems and partitions
+# save GRUB
+# save shrunken partition table
+# clone filesystems
+# restore original MBR and partition table
+# expand filesystems
+beginUpload() {
+ case $imgType in
+ [Nn])
+ validResizeOS
+ runPartprobe "$hd"
+ getPartitions "$hd"
+ [[ $osid == @([1-2]|[4-7]|9) ]] && win7partcnt=$(echo $parts | wc -w)
+ dots "Checking for fixed partitions"
+ part_number=0
+ for part in $parts; do
+ fsTypeSetting "$part"
+ getPartitionNumber "$part"
+ case $fstype in
+ ntfs|extfs)
+ continue
+ ;;
+ *)
+ fixed_size_partitions="$fixed_size_partitions:$part_number"
+ ;;
+ esac
+ done
+ echo "Done"
+ debugPause
+ dots "Getting Windows/Linux Partition Count"
+ countPartTypes "$hd" "ntfs" "ntfscnt"
+ countPartTypes "$hd" "extfs" "extfscnt"
+ if [[ $ntfscnt -eq 0 && $extfscnt -eq 0 ]]; then
+ echo "Failed"
+ debugPause
+ handleError "No resizable partitions found ($0)\n Args Passed: $*"
+ fi
+ echo "Done"
+ debugPause
+ echo " * NTFS Partition count of: $ntfscnt"
+ debugPause
+ echo " * EXTFS Partition count of: $extfscnt"
+ debugPause
+ case $osid in
+ [4-7]|9|50|51)
+ echo " * Setting up any additional fixed parts"
+ [[ $((ntfscnt + extfscnt)) -gt 0 && $part_number -gt 1 ]] && fixed_size_partitions="$fixed_size_partitions:1"
+ part_number=0
+ for part in $parts; do
+ getPartitionNumber "$part"
+ fsTypeSetting "$part"
+ [[ $fstype != ntfs ]] && continue
+ dots "Mounting partition ($part)"
+ if [[ ! -d /bcdstore ]]; then
+ mkdir -p /bcdstore >/dev/null 2>&1
+ case $? in
+ 0)
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError " * Could not create mount location ($0->${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 ($0->${FUNCNAME[0]})\n Args Passed: $*\n Reason: $(cat /tmp/ntfs-mount-output)"
+ ;;
+ esac
+ dots "BCD exists on $part in /bcdstore"
+ if [[ ! -f /bcdstore/Boot/BCD ]]; then
+ umount /bcdstore >/dev/null 2>&1
+ echo "No"
+ debugPause
+ else
+ umount /bcdstore >/dev/null 2>&1
+ echo "Yes"
+ debugPause
+ if [[ $part_number -gt 1 ]]; then
+ for ((increment=1; increment < $part_number; increment++)); do
+ fixed_size_partitions="$fixed_size_partitions:$increment"
+ done
+ fi
+ fi
+ done
+ ;;
+ esac
+ # All:
+ # save the list of fixed size partitions
+ fixed_size_partitions=$(echo $fixed_size_partitions | tr ':' '\n' | uniq | tr '\n' ':' | sed 's/:$//g')
+ echo "$fixed_size_partitions" > "$imagePath/d1.fixed_size_partitions"
+ # Windows 2000/XP, Vista, 7, 8, 8.1, Linux:
+ # Save unmodified partition table for download use
+ # Start filesytem type record
+ dots "Saving original partition table"
+ saveOriginalPartitions "$hd" "$imagePath" 1
+ swapuuidfilename=""
+ swapUUIDFileName "$imagePath" 1
+ mainuuidfilename=""
+ mainUUIDFileName "$imagePath" 1
+ echo -n "" > "$imagePath/d1.original.fstypes"
+ echo -n "" > $swapuuidfilename
+ echo "Done"
+ debugPause
+ echo " * Saving original disk/parts UUIDs"
+ debugPause
+ saveUUIDInformation "$hd" "$mainuuidfilename"
+ echo " * Shrinking Partitions on disk"
+ debugPause
+ for part in $parts; do
+ clearMountedDevices "$part"
+ removePageFile "$part"
+ shrinkPartition "$part" "$imagePath/d1.original.fstypes" "$fixed_size_partitions"
+ done
+ echo " * Saving shrunken partition table"
+ debugPause
+ sfdiskminimumpartitionfilename=""
+ sfdiskMinimumPartitionFileName "$imagePath" 1
+ savePartitionTablesAndBootLoaders "$hd" 1 "$imagePath" "$osid" "$imgPartitionType" "$sfdiskminimumpartitionfilename"
+ echo " * Processing Hard Disk: $hd"
+ for part in $parts; do
+ savePartition "$part" 1 "$imagePath" "$imgPartitionType"
+ done
+ dots "Restoring Original Partition Layout"
+ restoreOriginalPartitions "$hd" "$imagePath" 1
+ runPartprobe "$hd"
+ echo "Done"
+ debugPause
+ [[ $osid -eq 2 ]] && correctVistaMBR "$hd"
+ getPartitions "$hd"
+ for part in $parts; do
+ expandPartition "$part" "$fixed_size_partitions"
+ done
+ ;;
+ mps)
+ echo " * Processing Hard Disk: $hd"
+ echo " * Saving original disk/parts UUIDs"
+ debugPause
+ mainuuidfilename=""
+ mainUUIDFileName "$imagePath" 1
+ saveUUIDInformation "$hd" "$mainuuidfilename"
+ savePartitionTablesAndBootLoaders "$hd" 1 "$imagePath" "$osid" "$imgPartitionType"
+ getPartitions "$hd"
+ for part in $parts; do
+ savePartition "$part" 1 "$imagePath" "$imgPartitionType"
+ done
+ ;;
+ mpa)
+ disk_number=1
+ for disk in $disks; do
+ debugPause
+ echo " * Processing Hard Disk: $disk"
+ echo " * Saving original disk/parts UUIDs"
+ debugPause
+ mainuuidfilename=""
+ mainUUIDFileName "$imagePath" $disk_number
+ saveUUIDInformation "$disk" "$mainuuidfilename"
+ savePartitionTablesAndBootLoaders "$disk" "$disk_number" "$imagePath" "$osid" "$imgPartitionType"
+ runPartprobe "$disk"
+ getPartitions "$disk"
+ for part in $parts; do
+ savePartition "$part" "$disk_number" "$imagePath" "$imgPartitionType"
+ done
+ echo " * Disk $disk complete"
+ let disk_number+=1
+ done
+ ;;
+ dd)
+ imgpart="$imagePath/$img"
+ mkfifo /tmp/pigz1 >/dev/null 2>&1
+ uploadFormat "/tmp/pigz1" "$imgpart"
+ partclone.imager -c -s "$hd" -O /tmp/pigz1 -N -f 1
+ rm /tmp/pigz1 >/dev/null 2>&1
+ clearScreen
+ ;;
+ esac
+}
+findHDDInfo
+echo " * Now FOG will attempt to capture the image using Partclone"
+debugPause
+beginUpload
+completeTasking
diff --git a/draft/other-tools/fog/funcs.sh b/draft/other-tools/fog/funcs.sh
new file mode 100644
index 0000000..e6f574c
--- /dev/null
+++ b/draft/other-tools/fog/funcs.sh
@@ -0,0 +1,2196 @@
+#!/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 </usr/share/fog/lib/EOFNTFSRESTORE >/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 </usr/share/fog/lib/EOFNTFSRESTORE >/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/pigz1 | partimage restore $target stdin -f3 -b 2>/tmp/status.fog
+ else
+ echo " * Imaging using Partclone"
+ pigz -d -c </tmp/pigz1 | partclone.restore --ignore_crc -O $target -N -f 1
+ fi
+ [[ ! $? -eq 0 ]] && handleError "Image failed to restore and exited with exit code $? (${FUNCNAME[0]})\n Args Passed: $*"
+ rm -rf /tmp/pigz1 >/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 </usr/share/fog/lib/EOFMOUNT >/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 </usr/share/fog/lib/EOFFIXPARTS >/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
+}
diff --git a/draft/other-tools/fog/partition-funcs.sh b/draft/other-tools/fog/partition-funcs.sh
new file mode 100644
index 0000000..8d77ec5
--- /dev/null
+++ b/draft/other-tools/fog/partition-funcs.sh
@@ -0,0 +1,811 @@
+#!/bin/bash
+#
+# These functions are for dealing with resizing of partitions.
+# They currently work for MBR and Extended partition tables.
+# THE DO NOT WORK FOR GPT.
+# It is assumed that at most 1 extended partition will exist,
+# with any number of logical partitions.
+# Requires the sfdisk tool.
+# Assumes that sfdisk's "unit: sectors" means 512 byte sectors.
+#
+# $1 is the name of the disk drive
+# $2 is name of file to save to.
+saveSfdiskPartitions() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to save to (${FUNCNAME[0]})\n Args Passed: $*"
+ sfdisk -d $disk 2>/dev/null > $file
+ [[ ! $? -eq 0 ]] && majorDebugEcho "sfdisk failed in (${FUNCNAME[0]})"
+}
+# $1 is the name of the disk drive
+# $2 is name of file to save to.
+saveUUIDInformation() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to save to passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local hasgpt=0
+ hasGPT "$disk"
+ [[ $hasgpt -eq 0 ]] && return
+ rm -f $file
+ touch $file
+ local diskuuid=""
+ local partuuid=""
+ local partfsuuid=""
+ local parts=""
+ local part=""
+ local part_number=""
+ local strtoadd=""
+ local is_swap=0
+ getDiskUUID "$disk"
+ echo "$disk $diskuuid" >> $file
+ getPartitions "$disk"
+ for part in $parts; do
+ getPartitionNumber "$part"
+ partitionIsSwap "$part"
+ [[ $is_swap -gt 0 ]] && continue
+ getPartUUID "$part"
+ getPartFSUUID "$part"
+ [[ -n $partfsuuid ]] && strtoadd="$part $part_number:$partfsuuid"
+ [[ -n $partuuid ]] && strtoadd="$strtoadd $part_number:$partuuid"
+ echo "$strtoadd" >> $file
+ strtoadd=""
+ done
+}
+# $1 is the name of the disk drive
+# $2 is name of file to restore from
+restoreUUIDInformation() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to load from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ ! -r $file ]] && return
+ local diskuuid=""
+ local partuuid=""
+ local escape_disk=$(escapeItem $disk)
+ local escape_part=""
+ local is_swap=0
+ diskuuid=$(awk "/^$escape_disk\ /{print \$2}" $file)
+ [[ -n $diskuuid ]] && sgdisk -U $diskuuid $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to set disk guid (sgdisk -U) (${FUNCNAME[0]})\n Args Passed: $*"
+ getPartitions "$disk"
+ for part in $parts; do
+ partitionIsSwap "$part"
+ [[ $is_swap -gt 0 ]] && continue
+ escape_part=$(escapeItem $part)
+ local oIFS=$IFS
+ local IFS=$'\n'
+ read partuuid parttype <<< $(awk "/^$escape_part\ /{printf(\"%s\n%s\",\$2,\$3)}" $file)
+ IFS=$oIFS
+ [[ -n $parttype ]] && sgdisk -t $parttype $disk >/dev/null 2>&1 || true
+ [[ ! $? -eq 0 ]] && handleError " Failed to set partition type (sgdisk -t) (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -n $partuuid ]] && sgdisk -u $partuuid $disk >/dev/null 2>&1 || true
+ [[ ! $? -eq 0 ]] && handleError "Failed to set partition guid (sgdisk -u) (${FUNCNAME[0]})\n Args Passed: $*"
+ done
+}
+# $1 is the name of the disk drive
+# $2 is name of file to load from.
+applySfdiskPartitions() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to receive from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ sfdisk $disk < $file >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && majorDebugEcho "sfdisk failed in (${FUNCNAME[0]})"
+}
+# $1 is the name of the disk drive
+# $2 is the name of file to load from.
+applySgdiskPartitions() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to receive from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local escape_disk=$(escapeItem $disk)
+ local diskguid=$(awk -F: "/^$escape_disk:/{print \$3}" $file)
+ sgdisk -Z $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partitions (sgdisk -Z) (${FUNCNAME[0]})\n Args Passed: $*"
+ sgdisk -U $diskguid $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partitions (sgdisk -U) (${FUNCNAME[0]})\n Args Passed: $*"
+ local parts=""
+ local part=""
+ local part_number=""
+ local escape_part=""
+ local partstart=""
+ local partend=""
+ local parttype=""
+ local partcode=""
+ local partname=""
+ local awk_part_vars=""
+ getPartitions "$disk"
+ for part in $parts; do
+ escape_part=$(escapeItem $part)
+ getParititionNumber "$part"
+ awk_part_vars=$(awk -F: "/^$escape_part:/{printf(\"%d %d %d %d\",\$3,\$4,\$5,\$6)}" $file)
+ read partcode partstart partend partname <<< $awk_part_vars
+ parttype=$(awk -F: "/^part:$part_number:/{print \$5}" $file)
+ sgdisk -n $part_number:$partstart:$partend $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partition (sgdisk -n) (${FUNCNAME[0]})\n Args Passed: $*"
+ sgdisk -c $part_number:$partname $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partition (sgdisk -c) (${FUNCNAME[0]})\n Args Passed: $*"
+ sgdisk -t $part_number:$parttype $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partition (sgdisk -t) (${FUNCNAME[0]})\n Args Passed: $*"
+ sgdisk -u $part_number:$partcode $disk >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && handleError "Failed to restore partition (sgdisk -u) (${FUNCNAME[0]})\n Args Passed: $*"
+ done
+}
+# $1 is the name of the disk drive
+# $2 is name of file to load from.
+restoreSfdiskPartitions() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to receive from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ applySfdiskPartitions "$disk" "$file"
+ fdisk $disk < /usr/share/fog/lib/EOFRESTOREPART >/dev/null 2>&1
+ [[ ! $? -eq 0 ]] && majorDebugEcho "fdisk failed in (${FUNCNAME[0]})"
+}
+# $1 is the name of the disk drive
+# $2 is name of file to restore from.
+restoreSgdiskPartitions() {
+ local disk="$1"
+ local file="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to restore from (${FUNCNAME[0]})\n Args Passed: $*"
+ applySgdiskPartitions "$disk" "$file"
+}
+# $1 is the name of the disk drive
+hasExtendedPartition() {
+ local disk="$1"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ sfdisk -d $disk 2>/dev/null | egrep '(Id|type)=\ *[5f]' | wc -l
+ [[ ! $? -eq 0 ]] && majorDebugEcho "sfdisk failed in (${FUNCNAME[0]})"
+}
+# $1 is the name of the partition device (e.g. /dev/sda3)
+partitionHasEBR() {
+ local part="$1"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local part_number=0
+ local disk=""
+ local parttype=""
+ getDiskFromPartition "$part"
+ getPartitionNumber "$part"
+ getPartType "$part"
+ hasEBR=0
+ [[ $part_number -ge 5 ]] && hasEBR=1
+ [[ $parttype == +(0x5|0xf) ]] && hasEBR=1
+}
+# $1 is the name of the partition device (e.g. /dev/sda3)
+# $2 is the name of the file to save to (e.g. /net/dev/foo/d1p4.ebr)
+saveEBR() {
+ local part="$1"
+ local file="$2"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to receive from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local disk=""
+ getDiskFromPartition "$part"
+ local table_type=""
+ getPartitionTableType "$disk"
+ [[ $table_type != MBR ]] && return
+ local hasEBR=0
+ partitionHasEBR "$part"
+ [[ ! $hasEBR -gt 0 ]] && return
+ dots "Saving EBR for ($part)"
+ dd if=$part of=$file bs=512 count=1 >/dev/null 2>&1
+ case $? in
+ 0)
+ echo "Done"
+ debugPause
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError "Could not backup EBR (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+}
+# $1 = DriveName (e.g. /dev/sdb)
+# $2 = DriveNumber (e.g. 1)
+# $3 = ImagePath (e.g. /net/foo)
+saveAllEBRs() {
+ local disk="$1"
+ local disk_number="$2"
+ local imagePath="$3"
+ [[ -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 parts=""
+ local part=""
+ local part_number=0
+ local ebrfilename=""
+ getPartitions "$disk"
+ for part in $parts; do
+ getPartitionNumber "$part"
+ EBRFileName "$imagePath" "$disk_number" "$part_number"
+ saveEBR "$part" "$ebrfilename"
+ done
+}
+# $1 is the name of the partition device (e.g. /dev/sda3)
+# $2 is the name of the file to restore from (e.g. /net/foo/d1p4.ebr)
+restoreEBR() {
+ local part="$1"
+ local file="$2"
+ [[ -z $part ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to restore from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local disk=""
+ local table_type=""
+ getDiskFromPartition "$part"
+ getPartitionTableType "$disk"
+ [[ $table_type != MBR ]] && return
+ local hasEBR=0
+ partitionHasEBR "$part"
+ [[ ! $hasEBR -gt 0 ]] && return
+ [[ ! -e $file ]] && return
+ dots "Restoring EBR for ($part)"
+ dd of=$part if=$file bs=512 count=1 >/dev/null 2>&1
+ case $? in
+ 0)
+ echo "Done"
+ debugPause
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError "Could not reload EBR data (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+}
+# $1 = DriveName (e.g. /dev/sdb)
+# $2 = DriveNumber (e.g. 1)
+# $3 = ImagePath (e.g. /net/foo)
+# $4 = ImagePartitionType (e.g. all, mbr, 1, 2, 3, etc.)
+restoreAllEBRs() {
+ local disk="$1"
+ local disk_number="$2"
+ local imagePath="$3"
+ local imgPartitionType="$4"
+ local ebffilename=""
+ [[ -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 partition type passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local parts=""
+ local part=""
+ local part_number=0
+ local ebrfilename=""
+ getPartitions "$disk"
+ for part in $parts; do
+ getPartitionNumber "$part"
+ [[ $imgPartitionType != all && $imgPartitionType != $part_number ]] && continue
+ EBRFileName "$imagePath" "$disk_number" "$part_number"
+ restoreEBR "$part" "$ebrfilename"
+ done
+ runPartprobe "$disk"
+}
+# $1 is the name of the partition device (e.g. /dev/sda3)
+partitionIsSwap() {
+ local part="$1"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local fstype=""
+ fsTypeSetting "$part"
+ is_swap=0
+ [[ $fstype == swap ]] && is_swap=1
+}
+# $1 is the location of the file to store uuids in
+# $2 is the partition device name
+saveSwapUUID() {
+ local file="$1"
+ local part="$2"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to receive from passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local is_swap=0
+ partitionIsSwap "$part"
+ [[ $is_swap -eq 0 ]] && return
+ local uuid=$(blkid -s UUID $2 | cut -d\" -f2)
+ [[ -z $uuid ]] && return
+ echo " * Saving UUID ($uuid) for ($part)"
+ echo "$part $uuid" >> $file
+}
+# Linux swap partition strategy:
+#
+# Upload:
+#
+# In "n" mode, the empty swapUUIDFileName is created first. Then as each
+# partition is saved, if it is swap then saveSwapUUID is called.
+# In "mps" and "mpa" mode, savePartition is called for each partition.
+# savePartition then calles saveSwapUUID if the partition is swap.
+#
+# When uploading an image, the swapUUIDFileName (e.g. /images/foo/d1.original.swapuuids)
+# is created. For $imgPartitionType == "all", all swap partition UUIDs are saved.
+# For $imgPartitionType == "$partnum", the partition's UUID is saved, if it is a swap partition.
+# For all others, the swapUUIDFileName will not exist, or will be empty.
+#
+#
+# Download:
+#
+# When downloading an image, makeAllSwapSystems will be called.
+# In "n" mode this is done for those images without special configurations,
+# after normal partition restoration.
+# In "mps" mode this is always done
+# In "mpa" mode this is always done, for all disks.
+# makeAllSwapSystems will determine using
+# $imagePartitionType == "all" or == "$partnum" whether to
+# process the swapUUIDFileName contents. For each matching partition,
+# mkswap is used, and the UUID is set appropriately.
+#
+# Relevant functions:
+# swapUUIDFileName ImagePath DriveNumber
+# echos the standardized name for the UUID filename
+# partitionIsSwap PartitionName
+# echos 1 or 0 if fsTypeSetting says partition is or is not a swap partition.
+# makeSwapSystem SwapUUIDFileName PartitionName
+# if it finds partition in UUID file, then calls mkswap
+# makeAllSwapSystems DriveName DriveNumber ImagePath ImagePartitionType
+# checks ImagePartitionType for a match before calling makeSwapSystem
+# saveSwapUUID SwapUUIDFileName PartitionName
+# checks if paritionIsSwap, if so, obtains UUID and saves it
+# saveAllSwapUUIDs DriveName DriveNumber ImagePath
+# checks all partitions if partitionIsSwap, calles saveSwapUUID
+# savePartition:
+# calls saveSwapUUID for swap partitions
+#
+#
+# $1 = DriveName (e.g. /dev/sdb)
+# $2 = DriveNumber (e.g. 1)
+# $3 = ImagePath (e.g. /net/foo)
+saveAllSwapUUIDs() {
+ local disk="$1"
+ local disk_number="$2"
+ local imagePath="$3"
+ [[ -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 swapuuidfilename=""
+ swapUUIDFileName "$imagePath" "$disk_number"
+ local parts=""
+ local part=""
+ local is_swap=0
+ getPartitions "$disk"
+ for part in $parts; do
+ partitionIsSwap "$part"
+ [[ $is_swap -eq 0 ]] && continue
+ saveSwapUUID "$swapuuidfilename" "$part"
+ done
+}
+# $1 is the location of the file uuids are stored in
+# $2 is the partition device name
+makeSwapSystem() {
+ local file="$1"
+ local part="$2"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local uuid=""
+ local option=""
+ local disk=""
+ getDiskFromPartition "$part"
+ local parttype=0
+ local hasgpt=""
+ local escape_part=$(escapeItem $part)
+ hasGPT "$disk"
+ case $hasgpt in
+ 1)
+ uuid=$(awk "/^$escape_part/{print \$2}" $file)
+ [[ -n $uuid ]] && parttype=82
+ ;;
+ 0)
+ parttype=$(sfdisk -d $disk 2>/dev/null | awk -F[,=] "/^$escape_part/{print \$6}")
+ ;;
+ esac
+ [[ ! $parttype -eq 82 ]] && return
+ [[ -n $uuid ]] && option="-U $uuid"
+ dots "Restoring swap partition"
+ mkswap $option $part >/dev/null 2>&1
+ case $? in
+ 0)
+ echo "Done"
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError "Could not create swap on $part (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+ debugPause
+}
+# $1 is the partition device (e.g. /dev/sda1)
+# $2 is the new desired size in 1024 (1k) blocks
+# $3 is the image path (e.g. /net/dev/foo)
+resizeSfdiskPartition() {
+ local part="$1"
+ local size="$2"
+ local imagePath="$3"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $size ]] && handleError "No desired size passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local disk=""
+ getDiskFromPartition "$part"
+ local tmp_file="/tmp/sfdisk.$$"
+ local tmp_file2="/tmp/sfdisk2.$$"
+ saveSfdiskPartitions "$disk" "$tmp_file"
+ processSfdisk "$tmp_file" resize "$part" "$size" > "$tmp_file2"
+ if [[ $ismajordebug -gt 0 ]]; then
+ majorDebugEcho "Trying to fill the disk with these partitions:"
+ cat $tmp_file2
+ majorDebugPause
+ fi
+ applySfdiskPartitions "$disk" "$tmp_file2"
+ local sfdiskminimumpartitionfilename=""
+ sfdiskMinimumPartitionFileName "$imagePath" 1
+ saveSfdiskPartitions "$disk" "$imagePath"
+}
+# $1 is the disk device (e.g. /dev/sda)
+# $2 is the name of the original sfdisk -d output file used as a template
+# $3 is the : separated list of fixed size partitions (e.g. 1:2)
+# swap partitions are automatically added. Empty string is
+# ok.
+fillSfdiskWithPartitions() {
+ local disk="$1"
+ local file="$2"
+ local fixed="$3"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $file ]] && handleError "No file to use passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local disk_size=$(blockdev --getsize64 $disk | awk '{printf("%d\n",$1/1024);}')
+ local tmp_file2="/tmp/sfdisk2.$$"
+ processSfdisk "$file" filldisk "$disk" "$disk_size" "$fixed" > "$tmp_file2"
+ if [[ $ismajordebug -gt 0 ]]; then
+ majorDebugEcho "Trying to fill with the disk with these partititions:"
+ cat $tmp_file2
+ majorDebugPause
+ fi
+ [[ $? -eq 0 ]] && applySfdiskPartitions "$disk" "$tmp_file2"
+ runPartprobe "$disk"
+ rm -f $tmp_file2
+ majorDebugEcho "Applied the preceding table."
+ majorDebugShowCurrentPartitionTable "$disk" 1
+ majorDebugPause
+}
+#
+# processSfdisk() processes the output of sfdisk -d
+# and creates a new sfdisk -d like output, applying
+# the requested action. Read below to see the actions
+#
+# $1 the name of a file that is the output of sfdisk -d
+# $2 is the action "resize|other?"
+# $3 is the first parameter
+# $4 is the second parameter
+# ...
+#
+# actions:
+# processSfdisk foo.sfdisk resize /dev/sda1 100000
+# foo.sfdisk = sfdisk -d output
+# resize = action
+# /dev/sda1 = partition to modify
+# 100000 = 1024 byte blocks size to make it
+# output: new sfdisk -d like output
+#
+# processSfdisk foo.sfdisk move /dev/sda1 100000
+# foo.sfdisk = sfdisk -d output
+# move = action
+# /dev/sda1 = partition to modify
+# 100000 = 1024 byte blocks size to move it to
+# output: new sfdisk -d like output
+#
+# processSfdisk foo.sfdisk filldisk /dev/sda 100000 1:3:6
+# foo.sfdisk = sfdisk -d output
+# filldisk = action
+# /dev/sda = disk to modify
+# 100000 = 1024 byte blocks size of disk
+# 1:3:6 = partition numbers that are fixed in size, : separated
+# output: new sfdisk -d like output
+#
+# example file data
+# /dev/sda1 : start= 2048, size= 204800, Id= 7, bootable
+# /dev/sda2 : start= 206848, size= 50573312, Id= 7
+# /dev/sda3 : start= 50780160, size= 2048, Id=83
+# /dev/sda4 : start= 50784254, size= 16322562, Id= 5
+# /dev/sda5 : start= 50784256, size= 7811072, Id=83
+# /dev/sda6 : start= 58597376, size= 8509440, Id=82
+#
+processSfdisk() {
+ local data="$1"
+ local action="$2"
+ local target="$3"
+ local size="$4"
+ local fixed="$5"
+ [[ -z $data ]] && handleError "No data passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $action ]] && handleError "No action passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $target ]] && handleError "Device (disk or partition) not passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $size ]] && handleError "No desired size passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local minstart=$(awk -F'[ ,]+' '/start/{if ($4) print $4}' $data | sort -n | head -1)
+ local chunksize=""
+ getPartBlockSize "$disk" "chunksize"
+ case $osid in
+ [1-2])
+ [[ -z $minstart ]] && chunksize=512
+ [[ -z $minstart ]] && minstart=63
+ ;;
+ esac
+ local awkArgs="-v CHUNK_SIZE=$chunksize -v MIN_START=$minstart"
+ awkArgs="$awkArgs -v action=$action -v target=$target -v sizePos=$size"
+ [[ -n $fixed ]] && awkArgs="$awkArgs -v fixedList=$fixed"
+ # process with external awk script
+ /usr/share/fog/lib/procsfdisk.awk $awkArgs $data
+}
+#
+# GPT Functions below
+#
+# $1 : device name of drive
+getPartitionTableType() {
+ local disk="$1"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local mbr=$(yes '' | gdisk -l $disk | awk '/^\ *MBR:/{print $2}')
+ local gpt=$(yes '' | gdisk -l $disk | awk '/^\ *GPT:/{print $2}')
+ local type=""
+ local mbrtype=""
+ local gpttype=""
+ case $mbr in
+ present|MBR)
+ mbrtype="MBR"
+ ;;
+ hybrid)
+ mbrtype="HYBRID"
+ ;;
+ protective|not)
+ mbrtype=""
+ ;;
+ esac
+ case $gpt in
+ present|damaged)
+ gpttype="GPT"
+ ;;
+ not)
+ gpttype=""
+ ;;
+ esac
+ [[ -z $gpttype && -z $mbrtype ]] && handleError "Cannot determine partition type (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -n $gpttype && -n $mbrtype ]] && table_type="$gpttype-$mbrtype"
+ [[ -n $gpttype && -z $mbrtype ]] && table_type="$gpttype"
+ [[ -z $gpttype && -n $mbrtype ]] && table_type="$mbrtype"
+}
+#
+# Detect the desired partition table type,
+# using the available files in imagePath, don't rely
+# on the actual disk.
+#
+# Assumes GPT or MBR. Uses first 8 bytes of second block
+# which should hold "EFI PART". (https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_table_header_.28LBA_1.29)
+#
+# $1 : imagePath (e.g. /images/foo)
+# $2 : disk number (e.g. 1)
+getDesiredPartitionTableType() {
+ local imagePath="$1"
+ local disk_number="$2"
+ [[ -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: $*"
+ table_type="MBR"
+ local mbrfilename=""
+ MBRFileName "$imagePath" "$disk_number" "mbrfilename"
+ [[ ! -r $mbrfilename ]] && return
+ local tmpfile="/tmp/gptsig"
+ dd skip=512 bs=1 if=$mbrfilename of=$tmpfile count=8 >/dev/null 2>&1
+ touch $tmpfile
+ local gptsig=$(cat $tmpfile)
+ [[ $gptsig == "EFI PART" ]] && table_type="GPT"
+}
+# $1 : device name of drive
+hasHybridMBR() {
+ local disk="$1"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local mbr=$(gdisk -l $disk | awk '/^\ *MBR:/{print $2}')
+ [[ $mbr == hybrid ]] && echo 1 || echo 0
+}
+# $1 : device name of drive
+hasGPT() {
+ local disk="$1"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local gpt=$(gdisk -l $disk | awk -F'[(: )]' '/GPT:/ {print $5}')
+ [[ $gpt == present ]] && hasgpt=1
+ [[ $gpt == not ]] && hasgpt=0
+}
+#
+# Detect the partition table type, then call the correct
+# resizePartition function
+#
+# $1 is the partition device (e.g. /dev/sda1)
+# $2 is the new desired size in 1024 (1k) blocks
+# $3 is the image path (e.g. /net/dev/foo)
+resizePartition() {
+ local part="$1"
+ local size="$2"
+ local imagePath="$3"
+ [[ -z $part ]] && handleError "No partition passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $size ]] && handleError "No size passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $imagePath ]] && handleError "No image path passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local disk=""
+ local table_type=""
+ getDiskFromPartition "$part"
+ getPartitionTableType "$disk"
+ case $table_type in
+ MBR|GPT)
+ local sfdiskoriginalpartitionfilename=""
+ local sfdisklegacyoriginalpartitionfilename=""
+ resizeSfdiskPartition "$part" "$size" "$imagePath"
+ ;;
+ *)
+ handleError "Unexpected partition table type: $table_type (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+ # make sure kernel knows about the changes
+ runPartprobe "$disk"
+}
+#
+# Detect the partition table type, then save all relevant
+# partition information
+#
+# $1 : device name of the drive
+# $2 : imagePath
+# $3 : disk number
+saveOriginalPartitions() {
+ local disk="$1"
+ local imagePath="$2"
+ local disk_number="$3"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -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: $*"
+ local table_type=""
+ getPartitionTableType "$disk"
+ case $table_type in
+ MBR|GPT)
+ local sfdiskoriginalpartitionfilename=""
+ sfdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ saveSfdiskPartitions "$disk" "$sfdiskoriginalpartitionfilename"
+ ;;
+ GPT-MBR)
+ echo "Failed"
+ debugPause
+ runFixparts "$disk"
+ dots "Retrying to save partition table"
+ saveOriginalPartitions "$disk" "$imagePath" "$disk_number"
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError "Unexpected partition table type: $table_type (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+ runPartprobe "$disk"
+}
+#
+# Detect the partition table type, then restore partition
+# sizes, using saved partition information
+#
+# $1 : device name of the drive
+# $2 : imagePath
+# $3 : disk number
+restoreOriginalPartitions() {
+ local disk="$1"
+ local imagePath="$2"
+ local disk_number="$3"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -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: $*"
+ local table_type=""
+ getPartitionTableType "$disk"
+ case $table_type in
+ MBR|GPT)
+ local sfdiskoriginalpartitionfilename=""
+ local sfdisklegacyoriginalpartitionfilename=""
+ local sgdiskoriginalpartitionfilename=""
+ local cmdtorun='restoreSfdiskPartitions'
+ sfdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ sfdiskLegacyOriginalPartitionFileName "$imagePath" "$disk_number"
+ sgdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ local filename="$sfdiskoriginalpartitionfilename"
+ [[ ! -r $filename ]] && filename="$sfdisklegacyoriginalpartitionfilename"
+ [[ ! -r $filename ]] && filename="$sgdiskoriginalpartitionfilename" && cmdtorun='restoreSgdiskPartitions'
+ [[ ! -r $filename ]] && handleError "Failed to find a restore file (${FUNCNAME[0]})\n Args Passed: $*"
+ $cmdtorun "$disk" "$filename"
+ ;;
+ *)
+ handleError "Unexpected partition table type: $table_type (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+ # make sure kernel knows about the changes
+ runPartprobe "$disk"
+}
+#
+# Detect the partition table type, the fill the disk with
+# the partitions, using the correct routine.
+#
+# $1 : the disk device (e.g. /dev/sda)
+# $2 : imagePath (e.g. /images/foo)
+# $3 : disk number (e.g. 1)
+fillDiskWithPartitions() {
+ local disk="$1"
+ local imagePath="$2"
+ local disk_number="$3"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -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: $*"
+ local fixed_size_file=""
+ fixedSizePartitionsFileName "$imagePath" "$disk_number"
+ [[ -r $fixed_size_file ]] && fixed_size_partitions=$(cat $fixed_size_file)
+ local table_type=""
+ getDesiredPartitionTableType "$imagePath" "$disk_number"
+ local sfdiskoriginalpartitionfilename=""
+ local sfdisklegacyoriginalpartitionfilename=""
+ local sgdiskoriginalpartitionfilename=""
+ case $table_type in
+ MBR|GPT)
+ sfdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ sfdiskLegacyOriginalPartitionFileName "$imagePath" "$disk_number"
+ sgdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ local filename="$sfdiskoriginalpartitionfilename"
+ local cmdtorun='fillSfdiskWithPartitions'
+ [[ ! -r $filename ]] && filename="$sfdisklegacyoriginalpartitionfilename"
+ [[ ! -r $filename ]] && filename="$sgdiskoriginalpartitionfilename"
+ [[ $filename == $sgdiskoriginalpartitionfilename ]] && cmdtorun='fillSgdiskWithPartitions'
+ [[ ! -r $filename ]] && handleError "Failed to find a restore file (${FUNCNAME[0]})\n Args Passed: $*"
+ $cmdtorun "$disk" "$filename" "$fixed_size_partitions"
+ ;;
+ *)
+ echo "Failed"
+ debugPause
+ handleError "Unexpected partition table type: $table_type (${FUNCNAME[0]})\n Args Passed: $*"
+ ;;
+ esac
+ # make sure kernel knows about the changes
+ runPartprobe "$disk"
+}
+#
+# Check if it will be ok to call fillDiskWithPartitions
+#
+# $1 : the disk device (e.g. /dev/sda)
+# $2 : imagePath (e.g. /images/foo)
+# $3 : disk number (e.g. 1)
+fillDiskWithPartitionsIsOK() {
+ local disk="$1"
+ local imagePath="$2"
+ local disk_number="$3"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -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: $*"
+ local table_type=""
+ getDesiredPartitionTableType "$imagePath" "$disk_number"
+ local filename=""
+ local sfdiskoriginalpartitionfilename=""
+ local sfdisklegacyoriginalpartitionfilename=""
+ local sgdiskoriginalpartitionfilename=""
+ do_fill=1
+ case $table_type in
+ MBR|GPT)
+ sfdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ sfdiskLegacyOriginalPartitionFileName "$imagePath" "$disk_number"
+ sgdiskOriginalPartitionFileName "$imagePath" "$disk_number"
+ filename="$sfdiskoriginalpartitionfilename"
+ [[ ! -r $filename ]] && filename="$sfdisklegacyoriginalpartitionfilename"
+ [[ ! -r $filename ]] && filename="$sgdiskoriginalpartitionfilename"
+ [[ ! -r $filename ]] && do_fill=0
+ ;;
+ esac
+}
+#
+# Show the current partition table
+#
+# $1 : the disk device (e.g. /dev/sda)
+# $2 : disk number (e.g. 1)
+majorDebugShowCurrentPartitionTable() {
+ [[ $ismajordebug -le 0 ]] && return
+ local disk="$1"
+ local disk_number="$2"
+ [[ -z $disk ]] && handleError "No disk passed (${FUNCNAME[0]})\n Args Passed: $*"
+ [[ -z $disk_number ]] && handleError "No disk number passed (${FUNCNAME[0]})\n Args Passed: $*"
+ local table_type=""
+ getDesiredPartitionTableType "$imagePath" "$disk_number"
+ echo "Current partition table:"
+ case $table_type in
+ MBR|GPT)
+ sfdisk -d $disk
+ ;;
+ esac
+}
diff --git a/draft/other-tools/fog/procsfdisk.awk b/draft/other-tools/fog/procsfdisk.awk
new file mode 100644
index 0000000..ac18749
--- /dev/null
+++ b/draft/other-tools/fog/procsfdisk.awk
@@ -0,0 +1,361 @@
+#!/usr/bin/awk -f
+
+#$data is the filename of the output of sfdisk -d
+
+#cat $data | awk -F, '\
+
+# For readability, function parameters are on the first line. Locally scoped
+# variables are on the following lines.
+
+function display_output(partition_names, partitions, \
+ pName) {
+ if (!unit) {
+ unit = "sectors";
+ }
+ if (!label) {
+ type = "Id=";
+ } else {
+ type = "type=";
+ }
+ if (label && labelid && device) {
+ printf("label: %s\n", label);
+ printf("label-id: %s\n", labelid);
+ printf("device: %s\n", device);
+ }
+ printf("unit: %s\n\n", unit);
+ for(pName in partition_names) {
+ printf("%s : start=%10d, size=%10d, %s%2s", partitions[pName, "device"], partitions[pName, "start"], partitions[pName, "size"],
+ type, partitions[pName, "type"]);
+ if(label == "dos") {
+ if(partitions[pName, "flags"] != "") {
+ printf("%s", partitions[pName, "flags"]);
+ }
+ } else if (label == "gpt") {
+ if(partitions[pName, "uuid"] != "") {
+ printf(", uuid=%s", partitions[pName, "uuid"]);
+ }
+ if(partitions[pName, "name"] != "") {
+ printf(", name=%s", partitions[pName, "name"]);
+ }
+ if(partitions[pName, "attrs"] != "") {
+ printf(", attrs=%s", partitions[pName, "attrs"]);
+ }
+ } else {
+ if(partitions[pName, "flags"] != "") {
+ printf("%s", partitions[pName, "flags"]);
+ }
+ }
+ printf("\n");
+ }
+}
+
+function check_overlap(partition_names, partitions, new_part_name, new_start, new_size, \
+ extended_margin, new_type, new_part_number, pName, p_type, p_start, p_size, p_part_number) {
+ extended_margin = 2;
+ new_type = partitions[new_part_name, "type"];
+ new_start = new_start + 0;
+ new_size = new_size + 0;
+ new_part_number = partitions[new_part_name, "number"] + 0;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_start = partitions[pName, "start"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ p_part_number = partitions[pName, "number"] + 0;
+ # no overlap with self
+ if(new_part_name == pName) { continue; }
+ # ignore empty partitions
+ if(p_size == 0) { continue; }
+ # extended partitions must overlap logical partitions, but leave room for the extended partition table
+ if((p_type == "5" || p_type == "f") && (new_part_number >= 5)) {
+ # new_start is outside of [p_start+margin, p_start + p_size) OR
+ # new_start + new_size is outside of (p_start+margin, p_start + p_size]
+ if((new_start < p_start + extended_margin || new_start >= p_start + p_size) || (new_start + new_size <= p_start + extended_margin || new_start + new_size > p_start + p_size)) {
+ return 1;
+ }
+ }
+ # extended partitions must overlap logical partitions, but leave room for the extended partition table
+ else if((new_type == "5" || new_type == "f") && (p_part_number >= 5)) {
+ # logical partition must be contained in extended partition
+ # p_start is outside of [new_start+margin, new_start + new_size) OR
+ # p_start + p_size is outside of (new_start+margin, new_start + new_size]
+ if((p_start < new_start + extended_margin || p_start >= new_start + new_size) || (p_start + p_size <= new_start + extended_margin || p_start + p_size > new_start + new_size)) {
+ return 1;
+ }
+ }
+ # all other overlap possibilities
+ else {
+ # new_start is inside of [p_start, p_start + p_size) OR
+ # new_start + new_size is inside of (p_start, p_start + p_size]
+ if((new_start >= p_start && new_start < p_start + p_size) || (new_start + new_size > p_start && new_start + new_size <= p_start + p_size)) {
+ return 1;
+ }
+ # p_start is inside of [new_start, new_start + new_size) OR
+ # p_start + p_size is inside of (new_start, new_start + new_size]
+ if((p_start >= new_start && p_start < new_start + new_size) || (p_start + p_size > new_start && p_start + p_size <= new_start + new_size)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+function check_all_partitions(partition_names, partitions, \
+ pName, p_start, p_size) {
+ for(pName in partition_names) {
+ p_start = partitions[pName, "start"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ if(check_overlap(partition_names, partitions, pName, p_start, p_size) != 0) {
+ printf("ERROR in new partition table, quitting.\n");
+ printf("ERROR: %s has an overlap.\n", pName);
+ #exit(1);
+ }
+ }
+ printf("# Partition table is consistent.\n");
+}
+
+function resize_partition(partition_names, partitions, args, \
+ pName, new_start, new_size) {
+ for(pName in partition_names) {
+ if(pName == target) {
+ if(unit == "sectors") {
+ new_start = partitions[pName, "start"];
+ new_size = sizePos*2;
+ if(check_overlap(partition_names, partitions, target, new_start, new_size) == 0) {
+ partitions[target, "start"] = new_start;
+ partitions[target, "size"] = new_size;
+ }
+ }
+ }
+ }
+}
+
+function move_partition(partition_names, partitions, args, \
+ pName, new_start, new_size) {
+ for(pName in partition_names) {
+ if(pName == target) {
+ if(unit == "sectors") {
+ new_start = (sizePos*2);
+ new_start = new_start - new_start % CHUNK_SIZE;
+ if(new_start < MIN_START) { new_start = MIN_START; }
+ new_size = partitions[pName, "size"];
+ if(check_overlap(partition_names, partitions, target, new_start, new_size) == 0) {
+ partitions[target, "start"] = new_start;
+ partitions[target, "size"] = new_size;
+ }
+ }
+ }
+ }
+}
+
+function fill_disk(partition_names, partitions, args, \
+ disk, disk_size, n, fixed_partitions, original_variable, \
+ original_fixed, new_variable, new_fixed, new_logical, pName, \
+ p_type, p_number, p_size, found, i, partition_starts, \
+ ordered_starts, old_sorted_in, curr_start) {
+ # processSfdisk foo.sfdisk filldisk /dev/sda 100000 1:3:6
+ # foo.sfdisk = sfdisk -d output
+ # filldisk = action
+ # /dev/sda = disk to modify
+ # 100000 = 1024 byte blocks size of disk
+ # 1:3:6 = partition numbers that are fixed in size, : separated
+ disk = target;
+ disk_size = sizePos*2;
+ # add swap partitions to the fixed list
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + "";
+ if(p_type == "82") {
+ fixedList = fixedList ":" p_number;
+ }
+ }
+ n = split(fixedList, fixed_partitions, ":");
+ #
+ # Find the total fixed and variable space
+ #
+ original_variable = 0;
+ original_fixed = MIN_START;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ partition_starts[partitions[pName, "start"] + 0] = pName;
+ # skip extended partition, only count its logicals and the CHUNK for its partition table
+ if(p_type == "5" || p_type == "f") {
+ original_fixed += CHUNK_SIZE;
+ continue;
+ }
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ if(p_number >= 5) {
+ original_fixed += CHUNK_SIZE;
+ }
+ if(p_size == 0) { fixed_partitions[pName] = p_number; };
+ found = 0; for(i in fixed_partitions) { if(fixed_partitions[i] == p_number) { found = 1; } };
+ if(found) {
+ original_fixed += partitions[pName, "size"];
+ } else {
+ original_variable += partitions[pName, "size"];
+ }
+ }
+ #
+ # Assign the new sizes to partitions
+ #
+ new_fixed = original_fixed;
+ new_variable = disk_size - original_fixed;
+ new_logical = 0;
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ found = 0;
+ for(i in fixed_partitions) {
+ if(fixed_partitions[i] == p_number) {
+ found = 1;
+ }
+ };
+ if(p_type == "5" || p_type == "f") {
+ partitions[pName, "newsize"] = CHUNK_SIZE;
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ } else if(found) {
+ partitions[pName, "newsize"] = p_size;
+ partitions[pName, "size"] = partitions[pName, "newsize"];
+ } else {
+ partitions[pName, "newsize"] = (new_variable*p_size/original_variable);
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ }
+ if(p_number >= 5) {
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ new_logical += partitions[pName, "size"] + CHUNK_SIZE;
+ }
+ }
+ #
+ # Assign the new size to the extended partition
+ #
+ for(pName in partition_names) {
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ if(p_type == "5" || p_type == "f") {
+ partitions[pName, "newsize"] += new_logical;
+ partitions[pName, "size"] = partitions[pName, "newsize"] - partitions[pName, "newsize"] % CHUNK_SIZE;
+ }
+ }
+ #
+ # Assign the new start positions
+ #
+ asort(partition_starts, ordered_starts, "@ind_num_asc");
+ old_sorted_in = PROCINFO["sorted_in"];
+ PROCINFO["sorted_in"] = "@ind_num_asc";
+ curr_start = MIN_START;
+ for(i in ordered_starts) {
+ pName = ordered_starts[i];
+ p_type = partitions[pName, "type"];
+ p_number = partitions[pName, "number"] + 0;
+ p_size = partitions[pName, "size"] + 0;
+ p_start = partitions[pName, "start"] + 0;
+ for (j in fixed_partitions) {
+ if (fixed_partitions[j] == p_number) {
+ curr_start = p_start;
+ }
+ }
+ if(p_size > 0) {
+ partitions[pName, "start"] = curr_start;
+ }
+ if(p_type == "5" || p_type == "f") {
+ curr_start += CHUNK_SIZE;
+ } else {
+ curr_start += p_size;
+ }
+ # + CHUNK_SIZE to allow for margin after each logical partition (required if 2 or more logical partitions exist)
+ if(p_number >= 5) {
+ curr_start += CHUNK_SIZE;
+ }
+ }
+ PROCINFO["sorted_in"] = old_sorted_in;
+ check_all_partitions(partition_names, partitions);
+}
+
+BEGIN{
+ #Arguments - Use "-v var=val" when calling this script
+ #CHUNK_SIZE;
+ #MIN_START;
+ #action;
+ #target;
+ #sizePos;
+ #fixedList;
+ label = "";
+ unit = "";
+ partitions[0] = "";
+ partition_names[0] = "";
+}
+
+/^label:/{ label = $2 }
+/^label-id:/{ labelid = $2 }
+/^device:/{ device = $2 }
+/^unit:/{ unit = $2; }
+
+/start=/{
+ # Get Partition Name
+ part_name=$1
+ partitions[part_name, "device"] = part_name
+ partition_names[part_name] = part_name
+
+ # Isolate Partition Number
+ # The regex can handle devices like mmcblk0p3
+ part_number = gensub(/^[^0-9]*[0-9]*[^0-9]+/, "", 1, part_name)
+ partitions[part_name, "number"] = part_number
+
+ # Separate attributes
+ split($0, fields, ",")
+
+ # Get start value
+ gsub(/.*start= */, "", fields[1])
+ partitions[part_name, "start"] = fields[1]
+ # Get size value
+ gsub(/.*size= */, "", fields[2])
+ partitions[part_name, "size"] = fields[2]
+ # Get type/id value
+ gsub(/.*(type|Id)= */, "", fields[3])
+ partitions[part_name, "type"] = fields[3]
+
+ if ( label == "dos" )
+ {
+ split($0, typeList, "type=")
+ part_flags = gensub(/^[^\,$]*/, "",1,typeList[2])
+ partitions[part_name, "flags"] = part_flags;
+ }
+ # GPT elements
+ else if ( label == "gpt" )
+ {
+ # Get uuid value
+ gsub(/.*uuid= */, "", fields[4])
+ partitions[part_name, "uuid"] = fields[4]
+ # Get name value
+ gsub(/.*name= */, "", fields[5])
+ partitions[part_name, "name"] = fields[5]
+ # Get attrs value
+ if (fields[6])
+ {
+ gsub(/.*attrs= */, "", fields[6])
+ partitions[part_name, "attrs"] = fields[6]
+ }
+ }
+ else
+ {
+ split($0, typeList, "Id=")
+ part_flags = gensub(/^[^\,$]*/, "",1,typeList[2])
+ partitions[part_name, "flags"] = part_flags;
+ }
+}
+
+END{
+ delete partitions[0];
+ delete partition_names[0];
+ if(action == "resize") {
+ resize_partition(partition_names, partitions, args);
+ } else if(action == "move") {
+ move_partition(partition_names, partitions, args);
+ } else if(action == "filldisk") {
+ fill_disk(partition_names, partitions, args);
+ }
+ display_output(partition_names, partitions);
+}