1#!/bin/sh 2 3# Get the mtd device number (mtdX) 4findmtd() { 5 m="$(grep -xl "$1" /sys/class/mtd/*/name)" 6 m="${m%/name}" 7 m="${m##*/}" 8 echo "${m}" 9} 10 11# Get the ubi device number (ubiX_Y) 12findubi() { 13 u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)" 14 u="${u%/name}" 15 u="${u##*/}" 16 echo "${u}" 17} 18 19# Get the mount information 20is_mounted() { 21 grep -q "$1" /proc/mounts 22 return $? 23} 24 25# Attach the pnor mtd device to ubi. 26attach_ubi() { 27 pnormtd="$(findmtd pnor)" 28 pnor="${pnormtd#mtd}" 29 pnordev="/dev/mtd${pnor}" 30 31 if [ -d "/sys/class/ubi/ubi${pnor}" ]; then 32 # Already attached 33 return 0 34 fi 35 36 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}" 37 rc=$? 38 if [ ${rc} -ne 0 ]; then 39 # Check the pnor mtd device is formatted as ubi by reading the first 3 byes, 40 # which should be the ascii chars 'UBI' 41 magic="$(hexdump -C -n 3 ${pnordev})" 42 if [[ "${magic}" =~ "UBI" ]]; then 43 # Device already formatted as ubi, ubiattach failed for some other reason 44 return ${rc} 45 else 46 # Format device as ubi 47 echo "Starting ubiformat ${pnordev}" 48 ubiformat "${pnordev}" -y -q 49 # Retry the ubiattach 50 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}" 51 fi 52 fi 53} 54 55mount_squashfs() { 56 pnormtd="$(findmtd pnor)" 57 ubidev="/dev/ubi${pnormtd#mtd}" 58 mountdir="/media/${name}" 59 vol="$(findubi "${name}")" 60 img="/tmp/images/${version}/pnor.xz.squashfs" 61 filesize="$(ls -sh $img | awk -F " " {'print $1'})" 62 63 if is_mounted "${name}"; then 64 echo "${name} is already mounted." 65 return 0 66 fi 67 68 if [ ! -z "${vol}" ]; then 69 ubirmvol "${ubidev}" -N "${name}" 70 fi 71 72 if [ ! -d "${mountdir}" ]; then 73 mkdir "${mountdir}" 74 fi 75 76 # Set size of read-only partition equal to pnor.xz.squashfs 77 ubimkvol "${ubidev}" -N "${name}" -s "${filesize}"KiB --type=static 78 vol="$(findubi "${name}")" 79 80 if [ $? != 0 ]; then 81 echo "Unable to create RO volume!" 82 return 1 83 fi 84 85 ubidevid="${vol#ubi}" 86 ubiupdatevol "/dev/ubi${ubidevid}" "${img}" 87 88 if [ $? != 0 ]; then 89 echo "Unable to update RO volume!" 90 return 1 91 fi 92 93 ubiblock --create "/dev/ubi${ubidevid}" 94 95 if [ $? != 0 ]; then 96 echo "Unable to create UBI block for RO volume!" 97 return 1 98 fi 99 100 mount -t squashfs -o ro "/dev/ubiblock${ubidevid}" "${mountdir}" 101 102 if [ $? != 0 ]; then 103 echo "Unable to mount RO volume!" 104 return 1 105 fi 106} 107 108mount_ubi() { 109 pnormtd="$(findmtd pnor)" 110 pnor="${pnormtd#mtd}" 111 ubidev="/dev/ubi${pnor}" 112 pnordev="/dev/mtd${pnor}" 113 114 if [[ "${name}" == "pnor-patch" ]]; then 115 if [[ "$(fw_printenv fieldmode 2>/dev/null)" == "fieldmode=true" ]]; then 116 return 0 117 fi 118 if [[ ! "$(hexdump -C -n 3 ${pnordev})" =~ "UBI" ]]; then 119 return 0 120 fi 121 mountdir="/usr/local/share/pnor" 122 else 123 mountdir="/media/${name}" 124 fi 125 126 if [[ "${name}" == "pnor-prsv" ]]; then 127 size="2MiB" 128 else 129 size="16MiB" 130 fi 131 132 if [ ! -d "${mountdir}" ]; then 133 mkdir -p "${mountdir}" 134 fi 135 136 vol="$(findubi "${name}")" 137 if [ -z "${vol}" ]; then 138 ubimkvol "${ubidev}" -N "${name}" -s "${size}" 139 fi 140 141 if ! is_mounted "${name}"; then 142 mountdev="ubi${pnor}:${name}" 143 mount -t ubifs "${mountdev}" "${mountdir}" 144 fi 145} 146 147umount_ubi() { 148 pnormtd="$(findmtd pnor)" 149 pnor="${pnormtd#mtd}" 150 ubidev="/dev/ubi${pnor}" 151 mountdir="/media/${name}" 152 153 if is_mounted "${name}"; then 154 umount "${mountdir}" 155 fi 156 157 vol="$(findubi "${name}")" 158 id="${vol##*_}" 159 if [ -n "${id}" ]; then 160 ubirmvol "${ubidev}" -n "${id}" 161 fi 162 163 if [ -d "${mountdir}" ]; then 164 rm -r "${mountdir}" 165 fi 166} 167 168remount_ubi() { 169 pnormtd="$(findmtd pnor)" 170 pnor="${pnormtd#mtd}" 171 pnordev="/dev/mtd${pnor}" 172 173 # Re-Attach the pnor mtd device to ubi 174 if [[ $(hexdump -C -n 3 ${pnordev}) =~ "UBI" ]]; then 175 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}" 176 else 177 # Device not formatted as ubi. 178 return 0 179 fi 180 181 # Get information on all ubi volumes 182 ubinfo=$(ubinfo -d ${pnor}) 183 presentVolumes=${ubinfo##*:} 184 IFS=', ' read -r -a array <<< "$presentVolumes" 185 for element in ${array[@]}; 186 do 187 elementProperties=$(ubinfo -d $pnor -n $element) 188 # Get ubi volume name by getting rid of additional properties 189 name=${elementProperties#*Name:} 190 name="${name%Character*}" 191 name="$(echo -e "${name}" | tr -d '[:space:]')" 192 193 if [[ ${name} == pnor-prsv ]] || [[ ${name} == pnor-rw* ]] || [[ ${name} == pnor-ro* ]]; then 194 mountdir="/media/${name}" 195 if [ ! -d "${mountdir}" ]; then 196 mkdir -p "${mountdir}" 197 fi 198 199 if [[ ${name} == pnor-ro* ]] 200 then 201 ubiblock --create /dev/ubi${pnor}_${element} 202 mount -t squashfs -o ro "/dev/ubiblock${pnor}_${element}" "${mountdir}" 203 else 204 mount -t ubifs "ubi${pnor}:${name}" "${mountdir}" 205 fi 206 fi 207 done 208} 209 210ubi_cleanup() { 211 # When ubi_cleanup is run, it expects one or no active version. 212 activeVersion=$(busctl --list --no-pager tree \ 213 org.open_power.Software.Host.Updater | \ 214 grep /xyz/openbmc_project/software/ | tail -c 9) 215 216 if [[ -z "$activeVersion" ]]; then 217 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | cut -c 14-) 218 vols=(${vols}) 219 else 220 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | \ 221 grep -v "$activeVersion" | cut -c 14-) 222 vols=(${vols}) 223 fi 224 225 for (( index=0; index<${#vols[@]}; index++ )); do 226 name=${vols[index]} 227 umount_ubi 228 done 229} 230 231clear_volatile() { 232 service=$(mapper get-service /org/open_power/control/volatile) 233 clearVolatileEnabled=$(busctl get-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled) 234 if [[ "$clearVolatileEnabled" != "b true" ]]; then 235 return 0 236 fi 237 238 PNOR_TOC_FILE="pnor.toc" 239 PNOR_RO_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/ro/" 240 PNOR_RW_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/rw/" 241 PNOR_PRSV_ACTIVE_PATH="/var/lib/phosphor-software-manager/pnor/prsv/" 242 243 # toc partition string format: 244 # partition27=HB_VOLATILE,0x02ba9000,0x02bae000,00,ECC,VOLATILE,READWRITE 245 tocFilePath="${PNOR_RO_ACTIVE_PATH}${PNOR_TOC_FILE}" 246 volatiles=($(grep VOLATILE "${tocFilePath}" | grep -Eo '^partition([0-9]+)=([A-Za-z0-9_]+)')) 247 for (( index=0; index<${#volatiles[@]}; index++ )); do 248 volatileName="$(echo ${volatiles[${index}]} | awk -F '=' '{print $2}')" 249 250 rwVolatile="${PNOR_RW_ACTIVE_PATH}${volatileName}" 251 if [ -f "${rwVolatile}" ]; then 252 echo "Clear $rwVolatile" 253 rm "${rwVolatile}" 254 fi 255 prsvVolatile="${PNOR_PRSV_ACTIVE_PATH}${volatileName}" 256 if [ -f "${prsvVolatile}" ]; then 257 echo "Clear $prsvVolatile" 258 rm "${prsvVolatile}" 259 fi 260 done 261 # Always reset the sensor after clearing 262 busctl set-property $service /org/open_power/control/volatile xyz.openbmc_project.Object.Enable Enabled b false 263} 264 265case "$1" in 266 ubiattach) 267 attach_ubi 268 ;; 269 squashfsmount) 270 name="$2" 271 version="$3" 272 mount_squashfs 273 ;; 274 ubimount) 275 name="$2" 276 mount_ubi 277 ;; 278 ubiumount) 279 name="$2" 280 umount_ubi 281 ;; 282 ubiremount) 283 remount_ubi 284 ;; 285 ubicleanup) 286 ubi_cleanup 287 ;; 288 clearvolatile) 289 clear_volatile 290 ;; 291 *) 292 echo "Invalid argument" 293 exit 1 294 ;; 295esac 296rc=$? 297if [ ${rc} -ne 0 ]; then 298 echo "$0: error ${rc}" 299 exit ${rc} 300fi 301