cros_generate_update_payload: Use e2cp instead of mounting STATE.

In old test images (about 1 year or older) we need to patch the kernel
in KERN-A with a vblock found in a file in the STATE partition. This
file was accessed mount the stateful partition read-only and copying the
file there, requiring this script to be run as root and leading to some
race conditions stated in crbug.com/358933.

This patch uses the e2cp tool instead to copy this file out of the
stateful partition and patch the kernel with it.

CQ-DEPEND=CL:283508
BUG=chromium:507422,chromium:305832
TEST=`cros_generate_update_payload --extract` on old lumpy 2913.331.0 test image extracts the same kernel.

Change-Id: I48e4ad369f7451d8ad824450bfad8f7d0d6c7b2c
Reviewed-on: https://chromium-review.googlesource.com/283564
Reviewed-by: Gabe Black <gabeblack@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/host/cros_generate_update_payload b/host/cros_generate_update_payload
index de4e452..0ece22a 100755
--- a/host/cros_generate_update_payload
+++ b/host/cros_generate_update_payload
@@ -85,51 +85,17 @@
 FLAGS "$@" || exit 1
 eval set -- "${FLAGS_ARGV}"
 
-# We use this directory to create mount points as a way around crbug.com/358933.
-# Use FLAGS_work_dir instead when that workaround is no longer needed.
-# When that bug affects us, we will leak temp directories. They should
-# be cleaned up on the build servers at the end of cbuildbot.
-MOUNTS_ROOT="/tmp/crbug_358933"
-
+STATE_PART_NUM=1
 ROOTFS_PART_NUM=3
 
 SRC_KERNEL=""
 SRC_ROOT=""
 DST_KERNEL=""
 DST_ROOT=""
-STATE_MNT=""
-
-# umount a loopback device, and remove the mount point.
-umount_and_rmdir() {
-  local mnt_point="$1"
-
-  local umount_ret
-  local rmdir_ret=0
-
-  if [[ ! -d  "${mnt_point}" ]]; then
-    return 0
-  fi
-
-  sudo umount -v "${mnt_point}" || return 1
-  sudo rmdir -v "${mnt_point}" || rmdir_ret=$?
-  if [[ ${rmdir_ret} -ne 0 ]]; then
-    warn "sudo rmdir -v ${mnt_point} exited with: ${rmdir_ret}"
-    warn "Please note this failure in crbug.com/358933"
-  fi
-
-  # If the rmdir fails, we still return success and keep going. This punts
-  # failures up the chain of cleanup code, and makes them responsible for
-  # crbug.com/358933.
-
-  return 0
-}
 
 cleanup() {
   local err=""
 
-  umount_and_rmdir "${STATE_MNT}" || err=1
-  STATE_MNT=""
-
   if [[ -z "${FLAGS_src_kern_path}" ]]; then
     rm -f "${SRC_KERNEL}" || err=1
   fi
@@ -185,19 +151,21 @@
 }
 
 patch_kernel() {
-  local IMAGE="$1"
-  local KERN_FILE="$2"
+  local image="$1"
+  local kern_file="$2"
+  local err=""
 
-  # Keep `local` decl split from assignment so return code is checked.
-  local offset
-  offset=$(partoffset "${IMAGE}" 1)
-  : $(( offset *= 512 ))
-  STATE_MNT=$(mktemp -d --tmpdir="${MOUNTS_ROOT}" state.XXXXXX)
-  sudo mount -o ro,loop,offset="${offset}" "${IMAGE}" "${STATE_MNT}"
-  dd if="${STATE_MNT}"/vmlinuz_hd.vblock of="${KERN_FILE}" conv=notrunc \
-      2>/dev/null
-  umount_and_rmdir "${STATE_MNT}"
-  STATE_MNT=""
+  local state_out vblock
+  state_out=$(extract_partition_to_temp_file "${image}" "${STATE_PART_NUM}" "")
+  vblock=$(mktemp --tmpdir="${FLAGS_work_dir}" vmlinuz_hd.vblock.XXXXXX)
+  e2cp "${state_out}:/vmlinuz_hd.vblock" "${vblock}" || err+="e2cp failed."
+  dd if="${vblock}" of="${kern_file}" conv=notrunc status=none ||
+    err+="dd failed."
+  rm -f "${state_out}" "${vblock}"
+
+  if [[ -n "${err}" ]]; then
+    die "Error patching the kernel: ${err}"
+  fi
 }
 
 extract_kern() {
@@ -221,8 +189,6 @@
     "${root_out}"
 }
 
-mkdir -p "${MOUNTS_ROOT}"
-
 if [[ -n "${FLAGS_src_image}" ]] && \
    [[ "${FLAGS_outside_chroot}" -eq "${FLAGS_FALSE}" ]]; then
   # We need to be in the chroot for generating delta images.