Chromium Code Reviews| Index: build_image | 
| diff --git a/build_image b/build_image | 
| index bd49af5054b2e468f99711d3bceb26d170ed4404..d25fb4e123da517900dc1367ac22885dfe326288 100755 | 
| --- a/build_image | 
| +++ b/build_image | 
| @@ -84,6 +84,11 @@ DEFINE_string verity_algorithm "sha1" \ | 
| DEFINE_string oem_customization "" \ | 
| "Path to directory containing OEM partner partition contents" | 
| +DEFINE_string base_image "" \ | 
| + "Path to base image for which this image will be derived from" | 
| +DEFINE_boolean zero_freespace ${FLAGS_FALSE} \ | 
| 
 
petkov
2010/12/10 18:33:30
any downside in defaulting this to TRUE?
 
 | 
| + "Zeroes the freespace to improve compression for delta updates" | 
| + | 
| # Parse command line. | 
| FLAGS "$@" || exit 1 | 
| eval set -- "${FLAGS_ARGV}" | 
| @@ -128,6 +133,11 @@ if [ "${FLAGS_installmask}" -eq "${FLAGS_TRUE}" ] ; then | 
| INSTALL_MASK="${DEFAULT_INSTALL_MASK}" | 
| fi | 
| +# Make sure base image exists before we go too far | 
| +if [ ! -z "${FLAGS_base_image}" ] && [ ! -f "${FLAGS_base_image}" ] ; then | 
| 
 
petkov
2010/12/10 18:33:30
if [ -n "${FLAGS_base_image}" ] ...
 
sosa
2010/12/10 19:28:10
-n instead of ! -z
 
 | 
| + die "Cannot find base image ${FLAGS_base_image}" | 
| +fi | 
| + | 
| # Reduce the size of factory install shim. | 
| if [ "${FLAGS_factory_install}" -eq "${FLAGS_TRUE}" ] || | 
| [ "${FLAGS_dev_install}" -eq "${FLAGS_TRUE}" ] ; then | 
| @@ -225,10 +235,14 @@ ESP_FS_DIR=${OUTPUT_DIR}/esp | 
| DEVKEYSDIR="/usr/share/vboot/devkeys" | 
| +NEW_ROOT_FS=${OUTPUT_DIR}/new.image | 
| +NEW_ROOT_FS_DIR=/tmp/mnew | 
| 
 
sosa
2010/12/10 19:28:10
Create a temp dir ... why use the same one everyti
 
 | 
| + | 
| LOOP_DEV= | 
| STATEFUL_LOOP_DEV= | 
| OEM_LOOP_DEV= | 
| ESP_LOOP_DEV= | 
| +NEW_ROOT_FS_LOOP_DEV= | 
| # ${DEV_IMAGE_ROOT} specifies the location of where developer packages will | 
| # be installed on the stateful dir. On a Chromium OS system, this will | 
| @@ -503,6 +517,91 @@ update_base_packages() { | 
| -s "${STATEFUL_FS_DIR}" -e "${ESP_FS_DIR}" | 
| } | 
| +zero_rootfs_freespace() { | 
| + # Disable die on error so dd can write until EOF | 
| 
 
sosa
2010/12/10 19:28:10
Make this more function-y .. i.e. use $1 $2 etc
 
 | 
| + set +e | 
| 
 
sosa
2010/12/10 19:28:10
Don't set +e / -e ... use || instead on the dd lin
 
 | 
| + | 
| + local rootfs_dir=$1 | 
| + echo "Zeroing freespace" | 
| + sudo dd if=/dev/zero of="${rootfs_dir}/filler" 2>/dev/null | 
| + sudo rm "${rootfs_dir}/filler" | 
| + | 
| + set -e | 
| +} | 
| + | 
| +align_rootfs_cleanup() { | 
| + # Disable die on error. | 
| + set +e | 
| + | 
| + if [ -n "${NEW_ROOT_FS_LOOP_DEV}" ] ; then | 
| + sudo umount -d "${NEW_ROOT_FS_DIR}" | 
| + sudo rmdir "${NEW_ROOT_FS_DIR}" | 
| + NEW_ROOT_FS_LOOP_DEV= | 
| + fi | 
| + | 
| + # Turn die on error back on. | 
| + set -e | 
| +} | 
| + | 
| +align_rootfs() { | 
| + | 
| + echo "Aligning rootfs on-disk file layout to base image" | 
| 
 
sosa
2010/12/10 19:28:10
info
 
 | 
| + | 
| + # Extract rootfs from base image to output directory. | 
| + local rootfs_offset=$(partoffset "${FLAGS_base_image}" 3) | 
| + local rootfs_count=$(partsize "${FLAGS_base_image}" 3) | 
| + dd if="${FLAGS_base_image}" of="${NEW_ROOT_FS}" bs=512 conv=fsync \ | 
| + skip=${rootfs_offset} count=${rootfs_count} &> /dev/null | 
| + enable_rw_mount "${NEW_ROOT_FS}" | 
| 
 
sosa
2010/12/10 19:28:10
Why is this necessary?  Can't rw just be set in th
 
 | 
| + | 
| + # Mount the new image. | 
| + NEW_ROOT_FS_LOOP_DEV=$(sudo losetup -f) | 
| 
 
sosa
2010/12/10 19:28:10
Not sure you even have to do this rather than moun
 
 | 
| + if [ -z "${NEW_ROOT_FS_LOOP_DEV}" ] ; then | 
| + echo "No free loop device. Free up a loop device or reboot. exiting. " | 
| + exit 1 | 
| + fi | 
| + | 
| + sudo mkdir -p "${NEW_ROOT_FS_DIR}" | 
| + sudo losetup "${NEW_ROOT_FS_LOOP_DEV}" "${NEW_ROOT_FS}" | 
| + sudo mount "${NEW_ROOT_FS_LOOP_DEV}" "${NEW_ROOT_FS_DIR}" | 
| + | 
| + trap "align_rootfs_cleanup" EXIT | 
| + | 
| + # Temporarily make immutable files mutable. | 
| + immutable_files=() | 
| 
 
sosa
2010/12/10 19:28:10
local?
 
 | 
| + NEW_ROOT_FS_DIR_ESCAPED=$(echo "${NEW_ROOT_FS_DIR}" | sed 's/\//\\\//g') | 
| 
 
sosa
2010/12/10 19:28:10
Why global?
 
sosa
2010/12/10 19:28:10
Use a diff seperater in your sed than / to make th
 
 | 
| + local enum_files_cmd='sudo find "${NEW_ROOT_FS_DIR}" -xdev -type f' | 
| 
 
sosa
2010/12/10 19:28:10
Why exclude directories and such?
 
 | 
| + eval $enum_files_cmd | sed "s/${NEW_ROOT_FS_DIR_ESCAPED}//" | \ | 
| 
 
sosa
2010/12/10 19:28:10
{}
 
 | 
| + while read -r FILE ; do | 
| + immutable=$(sudo lsattr "${NEW_ROOT_FS_DIR}$FILE" | cut -d' ' -f1 | \ | 
| 
 
sosa
2010/12/10 19:28:10
shouldn't there be spaces in the cut
 
 | 
| + grep -q i ; echo $?) | 
| + if [ $immutable -eq 0 ] ; then | 
| 
 
sosa
2010/12/10 19:28:10
{}
 
sosa
2010/12/10 19:28:10
No spaces before ; same elsewhere
 
 | 
| + immutable_files=("${immutable_files[@]}" "${NEW_ROOT_FS_DIR}$FILE") | 
| + sudo chattr -i "${NEW_ROOT_FS_DIR}$FILE" | 
| 
 
sosa
2010/12/10 19:28:10
Little confused ... you set this immmutable twice
 
 | 
| + fi | 
| + done | 
| + | 
| + # Copy files over top of base image files to preserve file layout as much | 
| + # as possible. | 
| 
 
sosa
2010/12/10 19:28:10
Layout?  maybe metadata is more accurate
 
 | 
| + sudo rsync -a -H -A -x --force --inplace \ | 
| + "${ROOT_FS_DIR}/" "${NEW_ROOT_FS_DIR}" | 
| + | 
| + for FILE in ${immutable_files[*]} ; do | 
| + sudo chattr -i "${NEW_ROOT_FS_DIR}$FILE" | 
| + done | 
| + | 
| + # Zero out free space, this makes it more compressible leading to a smaller | 
| + # delta update. | 
| + if [ "${FLAGS_zero_freespace}" -eq "${FLAGS_TRUE}" ] ; then | 
| + zero_rootfs_freespace "${NEW_ROOT_FS_DIR}" | 
| + fi | 
| + | 
| + sudo umount -d "${NEW_ROOT_FS_DIR}" | 
| + sudo rmdir "${NEW_ROOT_FS_DIR}" | 
| + | 
| + trap - EXIT | 
| +} | 
| + | 
| create_base_image() { | 
| local image_name=$1 | 
| @@ -528,7 +627,7 @@ create_base_image() { | 
| seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1)) | 
| sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}" | 
| # Specify a block size and block count to avoid using the hash pad. | 
| - sudo mkfs.ext2 -b 4096 "${LOOP_DEV}" "$((ROOT_SIZE_BYTES / 4096))" | 
| + sudo mkfs.ext2 -O ^has_journal -b 4096 "${LOOP_DEV}" "$((ROOT_SIZE_BYTES / 4096))" | 
| # Tune and mount rootfs. | 
| DISK_LABEL="C-ROOT" | 
| @@ -683,8 +782,19 @@ create_base_image() { | 
| # Create an empty esp image to be updated in by update_bootloaders.sh. | 
| ${SCRIPTS_DIR}/create_esp.sh --to="${ESP_FS_IMG}" | 
| + # Align the rootfs to the previous if there's a base image to align to | 
| + if [ -n "${FLAGS_base_image}" ] ; then | 
| + align_rootfs | 
| + fi | 
| + | 
| cleanup | 
| + # Copy new aligned image over to of rootfs.img | 
| + if [ -n "${FLAGS_base_image}" ] ; then | 
| + rm "${ROOT_FS_IMG}" | 
| + mv "${NEW_ROOT_FS}" "${ROOT_FS_IMG}" | 
| + fi | 
| + | 
| trap delete_prompt EXIT | 
| # Create the GPT-formatted image. |