Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
Kees Cook | 224817f | 2012-06-28 12:33:59 -0700 | [diff] [blame] | 3 | # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 4 | # Use of this source code is governed by a BSD-style license that can be |
| 5 | # found in the LICENSE file. |
| 6 | |
| 7 | # Helper script that mounts chromium os image from a device or directory |
| 8 | # and creates mount points for /var and /usr/local (if in dev_mode). |
| 9 | |
Kees Cook | 84a4c7a | 2011-10-18 13:21:41 -0700 | [diff] [blame] | 10 | # Helper scripts should be run from the same location as this script. |
LaMont Jones | 52be727 | 2019-10-21 08:16:35 -0600 | [diff] [blame] | 11 | echo "Entering $0 $*" >&2 |
LaMont Jones | 52be727 | 2019-10-21 08:16:35 -0600 | [diff] [blame] | 12 | |
Kees Cook | 84a4c7a | 2011-10-18 13:21:41 -0700 | [diff] [blame] | 13 | SCRIPT_ROOT=$(dirname "$(readlink -f "$0")") |
David James | 359d3e1 | 2012-07-10 13:09:48 -0700 | [diff] [blame] | 14 | . "${SCRIPT_ROOT}/common.sh" || exit 1 |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 15 | . "${SCRIPT_ROOT}/build_library/filesystem_util.sh" || exit 1 |
| 16 | . "${SCRIPT_ROOT}/build_library/disk_layout_util.sh" || exit 1 |
Mike Frysinger | df7d5e6 | 2019-08-21 23:24:51 -0400 | [diff] [blame] | 17 | . "${SCRIPT_ROOT}/build_library/ext2_sb_util.sh" || exit 1 |
Greg Spencer | 798d75f | 2011-02-01 22:04:49 -0800 | [diff] [blame] | 18 | |
Gwendal Grignou | 01cf7f1 | 2018-05-03 12:12:23 -0700 | [diff] [blame] | 19 | if [[ ${INSIDE_CHROOT} -ne 1 ]]; then |
| 20 | INSTALL_ROOT="${SRC_ROOT}/platform2/chromeos-common-script/share" |
Dale Curtis | d569a90 | 2011-02-02 20:30:14 -0800 | [diff] [blame] | 21 | else |
Gwendal Grignou | 0f61849 | 2014-04-07 20:05:58 +0000 | [diff] [blame] | 22 | INSTALL_ROOT=/usr/share/misc |
Dale Curtis | d569a90 | 2011-02-02 20:30:14 -0800 | [diff] [blame] | 23 | fi |
Greg Spencer | 798d75f | 2011-02-01 22:04:49 -0800 | [diff] [blame] | 24 | # Load functions and constants for chromeos-install |
David James | 359d3e1 | 2012-07-10 13:09:48 -0700 | [diff] [blame] | 25 | . "${INSTALL_ROOT}/chromeos-common.sh" || exit 1 |
Greg Spencer | 798d75f | 2011-02-01 22:04:49 -0800 | [diff] [blame] | 26 | |
Bill Richardson | fc752ff | 2010-06-11 09:16:09 -0700 | [diff] [blame] | 27 | locate_gpt |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 28 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 29 | # Default value for FLAGS_image. |
| 30 | DEFAULT_IMAGE="chromiumos_image.bin" |
| 31 | |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 32 | # Flags. |
| 33 | DEFINE_string board "$DEFAULT_BOARD" \ |
| 34 | "The board for which the image was built." b |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 35 | DEFINE_boolean read_only ${FLAGS_FALSE} \ |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 36 | "Mount in read only mode -- skips stateful items." |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 37 | DEFINE_boolean safe ${FLAGS_FALSE} \ |
Nick Sanders | 867fde2 | 2010-11-16 20:05:06 -0800 | [diff] [blame] | 38 | "Mount rootfs in read only mode." |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 39 | DEFINE_boolean unmount ${FLAGS_FALSE} \ |
Mike Frysinger | 57aac27 | 2018-04-30 03:30:33 -0400 | [diff] [blame] | 40 | "Unmount previously mounted image." u |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 41 | DEFINE_string from "" \ |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 42 | "Directory, image, or device with image on it" f |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 43 | DEFINE_string image "${DEFAULT_IMAGE}" \ |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 44 | "Name of the bin file if a directory is specified in the from flag" i |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 45 | DEFINE_string partition_script "partition_script.sh" \ |
| 46 | "Name of the script with the partition layout if a directory is specified" |
Alex Deymo | 3249ec6 | 2015-03-05 14:09:38 -0800 | [diff] [blame] | 47 | DEFINE_string rootfs_mountpt "/tmp/m" "Mount point for rootfs" r |
| 48 | DEFINE_string stateful_mountpt "/tmp/s" \ |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 49 | "Mount point for stateful partition" s |
Alex Deymo | 3249ec6 | 2015-03-05 14:09:38 -0800 | [diff] [blame] | 50 | DEFINE_string esp_mountpt "" \ |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 51 | "Mount point for esp partition" e |
Alex Deymo | 3249ec6 | 2015-03-05 14:09:38 -0800 | [diff] [blame] | 52 | DEFINE_boolean delete_mountpts ${FLAGS_FALSE} \ |
| 53 | "Delete the mountpoint directories when unmounting." |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 54 | DEFINE_boolean most_recent ${FLAGS_FALSE} "Use the most recent image dir" m |
Nicolas Norvez | 1b86c8d | 2017-12-12 11:02:12 -0800 | [diff] [blame] | 55 | DEFINE_string local_build_dir "/build" \ |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 56 | "Temporary root directory (under the sysroot) where ebuilds can install "\ |
| 57 | "temporary files during the build." |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 58 | |
| 59 | # Parse flags |
| 60 | FLAGS "$@" || exit 1 |
| 61 | eval set -- "${FLAGS_ARGV}" |
| 62 | |
| 63 | # Die on error |
Brian Harring | 7f175a5 | 2012-03-02 05:37:00 -0800 | [diff] [blame] | 64 | switch_to_strict_mode |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 65 | |
Mike Frysinger | 1e4bd4c | 2018-04-30 04:22:08 -0400 | [diff] [blame] | 66 | # We don't accept any positional args, so reject to catch typos. |
| 67 | if [[ $# -ne 0 ]]; then |
| 68 | die_notrace "${SCRIPT_NAME} takes no arguments; given: $*" |
| 69 | fi |
| 70 | |
Chris Sosa | f37f64d | 2012-03-09 15:45:08 -0800 | [diff] [blame] | 71 | # Find the last image built on the board. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 72 | if [[ ${FLAGS_most_recent} -eq ${FLAGS_TRUE} ]] ; then |
Alex Klein | 999443c | 2018-10-17 12:02:05 -0600 | [diff] [blame] | 73 | FLAGS_from="${IMAGES_DIR}/${FLAGS_board}/latest" |
Chris Sosa | f37f64d | 2012-03-09 15:45:08 -0800 | [diff] [blame] | 74 | fi |
| 75 | |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 76 | # If --from is a block device, --image can't also be specified. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 77 | if [[ -b "${FLAGS_from}" ]]; then |
| 78 | if [[ "${FLAGS_image}" != "${DEFAULT_IMAGE}" ]]; then |
Brian Harring | 7f175a5 | 2012-03-02 05:37:00 -0800 | [diff] [blame] | 79 | die_notrace "-i ${FLAGS_image} can't be used with block device ${FLAGS_from}" |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 80 | fi |
| 81 | fi |
| 82 | |
| 83 | # Allow --from /foo/file.bin |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 84 | if [[ -f "${FLAGS_from}" ]]; then |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 85 | # If --from is specified as a file, --image cannot be also specified. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 86 | if [[ "${FLAGS_image}" != "${DEFAULT_IMAGE}" ]]; then |
Brian Harring | 7f175a5 | 2012-03-02 05:37:00 -0800 | [diff] [blame] | 87 | die_notrace "-i ${FLAGS_image} can't be used with --from file ${FLAGS_from}" |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 88 | fi |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 89 | # The order is important here. We want to override FLAGS_image before |
| 90 | # destroying FLAGS_from. |
| 91 | FLAGS_image="$(basename "${FLAGS_from}")" |
| 92 | FLAGS_from="$(dirname "${FLAGS_from}")" |
Nick Sanders | f9c49ad | 2011-03-21 18:56:04 -0700 | [diff] [blame] | 93 | fi |
| 94 | |
Mike Frysinger | 4993c94 | 2019-08-21 23:15:12 -0400 | [diff] [blame] | 95 | # Fixes symlinks that are incorrectly prefixed with the build root $1 |
| 96 | # rather than the real running root '/'. |
| 97 | fix_broken_symlinks() { |
| 98 | local build_root=$1 |
| 99 | local symlinks=$(find "${build_root}/usr/local" -lname "${build_root}/*") |
| 100 | local symlink |
| 101 | for symlink in ${symlinks}; do |
| 102 | echo "Fixing ${symlink}" |
| 103 | local target=$(ls -l "${symlink}" | cut -f 2 -d '>') |
| 104 | # Trim spaces from target (bashism). |
| 105 | target=${target/ /} |
| 106 | # Make new target (removes rootfs prefix). |
| 107 | new_target=$(echo ${target} | sed "s#${build_root}##") |
| 108 | |
| 109 | echo "Fixing symlink ${symlink}" |
| 110 | sudo unlink "${symlink}" |
| 111 | sudo ln -sf "${new_target}" "${symlink}" |
| 112 | done |
| 113 | } |
| 114 | |
Joshua Emele | fcc7971 | 2017-03-14 17:34:30 -0700 | [diff] [blame] | 115 | load_image_partition_numbers() { |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 116 | local partition_script="${FLAGS_from}/${FLAGS_partition_script}" |
| 117 | # Attempt to load the partition script from the rootfs when not found in the |
| 118 | # FLAGS_from directory. |
| 119 | if [[ ! -f "${partition_script}" ]]; then |
| 120 | partition_script="${FLAGS_rootfs_mountpt}/${PARTITION_SCRIPT_PATH}" |
| 121 | fi |
| 122 | if [[ -f "${partition_script}" ]]; then |
| 123 | . "${partition_script}" |
| 124 | load_partition_vars |
Joshua Emele | fcc7971 | 2017-03-14 17:34:30 -0700 | [diff] [blame] | 125 | return |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 126 | fi |
Joshua Emele | fcc7971 | 2017-03-14 17:34:30 -0700 | [diff] [blame] | 127 | |
| 128 | # Without a partition script, infer numbers from the payload image. |
| 129 | local image |
| 130 | if [[ -b "${FLAGS_from}" ]]; then |
| 131 | image="${FLAGS_from}" |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 132 | elif [[ -n "${FLAGS_from}" ]]; then |
Joshua Emele | fcc7971 | 2017-03-14 17:34:30 -0700 | [diff] [blame] | 133 | image="${FLAGS_from}/${FLAGS_image}" |
| 134 | if [[ ! -f "${image}" ]]; then |
| 135 | die "Image ${image} does not exist." |
| 136 | fi |
| 137 | fi |
| 138 | PARTITION_NUM_STATE="$(get_image_partition_number "${image}" "STATE")" |
| 139 | PARTITION_NUM_ROOT_A="$(get_image_partition_number "${image}" "ROOT-A")" |
| 140 | PARTITION_NUM_OEM="$(get_image_partition_number "${image}" "OEM")" |
| 141 | PARTITION_NUM_EFI_SYSTEM="$(get_image_partition_number "${image}" \ |
| 142 | "EFI-SYSTEM")" |
Alex Deymo | 0b8ba82 | 2015-03-02 21:36:33 -0800 | [diff] [blame] | 143 | } |
| 144 | |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 145 | unmount_local_build_root() { |
| 146 | local build_dir="${FLAGS_rootfs_mountpt}/${FLAGS_local_build_dir}" |
| 147 | local rootfs="${build_dir}/rootfs" |
| 148 | info "Unmounting temporary rootfs ${rootfs}." |
| 149 | if [[ -d "${rootfs}" ]]; then |
| 150 | sudo umount "${rootfs}" |
| 151 | sudo rmdir "${rootfs}" |
| 152 | fi |
Nicolas Norvez | 789c1b7 | 2017-12-14 13:17:56 -0800 | [diff] [blame] | 153 | if [[ -d "${build_dir}" ]]; then |
| 154 | sudo rmdir "${build_dir}" |
| 155 | fi |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 156 | sudo rm -rf "${LOCAL_BUILDROOT_MOUNTPOINT}" |
| 157 | } |
| 158 | |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 159 | # Common unmounts for either a device or directory |
Mike Frysinger | 6b1abb2 | 2012-05-11 13:44:06 -0400 | [diff] [blame] | 160 | unmount_image() { |
Mike Frysinger | 84f66f5 | 2012-01-12 12:00:07 -0500 | [diff] [blame] | 161 | info "Unmounting image from ${FLAGS_stateful_mountpt}" \ |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 162 | "and ${FLAGS_rootfs_mountpt}" |
| 163 | # Don't die on error to force cleanup |
| 164 | set +e |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 165 | |
| 166 | if [[ ${FLAGS_read_only} -eq ${FLAGS_FALSE} ]]; then |
Nicolas Norvez | 1b86c8d | 2017-12-12 11:02:12 -0800 | [diff] [blame] | 167 | if [[ ${FLAGS_safe} -eq ${FLAGS_FALSE} ]]; then |
| 168 | unmount_local_build_root |
| 169 | fi |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 170 | fi |
| 171 | |
Chris Sosa | 9673f3b | 2010-05-18 13:24:40 -0700 | [diff] [blame] | 172 | # Reset symlinks in /usr/local. |
Mike Frysinger | 3c74b3d | 2012-10-12 14:26:03 -0400 | [diff] [blame] | 173 | if mount | egrep -q ".* ${FLAGS_stateful_mountpt} .*\(rw,"; then |
Mike Frysinger | 79d7ddd | 2015-03-08 22:18:52 -0400 | [diff] [blame] | 174 | setup_symlinks_on_root "." "/var" "${FLAGS_stateful_mountpt}" |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 175 | fix_broken_symlinks "${FLAGS_rootfs_mountpt}" |
| 176 | fi |
Mike Frysinger | ae2e3c3 | 2013-06-26 20:20:55 -0400 | [diff] [blame] | 177 | |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 178 | local loopdev |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 179 | local filename |
| 180 | if [[ -b "${FLAGS_from}" ]]; then |
| 181 | filename="${FLAGS_from}" |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 182 | elif [[ -n "${FLAGS_from}" ]]; then |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 183 | filename="${FLAGS_from}/${FLAGS_image}" |
| 184 | if [[ ! -f "${filename}" ]]; then |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 185 | die "Image ${filename} does not exist." |
Mike Frysinger | 9140d77 | 2013-08-05 18:44:11 -0400 | [diff] [blame] | 186 | fi |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 187 | fi |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 188 | if [[ -z "${filename}" ]]; then |
| 189 | warn "Umount called without passing the image. Some filesystems can't" \ |
| 190 | "be unmounted in this way." |
| 191 | else |
| 192 | loopdev="$(loopback_partscan "${filename}")" |
| 193 | fi |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 194 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 195 | # Unmount in reverse order: EFI, OEM, stateful and rootfs. |
| 196 | local var_name mountpoint fs_format fs_options |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 197 | local part_label part_num part_loop |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 198 | for part_label in EFI_SYSTEM OEM STATE ROOT_A; do |
| 199 | var_name="${part_label}_MOUNTPOINT" |
| 200 | mountpoint="${!var_name}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 201 | [[ -n "${mountpoint}" ]] || continue |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 202 | var_name="PARTITION_NUM_${part_label}" |
| 203 | part_num="${!var_name}" |
Mike Frysinger | 2cf9667 | 2018-04-30 04:08:32 -0400 | [diff] [blame] | 204 | if [[ -z "${part_num}" ]]; then |
| 205 | # Depending on how it was mounted, clear all existing mounts. |
| 206 | sudo umount -R "${mountpoint}" |
| 207 | continue |
| 208 | fi |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 209 | part_loop="${loopdev}p${part_num}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 210 | |
| 211 | if [[ -z "${filename}" ]]; then |
| 212 | # TODO(deymo): Remove this legacy umount. |
| 213 | if ! mountpoint -q "${mountpoint}"; then |
| 214 | die "You must pass --image or --from when using --unmount to unmount" \ |
| 215 | "this image." |
| 216 | fi |
| 217 | safe_umount_tree "${mountpoint}" |
| 218 | continue |
| 219 | fi |
| 220 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 221 | # Get the variables loaded with load_partition_vars during mount_*. |
| 222 | var_name="FS_FORMAT_${part_num}" |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 223 | fs_format="${!var_name}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 224 | var_name="FS_OPTIONS_${part_num}" |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 225 | fs_options="${!var_name}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 226 | |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 227 | fs_umount "${part_loop}" "${mountpoint}" "${fs_format}" "${fs_options}" |
Mike Frysinger | 9140d77 | 2013-08-05 18:44:11 -0400 | [diff] [blame] | 228 | done |
| 229 | |
Mike Frysinger | 34d2ce4 | 2019-07-12 20:26:39 -0400 | [diff] [blame] | 230 | if [[ -n "${loopdev}" ]]; then |
| 231 | sudo losetup -d "${loopdev}" |
| 232 | fi |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 233 | |
Alex Deymo | 3249ec6 | 2015-03-05 14:09:38 -0800 | [diff] [blame] | 234 | # We need to remove the mountpoints after we unmount all the partitions since |
| 235 | # there could be nested mounts. |
| 236 | if [[ ${FLAGS_delete_mountpts} -eq ${FLAGS_TRUE} ]]; then |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 237 | for part_label in EFI_SYSTEM OEM STATE ROOT_A; do |
| 238 | var_name="${part_label}_MOUNTPOINT" |
| 239 | mountpoint="${!var_name}" |
Alex Deymo | 3249ec6 | 2015-03-05 14:09:38 -0800 | [diff] [blame] | 240 | # Check this is a directory. |
| 241 | [[ -n "${mountpoint}" && -d "${mountpoint}" ]] || continue |
| 242 | fs_remove_mountpoint "${mountpoint}" |
| 243 | done |
| 244 | fi |
| 245 | |
Brian Harring | 7f175a5 | 2012-03-02 05:37:00 -0800 | [diff] [blame] | 246 | switch_to_strict_mode |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 247 | } |
| 248 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 249 | mount_usb_partitions() { |
| 250 | local ro_rw="rw" |
| 251 | local rootfs_ro_rw="rw" |
| 252 | if [[ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ]]; then |
| 253 | ro_rw="ro" |
| 254 | fi |
| 255 | if [[ ${FLAGS_read_only} -eq ${FLAGS_TRUE} || |
| 256 | ${FLAGS_safe} -eq ${FLAGS_TRUE} ]]; then |
| 257 | rootfs_ro_rw="ro" |
| 258 | fi |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 259 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 260 | if [[ -f "${FLAGS_from}/${FLAGS_partition_script}" ]]; then |
| 261 | . "${FLAGS_from}/${FLAGS_partition_script}" |
| 262 | load_partition_vars |
| 263 | fi |
| 264 | |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 265 | fs_mount "${FLAGS_from}${PARTITION_NUM_ROOT_A}" "${ROOT_A_MOUNTPOINT}" \ |
| 266 | "${FS_FORMAT_ROOT_A}" "${rootfs_ro_rw}" |
| 267 | fs_mount "${FLAGS_from}${PARTITION_NUM_STATE}" "${STATE_MOUNTPOINT}" \ |
| 268 | "${FS_FORMAT_STATE}" "${ro_rw}" |
| 269 | fs_mount "${FLAGS_from}${PARTITION_NUM_OEM}" "${OEM_MOUNTPOINT}" \ |
| 270 | "${FS_FORMAT_OEM}" "${ro_rw}" |
Mike Frysinger | ae2e3c3 | 2013-06-26 20:20:55 -0400 | [diff] [blame] | 271 | |
Steven 'Steve' Kendall | 7fbc313 | 2016-06-03 13:19:00 -0400 | [diff] [blame] | 272 | if [[ -n "${FLAGS_esp_mountpt}" && \ |
| 273 | -e ${FLAGS_from}${PARTITION_NUM_EFI_SYSTEM} ]]; then |
| 274 | fs_mount "${FLAGS_from}${PARTITION_NUM_EFI_SYSTEM}" \ |
Ian Coolidge | 094d543 | 2017-02-09 01:18:17 -0800 | [diff] [blame] | 275 | "${EFI_SYSTEM_MOUNTPOINT}" "${FS_FORMAT_EFI_SYSTEM}" "${ro_rw}" |
Chris Masone | 3adf3f7 | 2010-07-09 16:44:18 -0700 | [diff] [blame] | 276 | fi |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 277 | } |
| 278 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 279 | mount_gpt_partitions() { |
| 280 | local filename="${FLAGS_from}/${FLAGS_image}" |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 281 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 282 | local ro_rw="rw" |
| 283 | if [[ ${FLAGS_read_only} -eq ${FLAGS_TRUE} ]]; then |
| 284 | ro_rw="ro" |
Chris Sosa | 4e155ea | 2013-12-19 16:29:37 -0800 | [diff] [blame] | 285 | fi |
| 286 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 287 | if [[ ! -f "${filename}" ]]; then |
| 288 | die "Image ${filename} does not exist." |
Nick Sanders | 867fde2 | 2010-11-16 20:05:06 -0800 | [diff] [blame] | 289 | fi |
| 290 | |
Ian Coolidge | 429e9c4 | 2017-02-10 00:49:36 -0800 | [diff] [blame] | 291 | if [[ -f "${FLAGS_from}/${FLAGS_partition_script}" ]]; then |
| 292 | . "${FLAGS_from}/${FLAGS_partition_script}" |
| 293 | load_partition_vars |
| 294 | fi |
| 295 | |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 296 | local loopdev="$(loopback_partscan "${filename}")" |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 297 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 298 | # Mount in order: rootfs, stateful, OEM and EFI. |
| 299 | local var_name mountpoint fs_format |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 300 | local part_label part_num part_loop part_ro_rw |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 301 | for part_label in ROOT_A STATE OEM EFI_SYSTEM; do |
| 302 | var_name="${part_label}_MOUNTPOINT" |
| 303 | mountpoint="${!var_name}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 304 | [[ -n "${mountpoint}" ]] || continue |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 305 | |
| 306 | var_name="PARTITION_NUM_${part_label}" |
| 307 | part_num="${!var_name}" |
Joshua Emele | d60789f | 2017-06-23 17:09:45 -0700 | [diff] [blame] | 308 | [[ -n "${part_num}" ]] || continue |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 309 | part_loop="${loopdev}p${part_num}" |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 310 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 311 | var_name="FS_FORMAT_${part_num}" |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 312 | fs_format="${!var_name}" |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 313 | |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 314 | # For the rootfs, make sure it's writable so callers can modify it, |
| 315 | # unless the caller explicitly requested otherwise. |
| 316 | # cros_make_image_bootable should restore the bit if needed. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 317 | part_ro_rw="${ro_rw}" |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 318 | if [[ "${part_label}" == ROOT_* ]]; then |
| 319 | if [[ ${FLAGS_safe} -eq ${FLAGS_TRUE} ]]; then |
| 320 | part_ro_rw="ro" |
| 321 | elif [[ ${FLAGS_read_only} -eq ${FLAGS_FALSE} ]]; then |
| 322 | enable_rw_mount "${part_loop}" |
| 323 | fi |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 324 | fi |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 325 | |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 326 | if ! fs_mount "${part_loop}" "${mountpoint}" "${fs_format}" \ |
| 327 | "${part_ro_rw}"; then |
| 328 | error "mount failed: image=${filename} device=${part_loop}" \ |
| 329 | "target=${mountpoint} format=${fs_format} ro/rw=${part_ro_rw}" |
| 330 | sudo losetup -d "${loopdev}" |
Gaurav Shah | 05618a6 | 2014-01-20 15:06:54 -0800 | [diff] [blame] | 331 | return 1 |
| 332 | fi |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 333 | done |
Mike Frysinger | 0b2e726 | 2018-04-30 04:07:58 -0400 | [diff] [blame] | 334 | |
| 335 | # Detach the loopback now even though we have mounts. This way when the last |
| 336 | # mount is freed, the kernel will automatically release the loopback. |
| 337 | sudo losetup -d "${loopdev}" |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 338 | } |
| 339 | |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 340 | # Create a local buildroot that can be used by ebuilds that need to install |
| 341 | # temporary files during the build even though those files should not be in the |
| 342 | # final image. This is typically the case of ebuilds that install files to |
| 343 | # Android's /vendor directory before board_specific_setup repacks them to the |
| 344 | # final vendor image. Those ebuilds can instead install files to |
Nicolas Norvez | 1b86c8d | 2017-12-12 11:02:12 -0800 | [diff] [blame] | 345 | # /build/rootfs/opt/google/containers/.../vendor where board_specific_setup |
| 346 | # will pick them up and add them to the final vendor image. |
| 347 | # To avoid running out of space in the root partition during the build, use a |
| 348 | # separate directory outside of the image and bindmount it to the local |
| 349 | # buildroot. |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 350 | mount_local_build_root() { |
| 351 | local build_dir="${FLAGS_rootfs_mountpt}/${FLAGS_local_build_dir}" |
| 352 | local rootfs="${build_dir}/rootfs" |
| 353 | if [[ ! -d "${rootfs}" ]]; then |
| 354 | sudo mkdir -p "${rootfs}" |
| 355 | fi |
| 356 | info "Mounting temporary rootfs ${LOCAL_BUILDROOT_MOUNTPOINT} to ${rootfs}." |
| 357 | if [[ ! -d "${LOCAL_BUILDROOT_MOUNTPOINT}" ]]; then |
| 358 | sudo mkdir -p "${LOCAL_BUILDROOT_MOUNTPOINT}" |
| 359 | fi |
| 360 | sudo mount --bind "${LOCAL_BUILDROOT_MOUNTPOINT}" "${rootfs}" |
| 361 | } |
| 362 | |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 363 | # Mount a gpt based image. |
Mike Frysinger | 6b1abb2 | 2012-05-11 13:44:06 -0400 | [diff] [blame] | 364 | mount_image() { |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 365 | mkdir -p "${FLAGS_rootfs_mountpt}" |
| 366 | mkdir -p "${FLAGS_stateful_mountpt}" |
Chris Masone | 3adf3f7 | 2010-07-09 16:44:18 -0700 | [diff] [blame] | 367 | if [[ -n "${FLAGS_esp_mountpt}" ]]; then |
Will Drewry | fb48fa3 | 2010-07-02 16:35:27 -0500 | [diff] [blame] | 368 | mkdir -p "${FLAGS_esp_mountpt}" |
Chris Masone | 3adf3f7 | 2010-07-09 16:44:18 -0700 | [diff] [blame] | 369 | fi |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 370 | # Get the partitions for the image / device. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 371 | if [[ -b "${FLAGS_from}" ]]; then |
| 372 | mount_usb_partitions |
| 373 | elif ! mount_gpt_partitions; then |
J. Richard Barnette | 25d540d | 2012-01-18 15:40:10 -0800 | [diff] [blame] | 374 | echo "Current loopback device status:" |
| 375 | sudo losetup --all | sed 's/^/ /' |
| 376 | die "Failed to mount all partitions in ${FLAGS_from}/${FLAGS_image}" |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 377 | fi |
| 378 | |
Mike Frysinger | 141ef06 | 2019-07-12 22:10:29 -0400 | [diff] [blame] | 379 | # Mount directories and setup symlinks. Create dirs on demand in case they |
| 380 | # were wiped out for some reason (devs like to dev!). |
| 381 | mkdir_and_mount() { |
| 382 | local src="$1" dst="$2" |
| 383 | if [[ ! -d "${src}" ]]; then |
| 384 | sudo mkdir "${src}" |
| 385 | fi |
| 386 | if [[ ! -d "${dst}" ]]; then |
| 387 | sudo mkdir "${dst}" |
| 388 | fi |
| 389 | sudo mount --bind "${src}" "${dst}" |
| 390 | } |
| 391 | mkdir_and_mount "${FLAGS_stateful_mountpt}" \ |
Chris Sosa | 4e155ea | 2013-12-19 16:29:37 -0800 | [diff] [blame] | 392 | "${FLAGS_rootfs_mountpt}/mnt/stateful_partition" |
Mike Frysinger | 141ef06 | 2019-07-12 22:10:29 -0400 | [diff] [blame] | 393 | mkdir_and_mount "${FLAGS_stateful_mountpt}/var_overlay" \ |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 394 | "${FLAGS_rootfs_mountpt}/var" |
Mike Frysinger | 141ef06 | 2019-07-12 22:10:29 -0400 | [diff] [blame] | 395 | mkdir_and_mount "${FLAGS_stateful_mountpt}/dev_image" \ |
Chris Sosa | 9673f3b | 2010-05-18 13:24:40 -0700 | [diff] [blame] | 396 | "${FLAGS_rootfs_mountpt}/usr/local" |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 397 | |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 398 | if [[ ${FLAGS_read_only} -eq ${FLAGS_FALSE} ]]; then |
Nicolas Norvez | 1b86c8d | 2017-12-12 11:02:12 -0800 | [diff] [blame] | 399 | if [[ ${FLAGS_safe} -eq ${FLAGS_FALSE} ]]; then |
| 400 | mount_local_build_root |
| 401 | fi |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 402 | # Setup symlinks in /usr/local so you can emerge packages into /usr/local. |
Mike Frysinger | 79d7ddd | 2015-03-08 22:18:52 -0400 | [diff] [blame] | 403 | setup_symlinks_on_root "." \ |
Kees Cook | 224817f | 2012-06-28 12:33:59 -0700 | [diff] [blame] | 404 | "${FLAGS_stateful_mountpt}/var_overlay" "${FLAGS_stateful_mountpt}" |
Chris Sosa | e7f1a2b | 2010-09-28 18:24:13 -0700 | [diff] [blame] | 405 | fi |
Mike Frysinger | 84f66f5 | 2012-01-12 12:00:07 -0500 | [diff] [blame] | 406 | info "Image specified by ${FLAGS_from} mounted at"\ |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 407 | "${FLAGS_rootfs_mountpt} successfully." |
| 408 | } |
| 409 | |
Chris Sosa | c60e567 | 2010-11-12 10:54:25 -0800 | [diff] [blame] | 410 | # Turn paths into absolute paths. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 411 | [[ -n "${FLAGS_from}" ]] && FLAGS_from="$(readlink -f "${FLAGS_from}")" |
| 412 | FLAGS_rootfs_mountpt="$(readlink -f "${FLAGS_rootfs_mountpt}")" |
| 413 | FLAGS_stateful_mountpt="$(readlink -f "${FLAGS_stateful_mountpt}")" |
| 414 | |
| 415 | # Partition mountpoints based on the flags. |
Ian Coolidge | 392f7bb | 2017-02-04 17:08:31 -0800 | [diff] [blame] | 416 | ROOT_A_MOUNTPOINT="${FLAGS_rootfs_mountpt}" |
| 417 | STATE_MOUNTPOINT="${FLAGS_stateful_mountpt}" |
| 418 | OEM_MOUNTPOINT="${FLAGS_rootfs_mountpt}/usr/share/oem" |
| 419 | EFI_SYSTEM_MOUNTPOINT="${FLAGS_esp_mountpt}" |
Nicolas Norvez | 89d3f99 | 2017-11-20 16:52:12 -0800 | [diff] [blame] | 420 | LOCAL_BUILDROOT_MOUNTPOINT="${FLAGS_rootfs_mountpt}-local-build-dir" |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 421 | |
Joshua Emele | fcc7971 | 2017-03-14 17:34:30 -0700 | [diff] [blame] | 422 | # Read the image partition numbers from the GPT. |
| 423 | load_image_partition_numbers |
| 424 | |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 425 | # Perform desired operation. |
Alex Deymo | d5449c8 | 2015-02-05 11:28:48 -0800 | [diff] [blame] | 426 | if [[ ${FLAGS_unmount} -eq ${FLAGS_TRUE} ]]; then |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 427 | unmount_image |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 428 | else |
Chris Sosa | 702618f | 2010-05-14 12:52:32 -0700 | [diff] [blame] | 429 | mount_image |
Chris Sosa | fb78b42 | 2010-04-19 14:56:18 -0700 | [diff] [blame] | 430 | fi |