Allow the image to be up to 10MB larger than specified.

We ran into a case in the reven-vmtest postsubmit builder where
image_to_vm.sh was failing because the stateful partition on our test
images was 8198MB, while the disk layout specifies 8192MB.

After some investigation we narrowed the issue down to the `fs_align`
attribute in disk_layout_v2.json: without that attribute the stateful
partition comes out as specified.

This change makes image_to_vm.sh more permissive when resizing the
stateful partition: the partition on the image can now be up to 10MB
larger than is specified in the disk layout.

BUG=b:199909888
TEST=setup_board --board reven-vmtest
     ./build_packages --board reven-vmtest
     ./build_image --board reven-vmtest test
     ./image_to_vm.sh --board reven-vmtest --test_image

Change-Id: I6a378abc5125c720a8cea1900c8d455a36481b2f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosutils/+/3173634
Tested-by: Joseph Sussman <josephsussman@google.com>
Auto-Submit: Joseph Sussman <josephsussman@google.com>
Reviewed-by: Alex Klein <saklein@chromium.org>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Commit-Queue: Joseph Sussman <josephsussman@google.com>
diff --git a/image_to_vm.sh b/image_to_vm.sh
index 3625c14..46f3b5d 100755
--- a/image_to_vm.sh
+++ b/image_to_vm.sh
@@ -151,10 +151,24 @@
 original_image_size=$(bd_safe_size "${SRC_STATE}")
 if [ "${original_image_size}" -gt "${STATEFUL_SIZE_BYTES}" ]; then
   if [ $(( original_image_size - STATEFUL_SIZE_BYTES )) -lt \
-      $(( 1024 * 1024 )) ]; then
-    # cgpt.py sometimes makes the stateful a tiny bit larger to
-    # counteract alignment losses.
-    # This is fine -- just keep using the slightly larger partition as it is.
+      $(( 10 * 1024 * 1024 )) ]; then
+    # cgpt.py adds makeup padding to paritions to counteract alignment losses.
+    # Each partition gets expanded by an additional `fs_block_size` bytes, and
+    # in the case where `fs_align` is defined, rootfs and data partitions get
+    # expanded by `fs_align` bytes:
+    #
+    # https://chromium.googlesource.com/chromiumos/platform/crosutils/+/HEAD/build_library/cgpt.py#554
+    #
+    # The original legacy_disk_layout.json does not specify `fs_align`, which
+    # results in an image size that is only slightly larger than is specified
+    # in the disk layout. disk_layout_v2.json sets `fs_align` to 2MiB, which
+    # results in a significantly larger delta. Therefore:
+    #
+    # max_delta = fs_align * (# in use data and rootfs partitions + 1)
+    #
+    # With that in mind, set the maximum delta to 10MiB for now: this should be
+    # sufficient to support both disk_layout_v2.json and disk_layout_v3.json
+    # based layouts.
     TEMP_STATE="${SRC_STATE}"
   else
     die "Cannot resize stateful image to smaller than original. Exiting."