blob: 93212f3846e6e5b981583506fa893292f039bbcf [file] [log] [blame]
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
description "Updates devices using fwupdtool"
author "chromium-os-dev@chromium.org"
# This job is started by udev via custom events.
# Job duration is expected to be O(minutes) depending on the number of
# devices with pending updates.
start on fwupdtool-update
task
oom score -100 # Very unlikely.
instance $GUID-$AT_BOOT
# Device GUID to be updated by fwupdtool update invocation.
import GUID
# FWUPD plugin to be used by fwupdtool update invokation.
import PLUGIN
# Are we running at boot time.
import AT_BOOT
# Update .cab file. Used to allow downgrades.
import FIRMWARE_FILE
env LANG=en_US.UTF-8
env CACHE_DIRECTORY="/var/cache/fwupd"
env AT_BOOT="false"
env FILTER="usable-during-update"
env REGEX="^[0-9a-f]\{8\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{12\}$"
# TODO(259354228): Remove once resolv.conf migration to dns-proxy is done.
# Need access to /run/shill to download from LVFS mirror (DNS resolution).
# Need access to /run/dns-proxy to download from LVFS mirror (DNS resolution).
env MINIJAIL_ARGS="--profile=minimalistic-mountns --uts -l -p -N \
-k /run,/run,tmpfs -b /run/dbus -b /run/shill -b /run/dns-proxy \
-u fwupd -g fwupd"
env MINIJAIL_ARGS_TOOL="--uts -l -p -N \
-v -P /mnt/empty -b / -b /proc -r -t -b /dev,,1 -k run,/run,tmpfs \
-k /var,/var,tmpfs -b /var/cache/fwupd,,1 -b /var/lib/fwupd,,1 \
-b /run/lock,,1 -b /sys,,1 -u fwupd -g fwupd -G"
env FWUPD_PATH="/usr/bin/fwupdmgr"
env FWUPD_ARGS=""
env FWUPD_RET=0
tmpfiles /usr/lib/tmpfiles.d/fwupd.conf
pre-start script
# Abort if the rootfs is on removable media. e.g. It's on a USB stick.
. /usr/share/misc/chromeos-common.sh
. /usr/sbin/write_gpt.sh
load_base_vars
if rootdev_removable; then
logger -p warn -t "${UPSTART_JOB}" "Attempting update from removable media"
stop
exit 0
fi
for guid in ${GUID}; do
if [ $(expr "${guid}" : "${REGEX}") -eq 0 ]; then
logger -p err -t "${UPSTART_JOB}" "Invalid GUID: ${guid}"
exit 1
fi
done
for plugin in ${PLUGIN}; do
if ! minijail0 ${MINIJAIL_ARGS} -- "${FWUPD_PATH}" get-plugins \
| grep -x -F "${plugin}:"; then
logger -p err -t "${UPSTART_JOB}" "Unsupported plugin: ${plugin}"
exit 1
fi
done
end script
script
for plugin in ${PLUGIN}; do
case "${plugin}" in "nvme")
# Grant cap_sys_admin for nvme plugin to issue admin ioctl commands.
MINIJAIL_ARGS="${MINIJAIL_ARGS_TOOL} -c cap_dac_override,cap_sys_admin+e"
FWUPD_PATH="/usr/bin/fwupdtool"
esac
done
if [ -n "${FIRMWARE_FILE}" ]; then
# Grant access to /run/imageloader if the firmware file path starts with
# that prefix.
case "${FIRMWARE_FILE}" in /run/imageloader/*)
MINIJAIL_ARGS="${MINIJAIL_ARGS} \
-k /run/imageloader,/run/imageloader,none,MS_BIND|MS_REC"
esac
FWUPD_ARGS="install ${FIRMWARE_FILE} ${GUID} --allow-older"
else
FWUPD_ARGS="update ${GUID}"
fi
# Do not filter un-usable devices during boot time.
if [ "${AT_BOOT}" = "true" ]; then
FILTER=
fi
CURRENT_TIME="$(date +%s)"
syslog-cat --identifier="${UPSTART_JOB}" -- minijail0 ${MINIJAIL_ARGS} \
-- "${FWUPD_PATH}" ${FWUPD_ARGS} --filter="${FILTER}" || FWUPD_RET=$?
ELAPSED_TIME="$(($(date +%s) - ${CURRENT_TIME} + 1))"
metrics_client -e Platform.Fwupd.UpdateStatus "${FWUPD_RET}" 2
if [ "${FWUPD_RET}" -eq 0 ]; then
metrics_client Platform.Fwupd.UpdateDuration "${ELAPSED_TIME}" 0 7200 10
fi
# If there is a pending update we will delay until next boot.
if [ "${AT_BOOT}" = "false" ]; then
if minijail0 ${MINIJAIL_ARGS} \
-- "${FWUPD_PATH}" get-updates ${GUID} --filter=~"${FILTER}"; then
for guid in ${GUID}; do
echo "${PLUGIN}" > /var/lib/fwupd/pending/${guid}
done
fi
fi
end script