1#!/bin/bash 2# 3# Copyright 2011 The ChromiumOS Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7# shellcheck disable=SC2039,SC2059,SC2155 8 9# shellcheck source=./common_minimal.sh 10. "$(dirname "$0")/common_minimal.sh" 11CROS_LOG_PREFIX="${PROG}: " 12 13# Performs clean up by executing actions in the cleanup_actions array in 14# reversed order. 15cleanup() { 16 # Save the existing return value. 17 rv=$? 18 set +e 19 20 cleanup_temps_and_mounts 21 cleanup_loopbacks 22 23 set -e 24 return $rv 25} 26 27# ANSI color codes used when displaying messages. 28# Taken from src/scripts/common.sh. 29V_BOLD_GREEN="\e[1;32m" 30V_BOLD_RED="\e[1;31m" 31V_BOLD_YELLOW="\e[1;33m" 32V_VIDOFF="\e[0m" 33 34# Prints an informational message. 35# Taken from src/scripts/common.sh. 36# Arg: MESSAGE 37info() { 38 echo -e >&2 "${V_BOLD_GREEN}${CROS_LOG_PREFIX:-}INFO : $*${V_VIDOFF}" 39} 40 41# Prints a warning message. 42# Taken from src/scripts/common.sh. 43# Arg: MESSAGE 44warn() { 45 echo -e >&2 "${V_BOLD_YELLOW}${CROS_LOG_PREFIX:-}WARNING: $*${V_VIDOFF}" 46} 47 48# Prints the specified error and exit the script with an error code. 49# Taken from src/scripts/common.sh. 50# Args: MESSAGE 51error() { 52 echo -e >&2 "${V_BOLD_RED}${CROS_LOG_PREFIX:-}ERROR : $*${V_VIDOFF}" 53} 54 55TEMP_LOOP_LIST=$(mktemp) 56 57# Setup a loopback device for a file and scan for partitions, with retries. 58# 59# $1 - The file to back the new loopback device. 60# $2-$N - Additional arguments to pass to losetup. 61loopback_partscan() { 62 local lb_dev image="$1" 63 shift 64 65 # We know partition scanning & dev node creation can be racy with udev and 66 # the kernel, and the kernel does not sleep/wait for it to finish. We have 67 # to use the partx tool manually as it will sleep until things are finished. 68 lb_dev=$(sudo losetup --show -f "$@" "${image}") 69 70 # Cache the path so we can clean it up. 71 echo "${lb_dev}" >>"${TEMP_LOOP_LIST}" 72 73 # Ignore problems deleting existing partitions. There shouldn't be any 74 # which will upset partx, but that's actually ok. 75 sudo partx -d "${lb_dev}" 2>/dev/null || true 76 sudo partx -a "${lb_dev}" 77 78 echo "${lb_dev}" 79} 80 81# Detach a loopback device set up earlier. 82# 83# $1 - The loop device to detach. 84# $2-$N - Additional arguments to pass to losetup. 85loopback_detach() { 86 # Retry the deletes before we detach. crbug.com/469259 87 local i 88 for (( i = 0; i < 10; i++ )); do 89 if sudo partx -d "$1"; then 90 break 91 fi 92 warn "Sleeping & retrying ..." 93 sync 94 sleep 1 95 done 96 sudo losetup --detach "$@" 97} 98 99# Clear out all loopback devices we setup. 100cleanup_loopbacks() { 101 local line 102 while read -r line; do 103 info "Cleanup: detaching ${line}" 104 loopback_detach "${line}" 2>/dev/null 105 done <"${TEMP_LOOP_LIST}" 106 rm -f "${TEMP_LOOP_LIST}" 107} 108 109# Usage: lsbval path-to-lsb-file key 110# Returns the value for the given lsb-release file variable. 111lsbval() { 112 local lsbfile="$1" 113 local key="$2" 114 grep "^${key}=" "${lsbfile}" | sed "s/^${key}=//" 115} 116 117# Usage: get_board_from_lsb_release rootfs 118# Returns the exact board name from /etc/lsb-release. This may contain 119# dashes or other characters not suitable for variable names. See the 120# next function for that. 121get_board_from_lsb_release() { 122 local rootfs="$1" 123 lsbval "${rootfs}/etc/lsb-release" CHROMEOS_RELEASE_BOARD 124} 125 126# Usage: get_boardvar_from_lsb_release rootfs 127# Returns the board name from /etc/lsb-release in a mangled form that can 128# be used in variable names. e.g. dashes are turned into underscores. 129get_boardvar_from_lsb_release() { 130 get_board_from_lsb_release "$@" | sed 's:[-]:_:g' 131} 132 133# Usage: restore_lsb_selinux lsb-file 134# restore lsb-release security.selinux attribute 135restore_lsb_selinux() { 136 sudo setfattr -n security.selinux -v "u:object_r:cros_conf_file:s0" "$1" 137} 138 139# Extracts a firmware updater bundle (for firmware image binaries) file 140# (generated by src/platform/firmware/pack_firmware.sh). 141# Args: INPUT_FILE OUTPUT_DIR 142extract_firmware_bundle() { 143 local input="$(readlink -f "$1")" 144 local output_dir="$2" 145 if [[ ! -s "${input}" ]]; then 146 return 1 147 elif grep -q '^##CUTHERE##' "${input}"; then 148 # Bundle supports self-extraction (--unpack, or --sb_extract) 149 "${input}" --unpack "${output_dir}" || 150 "${input}" --sb_extract "${output_dir}" || 151 die "Extracting firmware autoupdate (--unpack) failed." 152 else 153 # Legacy bundle - try uudecode. 154 uudecode -o - "${input}" | tar -C "${output_dir}" -zxf - 2>/dev/null || 155 die "Extracting firmware autoupdate failed." 156 fi 157} 158 159# This will override the trap set in common_minmal.sh 160trap "cleanup" INT TERM EXIT 161