Index: build_image |
diff --git a/build_image b/build_image |
index 492b160e786f394ec3cb5c5a2940f99e6db369bc..0f8324bd006d2bcad268e79b491e87bd81409db1 100755 |
--- a/build_image |
+++ b/build_image |
@@ -51,6 +51,9 @@ DEFINE_integer rootfs_partition_size 1024 \ |
"rootfs parition size in MBs." |
DEFINE_integer rootfs_size 720 \ |
"rootfs filesystem size in MBs." |
+# ceil(0.1 * rootfs_size) is a good minimum. |
+DEFINE_integer rootfs_hash_pad 8 \ |
+ "MBs reserved at the end of the rootfs image." |
DEFINE_integer statefulfs_size 1024 \ |
"stateful filesystem size in MBs." |
DEFINE_boolean preserve ${FLAGS_FALSE} \ |
@@ -91,8 +94,10 @@ if [ -z "${FLAGS_board}" ] ; then |
exit 1 |
fi |
-if [ "${FLAGS_rootfs_size}" -gt "${FLAGS_rootfs_partition_size}" ] ; then |
- error "rootfs (${FLAGS_rootfs_size} MB) is bigger than partition (${FLAGS_rootfs_partition_size} MB)." |
+if [ "$((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad))" -gt \ |
+ "${FLAGS_rootfs_partition_size}" ] ; then |
+ error "rootfs ($((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad)) MB) is \ |
+bigger than partition (${FLAGS_rootfs_partition_size} MB)." |
exit 1 |
fi |
@@ -293,8 +298,10 @@ make_image_bootable() { |
--image "${image_name}" -r "${ROOT_FS_DIR}" \ |
-s "${STATEFUL_FS_DIR}" |
+ # The rootfs should never be mounted rw again after this point without |
+ # re-calling make_image_bootable. |
sudo mount -o remount,ro "${ROOT_FS_DIR}" |
- root_dev=$(mount | grep -- "${ROOT_FS_DIR}" | cut -f1 -d' ' | tail -1) |
+ root_dev=$(mount | grep -- "on ${ROOT_FS_DIR} type" | cut -f1 -d' ' | tail -1) |
DEVKEYSDIR="/usr/share/vboot/devkeys" |
@@ -308,7 +315,7 @@ make_image_bootable() { |
--working_dir="${OUTPUT_DIR}" \ |
--keep_work \ |
--rootfs_image=${root_dev} \ |
- --rootfs_hash=${OUTPUT_DIR}/rootfs.hash \ |
+ --rootfs_hash=${ROOT_FS_HASH} \ |
--verity_hash_alg=${FLAGS_verity_algorithm} \ |
--verity_tree_depth=${FLAGS_verity_depth} \ |
--verity_max_ios=${FLAGS_verity_max_ios} \ |
@@ -316,6 +323,25 @@ make_image_bootable() { |
--root=${cros_root} \ |
--keys_dir="${DEVKEYSDIR}" |
+ local rootfs_hash_size=$(stat -c '%s' ${ROOT_FS_HASH}) |
+ info "Appending rootfs.hash (${rootfs_hash_size} bytes) to the root fs" |
+ if [[ ${rootfs_hash_size} -gt $((FLAGS_rootfs_hash_pad * 1024 * 1024)) ]] |
+ then |
+ die "--rootfs_hash_pad reserves less than the needed ${rootfs_hash_size}" |
+ fi |
+ # Unfortunately, mount_gpt_image uses mount and not losetup to create the |
+ # loop devices. This means that they are not the correct size. We have to |
+ # write directly to the image to append the hash tree data. |
+ local hash_offset="$(partoffset ${OUTPUT_DIR}/${image_name} 3)" |
+ hash_offset=$((hash_offset + ((1024 * 1024 * ${FLAGS_rootfs_size}) / 512))) |
+ sudo dd bs=512 \ |
+ seek=${hash_offset} \ |
+ if="${ROOT_FS_HASH}" \ |
+ of="${OUTPUT_DIR}/${image_name}" \ |
+ conv=notrunc |
+ # We don't need to keep the file around anymore. |
+ sudo rm "${ROOT_FS_HASH}" |
+ |
# Move the verification block needed for the hard disk install to the |
# stateful partition. Mount stateful fs, copy file, and umount fs. |
# In original CL: http://codereview.chromium.org/2868044, this was done in |
@@ -510,7 +536,18 @@ create_base_image() { |
sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" |
sudo mkfs.ext3 "${LOOP_DEV}" |
+ # Pad out 10% for the hash tree. This currently _exact_ for |
+ # default configuration. More space may be needed for different options. |
+ ROOT_HASH_PAD=$((FLAGS_rootfs_hash_pad * 1024 * 1024)) |
+ info "Padding the rootfs image by ${ROOT_HASH_PAD} bytes for hash data" |
+ dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 \ |
+ seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1)) |
+ # Update to reflect the new capacity in the loop device. |
+ sudo losetup -c "${LOOP_DEV}" |
+ |
# Tune and mount rootfs. |
+ # TODO(wad) rename the disk label to match the GPT since we |
+ # can't change it later. |
DISK_LABEL="C-KEYFOB" |
sudo tune2fs -L "${DISK_LABEL}" -U "${UUID}" -c 0 -i 0 "${LOOP_DEV}" |
sudo mount "${LOOP_DEV}" "${ROOT_FS_DIR}" |