1#!/bin/sh
2
3clear_volatile() {
4  service=$(mapper get-service /org/open_power/control/volatile)
5  clearVolatileEnabled=$(busctl get-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled)
6  if [[ "$clearVolatileEnabled" != "b true" ]]; then
7    return 0
8  fi
9
10  PNOR_TOC_FILE="pnor.toc"
11  PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro/"
12  PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw/"
13  PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv/"
14
15  # toc partition string format:
16  # partition27=HB_VOLATILE,0x02ba9000,0x02bae000,00,ECC,VOLATILE,READWRITE
17  tocFilePath="${PNOR_RO_ACTIVE_PATH}${PNOR_TOC_FILE}"
18  volatiles=($(grep VOLATILE "${tocFilePath}" | grep -Eo '^partition([0-9]+)=([A-Za-z0-9_]+)'))
19  for (( index=0; index<${#volatiles[@]}; index++ )); do
20    volatileName="$(echo ${volatiles[${index}]} | awk -F '=' '{print $2}')"
21
22    rwVolatile="${PNOR_RW_ACTIVE_PATH}${volatileName}"
23    if [ -f "${rwVolatile}" ]; then
24      echo "Clear $rwVolatile"
25      rm "${rwVolatile}"
26    fi
27    prsvVolatile="${PNOR_PRSV_ACTIVE_PATH}${volatileName}"
28    if [ -f "${prsvVolatile}" ]; then
29      echo "Clear $prsvVolatile"
30      rm "${prsvVolatile}"
31    fi
32  done
33  # Always reset the sensor after clearing
34  busctl set-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled b false
35}
36
37update_symlinks() {
38  PNOR_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/"
39  HOSTFW_ACTIVE_PATH="/var/lib/phosphor-software-manager/hostfw/"
40  PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro"
41  PNOR_RO_PREFIX="/media/pnor-ro-"
42  PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw"
43  PNOR_RW_PREFIX="/media/pnor-rw-"
44  PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv"
45  PNOR_PRSV="/media/pnor-prsv"
46  PERSISTENCE_PATH="/var/lib/obmc/openpower-pnor-code-mgmt/"
47  PNOR_PATCH_LOCATION="/usr/local/share/pnor/"
48  MMC_BASE_PATH="/media/hostfw"
49  MMC_RO_PATH="${MMC_BASE_PATH}/running-ro"
50  MMC_RUNNING_PATH="${MMC_BASE_PATH}/running"
51  MMC_ALTERNATE_PATH="${MMC_BASE_PATH}/alternate"
52  MMC_STAGING_PATH="${MMC_BASE_PATH}/staging"
53  HOSTFW_RUNNING_PATH="${HOSTFW_ACTIVE_PATH}/running"
54  HOSTFW_ALTERNATE_PATH="${HOSTFW_ACTIVE_PATH}/alternate"
55  HOSTFW_STAGING_PATH="${HOSTFW_ACTIVE_PATH}/staging"
56
57  # Get a list of all active PNOR versions
58  data="$(ls -d ${PNOR_RO_PREFIX}* 2>/dev/null)"
59  IFS=$'\n'  array=(${data})
60
61  currentVersion=""
62  lowestPriority=255
63  for element in ${array[@]}; do
64    #Remove the PNOR_RO_PREFIX from the path to get version ID.
65    versionId="${element#${PNOR_RO_PREFIX}}"
66
67    # Get the priority of active versions from persistence files.
68    if [[ -f "${PERSISTENCE_PATH}${versionId}" ]]; then
69      data="$(grep -r "priority" ${PERSISTENCE_PATH}${versionId})"
70      priority="${data: -1}"
71      if [[ priority -le lowestPriority  ]]; then
72        lowestPriority=${priority}
73        currentVersion=${versionId}
74      fi
75    fi
76  done
77
78  if [ ! -z $currentVersion ]; then
79      # Use active version
80      roTarget="${PNOR_RO_PREFIX}${currentVersion}"
81      rwTarget="${PNOR_RW_PREFIX}${currentVersion}"
82      prsvTarget="${PNOR_PRSV}"
83  elif [ -d "${MMC_BASE_PATH}" ]; then
84      # Use eMMC
85      roTarget="${MMC_RO_PATH}"
86      rwTarget="${MMC_RUNNING_PATH}"
87      prsvTarget="${MMC_RUNNING_PATH}"
88
89      if [ ! -d "${HOSTFW_ACTIVE_PATH}" ]; then
90          mkdir -p "${HOSTFW_ACTIVE_PATH}"
91      fi
92      # Symlinks used by PLDM
93      if [[ $(readlink -f "${HOSTFW_RUNNING_PATH}") != ${MMC_RUNNING_PATH} ]]; then
94          rm -f ${HOSTFW_RUNNING_PATH}
95          ln -sfv ${MMC_RUNNING_PATH} ${HOSTFW_RUNNING_PATH}
96      fi
97      if [[ $(readlink -f "${HOSTFW_ALTERNATE_PATH}") != ${MMC_ALTERNATE_PATH} ]]; then
98          rm -f ${HOSTFW_ALTERNATE_PATH}
99          ln -sfv ${MMC_ALTERNATE_PATH} ${HOSTFW_ALTERNATE_PATH}
100      fi
101      if [[ $(readlink -f "${HOSTFW_STAGING_PATH}") != ${MMC_STAGING_PATH} ]]; then
102          rm -f ${HOSTFW_STAGING_PATH}
103          ln -sfv ${MMC_STAGING_PATH} ${HOSTFW_STAGING_PATH}
104      fi
105  fi
106
107  if [ ! -d "${PNOR_ACTIVE_PATH}" ]; then
108        mkdir -p "${PNOR_ACTIVE_PATH}"
109  fi
110
111  # If the RW or RO active links doesn't point to the version with
112  # lowest priority, then remove the symlink and create new ones.
113  if [[ $(readlink -f "${PNOR_RO_ACTIVE_PATH}") != ${roTarget}  ]]; then
114    rm -f ${PNOR_RO_ACTIVE_PATH}
115    rm -rf ${PNOR_PATCH_LOCATION}*
116    ln -sfv ${roTarget} ${PNOR_RO_ACTIVE_PATH}
117  fi
118
119  if [[ $(readlink -f "${PNOR_RW_ACTIVE_PATH}") != ${rwTarget}  ]]; then
120    rm -f ${PNOR_RW_ACTIVE_PATH}
121    ln -sfv ${rwTarget} ${PNOR_RW_ACTIVE_PATH}
122  fi
123
124  if [[ $(readlink -f "${PNOR_PRSV_ACTIVE_PATH}") != ${prsvTarget} ]]; then
125    rm -f ${PNOR_PRSV_ACTIVE_PATH}
126    ln -sfv ${prsvTarget} ${PNOR_PRSV_ACTIVE_PATH}
127  fi
128}
129
130case "$1" in
131  clearvolatile)
132    clear_volatile
133    ;;
134  updatesymlinks)
135    update_symlinks
136    ;;
137  *)
138    echo "Invalid argument"
139    exit 1
140    ;;
141esac
142rc=$?
143if [ ${rc} -ne 0 ]; then
144  echo "$0: error ${rc}"
145  exit ${rc}
146fi
147