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