blob: 3d37f852445d454fb866508130d87dc7b5af5454 [file] [log] [blame]
#!/bin/bash
# Statically setting the BM_MODE
BM_MODE="@BM_MODE@"
GPIO_CHIP="@GPIO_CHIP@"
GPIO_LINE="@GPIO_LINE@"
HIDE_BOOT_DRIVE="@HIDE_BOOT_DRIVE@"
SHOW_BOOT_DRIVE="@SHOW_BOOT_DRIVE@"
ENABLE_BM_FILE="@ENABLE_BM_FILE@"
ENABLE_CONSOLE_FILE="@ENABLE_CONSOLE_FILE@"
BMREADY_FILE="@BMREADY_FILE@"
declare -A HOST_TO_HOSTLOGGER_SERVICE="@HOST_TO_HOSTLOGGER_SERVICE@"
READ_ONLY_CONSOLE_FLAG="/run/readonly-console.flag"
function override_obmc_console_in_bm_mode() {
host_console_client_service="serial-to-host@.service"
bmc_console_client_service="serial-to-bmc@.service"
systemd_runtime_dir='/run/systemd/system'
host_console_client_dir="${systemd_runtime_dir}/${host_console_client_service}.d"
bmc_console_client_dir="${systemd_runtime_dir}/${bmc_console_client_service}.d"
touch "${READ_ONLY_CONSOLE_FLAG}"
mkdir -p "${host_console_client_dir}" "${bmc_console_client_dir}"
echo "[Unit]
ConditionPathExists=${READ_ONLY_CONSOLE_FLAG}
[Service]
RestartPreventExitStatus=
RestartPreventExitStatus=SIGINT SIGQUIT SIGTSTP
SuccessExitStatus=
SuccessExitStatus=SIGINT SIGQUIT SIGTSTP
ExecStart=
ExecStart=-/sbin/agetty -8 -n -l /usr/libexec/readonly-obmc-console-client -i -N -R -L %I 115200 xterm
ExecStopPost=
ExecStopPost=-/bin/sh -c 'systemctl start --no-block serial-to-bmc@%i'
" > "${host_console_client_dir}/50-bm-override.conf"
echo "[Service]
ExecStopPost=
ExecStopPost=/bin/bash -c \"if [ -f ${READ_ONLY_CONSOLE_FLAG} ]; then \
systemctl start --no-block serial-to-host@%i; \
else \
systemctl start --no-block serial-to-bmc@%i; \
fi\"
" > "${bmc_console_client_dir}/50-bm-override.conf"
}
function override_hostlogger_in_bm_mode() {
systemd_runtime_dir='/run/systemd/system'
systemd_etc_dir='/etc/systemd/system'
for host_num in "${!HOST_TO_HOSTLOGGER_SERVICE[@]}"
do
hostlogger_service="${HOST_TO_HOSTLOGGER_SERVICE[$host_num]}"
if [ "$hostlogger_service" = "hostlogger@*.service" ]; then
# If using the default setting with wildcard in the service name,
# we need to remove the wildcard from the directory name.
hostlogger_override_dir="${systemd_runtime_dir}/hostlogger@.service.d"
else
hostlogger_override_dir="${systemd_runtime_dir}/${hostlogger_service}.d"
fi
bare_metal_active_target="gbmc-bare-metal-active@${host_num}.target"
mkdir -p ${hostlogger_override_dir}
echo "[Unit]
BindsTo=${bare_metal_active_target}
Before=${bare_metal_active_target}
[Install]
WantedBy=
WantedBy=${bare_metal_active_target}
" > "${hostlogger_override_dir}/50-bm-override.conf"
# Overriding Install section does not work for already installed service
# Moving the service directly and recover it when turning off BM mode.
# mv seems not happy with jffs + symlink.
mkdir -p ${systemd_etc_dir}/${bare_metal_active_target}.wants
cp -P ${systemd_etc_dir}/multi-user.target.wants/${hostlogger_service} \
${systemd_etc_dir}/${bare_metal_active_target}.wants/
rm ${systemd_etc_dir}/multi-user.target.wants/${hostlogger_service}
done
# looks like we need to stop from any existing transaction to really prevent
# it from starting
systemctl stop hostlogger@*.service
}
function recover_hostlogger_in_bm_mode() {
systemd_etc_dir='/etc/systemd/system'
mkdir -p ${systemd_etc_dir}/multi-user.target.wants
for host_num in "${!HOST_TO_HOSTLOGGER_SERVICE[@]}"
do
hostlogger_service="${HOST_TO_HOSTLOGGER_SERVICE[$host_num]}"
bare_metal_active_target="gbmc-bare-metal-active@${host_num}.target"
# If this hostlogger service is already in multi-user target, skip it
if test -f ${systemd_etc_dir}/multi-user.target.wants/${hostlogger_service}; then
continue
fi
cp -P ${systemd_etc_dir}/${bare_metal_active_target}.wants/${hostlogger_service} \
${systemd_etc_dir}/multi-user.target.wants/ 2> /dev/null
rm ${systemd_etc_dir}/${bare_metal_active_target}.wants/${hostlogger_service} 2> /dev/null
done
}
function hide_boot_drive_in_bm_mode() {
if [[ -n "${HIDE_BOOT_DRIVE}" ]]; then
echo "hiding the boot drive with '${HIDE_BOOT_DRIVE}'" >&2
${HIDE_BOOT_DRIVE}
else
echo "hiding the boot drive with GPIO (${GPIO_CHIP}/${GPIO_LINE})" >&2
gpioset --mode=signal --background "${GPIO_CHIP}" "${GPIO_LINE}"=0
fi
}
function show_boot_drive() {
if [[ -n "${SHOW_BOOT_DRIVE}" ]]; then
echo "showing the boot drive with '${SHOW_BOOT_DRIVE}'" >&2
${SHOW_BOOT_DRIVE}
else
echo "showing the boot drive with GPIO (${GPIO_CHIP}/${GPIO_LINE})" >&2
gpioset --mode=time -s 1 "${GPIO_CHIP}" "${GPIO_LINE}"=1
fi
}
function main() {
# In Bare Metal mode, power off the boot drive
if [[ "$BM_MODE" -eq "1" || -f "$ENABLE_BM_FILE" ]]; then
# Turn off the power to the boot drive
# and keep asserting the power down
if ! hide_boot_drive_in_bm_mode; then
echo "Unable to hide cSSD/cnSSD - skip adding ${BMREADY_FILE}"
exit 1
fi
echo "Successfully set the GPIO to hide cSSD/cnSSD creating ${BMREADY_FILE}"
# Disable usb network
ln -s /dev/null /run/systemd/system/google-usb-dynamic.service 2> /dev/null
# Change the host console to read only, unless we require to keep the
# console
if [[ ! -f "$ENABLE_CONSOLE_FILE" ]]; then
override_hostlogger_in_bm_mode
override_obmc_console_in_bm_mode
fi
systemctl daemon-reload
touch "${BMREADY_FILE}"
else
# daemon-reload only if we are really recoverying from bm mode
recover_hostlogger_in_bm_mode && systemctl daemon-reload
# Turn on the power to the boot drive
echo "Powering on the cSSD/cnSSD as we are not in BM mode - remove ${BMREADY_FILE}"
rm -f "${BMREADY_FILE}"
show_boot_drive
fi
}
main "$@"