Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Unified Diff: build_image

Issue 5682006: Add support for preserving on-disk file layout (Closed) Base URL: http://git.chromium.org/git/crosutils.git@master
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698