1#!/bin/bash 2 3# Get the mtd device number (mtdX) 4function findmtd() { 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) 12function findubi() { 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 20function is_mounted() { 21 grep -q "$1" /proc/mounts 22 return $? 23} 24 25# Attach the pnor mtd device to ubi. 26function attach_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 55function mount_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 # shellcheck disable=SC2012 # ls provides the size in human-readable form 62 filesize="$(ls -sh "$img" | awk -F " " '{print $1}')" 63 64 if is_mounted "${name}"; then 65 echo "${name} is already mounted." 66 return 0 67 fi 68 69 if [ -n "${vol}" ]; then 70 ubirmvol "${ubidev}" -N "${name}" 71 fi 72 73 if [ ! -d "${mountdir}" ]; then 74 mkdir "${mountdir}" 75 fi 76 77 # Set size of read-only partition equal to pnor.xz.squashfs 78 ubimkvol "${ubidev}" -N "${name}" -s "${filesize}"KiB --type=static 79 if ! vol="$(findubi "${name}")"; then 80 echo "Unable to create RO volume!" 81 return 1 82 fi 83 84 ubidevid="${vol#ubi}" 85 if ! ubiupdatevol "/dev/ubi${ubidevid}" "${img}"; then 86 echo "Unable to update RO volume!" 87 return 1 88 fi 89 90 if ! ubiblock --create "/dev/ubi${ubidevid}"; then 91 echo "Unable to create UBI block for RO volume!" 92 return 1 93 fi 94 95 if ! mount -t squashfs -o ro "/dev/ubiblock${ubidevid}" "${mountdir}"; then 96 echo "Unable to mount RO volume!" 97 return 1 98 fi 99} 100 101function mount_ubi() { 102 pnormtd="$(findmtd pnor)" 103 pnor="${pnormtd#mtd}" 104 ubidev="/dev/ubi${pnor}" 105 pnordev="/dev/mtd${pnor}" 106 107 if [[ "${name}" == "pnor-patch" ]]; then 108 if [[ "$(fw_printenv fieldmode 2>/dev/null)" == "fieldmode=true" ]]; then 109 return 0 110 fi 111 if [[ ! "$(hexdump -C -n 3 "${pnordev}")" =~ "UBI" ]]; then 112 return 0 113 fi 114 mountdir="/usr/local/share/pnor" 115 else 116 mountdir="/media/${name}" 117 fi 118 119 if [[ "${name}" == "pnor-prsv" ]]; then 120 size="2MiB" 121 else 122 size="16MiB" 123 fi 124 125 if [ ! -d "${mountdir}" ]; then 126 mkdir -p "${mountdir}" 127 fi 128 129 vol="$(findubi "${name}")" 130 if [ -z "${vol}" ]; then 131 ubimkvol "${ubidev}" -N "${name}" -s "${size}" 132 fi 133 134 if ! is_mounted "${name}"; then 135 mountdev="ubi${pnor}:${name}" 136 mount -t ubifs "${mountdev}" "${mountdir}" 137 fi 138} 139 140function umount_ubi() { 141 pnormtd="$(findmtd pnor)" 142 pnor="${pnormtd#mtd}" 143 ubidev="/dev/ubi${pnor}" 144 mountdir="/media/${name}" 145 146 if is_mounted "${name}"; then 147 umount "${mountdir}" 148 fi 149 150 vol="$(findubi "${name}")" 151 id="${vol##*_}" 152 if [ -n "${id}" ]; then 153 ubirmvol "${ubidev}" -n "${id}" 154 fi 155 156 if [ -d "${mountdir}" ]; then 157 rm -r "${mountdir}" 158 fi 159} 160 161function remount_ubi() { 162 pnormtd="$(findmtd pnor)" 163 pnor="${pnormtd#mtd}" 164 pnordev="/dev/mtd${pnor}" 165 166 # Re-Attach the pnor mtd device to ubi 167 if [[ $(hexdump -C -n 3 "${pnordev}") =~ "UBI" ]]; then 168 ubiattach /dev/ubi_ctrl -m "${pnor}" -d "${pnor}" 169 else 170 # Device not formatted as ubi. 171 return 0 172 fi 173 174 # Get information on all ubi volumes 175 ubinfo=$(ubinfo -d "${pnor}") 176 presentVolumes=${ubinfo##*:} 177 IFS=', ' read -r -a array <<< "$presentVolumes" 178 for element in "${array[@]}"; 179 do 180 elementProperties=$(ubinfo -d "$pnor" -n "$element") 181 # Get ubi volume name by getting rid of additional properties 182 name=${elementProperties#*Name:} 183 name="${name%Character*}" 184 name="$(echo -e "${name}" | tr -d '[:space:]')" 185 186 if [[ ${name} == pnor-prsv ]] || [[ ${name} == pnor-rw* ]] || [[ ${name} == pnor-ro* ]]; then 187 mountdir="/media/${name}" 188 if [ ! -d "${mountdir}" ]; then 189 mkdir -p "${mountdir}" 190 fi 191 192 if [[ ${name} == pnor-ro* ]] 193 then 194 ubiblock --create "/dev/ubi${pnor}_${element}" 195 mount -t squashfs -o ro "/dev/ubiblock${pnor}_${element}" "${mountdir}" 196 else 197 mount -t ubifs "ubi${pnor}:${name}" "${mountdir}" 198 fi 199 fi 200 done 201} 202 203function ubi_cleanup() { 204 # When ubi_cleanup is run, it expects one or no active version. 205 activeVersion=$(busctl --list --no-pager tree \ 206 org.open_power.Software.Host.Updater | \ 207 grep /xyz/openbmc_project/software/ | tail -c 9) 208 209 if [[ -z "$activeVersion" ]]; then 210 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | cut -c 14-) 211 mapfile -t array <<< "${vols}" 212 else 213 vols=$(ubinfo -a | grep -e "pnor-ro-" -e "pnor-rw-" | \ 214 grep -v "$activeVersion" | cut -c 14-) 215 mapfile -t array <<< "${vols}" 216 fi 217 218 for (( index=0; index<${#array[@]}; index++ )); do 219 name=${array[index]} 220 umount_ubi 221 done 222} 223 224case "$1" in 225 ubiattach) 226 attach_ubi 227 ;; 228 squashfsmount) 229 name="$2" 230 version="$3" 231 mount_squashfs 232 ;; 233 ubimount) 234 name="$2" 235 mount_ubi 236 ;; 237 ubiumount) 238 name="$2" 239 umount_ubi 240 ;; 241 ubiremount) 242 remount_ubi 243 ;; 244 ubicleanup) 245 ubi_cleanup 246 ;; 247 *) 248 echo "Invalid argument" 249 exit 1 250 ;; 251esac 252rc=$? 253if [ ${rc} -ne 0 ]; then 254 echo "$0: error ${rc}" 255 exit ${rc} 256fi 257