Move script, systemd conf, service files into repo
Move the common scripts, systemd configuration and service files
from openbmc/openbmc to the local one.
Tested: The moved files are installed in their respective locations
and code update on Witherspoon is successful.
Change-Id: I2dc435db49dfbaf6e0a97cb58a9678c3462d1528
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 50ecf3d..c2478d1 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,9 @@
phosphor-download-manager \
phosphor-image-updater
+dist_bin_SCRIPTS = \
+ obmc-flash-bmc
+
phosphor_version_software_manager_SOURCES = \
image_manager_main.cpp \
watch.cpp \
@@ -42,6 +45,19 @@
item_updater.cpp \
item_updater_main.cpp
+if HAVE_SYSTEMD
+systemdsystemunit_DATA = \
+ obmc-flash-bmc-setenv@.service \
+ xyz.openbmc_project.Software.BMC.Updater.service \
+ xyz.openbmc_project.Software.Download.service \
+ xyz.openbmc_project.Software.Sync.service \
+ xyz.openbmc_project.Software.Version.service
+
+tmpfilesdir=${exec_prefix}/lib/tmpfiles.d/
+dist_tmpfiles_DATA = \
+ software.conf
+endif
+
if UBIFS_LAYOUT
include ubi/Makefile.am.include
else
@@ -68,6 +84,8 @@
sync_manager_main.cpp
phosphor_sync_software_manager_CXXFLAGS = $(generic_cxxflags)
phosphor_sync_software_manager_LDFLAGS = $(generic_ldflags)
+dist_sysconf_DATA = \
+ synclist
endif
nodist_phosphor_image_updater_SOURCES = \
diff --git a/obmc-flash-bmc b/obmc-flash-bmc
new file mode 100644
index 0000000..0b1b16e
--- /dev/null
+++ b/obmc-flash-bmc
@@ -0,0 +1,516 @@
+#!/bin/bash
+set -eo pipefail
+
+# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
+findrootmtd() {
+ rootmatch=" on / "
+ m="$(mount | grep "${rootmatch}" | grep "ubiblock")"
+ m="${m##*ubiblock}"
+ m="${m%_*}"
+ if [ -z "${m}" ]; then
+ # default to bmc mtd (0)
+ m=0
+ fi
+ echo "mtd${m}"
+}
+
+findrootubi() {
+ rootmatch=" on / "
+ m="$(mount | grep "${rootmatch}")"
+ m="${m##*ubiblock}"
+ m="${m% on*}"
+ echo "ubi${m}"
+}
+
+# Get the mtd device number (mtdX)
+findmtd() {
+ m="$(grep -xl "$1" /sys/class/mtd/*/name)"
+ m="${m%/name}"
+ m="${m##*/}"
+ echo "${m}"
+}
+
+# Get the mtd device number only (return X of mtdX)
+findmtdnum() {
+ m="$(findmtd "$1")"
+ m="${m##mtd}"
+ echo "${m}"
+}
+
+# Get the ubi device number (ubiX_Y)
+findubi() {
+ u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
+ u="${u%/name}"
+ u="${u##*/}"
+ echo "${u}"
+}
+
+# Get the ubi device number (ubiX_Y) on a specific mtd
+findubi_onmtd() {
+ u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
+ u="${u%/name}"
+ u="${u##*/}"
+ echo "${u}"
+}
+
+# Get all ubi device names on a specific mtd that match requested string
+findubiname_onmtd() {
+ u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
+ u="${u%/name}"
+ u="${u##*/}"
+ echo "${u}"
+}
+
+# Get the name from the requested ubiX_Y volume
+findname() {
+ n="$(cat /sys/class/ubi/$1/name)"
+ echo "${n}"
+}
+
+# Set the u-boot envs that perform a side switch on failure to boot
+set_wdt2bite() {
+ if ! fw_printenv wdt2bite 2>/dev/null; then
+ fw_setenv wdt2bite "mw.l 0x1e785024 0xa 1; mw.b 0x1e78502c 0xb3 1"
+ fw_setenv bootalt "run wdt2bite"
+ fw_setenv obmc_bootcmd "ubi part obmc-ubi; run do_rwreset; ubi read \
+\${loadaddr} \${kernelname}; bootm \${loadaddr} || run bootalt"
+ fi
+}
+
+# Make space on flash before creating new volumes. This can be enhanced
+# determine current flash usage. For now only keep a "keepmax" number of them
+ubi_remove_volumes()
+{
+ rootubi="$(findrootubi)"
+ rootname="$(findname "${rootubi}")"
+ rootversion="${rootname##*-}"
+ rootkernel="kernel-${rootversion}"
+
+ # Just keep max number of volumes before updating, don't delete the version
+ # the BMC is booted from, and when a version is identified to be deleted,
+ # delete both the rofs and kernel volumes for that version.
+ rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")"
+ rmnames=(${rmnames})
+ ubicount="${#rmnames[@]}"
+ while [ ${ubicount} -ge ${keepmax} ]; do
+ # Loop through existing volumes and skip currently active ones
+ for (( index=0; index<${#rmnames[@]}; index++ )); do
+ rmname="${rmnames[${index}]}"
+ rmversion="${rmname##*-}"
+ [ "${rmversion}" == "${version}" ] && continue
+ rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")"
+ if [[ ( "${rmubi}" != "${rootubi}" ) &&
+ ( "${rmname}" != "${rootkernel}" ) ]]; then
+ ubi_remove "rofs-${rmversion}" "${ro}"
+ ubi_remove "kernel-${rmversion}" "${ro}"
+ # Remove priority value
+ fw_setenv "${rmversion}"
+ break
+ fi
+ done
+ # Decrease count regardless to avoid an infinite loop
+ (( ubicount-- ))
+ done
+}
+
+ubi_rw() {
+ rwmtd="$(findmtd "${reqmtd}")"
+ rw="${rwmtd#mtd}"
+ ubidev="/dev/ubi${rw}"
+
+ # Update rwfs_size, check imgsize was specified, otherwise it'd clear the var
+ if [ ! -z "$imgsize" ]; then
+ rwsize="$(fw_printenv -n rwfs_size 2>/dev/null)" || true
+ if [[ "${imgsize}" != "${rwsize}" ]]; then
+ fw_setenv rwfs_size "${imgsize}"
+ fi
+ fi
+
+ vol="$(findubi "${name}")"
+ if [ -z "${vol}" ]; then
+ ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}"
+ fi
+}
+
+ubi_ro() {
+ keepmax=2 # Default 2 volumes per mtd
+ romtd="$(findmtd "${reqmtd}")"
+ romtd2="$(findmtd "${reqmtd2}")"
+
+ if [ ! "${romtd}" == "${romtd2}" ]; then
+ # Request to use alternate mtd device, choose the non-root one
+ keepmax=1 # 1 volume on each of the requested mtds
+ rootmtd="$(findrootmtd)"
+ if [ "${rootmtd}" == "${romtd}" ]; then
+ romtd="${romtd2}"
+ fi
+ fi
+ ro="${romtd#mtd}"
+ ubidev="/dev/ubi${ro}"
+
+ ubi_remove_volumes
+
+ if [ -z "${imgfile}" ]; then
+ echo "Unable to create read-only volume. Image file not specified."
+ return 1
+ fi
+
+ # Create a ubi volume, dynamically sized to fit BMC image if size unspecified
+ img="/tmp/images/${version}/${imgfile}"
+ imgsize="$(stat -c '%s' ${img})"
+
+ vol="$(findubi "${name}")"
+ if [ ! -z "${vol}" ]; then
+ # Allow a duplicate kernel volume on the alt mtd
+ if [[ "${name}" =~ "kernel" ]]; then
+ vol="$(findubi_onmtd "${name}" "${ro}")"
+ fi
+ fi
+ if [ -z "${vol}" ]; then
+ ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
+ vol="$(findubi "${name}")"
+ fi
+}
+
+# Squashfs images need a ubi block
+ubi_block() {
+ vol="$(findubi "${name}")"
+ ubidevid="${vol#ubi}"
+ block="/dev/ubiblock${ubidevid}"
+ if [ ! -e "$block" ]; then
+ ubiblock --create "/dev/ubi${ubidevid}"
+ fi
+}
+
+ubi_updatevol() {
+ vol="$(findubi "${name}")"
+ ubidevid="${vol#ubi}"
+ img="/tmp/images/${version}/${imgfile}"
+ ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
+}
+
+ubi_remove() {
+ rmname="$1"
+ rmmtd="$2"
+ if [ ! -z "${rmmtd}" ]; then
+ vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
+ else
+ vol="$(findubi "${rmname}")"
+ fi
+
+ if [ ! -z "$vol" ]; then
+ vol="${vol%_*}"
+
+ if grep -q "$rmname" /proc/mounts; then
+ mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
+ umount "$mountdir"
+ rm -r "$mountdir"
+ fi
+
+ ubirmvol "/dev/${vol}" -N "$rmname"
+ fi
+}
+
+ubi_cleanup() {
+ # When ubi_cleanup is run, it expects one or no active version.
+ activeVersion=$(busctl --list --no-pager tree \
+ xyz.openbmc_project.Software.BMC.Updater | \
+ grep /xyz/openbmc_project/software/ | tail -c 9)
+
+ if [[ -z "$activeVersion" ]]; then
+ vols=$(ubinfo -a | grep "rofs-" | cut -c 14-)
+ vols=(${vols})
+ else
+ vols=$(ubinfo -a | grep "rofs-" | \
+ grep -v "$activeVersion" | cut -c 14-)
+ vols=(${vols})
+ fi
+
+ for (( index=0; index<${#vols[@]}; index++ )); do
+ ubi_remove ${vols[index]}
+ done
+}
+
+mount_alt_rwfs() {
+ altNum="$(findmtdnum "alt-bmc")"
+ if [ ! -z "${altNum}" ]; then
+ altRwfs=$(ubinfo -a -d ${altNum} | grep -w "rwfs") || true
+ if [ ! -z "${altRwfs}" ]; then
+ altVarMount="/media/alt/var"
+ mkdir -p "${altVarMount}"
+ if mount ubi"${altNum}":rwfs "${altVarMount}" -t ubifs -o defaults; then
+ mkdir -p "${altVarMount}"/persist/etc
+ fi
+ fi
+ fi
+}
+
+remount_ubi() {
+ bmcmtd="$(findmtd "bmc")"
+ altbmcmtd="$(findmtd "alt-bmc")"
+ mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
+
+ IFS=',' read -r -a mtds <<< "$mtds"
+ mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
+ for mtd in ${mtds[@]}; do
+ # Get information on all ubi volumes
+ ubinfo=$(ubinfo -d ${mtd})
+ presentVolumes=${ubinfo##*:}
+ IFS=', ' read -r -a array <<< "$presentVolumes"
+ for element in ${array[@]}; do
+ elementProperties=$(ubinfo -d $mtd -n $element)
+ # Get ubi volume name by getting rid of additional properties
+ name=${elementProperties#*Name:}
+ name="${name%Character*}"
+ name="$(echo -e "${name}" | tr -d '[:space:]')"
+
+ if [[ ${name} == rofs-* ]]; then
+ mountdir="/media/${name}"
+
+ if [ ! -d ${mountdir} ]; then
+ mkdir -p "${mountdir}"
+ # U-Boot will create the ubiblock for the running version, but not
+ # for the version on the other chip
+ if [ ! -e "/dev/ubiblock${mtd}_${element}" ]; then
+ ubiblock --create /dev/ubi${mtd}_${element}
+ fi
+ mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
+ fi
+ fi
+ done
+ done
+
+ set_wdt2bite
+}
+
+# Read the current env variable and set it on the alternate boot env
+copy_env_var_to_alt() {
+ varName=$1
+ value="$(fw_printenv -n "${varName}")"
+ fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
+}
+
+# When the alternate bmc chip boots, u-boot thinks its the primary mtdX.
+# Therefore need to swap the chip numbers when copying the ubiblock and root to
+# alternate bmc u-boot environment.
+copy_ubiblock_to_alt() {
+ value="$(fw_printenv -n ubiblock)"
+ bmcNum="$(findmtdnum "bmc")"
+ altNum="$(findmtdnum "alt-bmc")"
+ replaceAlt="${value/${altNum},/${bmcNum},}"
+
+ if [[ "${value}" == "${replaceAlt}" ]]; then
+ replaceBmc="${value/${bmcNum},/${altNum},}"
+ value=${replaceBmc}
+ else
+ value=${replaceAlt}
+ fi
+
+ fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
+}
+
+copy_root_to_alt() {
+ value="$(fw_printenv -n root)"
+ bmcNum="$(findmtdnum "bmc")"
+ altNum="$(findmtdnum "alt-bmc")"
+ replaceAlt="${value/${altNum}_/${bmcNum}_}"
+
+ if [[ "${value}" == "${replaceAlt}" ]]; then
+ replaceBmc="${value/${bmcNum}_/${altNum}_}"
+ value=${replaceBmc}
+ else
+ value=${replaceAlt}
+ fi
+
+ fw_setenv -c /etc/alt_fw_env.config root "${value}"
+}
+
+ubi_setenv() {
+ # The U-Boot environment maintains two banks of environment variables.
+ # The banks need to be consistent with each other to ensure that these
+ # variables can reliably be read from file. In order to guarantee that the
+ # banks are both correct, we need to run fw_setenv twice.
+ variable=$1
+ if [[ "$variable" == *"="* ]]; then
+ varName="${variable%=*}"
+ value="${variable##*=}"
+ # Write only if var is not set already to the requested value
+ currentValue="$(fw_printenv -n "${varName}" 2>/dev/null)" || true
+ if [[ "${currenValue}" != "${value}" ]]; then
+ fw_setenv "$varName" "$value"
+ fw_setenv "$varName" "$value"
+ fi
+ else
+ fw_setenv "$variable"
+ fw_setenv "$variable"
+ fi
+}
+
+mtd_write() {
+ flashmtd="$(findmtd "${reqmtd}")"
+ img="/tmp/images/${version}/${imgfile}"
+ flashcp -v ${img} /dev/${flashmtd}
+}
+
+backup_env_vars() {
+ copy_env_var_to_alt kernelname
+ copy_ubiblock_to_alt
+ copy_root_to_alt
+}
+
+update_env_vars() {
+ vol="$(findubi rofs-"${version}")"
+ if [ -z "${vol}" ]; then
+ return 1
+ fi
+ ubidevid="${vol#ubi}"
+ block="/dev/ubiblock${ubidevid}"
+ if [ ! -e "${block}" ]; then
+ return 1
+ fi
+ ubi_setenv "kernelname=kernel-${version}"
+ ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
+ ubi_setenv "root=${block}"
+}
+
+#TODO: Replace the implementation with systemd-inhibitors lock
+# once systemd/systemd#949 is resolved
+rebootguardenable() {
+ dir="/run/systemd/system/"
+ file="reboot-guard.conf"
+ units=("reboot" "poweroff" "halt")
+
+ for unit in "${units[@]}"; do
+ mkdir -p ${dir}${unit}.target.d
+ echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
+ done
+}
+
+#TODO: Replace the implementation with systemd-inhibitors lock
+# once systemd/systemd#949 is resolved
+rebootguarddisable() {
+ dir="/run/systemd/system/"
+ file="reboot-guard.conf"
+ units=("reboot" "poweroff" "halt")
+
+ for unit in "${units[@]}"; do
+ rm -rf ${dir}${unit}.target.d/${file}
+ done
+}
+
+# Create a copy in the alt mtd
+create_vol_in_alt() {
+ alt="alt-bmc"
+ altmtd="$(findmtd "${alt}")"
+ if [ ! -z "${altmtd}" ]; then
+ reqmtd="${alt}"
+ reqmtd2="${alt}"
+ ubi_ro
+ ubi_updatevol
+ fi
+}
+
+# Copy contents of one MTD device to another
+mtd_copy() {
+ in=$1
+ out=$2
+
+ # Must erase MTD first to prevent corruption
+ flash_eraseall "${out}"
+ dd if="${in}" of="${out}"
+}
+
+mirroruboot() {
+ bmc="$(findmtd "u-boot")"
+ bmcdev="/dev/${bmc}"
+ alt="$(findmtd "alt-u-boot")"
+ altdev="/dev/${alt}"
+
+ checksum_bmc="$(md5sum "${bmcdev}")"
+ checksum_bmc="${checksum_bmc% *}"
+ checksum_alt="$(md5sum "${altdev}")"
+ checksum_alt="${checksum_alt% *}"
+
+ if [[ "${checksum_bmc}" != "${checksum_alt}" ]]; then
+ bmcenv="$(findmtd "u-boot-env")"
+ bmcenvdev="/dev/${bmcenv}"
+ altenv="$(findmtd "alt-u-boot-env")"
+ altenvdev="/dev/${altenv}"
+
+ echo "Mirroring U-boot to alt chip"
+ mtd_copy "${bmcdev}" "${altdev}"
+ mtd_copy "${bmcenvdev}" "${altenvdev}"
+
+ copy_ubiblock_to_alt
+ copy_root_to_alt
+ fi
+}
+
+case "$1" in
+ mtduboot)
+ reqmtd="$2"
+ version="$3"
+ imgfile="image-u-boot"
+ mtd_write
+ ;;
+ ubirw)
+ reqmtd="$2"
+ name="$3"
+ imgsize="$4"
+ ubi_rw
+ ;;
+ ubiro)
+ reqmtd="$(echo "$2" | cut -d "+" -f 1)"
+ reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
+ name="$3"
+ version="$4"
+ imgfile="image-rofs"
+ ubi_ro
+ ubi_updatevol
+ ubi_block
+ ;;
+ ubikernel)
+ reqmtd="$(echo "$2" | cut -d "+" -f 1)"
+ reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
+ name="$3"
+ version="$4"
+ imgfile="image-kernel"
+ ubi_ro
+ ubi_updatevol
+ create_vol_in_alt
+ ;;
+ ubiremove)
+ name="$2"
+ ubi_remove "${name}"
+ ;;
+ ubicleanup)
+ ubi_cleanup
+ ;;
+ ubisetenv)
+ ubi_setenv "$2"
+ ;;
+ ubiremount)
+ remount_ubi
+ mount_alt_rwfs
+ ;;
+ createenvbackup)
+ backup_env_vars
+ ;;
+ updateubootvars)
+ version="$2"
+ update_env_vars
+ ;;
+ rebootguardenable)
+ rebootguardenable
+ ;;
+ rebootguarddisable)
+ rebootguarddisable
+ ;;
+ mirroruboot)
+ mirroruboot
+ ;;
+ *)
+ echo "Invalid argument"
+ exit 1
+ ;;
+esac
diff --git a/obmc-flash-bmc-setenv@.service b/obmc-flash-bmc-setenv@.service
new file mode 100644
index 0000000..3e5408d
--- /dev/null
+++ b/obmc-flash-bmc-setenv@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Set U-Boot environment variable
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/usr/bin/obmc-flash-bmc ubisetenv %I
diff --git a/software.conf b/software.conf
new file mode 100644
index 0000000..09ecd92
--- /dev/null
+++ b/software.conf
@@ -0,0 +1,3 @@
+# /tmp/images is the software image upload directory
+# It should not be deleted if the UBI code update is used.
+x /tmp/images
diff --git a/synclist b/synclist
new file mode 100644
index 0000000..3836673
--- /dev/null
+++ b/synclist
@@ -0,0 +1,3 @@
+/etc/hostname
+/etc/machine-id
+/etc/systemd/network/
diff --git a/ubi/Makefile.am.include b/ubi/Makefile.am.include
index b343a74..123f58d 100644
--- a/ubi/Makefile.am.include
+++ b/ubi/Makefile.am.include
@@ -3,7 +3,7 @@
%reldir%/item_updater_helper.cpp
if HAVE_SYSTEMD
-systemdsystemunit_DATA = \
+systemdsystemunit_DATA += \
%reldir%/obmc-flash-bmc-cleanup.service \
%reldir%/obmc-flash-bmc-mirroruboot.service \
%reldir%/obmc-flash-bmc-ubiremount.service \
diff --git a/xyz.openbmc_project.Software.BMC.Updater.service b/xyz.openbmc_project.Software.BMC.Updater.service
new file mode 100644
index 0000000..9fd6466
--- /dev/null
+++ b/xyz.openbmc_project.Software.BMC.Updater.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=OpenBMC Software Update Manager
+Wants=xyz.openbmc_project.Software.Version.service
+Before=xyz.openbmc_project.Software.Version.service
+Wants=obmc-mapper.target
+After=obmc-mapper.target
+
+[Service]
+ExecStart=/usr/bin/phosphor-image-updater
+Restart=always
+Type=dbus
+BusName={BUSNAME}
+
+[Install]
+WantedBy=multi-user.target
diff --git a/xyz.openbmc_project.Software.Download.service b/xyz.openbmc_project.Software.Download.service
new file mode 100644
index 0000000..404691e
--- /dev/null
+++ b/xyz.openbmc_project.Software.Download.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Phosphor Download Manager
+
+[Service]
+ExecStart=/usr/bin/phosphor-download-manager
+Restart=always
+Type=dbus
+BusName={BUSNAME}
+
+[Install]
+WantedBy=multi-user.target
diff --git a/xyz.openbmc_project.Software.Sync.service b/xyz.openbmc_project.Software.Sync.service
new file mode 100644
index 0000000..5feeaa5
--- /dev/null
+++ b/xyz.openbmc_project.Software.Sync.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Phosphor Sync Manager that syncs files to the alternate BMC chip
+
+[Service]
+ExecStart=/usr/bin/phosphor-sync-software-manager
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/xyz.openbmc_project.Software.Version.service b/xyz.openbmc_project.Software.Version.service
new file mode 100644
index 0000000..9651ee2
--- /dev/null
+++ b/xyz.openbmc_project.Software.Version.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Phosphor Version Software Manager
+
+[Service]
+ExecStartPre=/bin/sh -c 'mkdir -p /tmp/images'
+ExecStart=/usr/bin/phosphor-version-software-manager
+Restart=always
+Type=dbus
+BusName={BUSNAME}
+
+[Install]
+WantedBy=multi-user.target