Fix a race condition when mounting loopback devices.

The previous code selected and configured the loopback device in two
separate stages.  This allowed for the possiblity that some other
code could claim the same loopback claimed by patch_kernel, leading
to failures.

BUG=chromium-os:24975
TEST=cros_generate_update_payload --output=<outfile> --image=<infile> --patch_kernel
TEST=image_to_live.sh

Change-Id: Ic081189f9431cb037a8b0eb02f0f9a19ad39d6d2
Reviewed-on: https://gerrit.chromium.org/gerrit/14716
Reviewed-by: David James <davidjames@chromium.org>
Tested-by: Richard Barnette <jrbarnette@chromium.org>
diff --git a/host/cros_generate_update_payload b/host/cros_generate_update_payload
index af1c4bc..edbf303 100755
--- a/host/cros_generate_update_payload
+++ b/host/cros_generate_update_payload
@@ -47,7 +47,6 @@
 DST_KERNEL=""
 DST_ROOT=""
 STATE_MNT=""
-STATE_LOOP_DEV=""
 
 # Pass an arg to not exit 1 at the end
 cleanup() {
@@ -63,14 +62,10 @@
     DST_MNT=""
   fi
   if [ -n "$STATE_MNT" ]; then
-    sudo umount "$STATE_MNT"
+    sudo umount -d "$STATE_MNT" || true
     [ -d "$STATE_MNT" ] && rmdir "$STATE_MNT"
     STATE_MNT=""
   fi
-  if [ -n "$STATE_LOOP_DEV" ]; then
-    sudo losetup -d "$STATE_LOOP_DEV"
-    STATE_LOOP_DEV=""
-  fi
   rm -f "$SRC_KERNEL"
   rm -f "$SRC_ROOT"
   rm -f "$DST_KERNEL"
@@ -109,18 +104,14 @@
 
   echo "Patching kernel" $KERN_FILE
   echo "   into" $IMAGE
-  STATE_LOOP_DEV=$(sudo losetup -f)
-  [ -n "$STATE_LOOP_DEV" ] || die "no free loop device"
   local offset=$(partoffset "${IMAGE}" 1)
   offset=$(($offset * 512))
-  sudo losetup -o "$offset" "$STATE_LOOP_DEV" "$IMAGE"
   STATE_MNT=$(mktemp -d /tmp/state.XXXXXX)
-  sudo mount --read-only "$STATE_LOOP_DEV" "$STATE_MNT"
+  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
-  sudo umount "$STATE_MNT"
+  sudo umount -d "$STATE_MNT"
+  rmdir "$STATE_MNT"
   STATE_MNT=""
-  sudo losetup -d "$STATE_LOOP_DEV"
-  STATE_LOOP_DEV=""
 }
 
 extract_kern_root() {