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
231case "$1" in
232  ubiattach)
233    attach_ubi
234    ;;
235  squashfsmount)
236    name="$2"
237    version="$3"
238    mount_squashfs
239    ;;
240  ubimount)
241    name="$2"
242    mount_ubi
243    ;;
244  ubiumount)
245    name="$2"
246    umount_ubi
247    ;;
248  ubiremount)
249    remount_ubi
250    ;;
251  ubicleanup)
252    ubi_cleanup
253    ;;
254  *)
255    echo "Invalid argument"
256    exit 1
257    ;;
258esac
259rc=$?
260if [ ${rc} -ne 0 ]; then
261  echo "$0: error ${rc}"
262  exit ${rc}
263fi
264