# Copyright 2016 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. | |
description "Update the Activation Date" | |
author "chromium-os-dev@chromium.org" | |
start on started system-services | |
stop on stopping system-services | |
# This sets the activation date to the RW_VPD of a device. Here we wait | |
# for a proper time sync to have taken place before setting the value | |
# to ensure that the time is correct. | |
script | |
FIELD_NAME="ActivateDate" | |
OOBE_COMPLETED_FILE="/home/chronos/.oobe_completed" | |
PARTITION="RW_VPD" | |
# TIMEFILE is updated by tlsdated whenever a time remote sync occurs. | |
TIMEFILE="/var/cache/tlsdated/timestamp" | |
check_timestamp() { | |
stat -c %Y "${TIMEFILE}" || : | |
} | |
# Get initial timestamp of TIMEFILE - we don't care about the contents | |
# of this file, only its timestamp. We will check the timestamp later | |
# to see if a remote time sync occurred. There is a race condition here, | |
# tlsdated only updates the time every 24 hours by default, so if we | |
# don't get the timefile timestamp before tlsdated updates the time on | |
# boot we will end up waiting 24 hours. This upstart should almost | |
# always win the race as tlsdated depends on having a valid network | |
# connection up. | |
# TODO(bhthompson): find a way to avoid the race. | |
TIMESTAMP=$(check_timestamp) | |
# Never run from a factory image. | |
if [ -f /root/.factory_test -o -f /root/.factory_installer ] ; then | |
exit 0 | |
fi | |
# Wait for OOBE to have completed. | |
while [ ! -f "${OOBE_COMPLETED_FILE}" ]; do | |
sleep 60 | |
done | |
# Wait for remote sync of clock, then write activation date. | |
while true; do | |
sleep 200 | |
# Only a non-empty TIMEFILE guarantees that a time sync has happened. | |
if [ "${TIMESTAMP}" != "$(check_timestamp)" -a -s "${TIMEFILE}" ] ; then | |
# Get system date with proper format for FUD. | |
year=$(expr \( $(date +%Y) \- 1980 \) \* 512) | |
month=$(expr $(date +%m) \* 32) | |
fuddata=$(expr $year \+ $month \+ $(date +%d)) | |
# Write FUD to battery. We could call it every time. | |
# EC firmware would only write once to battery if the FUD is cleared. | |
# The call will already return failed, but write would be succeed. | |
if ! ectool batteryparam set 0 $fuddata 2>&1; then | |
logger -t "$UPSTART_JOB" "Battery FUD already set." | |
fi | |
# Don't run if we have set the date already, we use dump_vpd_log so that | |
# we can leverage the cached VPD file. | |
# This is a soft check, the activate_date script will also check the vpd | |
# directly to see if a date has been set. | |
# | |
ACTIVATE_DATE=$(dump_vpd_log --stdout | grep ${FIELD_NAME} | cut -d '"' -f 4) | |
if [ -n "${ACTIVATE_DATE}" ]; then | |
exit 0 | |
fi | |
if ! activate_date 2>&1; then | |
logger -t "$UPSTART_JOB" "activate_date failed." | |
exit 0 | |
fi | |
if ! dump_vpd_log --force 2>&1; then | |
logger -t "$UPSTART_JOB" "dump_vpd_log failed." | |
exit 0 | |
fi | |
logger -t "$UPSTART_JOB" "Activation date set." | |
exit 0 | |
fi | |
done | |
end script |