Merge pull request #92 from marineam/images

Lots of image building updates
This commit is contained in:
Michael Marineau 2013-08-21 15:35:34 -07:00
commit 63713f2eee
14 changed files with 150 additions and 475 deletions

View File

@ -95,14 +95,6 @@ DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \
"Default all bootloaders to NOT use kernel-based root fs integrity checking."
DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \
"Default all bootloaders to NOT use bootcache."
DEFINE_integer verity_error_behavior 3 \
"Kernel verified boot error behavior (0: I/O errors, 1: reboot, 2: nothing)"
DEFINE_integer verity_max_ios -1 \
"Number of outstanding I/O operations dm-verity caps at."
DEFINE_string verity_algorithm "sha1" \
"Cryptographic hash algorithm used for kernel vboot."
DEFINE_string verity_salt "" \
"Salt for rootfs hash tree."
DEFINE_string keys_dir "/usr/share/vboot/devkeys" \
"Directory containing the signing keys."
@ -141,15 +133,11 @@ DEFINE_boolean enable_squashfs ${FLAGS_FALSE} \
DEFINE_string squash_sort_file "" \
"Specify the priority of files when squashing the rootfs."
DEFINE_string enable_serial "" \
"Enable serial port for printks. Example values: ttyS0"
# Parse the boot.desc and any overrides
eval set -- "${BOOT_DESC} ${FLAG_OVERRIDES}"
FLAGS "${@}" || exit 1
[ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt)
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
# Only now can we die on error. shflags functions leak non-zero error codes,

View File

@ -29,10 +29,6 @@ DEFINE_string disk_layout "default" \
"The disk layout type to use for this image."
DEFINE_boolean standard_backdoor ${FLAGS_TRUE} \
"Install standard backdoor credentials for testing"
DEFINE_string usb_disk /dev/sdb4 \
"Path syslinux should use to do a usb boot. Default: /dev/sdb4"
DEFINE_string enable_serial "" \
"Enable serial port for printks. Example values: ttyS0"
# include upload options
. "${BUILD_LIBRARY_DIR}/release_util.sh" || exit 1

View File

@ -4,7 +4,7 @@
. "${SRC_ROOT}/platform/dev/toolchain_utils.sh" || exit 1
# Overlays are parts of the disk that live on the stateful partition
# Overlays are parts of the disk that live on the state partition
ROOT_OVERLAYS=(var opt srv home usr/local)
cleanup_mounts() {
@ -28,10 +28,15 @@ cleanup_mounts() {
echo "Cleaning up mounts"
safe_umount_tree "${root_fs_dir}"
safe_umount_tree "${stateful_fs_dir}"
safe_umount_tree "${state_fs_dir}"
safe_umount_tree "${esp_fs_dir}"
safe_umount_tree "${oem_fs_dir}"
if [[ -n "${loop_dev}" ]]; then
sudo losetup -d "${loop_dev}"
loop_dev=
fi
# Turn die on error back on.
set -e
}
@ -40,14 +45,10 @@ create_base_image() {
local image_name=$1
local rootfs_verification_enabled=$2
local bootcache_enabled=$3
local image_type="usb"
local image_type="base"
if [[ "${FLAGS_disk_layout}" != "default" ]]; then
image_type="${FLAGS_disk_layout}"
else
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
image_type="factory_install"
fi
fi
check_valid_layout "base"
@ -56,43 +57,40 @@ create_base_image() {
info "Using image type ${image_type}"
root_fs_dir="${BUILD_DIR}/rootfs"
stateful_fs_dir="${BUILD_DIR}/stateful"
state_fs_dir="${BUILD_DIR}/state"
esp_fs_dir="${BUILD_DIR}/esp"
oem_fs_dir="${BUILD_DIR}/oem"
trap "cleanup_mounts && delete_prompt" EXIT
cleanup_mounts &> /dev/null
local root_fs_label="ROOT-A"
local root_fs_num=$(get_num ${image_type} ${root_fs_label})
local root_fs_img="${BUILD_DIR}/rootfs.image"
local root_fs_bytes=$(get_filesystem_size ${image_type} ${root_fs_num})
local stateful_fs_label="STATE"
local stateful_fs_num=$(get_num ${image_type} ${stateful_fs_label})
local stateful_fs_img="${BUILD_DIR}/stateful.image"
local stateful_fs_bytes=$(get_filesystem_size ${image_type} ${stateful_fs_num})
local stateful_fs_uuid=$(uuidgen)
local esp_fs_label="EFI-SYSTEM"
local esp_fs_num=$(get_num ${image_type} ${esp_fs_label})
local esp_fs_img="${BUILD_DIR}/esp.image"
local esp_fs_bytes=$(get_filesystem_size ${image_type} ${esp_fs_num})
local oem_fs_label="OEM"
local oem_fs_num=$(get_num ${image_type} ${oem_fs_label})
local oem_fs_img="${BUILD_DIR}/oem.image"
local oem_fs_bytes=$(get_filesystem_size ${image_type} ${oem_fs_num})
local oem_fs_uuid=$(uuidgen)
write_partition_table "${image_type}" "${BUILD_DIR}/${image_name}"
loop_dev=$(sudo losetup -P -f --show "${BUILD_DIR}/${image_name}")
local fs_block_size=$(get_fs_block_size)
local root_fs_label="ROOT-A"
local root_fs_num=$(get_num ${image_type} ${root_fs_label})
local root_fs_dev="${loop_dev}p${root_fs_num}"
local root_fs_bytes=$(get_filesystem_size ${image_type} ${root_fs_num})
local root_fs_blocks=$((root_fs_bytes / fs_block_size))
local state_fs_label="STATE"
local state_fs_num=$(get_num ${image_type} ${state_fs_label})
local state_fs_dev="${loop_dev}p${state_fs_num}"
local esp_fs_label="EFI-SYSTEM"
local esp_fs_num=$(get_num ${image_type} ${esp_fs_label})
local esp_fs_dev="${loop_dev}p${esp_fs_num}"
local oem_fs_label="OEM"
local oem_fs_num=$(get_num ${image_type} ${oem_fs_label})
local oem_fs_dev="${loop_dev}p${oem_fs_num}"
# Build root FS image.
info "Building ${root_fs_img}"
truncate --size="${root_fs_bytes}" "${root_fs_img}"
/sbin/mkfs.ext2 -F -q -b ${fs_block_size} "${root_fs_img}" \
"$((root_fs_bytes / fs_block_size))"
/sbin/tune2fs -L "${root_fs_label}" \
info "Building ROOT filesystem"
sudo mkfs.ext2 -F -q -b ${fs_block_size} "${root_fs_dev}" "${root_fs_blocks}"
sudo tune2fs -L "${root_fs_label}" \
-U clear \
-T 20091119110000 \
-c 0 \
@ -100,57 +98,56 @@ create_base_image() {
-m 0 \
-r 0 \
-e remount-ro \
"${root_fs_img}"
"${root_fs_dev}"
mkdir -p "${root_fs_dir}"
sudo mount -o loop "${root_fs_img}" "${root_fs_dir}"
sudo mount "${root_fs_dev}" "${root_fs_dir}"
df -h "${root_fs_dir}"
# Build stateful FS disk image.
info "Building ${stateful_fs_img}"
truncate --size="${stateful_fs_bytes}" "${stateful_fs_img}"
/sbin/mkfs.ext4 -F -q "${stateful_fs_img}"
/sbin/tune2fs -L "${stateful_fs_label}" -U "${stateful_fs_uuid}" \
-c 0 -i 0 "${stateful_fs_img}"
mkdir -p "${stateful_fs_dir}"
sudo mount -o loop "${stateful_fs_img}" "${stateful_fs_dir}"
# Build state FS disk image.
info "Building STATE filesystem"
sudo mkfs.ext4 -F -q "${state_fs_dev}"
sudo tune2fs -L "${state_fs_label}" \
-c 0 \
-i 0 \
"${state_fs_dev}"
mkdir -p "${state_fs_dir}"
sudo mount "${state_fs_dev}" "${state_fs_dir}"
# Build ESP disk image.
info "Building ${esp_fs_img}"
truncate --size="${esp_fs_bytes}" "${esp_fs_img}"
/usr/sbin/mkfs.vfat "${esp_fs_img}"
info "Building ESP filesystem"
sudo mkfs.vfat "${esp_fs_dev}"
# Build OEM FS disk image.
info "Building ${oem_fs_img}"
truncate --size="${oem_fs_bytes}" "${oem_fs_img}"
/sbin/mkfs.ext4 -F -q "${oem_fs_img}"
/sbin/tune2fs -L "${oem_fs_label}" -U "${oem_fs_uuid}" \
-c 0 -i 0 "${oem_fs_img}"
info "Building OEM filesystem"
sudo mkfs.ext4 -F -q "${oem_fs_dev}"
sudo tune2fs -L "${oem_fs_label}" \
-c 0 \
-i 0 \
"${oem_fs_dev}"
mkdir -p "${oem_fs_dir}"
sudo mount -o loop "${oem_fs_img}" "${oem_fs_dir}"
sudo mount "${oem_fs_dev}" "${oem_fs_dir}"
# Prepare stateful partition with some pre-created directories.
# Prepare state partition with some pre-created directories.
for i in ${ROOT_OVERLAYS}; do
sudo mkdir -p "${stateful_fs_dir}/overlays/$i"
sudo mkdir -p "${state_fs_dir}/overlays/$i"
sudo mkdir -p "${root_fs_dir}/$i"
sudo mount --bind "${stateful_fs_dir}/overlays/$i" "${root_fs_dir}/$i"
sudo mount --bind "${state_fs_dir}/overlays/$i" "${root_fs_dir}/$i"
done
sudo mkdir -p "${stateful_fs_dir}/overlays/usr/local"
sudo mkdir -p "${state_fs_dir}/overlays/usr/local"
# Create symlinks so that /usr/local/usr based directories are symlinked to
# /usr/local/ directories e.g. /usr/local/usr/bin -> /usr/local/bin, etc.
setup_symlinks_on_root "${stateful_fs_dir}/overlays/usr/local" \
"${stateful_fs_dir}/overlays/var" \
"${stateful_fs_dir}"
setup_symlinks_on_root "${state_fs_dir}/overlays/usr/local" \
"${state_fs_dir}/overlays/var" \
"${state_fs_dir}"
# Perform binding rather than symlinking because directories must exist
# on rootfs so that we can bind at run-time since rootfs is read-only.
info "Binding directories from stateful partition onto the rootfs"
info "Binding directories from state partition onto the rootfs"
# Setup the dev image for developer tools
sudo mkdir -p "${root_fs_dir}/usr/local"
sudo mount --bind "${stateful_fs_dir}/overlays/usr/local" "${root_fs_dir}/usr/local"
sudo mount --bind "${state_fs_dir}/overlays/usr/local" "${root_fs_dir}/usr/local"
# TODO(bp): remove these temporary fixes for /mnt/stateful_partition going moving
sudo mkdir -p "${root_fs_dir}/mnt/stateful_partition/"
@ -212,10 +209,11 @@ create_base_image() {
# trim the image size as much as possible.
emerge_to_image --root="${root_fs_dir}" ${BASE_PACKAGE}
# Record directories installed to the stateful partition.
sudo "${SCRIPTS_DIR}/gen_tmpfiles.py" --root="${root_fs_dir}" \
# Record directories installed to the state partition.
# Ignore /var/tmp, systemd covers this entry.
sudo "${BUILD_LIBRARY_DIR}/gen_tmpfiles.py" --root="${root_fs_dir}" \
--output="${root_fs_dir}/usr/lib/tmpfiles.d/base_image.conf" \
"${root_fs_dir}/var"
--ignore=/var/tmp "${root_fs_dir}/var"
# Set /etc/lsb-release on the image.
"${BUILD_LIBRARY_DIR}/set_lsb_release" \
@ -227,12 +225,6 @@ create_base_image() {
# cros_make_image_bootable.
create_boot_desc "${image_type}"
# Write out the GPT creation script.
# This MUST be done before writing bootloader templates else we'll break
# the hash on the root FS.
write_partition_script "${image_type}" \
"${root_fs_dir}/${PARTITION_SCRIPT_PATH}"
# Populates the root filesystem with legacy bootloader templates
# appropriate for the platform. The autoupdater and installer will
# use those templates to update the legacy boot partition (12/ESP)
@ -268,25 +260,15 @@ create_base_image() {
# Clean up symlinks so they work on a running target rooted at "/".
# Here development packages are rooted at /usr/local. However, do not
# create /usr/local or /var on host (already exist on target).
setup_symlinks_on_root "/usr/local" "/var" "${stateful_fs_dir}"
setup_symlinks_on_root "/usr/local" "/var" "${state_fs_dir}"
# Zero all fs free space to make it more compressible so auto-update
# payloads become smaller, not fatal since it won't work on linux < 3.2
sudo fstrim "${root_fs_dir}" || true
sudo fstrim "${stateful_fs_dir}" || true
sudo fstrim "${state_fs_dir}" || true
cleanup_mounts
# Create the GPT-formatted image.
build_gpt "${BUILD_DIR}/${image_name}" \
"${root_fs_img}" \
"${stateful_fs_img}" \
"${esp_fs_img}" \
"${oem_fs_img}"
# Clean up temporary files.
rm -f "${root_fs_img}" "${stateful_fs_img}" "${esp_fs_img}" "{oem_fs_img}"
# Emit helpful scripts for testers, etc.
emit_gpt_scripts "${BUILD_DIR}/${image_name}" "${BUILD_DIR}"

View File

@ -104,7 +104,6 @@ create_boot_desc() {
enable_bootcache_flag=--enable_bootcache
fi
[ -z "${FLAGS_verity_salt}" ] && FLAGS_verity_salt=$(make_salt)
cat <<EOF > ${BUILD_DIR}/boot.desc
--board=${BOARD}
--image_type=${image_type}
@ -112,8 +111,6 @@ create_boot_desc() {
--keys_dir="${DEVKEYSDIR}"
--boot_args="${FLAGS_boot_args}"
--nocleanup_dirs
--verity_algorithm=sha1
--enable_serial="${FLAGS_enable_serial}"
${enable_rootfs_verification_flag}
${enable_bootcache_flag}
EOF

View File

@ -3,10 +3,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import copy
import json
import os
import re
import subprocess
import sys
import uuid
from optparse import OptionParser
@ -93,41 +93,6 @@ def LoadPartitionConfig(filename):
return config
def GetTableTotals(config, partitions):
"""Calculates total sizes/counts for a partition table.
Args:
config: Partition configuration file object
partitions: List of partitions to process
Returns:
Dict containing totals data
"""
ret = {
'expand_count': 0,
'expand_min': 0,
'block_count': START_SECTOR * config['metadata']['block_size']
}
# Total up the size of all non-expanding partitions to get the minimum
# required disk size.
for partition in partitions:
if 'features' in partition and 'expand' in partition['features']:
ret['expand_count'] += 1
ret['expand_min'] += partition['blocks']
else:
ret['block_count'] += partition['blocks']
# At present, only one expanding partition is permitted.
# Whilst it'd be possible to have two, we don't need this yet
# and it complicates things, so it's been left out for now.
if ret['expand_count'] > 1:
raise InvalidLayout('1 expand partition allowed, %d requested'
% ret['expand_count'])
ret['min_disk_size'] = ret['block_count'] + ret['expand_min']
return ret
def GetPartitionTable(options, config, image_type):
@ -241,77 +206,72 @@ def GetPartitionTableFromConfig(options, layout_filename, image_type):
return partitions
def GetScriptShell():
"""Loads and returns the skeleton script for our output script.
Returns:
A string containg the skeleton script
"""
script_shell_path = os.path.join(os.path.dirname(__file__), 'cgpt_shell.sh')
with open(script_shell_path, 'r') as f:
script_shell = ''.join(f.readlines())
# Before we return, insert the path to this tool so somebody reading the
# script later can tell where it was generated.
script_shell = script_shell.replace('@SCRIPT_GENERATOR@', script_shell_path)
return script_shell
def WriteLayoutFunction(options, sfile, func_name, image_type, config):
"""Writes a shell script function to write out a given partition table.
def WritePartitionTable(options, image_type, layout_filename, disk_filename):
"""Writes the given partition table to a disk image or device.
Args:
options: Flags passed to the script
sfile: File handle we're writing to
func_name: Function name to write out for specified layout
image_type: Type of image eg base/test/dev/factory_install
config: Partition configuration file object
layout_filename: Path to partition configuration file
disk_filename: Path to disk image or device file
"""
def Cgpt(*args):
subprocess.check_call(['cgpt'] + [str(a) for a in args])
config = LoadPartitionConfig(layout_filename)
partitions = GetPartitionTable(options, config, image_type)
partition_totals = GetTableTotals(config, partitions)
disk_block_count = START_SECTOR * config['metadata']['block_size']
sfile.write('%s() {\ncreate_image $1 %d %s\n' % (
func_name, partition_totals['min_disk_size'],
config['metadata']['block_size']))
sfile.write('CURR=%d\n' % START_SECTOR)
sfile.write('$GPT create $1\n')
# Pass 1: Set up the expanding partition size.
for partition in partitions:
partition['var'] = partition['blocks']
disk_block_count += partition['blocks']
if partition['type'] != 'blank':
if partition['num'] == 1:
if 'features' in partition and 'expand' in partition['features']:
sfile.write('if [ -b $1 ]; then\n')
sfile.write('STATEFUL_SIZE=$(( $(numsectors $1) - %d))\n' %
partition_totals['block_count'])
sfile.write('else\n')
sfile.write('STATEFUL_SIZE=%s\n' % partition['blocks'])
sfile.write('fi\n')
partition['var'] = '$STATEFUL_SIZE'
sector = START_SECTOR
Cgpt('create', '-c', '-s', disk_block_count, disk_filename)
sfile.write('STATEFUL_SIZE=$((STATEFUL_SIZE-(STATEFUL_SIZE %% %d)))\n' %
config['metadata']['fs_block_size'])
# Pass 2: Write out all the cgpt add commands.
for partition in partitions:
if partition['type'] != 'blank':
sfile.write('$GPT add -i %d -b $CURR -s %s -t %s -l %s -u %s $1 && ' % (
partition['num'], str(partition['var']), partition['type'],
partition['label'], partition['uuid']))
Cgpt('add', '-i', partition['num'],
'-b', sector,
'-s', partition['blocks'],
'-t', partition['type'],
'-l', partition['label'],
'-u', partition['uuid'],
disk_filename)
sector += partition['blocks']
Cgpt('show', disk_filename)
def WriteMbrBoot(options, image_type, layout_filename,
disk_filename, mbr_filename):
"""Writes the protective MBR with the given boot code.
The EFI System Partition will be marked as the 'boot' partition.
Args:
options: Flags passed to the script
image_type: Type of image eg base/test/dev/factory_install
layout_filename: Path to partition configuration file
disk_filename: Path to disk image or device file
mbr_filename: Path to boot code, usually gptmbr.bin from syslinux.
"""
config = LoadPartitionConfig(layout_filename)
partitions = GetPartitionTable(options, config, image_type)
esp_number = None
for partition in partitions:
if partition['type'] == 'efi':
sfile.write('$GPT boot -p -b $2 -i %d $1\n' % partition['num'])
esp_number = partition['num']
break
if esp_number is None:
raise InvalidLayout('Table does not include an EFI partition.')
# Increment the CURR counter ready for the next partition.
sfile.write('CURR=$(( $CURR + %s ))\n' % partition['var'])
sfile.write('$GPT show $1\n')
sfile.write('}\n')
subprocess.check_call(['cgpt', 'boot', '-p', '-b', mbr_filename,
'-i', str(partition['num']), disk_filename])
def GetPartitionByNumber(partitions, num):
@ -350,26 +310,6 @@ def GetPartitionByLabel(partitions, label):
raise PartitionNotFound('Partition not found')
def WritePartitionScript(options, image_type, layout_filename, sfilename):
"""Writes a shell script with functions for the base and requested layouts.
Args:
options: Flags passed to the script
image_type: Type of image eg base/test/dev/factory_install
layout_filename: Path to partition configuration file
sfilename: Filename to write the finished script to
"""
config = LoadPartitionConfig(layout_filename)
with open(sfilename, 'w') as f:
script_shell = GetScriptShell()
f.write(script_shell)
WriteLayoutFunction(options, f, 'write_base_table', 'base', config)
WriteLayoutFunction(options, f, 'write_partition_table', image_type, config)
def GetBlockSize(options, layout_filename):
"""Returns the partition table block size.
@ -549,9 +489,14 @@ def DoParseOnly(options, image_type, layout_filename):
def main(argv):
action_map = {
'write': {
'usage': ['<image_type>', '<partition_config_file>', '<script_file>'],
'func': WritePartitionScript,
'write_gpt': {
'usage': ['<image_type>', '<partition_config_file>', '<disk_image>'],
'func': WritePartitionTable,
},
'write_mbr': {
'usage': ['<image_type>', '<partition_config_file>', '<disk_image>',
'<mbr_boot_code>'],
'func': WriteMbrBoot,
},
'readblocksize': {
'usage': ['<partition_config_file>'],

View File

@ -1,38 +0,0 @@
#!/bin/sh
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script is automatically generated by @SCRIPT_GENERATOR@
# Do not edit!
if ! type numsectors >/dev/null 2>&1; then
if [ -f "/usr/sbin/chromeos-common.sh" ]; then
. "/usr/sbin/chromeos-common.sh"
else
echo "Can't load chromeos-common.sh, dying!" 1>&2
exit 1
fi
fi
locate_gpt
# Usage: create_image <device> <min_disk_size> <block_size>
# If <device> is a block device, wipes out the GPT
# If it's not, it creates a new file of the requested size
create_image() {
local dev=$1
local min_disk_size=$2
local block_size=$3
if [ -b "${dev}" ]; then
# Zap any old partitions (otherwise gpt complains).
dd if=/dev/zero of="${dev}" conv=notrunc bs=512 count=32
dd if=/dev/zero of="${dev}" conv=notrunc bs=512 \
seek=$((${min_disk_size} - 1 - 33)) count=33
else
if [ ! -e "${dev}" ]; then
dd if=/dev/zero of="${dev}" bs=${block_size} count=1 \
seek=$((${min_disk_size} - 1))
fi
fi
}

View File

@ -18,19 +18,12 @@ DEFINE_string arch "x86" \
"The boot architecture: arm or x86. (Default: x86)"
DEFINE_string to "/tmp/boot" \
"Path to populate with bootloader templates (Default: /tmp/boot)"
DEFINE_string usb_disk /dev/sdb3 \
"Path syslinux should use to do a usb boot. Default: /dev/sdb3"
DEFINE_string boot_args "" \
"Additional boot arguments to pass to the commandline (Default: '')"
DEFINE_boolean enable_bootcache ${FLAGS_FALSE} \
"Default all bootloaders to NOT use boot cache."
DEFINE_boolean enable_rootfs_verification ${FLAGS_FALSE} \
"Controls if verity is used for root filesystem checking (Default: false)"
DEFINE_integer verity_error_behavior 3 \
"Verified boot error behavior [0: I/O errors, 1: reboot, 2: nothing] \
(Default: 3)"
DEFINE_integer verity_max_ios -1 \
"Optional number of outstanding I/O operations. (Default: 1024)"
# Parse flags
FLAGS "$@" || exit 1

View File

@ -17,7 +17,7 @@ install_dev_packages() {
trap "unmount_image ; delete_prompt" EXIT
mount_image "${BUILD_DIR}/${image_name}" "${root_fs_dir}" \
"${stateful_fs_dir}" "${esp_fs_dir}"
"${state_fs_dir}" "${esp_fs_dir}"
# Determine the root dir for developer packages.
local root_dev_dir="${root_fs_dir}/usr/local"
@ -90,7 +90,7 @@ EOF
# Zero all fs free space, not fatal since it won't work on linux < 3.2
sudo fstrim "${root_fs_dir}" || true
sudo fstrim "${stateful_fs_dir}" || true
sudo fstrim "${state_fs_dir}" || true
info "Developer image built and stored at ${image_name}"

View File

@ -3,7 +3,6 @@
# found in the LICENSE file.
CGPT_PY="${BUILD_LIBRARY_DIR}/cgpt.py"
PARTITION_SCRIPT_PATH="usr/sbin/write_gpt.sh"
cgpt_py() {
if [[ -n "${FLAGS_adjust_part-}" ]]; then
@ -20,7 +19,6 @@ cgpt_py() {
get_disk_layout_path() {
DISK_LAYOUT_PATH="${BUILD_LIBRARY_DIR}/legacy_disk_layout.json"
local partition_script_path=$(tempfile)
for overlay in $(cros_list_overlays --board "$BOARD"); do
local disk_layout="${overlay}/scripts/disk_layout.json"
if [[ -e ${disk_layout} ]]; then
@ -29,23 +27,9 @@ get_disk_layout_path() {
done
}
write_partition_script() {
write_partition_table() {
local image_type=$1
local partition_script_path=$2
get_disk_layout_path
local temp_script_file=$(mktemp)
sudo mkdir -p "$(dirname "${partition_script_path}")"
cgpt_py write "${image_type}" "${DISK_LAYOUT_PATH}" \
"${temp_script_file}"
sudo mv "${temp_script_file}" "${partition_script_path}"
}
run_partition_script() {
local outdev=$1
local root_fs_img=$2
local outdev=$2
local pmbr_img
case ${ARCH} in
@ -61,13 +45,10 @@ run_partition_script() {
;;
esac
if is_mounted "${root_fs_dir}"; then
safe_umount "${root_fs_dir}"
fi
sudo mount -o loop "${root_fs_img}" "${root_fs_dir}"
. "${root_fs_dir}/${PARTITION_SCRIPT_PATH}"
write_partition_table "${outdev}" "${pmbr_img}"
safe_umount "${root_fs_dir}"
get_disk_layout_path
cgpt_py write_gpt "${image_type}" "${DISK_LAYOUT_PATH}" "${outdev}"
cgpt_py write_mbr \
"${image_type}" "${DISK_LAYOUT_PATH}" "${outdev}" "${pmbr_img}"
}
get_fs_block_size() {
@ -131,9 +112,6 @@ check_valid_layout() {
get_disk_layout_type() {
DISK_LAYOUT_TYPE="base"
if should_build_image ${CHROMEOS_FACTORY_INSTALL_SHIM_NAME}; then
DISK_LAYOUT_TYPE="factory_install"
fi
}
emit_gpt_scripts() {
@ -204,7 +182,7 @@ build_gpt() {
local oem_img="$5"
get_disk_layout_type
run_partition_script "${outdev}" "${rootfs_img}"
write_partition_table "${DISK_LAYOUT_TYPE}" "${outdev}"
local sudo=
if [ ! -w "$outdev" ] ; then

View File

@ -1,7 +1,7 @@
#!/usr/bin/python
'''Scan an existing directory tree and record installed directories.
During build a number of directories under /var are created in the stateful
During build a number of directories under /var are created in the state
partition. We want to make sure that those are always there so create a record
of them using systemd's tempfiles config format so they are recreated during
boot if they go missing for any reason.
@ -19,6 +19,8 @@ def main():
parser = optparse.OptionParser(description=__doc__)
parser.add_option('--root', help='Remove root prefix from output')
parser.add_option('--output', help='Write output to the given file')
parser.add_option('--ignore', action='append', default=[],
help='Ignore one or more paths (use multiple times)')
opts, args = parser.parse_args()
if opts.root:
@ -56,6 +58,9 @@ def main():
else:
stripped = path
if stripped in opts.ignore:
continue
info = os.stat(path)
assert stat.S_ISDIR(info.st_mode)
mode = stat.S_IMODE(info.st_mode)

View File

@ -23,7 +23,7 @@
"label":"ROOT-A",
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
"type":"coreos-rootfs",
"blocks":"4194304",
"blocks":"2097152",
"fs_blocks":"262144"
},
{
@ -31,7 +31,7 @@
"label":"ROOT-B",
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
"type":"coreos-rootfs",
"blocks":"4194304",
"blocks":"2097152",
"fs_blocks":"262144"
},
{
@ -63,73 +63,10 @@
"num": 9,
"label":"STATE",
"type":"data",
"blocks":"2097152",
"features":["expand"]
}
],
"usb": [
{
"num": 3,
"label":"ROOT-A",
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
"type":"coreos-rootfs",
"blocks":"2539520",
"fs_blocks":"262144"
},
{
"num": 4,
"label":"ROOT-B",
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
"type":"coreos-rootfs",
"blocks":"1"
}
],
"factory_install": [
{
"num": 1,
"label":"EFI-SYSTEM",
"type":"efi",
"blocks":"65536"
},
{
"num": 3,
"label":"ROOT-A",
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
"type":"coreos-rootfs",
"blocks":"860160",
"fs_blocks":"102400"
},
{
"num": 4,
"label":"ROOT-B",
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
"type":"coreos-rootfs",
"blocks":"1"
},
{
"num": 9,
"label":"STATE",
"type":"data",
"blocks":"286720"
"blocks":"2097152"
}
],
"vm": [
{
"num": 3,
"label":"ROOT-A",
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
"type":"coreos-rootfs",
"blocks":"2097152",
"fs_blocks":"262144"
},
{
"num": 4,
"label":"ROOT-B",
"uuid":"e03dd35c-7c2d-4a47-b3fe-27f15780a57c",
"type":"coreos-rootfs",
"blocks":"2097152",
"fs_blocks":"262144"
},
{
"num": 9,
"label":"STATE",

View File

@ -180,14 +180,8 @@ unpack_source_disk() {
cp --sparse=always "${alternate_state_image}" "${TEMP_STATE}"
fi
TEMP_PMBR="${VM_TMP_DIR}"/pmbr
dd if="${VM_SRC_IMG}" of="${TEMP_PMBR}" bs=512 count=1
info "Initializing new partition table..."
TEMP_PARTITION_SCRIPT="${VM_TMP_DIR}/partition_script.sh"
write_partition_script "${disk_layout}" "${TEMP_PARTITION_SCRIPT}"
. "${TEMP_PARTITION_SCRIPT}"
write_partition_table "${VM_TMP_IMG}" "${TEMP_PMBR}"
write_partition_table "${disk_layout}" "${VM_TMP_IMG}"
}
resize_state_partition() {
@ -197,10 +191,10 @@ resize_state_partition() {
local original_size=$(stat -c%s "${TEMP_STATE}")
if [[ "${original_size}" -gt "${size_in_bytes}" ]]; then
die "Cannot resize stateful image to smaller than original."
die "Cannot resize state image to smaller than original."
fi
info "Resizing stateful partition to ${size_in_mb}MB"
info "Resizing state partition to ${size_in_mb}MB"
/sbin/e2fsck -pf "${TEMP_STATE}"
/sbin/resize2fs "${TEMP_STATE}" "${size_in_sectors}s"
}

View File

@ -68,7 +68,9 @@ if [ -z "${FLAGS_board}" ] ; then
die_notrace "--board is required."
fi
BOARD="$FLAGS_board"
# Loaded after flags are parsed because board_options depends on --board
. "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}"
# Default to the most recent image

View File

@ -1,104 +0,0 @@
#!/bin/bash
#
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Script to verify integrity of root file system for a GPT-based image
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
. "${SCRIPT_ROOT}/common.sh" || exit 1
# Load functions and constants for chromeos-install
[ -f /usr/lib/installer/chromeos-common.sh ] && \
INSTALLER_ROOT=/usr/lib/installer || \
INSTALLER_ROOT=$(dirname "$(readlink -f "$0")")
. "${INSTALLER_ROOT}/chromeos-common.sh" || exit 1
# Needed for partoffset and partsize calls
locate_gpt
# Script must be run inside the chroot.
restart_in_chroot_if_needed "$@"
DEFINE_string image "" "Device or an image path. Default: (empty)."
# Parse command line.
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
if [ -z $FLAGS_image ] ; then
die_notrace "Use --image to specify a device or an image file."
fi
# Turn path into an absolute path.
FLAGS_image=$(eval readlink -f ${FLAGS_image})
# Abort early if we can't find the image
if [ ! -b ${FLAGS_image} ] && [ ! -f $FLAGS_image ] ; then
die_notrace "No image found at $FLAGS_image"
fi
switch_to_strict_mode
get_partitions() {
if [ -b ${FLAGS_image} ] ; then
KERNEL_IMG=$(make_partition_dev "${FLAGS_image}" 2)
ROOTFS_IMG=$(make_partition_dev "${FLAGS_image}" 3)
return
fi
KERNEL_IMG=$(mktemp)
ROOTFS_IMG=$(mktemp)
local kernel_offset=$(partoffset "${FLAGS_image}" 2)
local kernel_count=$(partsize "${FLAGS_image}" 2)
local rootfs_offset=$(partoffset "${FLAGS_image}" 3)
local rootfs_count=$(partsize "${FLAGS_image}" 3)
# TODO(tgao): use loop device to save 1GB in temp space
dd if="${FLAGS_image}" of=${KERNEL_IMG} bs=512 skip=${kernel_offset} \
count=${kernel_count} &>/dev/null
dd if="${FLAGS_image}" of=${ROOTFS_IMG} bs=512 skip=${rootfs_offset} \
count=${rootfs_count} &>/dev/null
}
cleanup() {
for i in ${KERNEL_IMG} ${ROOTFS_IMG}; do
if [ ! -b ${i} ]; then
rm -f ${i}
fi
done
}
get_partitions
# Logic below extracted from src/platform/installer/chromeos-setimage
DUMP_KERNEL_CONFIG=/usr/bin/dump_kernel_config
KERNEL_CONFIG=$(sudo "${DUMP_KERNEL_CONFIG}" "${KERNEL_IMG}")
kernel_cfg="$(echo "${KERNEL_CONFIG}" | sed -e 's/.*dm="\([^"]*\)".*/\1/g' |
cut -f2- -d,)"
rootfs_sectors=$(echo ${kernel_cfg} | cut -f2 -d' ')
verity_algorithm=$(echo ${kernel_cfg} | cut -f8 -d' ')
# Compute the rootfs hash tree
VERITY=/bin/verity
# First argument to verity is reserved/unused and MUST be 0
table="vroot none ro,"$(sudo "${VERITY}" create 0 \
"${verity_algorithm}" \
"${ROOTFS_IMG}" \
$((rootfs_sectors / 8)) \
/dev/null)
expected_hash=$(echo ${kernel_cfg} | cut -f9 -d' ')
generated_hash=$(echo ${table} | cut -f2- -d, | cut -f9 -d' ')
cleanup
if [ "${expected_hash}" != "${generated_hash}" ]; then
warn "expected hash = ${expected_hash}"
warn "actual hash = ${generated_hash}"
die_notrace "Root filesystem has been modified unexpectedly!"
else
info "Root filesystem checksum match!"
fi