From fae03bd9bfb37c8c7b8277c6f79b780940a98925 Mon Sep 17 00:00:00 2001
From: Tom Rini <trini@konsulko.com>
Date: Tue, 3 Apr 2018 14:08:05 -0400
Subject: [PATCH 1/1] mkefi-agl.sh: Rework to utilize the wic images fully

- If we have bmaptool version 3 available and the bmap file, use the
  bmap file to write our image out.
- If we have a compressed image and cannot use bmaptool, use xzcat to
  decompress.
- Otherwise, just use dd to write
- Use blockdev to flush our images to disk.
- Use parted to fix the ALT GPT location, and then resize the rootfs to
  use the entire rest of the device.

Change-Id: I42dba019a9cdedf5d6361f25049f9aa9cf7fe805
Bug-AGL: SPEC-1300
Signed-off-by: Tom Rini <trini@konsulko.com>
---
 scripts/mkefi-agl.sh | 347 ++++++++-------------------------------------------
 1 file changed, 49 insertions(+), 298 deletions(-)

diff --git a/scripts/mkefi-agl.sh b/scripts/mkefi-agl.sh
index 14ade366eaca..6cecc2110697 100755
--- a/scripts/mkefi-agl.sh
+++ b/scripts/mkefi-agl.sh
@@ -34,39 +34,6 @@ LANG=C
 DEBUG=0
 exec 3>/dev/null
 
-#
-# Defaults
-#
-# 100 Mb for the boot partition
-BOOT_SIZE=100
-# min available space on TMP_DIR for uncompressing xz image in kB e.g. 5G (5000000)
-TMP_SIZE_MIN=5000000
-# TMP_DIR directory use for holding image file for uncompression (e.g. /tmp or $HOME)
-TMP_DIR=/tmp
-
-# Cleanup after die()
-cleanup() {
-	debug "Syncing and unmounting devices"
-	# Unmount anything we mounted
-	unmount $ROOTFS_MNT || error "Failed to unmount $ROOTFS_MNT"
-	unmount $BOOTFS_MNT || error "Failed to unmount $BOOTFS_MNT"
-	unmount $HDDIMG_ROOTFS_MNT || error "Failed to unmount $HDDIMG_ROOTFS_MNT"
-    unmount $HDDIMG_MNT || error "Failed to unmount $HDDIMG_MNT"
-	if [ "$IMG_TYPE" = "DISK" ]; then
-        debug "de-attaching loop devices"
-        for LOOP_DEVICE in `losetup --list |grep $HDDIMG | cut -d" " -f1` ; do
-           losetup -d $LOOP_DEVICE  1>&3 2>&1 || error "Detaching $LOOP_DEVICE from $HDDIMG failled"
-        done   
-     fi
-
-	# Remove the TMPDIR
-	debug "Removing temporary files"
-	if [ -d "$TMPDIR" ]; then
-		rm -rf "$TMPDIR" || error "Failed to remove $TMPDIR"
-	fi
-        [ -f "$TMP_DIR/TMP-AGL-wic-image.wic" ] || rm -f $TMP_DIR/TMP-AGL-wic-image.wic
-}
-
 trap 'die "Signal Received, Aborting..."' HUP INT TERM
 
 # Logging routines
@@ -93,7 +60,6 @@ success() {
 }
 die() {
 	error "$1"
-	cleanup
 	exit 1
 }
 debug() {
@@ -108,11 +74,11 @@ usage() {
 	echo ""
 	echo "Usage: $(basename $0) [-v] IDSK_IMAGE REMOVABLE_DEVICE"
 	echo "       -v: Verbose debug"
-	echo "       HDDIMG: The DISK_IMAGE file generated by Yocto the efi disk from"
-        echo "               Supported formats are .hddimg, .wic .wic.xz"
+	echo "       HDDIMG: The DISK_IMAGE file generated by Yocto"
+        echo "               Supported formats are .wic .wic.xz"
+	echo "               Optional bmap will be used if found"
 	echo "       REMOVABLE_DEVICE: The block device to write the image to, e.g. /dev/sdh"
 	echo "ex:"
-	echo "   mkefi-agl.sh   agl-demo-platform-intel-corei7-64.hddimg /dev/sdd"
         echo "   mkefi-agl.sh   agl-demo-platform-intel-corei7-64.wic.xz /dev/sdd"
 	exit 1
 }
@@ -195,6 +161,11 @@ fi
 HDDIMG=$1
 DEVICE=$2
 
+# Check for bmaptool
+if [ -x `command -v bmaptool` ]; then
+  bmaptool --version 2>&1 | grep -q 3 && HAS_BMAPTOOL="YES"
+fi
+
 LINK=$(readlink $DEVICE)
 if [ $? -eq 0 ]; then
 	DEVICE="$LINK"
@@ -213,55 +184,28 @@ if [ ! -e "$HDDIMG" ]; then
 fi
 HDDIMG_EXT=${HDDIMG##*.}
 case $HDDIMG_EXT in
-  hddimg)
-     IMG_TYPE="MOUNT"
-     IMG_COMPRESS="NO"
-     debug "Detected: uncompressed image type .hddimg"
-     ;;
   wic)
-     IMG_TYPE="DISK"
-     IMG_COMPRESS="NO"
      debug "Detected: uncompressed image type .wic"
+     if [ -f "${HDDIMG}.bmap" ]; then
+       HAS_BMAPFILE="YES"
+     fi
      ;;
   xz)
-     IMG_TYPE="DISK"
      IMG_COMPRESS="YES"
      debug "Detected: xz compressed image type .wic"
-     command -v xz >/dev/null 2>&1 || { die "xz command is not available, pleaes install xz package"; }
-     TMP_SIZE=`df -k $TMP_DIR | awk '/[0-9]%/{print $(NF-2)}'`
-     if [ "$TMP_SIZE" -lt "$TMP_SIZE_MIN" ]; then
-       die "Available space on $TMP_DIR must be at least $TMP_SIZE_MIN kB" 
+     if [ -f "`echo $HDDIMG | sed -e 's/.xz/.bmap/'`" ]; then
+       HAS_BMAPFILE="YES"
+     fi
+     if [ -z "${HAS_BMAPFILE}" ] || [ -z "${HAS_BMAPTOOL}" ]; then
+       command -v xzcat >/dev/null 2>&1 || { die "xzcat command is not available, pleaes install xz package"; }
      fi
-     printf "Starting decompression of the image. It may take some time ..."
-     xz --decompress --keep --format=auto --force --threads=0 --stdout > $TMP_DIR/TMP-AGL-wic-image.wic  $HDDIMG|| \
-         die "xz command failled: xz --decompress --keep --format=auto --force --threads=0 --stdout > $TMP_DIR/TMP-AGL-wic-image.wic"
-     HDDIMG="$TMP_DIR/TMP-AGL-wic-image.wic"
-     echo "Image uncompressed, starting doing real work ..."
      ;;
   *)
-     die "Unsupported image format: $HDDIMG_EXT Supported format are .hddimg .wic wic.xz"
+     die "Unsupported image format: $HDDIMG_EXT Supported format are wic and wic.xz"
      ;;
 esac
 
 #
-# Ensure the hddimg is not mounted
-#
-debug "will now try to umount /detach previous images"
-case $IMG_TYPE in
-  MOUNT)
-      unmount "$HDDIMG" || die "Failed to unmount $HDDIMG"
-      ;;
-  DISK)
-      [ `losetup --list |grep $HDDIMG | wc -l ` -gt 1 ] && die "Image mounted more than once, manual cleaning required see: losetup --list"
-      debug "ready to attach the wic image to aloop device"
-      LOOP_DEVICE=`losetup --find --show $HDDIMG`  && ( losetup -d $LOOP_DEVICE  1>&3 2>&1 || die "Detaching $LOOP_DEVICE from $HDDIMG failled")
-      ;;
-  *)
-      die "unknown image format $IMG_TYPE"
-      ;;
-esac
-
-#
 # Check if any $DEVICE partitions are mounted
 #
 unmount_device || die "Failed to unmount $DEVICE"
@@ -271,248 +215,55 @@ unmount_device || die "Failed to unmount $DEVICE"
 #
 image_details $HDDIMG
 device_details $(basename $DEVICE)
-echo -n "${INFO}Prepare EFI image on $DEVICE [y/N]?${CLEAR} "
+echo -n "${INFO}Copy AGL image to $DEVICE [y/N]?${CLEAR} "
 read RESPONSE
 if [ "$RESPONSE" != "y" ]; then
-	die "Image creation aborted"
-fi
-
-
-#
-# Prepare the temporary working space
-#
-TMPDIR=$(mktemp -d mkefidisk-XXX) || die "Failed to create temporary mounting directory."
-HDDIMG_MNT=$TMPDIR/hddimg
-HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs
-ROOTFS_MNT=$TMPDIR/rootfs
-BOOTFS_MNT=$TMPDIR/bootfs
-mkdir $HDDIMG_MNT || die "Failed to create $HDDIMG_MNT"
-mkdir $HDDIMG_ROOTFS_MNT || die "Failed to create $HDDIMG_ROOTFS_MNT"
-mkdir $ROOTFS_MNT || die "Failed to create $ROOTFS_MNT"
-mkdir $BOOTFS_MNT || die "Failed to create $BOOTFS_MNT"
-
-
-#
-# Partition $DEVICE
-#
-DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
-# If the device size is not reported there may not be a valid label
-if [ "$DEVICE_SIZE" = "" ] ; then
-	parted -s $DEVICE mklabel msdos || die "Failed to create MSDOS partition table"
-	DEVICE_SIZE=$(parted -s $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
-fi
-ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE))
-ROOTFS_START=$((BOOT_SIZE))
-ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE))
-
-# MMC devices use a partition prefix character 'p'
-PART_PREFIX=""
-if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/nvme0n}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
-	PART_PREFIX="p"
-fi
-BOOTFS=$DEVICE${PART_PREFIX}1
-ROOTFS=$DEVICE${PART_PREFIX}2
-
-TARGET_PART_PREFIX=""
-if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ] || [ ! "${TARGET_DEVICE#/dev/nvme0n}" = "${TARGET_DEVICE}" ]; then
-	TARGET_PART_PREFIX="p"
-fi
-TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2
-
-echo ""
-info "Boot partition size:   $BOOT_SIZE MB ($BOOTFS)"
-info "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)"
-echo ""
-
-# Use MSDOS by default as GPT cannot be reliably distributed in disk image form
-# as it requires the backup table to be on the last block of the device, which
-# of course varies from device to device.
-
-info "Partitioning installation media ($DEVICE)"
-
-debug "Deleting partition table on $DEVICE"
-dd if=/dev/zero of=$DEVICE bs=512 count=2 1>&3 2>&1 || die "Failed to zero beginning of $DEVICE"
-
-debug "Creating new partition table (MSDOS) on $DEVICE"
-parted -s $DEVICE mklabel msdos 1>&3 2>&1 || die "Failed to create MSDOS partition table"
-
-debug "Creating boot partition on $BOOTFS"
-parted -s $DEVICE mkpart primary 0% $BOOT_SIZE 1>&3 2>&1 || die "Failed to create BOOT partition"
-
-debug "Enabling boot flag on $BOOTFS"
-parted -s $DEVICE set 1 boot on 1>&3 2>&1 || die "Failed to enable boot flag"
-
-debug "Creating ROOTFS partition on $ROOTFS"
-parted -s $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END 1>&3 2>&1 || die "Failed to create ROOTFS partition"
-
-# as blkid does not provide PARTUUID on Ubuntu LTS 14.04 we myst hack via fdisk
-#ROOTFS_PARTUUID=$(blkid |grep -e "$ROOTFS" |sed -n 's/^.*PARTUUID=/PARTUUID=/p')
-export LC_ALL=C
-ROOTFS_DISKID=$(fdisk -l "$DEVICE" | grep -e "Disk identifier" | sed -n 's/^.*Disk identifier: 0x/PARTUUID=/p')
-if [ $ROOTFS_DISKID = "" ]; then
-    die "Failed to read DISKID"
+	die "Image duplication aborted"
 fi
-ROOTFS_PARTUUID="$ROOTFS_DISKID-02"
-debug "PARTUUID for ROOTFS is $ROOTFS_PARTUUID"
-
-if [ $DEBUG -eq 1 ]; then
-	parted -s $DEVICE print
-fi
-
 
 #
-# Check if any $DEVICE partitions are mounted after partitioning
+# Write the image
 #
-unmount_device || die "Failed to unmount $DEVICE partitions"
-
-
-#
-# Format $DEVICE partitions
-#
-info "Formatting partitions"
-debug "Formatting $BOOTFS as vfat"
-if [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
-	mkfs.vfat -I $BOOTFS -n "EFI" 1>&3 2>&1 || die "Failed to format $BOOTFS"
+if [ ! -z "${HAS_BMAPFILE}" ] && [ ! -z "${HAS_BMAPTOOL}" ]; then
+  bmaptool copy ${HDDIMG} ${DEVICE}
 else
-	mkfs.vfat $BOOTFS -n "EFI" 1>&3 2>&1 || die "Failed to format $BOOTFS"
+  if [ ! -z "${IMG_COMPRESS}" ]; then
+    xzcat -c ${HDDIMG} | dd of=${DEVICE} bs=4k
+  else
+    dd if=${HDDIMG} of=${DEVICE} bs=4k
+  fi
 fi
 
-debug "Formatting $ROOTFS as ext4"
-mkfs.ext4 -F $ROOTFS -L "ROOT" 1>&3 2>&1 || die "Failed to format $ROOTFS"
-
+printf "flushing data on removable device. May take a while ... "
+blockdev --flushbufs ${DEVICE}
+echo done
 
 #
-# Mounting image file system on loop devices
+# Resize the rootfs partition to take the rest of the device
 #
-case $IMG_TYPE in
-
-  MOUNT) 
-     debug "Mounting images and device in preparation for installation"
-     mount -o loop $HDDIMG $HDDIMG_MNT 1>&3 2>&1 || die "Failed to mount $HDDIMG"
-     mount -o loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount rootfs.img"
-     ;;
-  DISK)
-     debug "Attaching image and mounting partitions then device in preparation for installation"
-     LOOP_DEVICE=`losetup --find` || die "Failled to find an available loop device see: losetup --find"
-     losetup -P $LOOP_DEVICE $HDDIMG  1>&3 2>&1 || die "Attaching $LOOP_DEVICE from $HDDIMG failled"
-     mount "$LOOP_DEVICE"p2  $HDDIMG_ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp1 on $HDDIMG_ROOTFS_MNT"
-     mount "$LOOP_DEVICE"p1  $HDDIMG_MNT       1>&3 2>&1 || die "Failed to mount $LOOP_DEVICEp2 on $HDDIMG_MNT"
-     ;;
-  *)
-      die "unknown image format $IMG_TYPE"
-      ;;
-esac
-# Mount removable device
-     mount $ROOTFS $ROOTFS_MNT 1>&3 2>&1 || die "Failed to mount $ROOTFS on $ROOTFS_MNT"
-     mount $BOOTFS $BOOTFS_MNT 1>&3 2>&1 || die "Failed to mount $BOOTFS on $BOOTFS_MNT"
-
-
-info "Preparing boot partition"
-EFIDIR="$BOOTFS_MNT/EFI/BOOT"
-if [ -f $HDDIMG_MNT/vmlinuz ]; then
-   cp $HDDIMG_MNT/vmlinuz $BOOTFS_MNT 1>&3 2>&1 || die "Failed to copy vmlinuz"
-   KERNEL_TYPE="VMLINUZ"
-   debug "kernel is vmlinuz"
-fi
-if [ -f $HDDIMG_MNT/bzimage ]; then
-   cp $HDDIMG_MNT/bzimage $BOOTFS_MNT 1>&3 2>&1 || die "Failed to copy bzimage"
-   KERNEL_TYPE="BZIMAGE"
-   debug "kernel is bzimage"
-fi
-if [ -f $HDDIMG_MNT/microcode.cpio ]; then
-   cp $HDDIMG_MNT/microcode.cpio $BOOTFS_MNT 1>&3 2>&1 || die "Failed to copy microcode.cpio"
-   debug "microcode.cpio copied"
-fi
-[ -z $KERNEL_TYPE ] && die "Linux kernel type in $HDDIMG is unsupported"
-
-if [ -f $HDDIMG_MNT/initrd ]
-  then
-    echo "initrd detected"
-    cp $HDDIMG_MNT/initrd $BOOTFS_MNT 1>&3 2>&1 || die "Failed to copy initrd"
-  else
-    warn "initrd missing"
-fi
-echo "bootx64.efi" > $BOOTFS_MNT/startup.nsh || die "Failed to create startup.nsh"
-# Copy the efi loader and configs (booti*.efi and grub.cfg if it exists)
-cp -r $HDDIMG_MNT/EFI $BOOTFS_MNT 1>&3 2>&1 || die "Failed to copy EFI dir"
-# Silently ignore a missing systemd-boot or gummiboot loader dir (we might just be a GRUB image)
-cp -r $HDDIMG_MNT/loader $BOOTFS_MNT 1>&3 2>&1
-
-# Update the boot loaders configurations for an installed image
-# Remove any existing root= kernel parameters and:
-# o Add a root= parameter with the target rootfs
-# o Specify ro so fsck can be run during boot
-# o Specify rootwait in case the target media is an asyncronous block device
-#   such as MMC or USB disks
-# o Specify "quiet" to minimize boot time when using slow serial consoles
-
-# Look for a GRUB installation
-GRUB_CFG="$EFIDIR/grub.cfg"
-if [ -e "$GRUB_CFG" ]; then
-	info "Configuring GRUB"
-	# Delete the install entry
-	sed -i "/menuentry 'install'/,/^}/d" $GRUB_CFG
-	# Delete any LABEL= strings
-	sed -i "s/ LABEL=[^ ]*/ /" $GRUB_CFG
-        # detect config initrd=microcode.cpio
-        if  grep -q microcode $GRUB_CFG; then
-            warn "initrd=microcode.cpio detected, might not work on all boot configurations"
-        fi
-	sed -i "s@ root=[^ ]*@ @" $GRUB_CFG
-	sed -i "s@vmlinuz @vmlinuz root=$ROOTFS_PARTUUID @" $GRUB_CFG
-fi
-
-# look for a systemd-boot loader.conf file and create a default boot entry
-SYSTEMDBOOT_CFG="$BOOTFS_MNT/loader/loader.conf"
-if [ -e "$SYSTEMDBOOT_CFG" ]; then
-	info "Configuring SYSTEMD-BOOT"
-    SYSTEMDBOOT_BOOT="$BOOTFS_MNT/loader/entries/boot.conf"
-    SYSTEMDBOOT_DEBUG="$BOOTFS_MNT/loader/entries/debug.conf"
-    # Delete the install entry
-	sed -i "/menuentry 'install'/,/^}/d" $SYSTEMDBOOT_CFG
-	rm -rf "$BOOTFS_MNT/loader/entries/install.conf" 1>&3 2>&1
-	# Add PARTUUID to the boot entry file
-	if [ ! -e "$SYSTEMDBOOT_BOOT" ]; then
-        die "no boot.conf entry found in systemd-boot directories"
-    fi
-	# Delete any LABEL= strings
-	sed -i "s/ LABEL=[^ ]*/ /" $SYSTEMDBOOT_BOOT
-        # detect config initrd=microcode.cpio
-        if  grep -q microcode $SYSTEMDBOOT_BOOT; then
-            warn "initrd=microcode.cpio detected, might not work on all boot configurations"
-        fi
-	sed -i "s@ root=[^ ]*@ @" $SYSTEMDBOOT_BOOT
-	sed -i "s@options @options root=$ROOTFS_PARTUUID @" $SYSTEMDBOOT_BOOT
-fi
+partprobe ${DEVICE} 2>/dev/null
+debug "Correcting ALT GPT location"
+parted ${DEVICE} print fix >/dev/null 2>&1
+partprobe ${DEVICE} 2>/dev/null
 
+info "Resizing rootfs partition on $DEVICE"
+parted -s $DEVICE resizepart 2 100%
+partprobe ${DEVICE} 2>/dev/null
 
-# Ensure we have at least one EFI bootloader configured
-if [ ! -e $GRUB_CFG ]  && [ ! -e $SYSTEMDBOOT_CFG ] ; then
-	die "No EFI bootloader configuration found"
-fi
-
-printf "Copying ROOTFS files ... "
-command -v rsync >/dev/null 2>&1 # check if rsync exists
-if [ $DEBUG -eq 1 ] && [ $? -eq 0 ]; then
-	rsync --info=progress2 -h -aHAXW --no-compress  $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
-else
-	cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT 1>&3 2>&1 || die "Root FS copy failed"
-fi
-debug "removing any swap entry in /etc/fstab"
-sed --in-place '/swap/d' $ROOTFS_MNT/etc/fstab 
-
-printf "flushing data on removable device. May take a while ... "
-sync --file-system $ROOTFS_MNT
-echo done
-
-# We dont want udev to mount our root device while we're booting...
-if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
-	echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
+# MMC devices use a partition prefix character 'p'
+PART_PREFIX=""
+if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/nvme0n}" = "${DEVICE}" ]; then
+  PART_PREFIX="p"
 fi
 
+# Wait for probe to finish
+while [ ! -b ${DEVICE}${PART_PREFIX}2 ]; do
+  sleep 1
+done
+resize2fs ${DEVICE}${PART_PREFIX}2
 
-# Call cleanup to unmount devices and images and remove the TMPDIR
-cleanup
+# Final flush
+blockdev --flushbufs ${DEVICE}
 
 echo ""
 if [ $WARNINGS -ne 0 ] && [ $ERRORS -eq 0 ]; then
-- 
2.7.4

