mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-23 06:31:18 +02:00
enter_chroot: merge multiple mount requests into a single sudo
Every invocation of `sudo` delays things, so merge all of the mounts into a single `sudo` command when possible. This saves over 1 second on initial execution (out of ~4 seconds total). BUG=None TEST=`cros_sdk --enter true` still mounts & unmounts properly Change-Id: Ibc66507dc21250a81207d2f940645eaebe93c79c Reviewed-on: https://gerrit.chromium.org/gerrit/10901 Reviewed-by: David James <davidjames@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org> Commit-Ready: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
parent
23301afb5f
commit
286b5928c8
30
common.sh
30
common.sh
@ -378,6 +378,36 @@ function sudo_append() {
|
|||||||
sudo tee -a "$1" > /dev/null
|
sudo tee -a "$1" > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Execute multiple commands in a single sudo. Generally will speed things
|
||||||
|
# up by avoiding multiple calls to `sudo`. If any commands fail, we will
|
||||||
|
# call die with the failing command. We can handle a max of ~100 commands,
|
||||||
|
# but hopefully no one will ever try that many at once.
|
||||||
|
#
|
||||||
|
# $@ - The commands to execute, one per arg.
|
||||||
|
function sudo_multi() {
|
||||||
|
local i cmds
|
||||||
|
|
||||||
|
# Construct the shell code to execute. It'll be of the form:
|
||||||
|
# ... && ( ( command ) || exit <command index> ) && ...
|
||||||
|
# This way we know which command exited. The exit status of
|
||||||
|
# the underlying command is lost, but we never cared about it
|
||||||
|
# in the first place (other than it is non zero), so oh well.
|
||||||
|
for (( i = 1; i <= $#; ++i )); do
|
||||||
|
cmds+=" && ( ( ${!i} ) || exit $(( i + 10 )) )"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Execute our constructed shell code.
|
||||||
|
sudo -- sh -c ":${cmds[*]}" && i=0 || i=$?
|
||||||
|
|
||||||
|
# See if this failed, and if so, print out the failing command.
|
||||||
|
if [[ $i -gt 10 ]]; then
|
||||||
|
: $(( i -= 10 ))
|
||||||
|
die "sudo_multi failed: ${!i}"
|
||||||
|
elif [[ $i -ne 0 ]]; then
|
||||||
|
die "sudo_multi failed for unknown reason $i"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Locate all mounts below a specified directory.
|
# Locate all mounts below a specified directory.
|
||||||
#
|
#
|
||||||
# $1 - The root tree.
|
# $1 - The root tree.
|
||||||
|
@ -87,13 +87,16 @@ SYNCERPIDFILE="${FLAGS_chroot}/var/tmp/enter_chroot_sync.pid"
|
|||||||
|
|
||||||
|
|
||||||
MOUNTED_PATH=$(readlink -f "$FLAGS_chroot")
|
MOUNTED_PATH=$(readlink -f "$FLAGS_chroot")
|
||||||
function ensure_mounted {
|
function mount_queue_init {
|
||||||
|
MOUNT_QUEUE=()
|
||||||
|
}
|
||||||
|
|
||||||
|
function queue_mount {
|
||||||
# If necessary, mount $source in the host FS at $target inside the
|
# If necessary, mount $source in the host FS at $target inside the
|
||||||
# chroot directory with $mount_args.
|
# chroot directory with $mount_args.
|
||||||
local source="$1"
|
local source="$1"
|
||||||
local mount_args="$2"
|
local mount_args="$2"
|
||||||
local target="$3"
|
local target="$3"
|
||||||
local warn="$4"
|
|
||||||
|
|
||||||
local mounted_path="${MOUNTED_PATH}$target"
|
local mounted_path="${MOUNTED_PATH}$target"
|
||||||
|
|
||||||
@ -102,29 +105,23 @@ function ensure_mounted {
|
|||||||
# Already mounted!
|
# Already mounted!
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Attempt to make the mountpoint as the user. This depends on the
|
MOUNT_QUEUE+=(
|
||||||
# fact that all mountpoints that should be owned by root are
|
"mkdir -p '${mounted_path}'"
|
||||||
# already present. However, when distributions add new paths (such as
|
# The args are left unquoted on purpose.
|
||||||
# Ubuntu 11.10's /run), it might not yet exist in the chroot. If that
|
"mount ${mount_args} '${source}' '${mounted_path}'"
|
||||||
# happens, just create it as root.
|
)
|
||||||
if ! mkdir -p "${mounted_path}" 2>/dev/null; then
|
|
||||||
sudo mkdir -p "${mounted_path}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# NB: mount_args deliberately left unquoted
|
|
||||||
debug mount ${mount_args} "${source}" "${mounted_path}"
|
|
||||||
if ! sudo -- mount ${mount_args} "${source}" "${mounted_path}" ; then
|
|
||||||
if [ -z "${warn}" ]; then
|
|
||||||
die "Could not mount ${source} on ${mounted_path}"
|
|
||||||
else
|
|
||||||
warn "Failed to mount ${source}; perhaps it's on NFS?"
|
|
||||||
warn "${warn}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function process_mounts {
|
||||||
|
if [[ ${#MOUNT_QUEUE[@]} -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sudo_multi "${MOUNT_QUEUE[@]}"
|
||||||
|
mount_queue_init
|
||||||
|
}
|
||||||
|
|
||||||
function env_sync_proc {
|
function env_sync_proc {
|
||||||
# This function runs and performs periodic updates to the chroot env, if
|
# This function runs and performs periodic updates to the chroot env, if
|
||||||
# necessary.
|
# necessary.
|
||||||
@ -238,17 +235,18 @@ function setup_env {
|
|||||||
|
|
||||||
debug "Mounting chroot environment."
|
debug "Mounting chroot environment."
|
||||||
MOUNT_CACHE=$(mount)
|
MOUNT_CACHE=$(mount)
|
||||||
ensure_mounted none "-t proc" /proc
|
mount_queue_init
|
||||||
ensure_mounted none "-t sysfs" /sys
|
queue_mount none "-t proc" /proc
|
||||||
ensure_mounted /dev "--bind" /dev
|
queue_mount none "-t sysfs" /sys
|
||||||
ensure_mounted none "-t devpts" /dev/pts
|
queue_mount /dev "--bind" /dev
|
||||||
|
queue_mount none "-t devpts" /dev/pts
|
||||||
if [ -d /run ]; then
|
if [ -d /run ]; then
|
||||||
ensure_mounted /run "--bind" /run
|
queue_mount /run "--bind" /run
|
||||||
if [ -d /run/shm ]; then
|
if [ -d /run/shm ]; then
|
||||||
ensure_mounted /run/shm "--bind" /run/shm
|
queue_mount /run/shm "--bind" /run/shm
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
ensure_mounted "${FLAGS_trunk}" "--bind" "${CHROOT_TRUNK_DIR}"
|
queue_mount "${FLAGS_trunk}" "--bind" "${CHROOT_TRUNK_DIR}"
|
||||||
|
|
||||||
if [ $FLAGS_ssh_agent -eq $FLAGS_TRUE ]; then
|
if [ $FLAGS_ssh_agent -eq $FLAGS_TRUE ]; then
|
||||||
if [ -n "${SSH_AUTH_SOCK}" -a -d "${HOME}/.ssh" ]; then
|
if [ -n "${SSH_AUTH_SOCK}" -a -d "${HOME}/.ssh" ]; then
|
||||||
@ -258,10 +256,24 @@ function setup_env {
|
|||||||
cp "${HOME}"/.ssh/{known_hosts,*.pub} "${TARGET_DIR}/" 2>/dev/null || :
|
cp "${HOME}"/.ssh/{known_hosts,*.pub} "${TARGET_DIR}/" 2>/dev/null || :
|
||||||
copy_ssh_config "${TARGET_DIR}"
|
copy_ssh_config "${TARGET_DIR}"
|
||||||
ASOCK=${SSH_AUTH_SOCK%/*}
|
ASOCK=${SSH_AUTH_SOCK%/*}
|
||||||
ensure_mounted "${ASOCK}" "--bind" "${ASOCK}"
|
queue_mount "${ASOCK}" "--bind" "${ASOCK}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -d "$HOME/.subversion" ]; then
|
||||||
|
TARGET="/home/${USER}/.subversion"
|
||||||
|
mkdir -p "${FLAGS_chroot}${TARGET}"
|
||||||
|
queue_mount "${HOME}/.subversion" "--bind" "${TARGET}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if DEPOT_TOOLS=$(type -P gclient) ; then
|
||||||
|
DEPOT_TOOLS=${DEPOT_TOOLS%/*} # dirname
|
||||||
|
debug "Mounting depot_tools"
|
||||||
|
queue_mount "$DEPOT_TOOLS" --bind "$INNER_DEPOT_TOOLS_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
process_mounts
|
||||||
|
|
||||||
CHROME_ROOT="$(readlink -f "$FLAGS_chrome_root" || :)"
|
CHROME_ROOT="$(readlink -f "$FLAGS_chrome_root" || :)"
|
||||||
if [ -z "$CHROME_ROOT" ]; then
|
if [ -z "$CHROME_ROOT" ]; then
|
||||||
CHROME_ROOT="$(cat "${FLAGS_chroot}${CHROME_ROOT_CONFIG}" \
|
CHROME_ROOT="$(cat "${FLAGS_chroot}${CHROME_ROOT_CONFIG}" \
|
||||||
@ -279,16 +291,11 @@ function setup_env {
|
|||||||
debug "Mounting chrome source at: $INNER_CHROME_ROOT"
|
debug "Mounting chrome source at: $INNER_CHROME_ROOT"
|
||||||
sudo bash -c "echo '$CHROME_ROOT' > \
|
sudo bash -c "echo '$CHROME_ROOT' > \
|
||||||
'${FLAGS_chroot}${CHROME_ROOT_CONFIG}'"
|
'${FLAGS_chroot}${CHROME_ROOT_CONFIG}'"
|
||||||
ensure_mounted "$CHROME_ROOT" --bind "$INNER_CHROME_ROOT"
|
queue_mount "$CHROME_ROOT" --bind "$INNER_CHROME_ROOT"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if DEPOT_TOOLS=$(type -P gclient) ; then
|
process_mounts
|
||||||
DEPOT_TOOLS=${DEPOT_TOOLS%/*} # dirname
|
|
||||||
debug "Mounting depot_tools"
|
|
||||||
ensure_mounted "$DEPOT_TOOLS" --bind "$INNER_DEPOT_TOOLS_ROOT" \
|
|
||||||
"This may impact chromium build."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install fuse module. Skip modprobe when possible for slight
|
# Install fuse module. Skip modprobe when possible for slight
|
||||||
# speed increase when initializing the env.
|
# speed increase when initializing the env.
|
||||||
@ -313,12 +320,6 @@ function setup_env {
|
|||||||
# Always write the temp file so we can read it when exiting
|
# Always write the temp file so we can read it when exiting
|
||||||
echo "${SAVED_PREF:-false}" > "${FLAGS_chroot}${SAVED_AUTOMOUNT_PREF_FILE}"
|
echo "${SAVED_PREF:-false}" > "${FLAGS_chroot}${SAVED_AUTOMOUNT_PREF_FILE}"
|
||||||
|
|
||||||
if [ -d "$HOME/.subversion" ]; then
|
|
||||||
TARGET="/home/${USER}/.subversion"
|
|
||||||
mkdir -p "${FLAGS_chroot}${TARGET}"
|
|
||||||
ensure_mounted "${HOME}/.subversion" "--bind" "${TARGET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configure committer username and email in chroot .gitconfig. Change
|
# Configure committer username and email in chroot .gitconfig. Change
|
||||||
# to the root directory first so that random $PWD/.git/config settings
|
# to the root directory first so that random $PWD/.git/config settings
|
||||||
# do not get picked up. We want to stick to ~/.gitconfig only.
|
# do not get picked up. We want to stick to ~/.gitconfig only.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user