flatcar-scripts/mount_gpt_image.sh
Will Drewry 55b42c94ca cros_make_image_bootable, mount_gpt_image, common.sh: root filesystem changes: ext2, ro by default
This change makes more of the root filesyste metadata static across builds, but
more can be done there.  It also changes the root filesystem to use ext2 as
we don't need journaling in normal mode.  Optionally we could use ext3 for
non-verified if desired (it's an easy change).

In particular, this change cleans up the following:
- clears the rootfs uuid
- labels it C-ROOT (instead of C-KEYFOB)
- removes reserved inodes and blocks

The major feature of this change, however, is that it adds two simple
helpers to common.sh: disable_rw_mount and enable_rw_mount.  They will
set high order byte (le) in the ro compat field to be 0xff.  This will
tell the kernel that the filesystem uses features R24-R31 which are safe
for use on the running kernel iff the filesystem is mounted read-only.

These functions are called in cros_make_image_bootable and
mount_gpt_image, respectively.  mount_gpt_image will always
enable_rw_mount and cros_make_image_bootable will disable_rw_mount if
--enable_rootfs_verification is true.

The approach is ugly but reasonably well contained.  If ext2 ever gets a
new revision and new features in the same range are introduced, then we
would be getting inconsistent behavior.  That said, it is unlikely that
that churmn will happen and if the impact is negative, it will ideally
show up during testing.

N.B., this will likely result in changes needing to be made to the
signing scripts in vboot_reference to ensure that rw mounting is
enabled/disabled in the same way (E.g., during stamping).

BUG=chromium-os:7468
TEST=- built x86-generic, imaged to usb stick, attempted to mount rw /dev/sdc3 on the host and was properly bounced.
     - booted to the image just fine on a dogfood device.
     - mod'd for recovery, then installed and booted.
     - mod_image_for_test runs with no errors; booted the resulting image as well
     - booted a factory_install with the pending dm changes
     - BVT passed with build_image x86-generic (vboot enabled)
     - [in progress] autotest that checks if the rootdev = /dev/dm-0 and
       then does a dumpe2fs | grep -q FEATURE_R31

Review URL: http://codereview.chromium.org/3916002

Change-Id: If4dcba7568a110f4e32627c916d9e5741e5e5414
2010-10-20 15:44:11 -05:00

152 lines
4.8 KiB
Bash
Executable File

#!/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.
# Helper script that mounts chromium os image from a device or directory
# and creates mount points for /var and /usr/local (if in dev_mode).
. "$(dirname "$0")/common.sh"
# For functions related to gpt images.
. "$(dirname "$0")/chromeos-common.sh"
locate_gpt
get_default_board
# Flags.
DEFINE_string board "$DEFAULT_BOARD" \
"The board for which the image was built." b
DEFINE_boolean read_only $FLAGS_FALSE \
"Mount in read only mode -- skips stateful items."
DEFINE_boolean unmount $FLAGS_FALSE \
"Unmount previously mounted dir." u
DEFINE_string from "/dev/sdc" \
"Directory containing image or device with image on it" f
DEFINE_string image "chromiumos_image.bin"\
"Name of the bin file if a directory is specified in the from flag" i
DEFINE_string "rootfs_mountpt" "/tmp/m" "Mount point for rootfs" "r"
DEFINE_string "stateful_mountpt" "/tmp/s" \
"Mount point for stateful partition" "s"
DEFINE_string "esp_mountpt" "" \
"Mount point for esp partition" "e"
DEFINE_boolean most_recent ${FLAGS_FALSE} "Use the most recent image dir" m
# Parse flags
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Die on error
set -e
# Common unmounts for either a device or directory
function unmount_image() {
echo "Unmounting image from ${FLAGS_stateful_mountpt}" \
"and ${FLAGS_rootfs_mountpt}"
# Don't die on error to force cleanup
set +e
# Reset symlinks in /usr/local.
if mount | grep "${FLAGS_rootfs_mountpt} (rw,bind)"; then
setup_symlinks_on_root "/usr/local" "/var" \
"${FLAGS_stateful_mountpt}"
fix_broken_symlinks "${FLAGS_rootfs_mountpt}"
fi
sudo umount "${FLAGS_rootfs_mountpt}/usr/local"
sudo umount "${FLAGS_rootfs_mountpt}/var"
if [[ -n "${FLAGS_esp_mountpt}" ]]; then
sudo umount -d "${FLAGS_esp_mountpt}"
fi
sudo umount -d "${FLAGS_stateful_mountpt}"
sudo umount -d "${FLAGS_rootfs_mountpt}"
set -e
}
function get_usb_partitions() {
local ro_flag=""
[ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ] && ro_flag="-o ro"
sudo mount ${ro_flag} "${FLAGS_from}3" "${FLAGS_rootfs_mountpt}"
sudo mount ${ro_flag} "${FLAGS_from}1" "${FLAGS_stateful_mountpt}"
if [[ -n "${FLAGS_esp_mountpt}" ]]; then
sudo mount ${ro_flag} "${FLAGS_from}12" "${FLAGS_esp_mountpt}"
fi
}
function get_gpt_partitions() {
local filename="${FLAGS_image}"
# Mount the rootfs partition using a loopback device.
local offset=$(partoffset "${FLAGS_from}/${filename}" 3)
local ro_flag=""
if [ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ]; then
ro_flag="-o ro"
else
# Make sure any callers can actually mount and modify the fs
# if desired.
# cros_make_image_bootable should restore the bit if needed.
enable_rw_mount "${FLAGS_from}/${filename}" "$(( offset * 512 ))"
fi
sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
"${FLAGS_from}/${filename}" "${FLAGS_rootfs_mountpt}"
# Mount the stateful partition using a loopback device.
offset=$(partoffset "${FLAGS_from}/${filename}" 1)
sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
"${FLAGS_from}/${filename}" "${FLAGS_stateful_mountpt}"
# Mount the stateful partition using a loopback device.
if [[ -n "${FLAGS_esp_mountpt}" ]]; then
offset=$(partoffset "${FLAGS_from}/${filename}" 12)
sudo mount ${ro_flag} -o loop,offset=$(( offset * 512 )) \
"${FLAGS_from}/${filename}" "${FLAGS_esp_mountpt}"
fi
}
# Mount a gpt based image.
function mount_image() {
mkdir -p "${FLAGS_rootfs_mountpt}"
mkdir -p "${FLAGS_stateful_mountpt}"
if [[ -n "${FLAGS_esp_mountpt}" ]]; then
mkdir -p "${FLAGS_esp_mountpt}"
fi
# Get the partitions for the image / device.
if [ -b ${FLAGS_from} ] ; then
get_usb_partitions
else
get_gpt_partitions
fi
# Mount directories and setup symlinks.
sudo mount --bind "${FLAGS_stateful_mountpt}/var" \
"${FLAGS_rootfs_mountpt}/var"
sudo mount --bind "${FLAGS_stateful_mountpt}/dev_image" \
"${FLAGS_rootfs_mountpt}/usr/local"
# Setup symlinks in /usr/local so you can emerge packages into /usr/local.
if [ ${FLAGS_read_only} -eq ${FLAGS_FALSE} ]; then
setup_symlinks_on_root "${FLAGS_stateful_mountpt}/dev_image" \
"${FLAGS_stateful_mountpt}/var" "${FLAGS_stateful_mountpt}"
fi
echo "Image specified by ${FLAGS_from} mounted at"\
"${FLAGS_rootfs_mountpt} successfully."
}
# Find the last image built on the board.
if [ ${FLAGS_most_recent} -eq ${FLAGS_TRUE} ] ; then
IMAGES_DIR="${DEFAULT_BUILD_ROOT}/images/${FLAGS_board}"
FLAGS_from="${IMAGES_DIR}/$(ls -t ${IMAGES_DIR} 2>&-| head -1)"
fi
# Turn path into an absolute path.
FLAGS_from=`eval readlink -f ${FLAGS_from}`
# Perform desired operation.
if [ ${FLAGS_unmount} -eq ${FLAGS_TRUE} ] ; then
unmount_image
else
mount_image
fi