1#!/bin/bash
2set -eo pipefail
3
4# Get the root mtd device number (mtdX) from "/dev/ubiblockX_Y on /"
5findrootmtd() {
6  rootmatch=" on / "
7  m="$(mount | grep "${rootmatch}" | grep "ubiblock")"
8  m="${m##*ubiblock}"
9  m="${m%_*}"
10  if [ -z "${m}" ]; then
11    # default to bmc mtd (0)
12    m=0
13  fi
14  echo "mtd${m}"
15}
16
17findrootubi() {
18  rootmatch=" on / "
19  m="$(mount | grep "${rootmatch}")"
20  m="${m##*ubiblock}"
21  m="${m% on*}"
22  echo "ubi${m}"
23}
24
25# Get the mtd device number (mtdX)
26findmtd() {
27  m="$(grep -xl "$1" /sys/class/mtd/*/name)"
28  m="${m%/name}"
29  m="${m##*/}"
30  echo "${m}"
31}
32
33# Get the mtd device number only (return X of mtdX)
34findmtdnum() {
35  m="$(findmtd "$1")"
36  m="${m##mtd}"
37  echo "${m}"
38}
39
40# Get the ubi device number (ubiX_Y)
41findubi() {
42  u="$(grep -xl "$1" /sys/class/ubi/ubi?/subsystem/ubi*/name)"
43  u="${u%/name}"
44  u="${u##*/}"
45  echo "${u}"
46}
47
48# Get the ubi device number (ubiX_Y) on a specific mtd
49findubi_onmtd() {
50  u="$(grep -xl "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
51  u="${u%/name}"
52  u="${u##*/}"
53  echo "${u}"
54}
55
56# Get all ubi device names on a specific mtd that match requested string
57findubiname_onmtd() {
58  u="$(grep -h "$1" /sys/class/ubi/ubi"$2"/subsystem/ubi"$2"*/name)"
59  u="${u%/name}"
60  u="${u##*/}"
61  echo "${u}"
62}
63
64# Get the name from the requested ubiX_Y volume
65findname() {
66  n="$(cat /sys/class/ubi/$1/name)"
67  echo "${n}"
68}
69
70# Set the version path property to the flash location where the image was
71# successfully flashed
72set_flashid() {
73  busctl set-property xyz.openbmc_project.Software.BMC.Updater \
74    "/xyz/openbmc_project/software/${version}" \
75    xyz.openbmc_project.Common.FilePath \
76    Path s "$1"
77}
78
79# Set the u-boot envs that perform a side switch on failure to boot
80set_wdt2bite() {
81  if ! fw_printenv wdt2bite 2>/dev/null; then
82    fw_setenv wdt2bite "mw.l 0x1e785024 0xa 1; mw.b 0x1e78502c 0xb3 1"
83    fw_setenv bootalt "run wdt2bite"
84    fw_setenv obmc_bootcmd "ubi part obmc-ubi; run do_rwreset; ubi read \
85\${loadaddr} \${kernelname}; bootm \${loadaddr} || run bootalt"
86  fi
87}
88
89# Make space on flash before creating new volumes. This can be enhanced
90# determine current flash usage. For now only keep a "keepmax" number of them
91ubi_remove_volumes()
92{
93  rootubi="$(findrootubi)"
94  rootname="$(findname "${rootubi}")"
95  rootversion="${rootname##*-}"
96  rootkernel="kernel-${rootversion}"
97
98  # Just keep max number of volumes before updating, don't delete the version
99  # the BMC is booted from, and when a version is identified to be deleted,
100  # delete both the rofs and kernel volumes for that version.
101  rmnames="$(findubiname_onmtd "${name%-*}-" "${ro}")"
102  rmnames=(${rmnames})
103  ubicount="${#rmnames[@]}"
104  while [ ${ubicount} -ge ${keepmax} ]; do
105    # Loop through existing volumes and skip currently active ones
106    for (( index=0; index<${#rmnames[@]}; index++ )); do
107      rmname="${rmnames[${index}]}"
108      rmversion="${rmname##*-}"
109      [ "${rmversion}" == "${version}" ] && continue
110      rmubi="$(findubi_onmtd "rofs-${rmversion}" "${ro}")"
111      if [[ ( "${rmubi}" != "${rootubi}" ) &&
112            ( "${rmname}" != "${rootkernel}" ) ]]; then
113        ubi_remove "rofs-${rmversion}" "${ro}"
114        ubi_remove "kernel-${rmversion}" "${ro}"
115        # Remove priority value
116        fw_setenv "${rmversion}"
117        break
118      fi
119    done
120    # Decrease count regardless to avoid an infinite loop
121    (( ubicount-- ))
122  done
123}
124
125ubi_rw() {
126  rwmtd="$(findmtd "${reqmtd}")"
127  rw="${rwmtd#mtd}"
128  ubidev="/dev/ubi${rw}"
129
130  # Update rwfs_size, check imgsize was specified, otherwise it'd clear the var
131  if [ ! -z "$imgsize" ]; then
132    rwsize="$(fw_printenv -n rwfs_size 2>/dev/null)" || true
133    if [[ "${imgsize}" != "${rwsize}" ]]; then
134      fw_setenv rwfs_size "${imgsize}"
135    fi
136  fi
137
138  vol="$(findubi "${name}")"
139  if [ -z "${vol}" ]; then
140    ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}"
141  fi
142}
143
144ubi_ro() {
145  keepmax=2 # Default 2 volumes per mtd
146  romtd="$(findmtd "${reqmtd}")"
147  romtd2="$(findmtd "${reqmtd2}")"
148
149  if [ ! "${romtd}" == "${romtd2}" ]; then
150    # Request to use alternate mtd device, choose the non-root one
151    keepmax=1 # 1 volume on each of the requested mtds
152    rootmtd="$(findrootmtd)"
153    if [ "${rootmtd}" == "${romtd}" ]; then
154      romtd="${romtd2}"
155    fi
156  fi
157  ro="${romtd#mtd}"
158  ubidev="/dev/ubi${ro}"
159
160  ubi_remove_volumes
161
162  if [ -z "${imgfile}" ]; then
163    echo "Unable to create read-only volume. Image file not specified."
164    return 1
165  fi
166
167  # Create a ubi volume, dynamically sized to fit BMC image if size unspecified
168  img="/tmp/images/${version}/${imgfile}"
169  imgsize="$(stat -c '%s' ${img})"
170
171  vol="$(findubi "${name}")"
172  if [ ! -z "${vol}" ]; then
173    # Allow a duplicate kernel volume on the alt mtd
174    if [[ "${name}" =~ "kernel" ]]; then
175      vol="$(findubi_onmtd "${name}" "${ro}")"
176    fi
177  fi
178  if [ -z "${vol}" ]; then
179    ubimkvol "${ubidev}" -N "${name}" -s "${imgsize}" --type=static
180    vol="$(findubi "${name}")"
181  fi
182
183  set_flashid "${version}"
184}
185
186# Squashfs images need a ubi block
187ubi_block() {
188  vol="$(findubi "${name}")"
189  ubidevid="${vol#ubi}"
190  block="/dev/ubiblock${ubidevid}"
191  if [ ! -e "$block" ]; then
192    ubiblock --create "/dev/ubi${ubidevid}"
193  fi
194}
195
196ubi_updatevol() {
197  vol="$(findubi "${name}")"
198  ubidevid="${vol#ubi}"
199  img="/tmp/images/${version}/${imgfile}"
200  ubiupdatevol "/dev/ubi${ubidevid}" "${img}"
201}
202
203ubi_remove() {
204    rmname="$1"
205    rmmtd="$2"
206    if [ ! -z "${rmmtd}" ]; then
207      vol="$(findubi_onmtd "${rmname}" "${rmmtd}")"
208    else
209      vol="$(findubi "${rmname}")"
210    fi
211
212    if [ ! -z "$vol" ]; then
213        vol="${vol%_*}"
214
215        if grep -q "$rmname" /proc/mounts; then
216            mountdir=$(grep "$rmname" /proc/mounts | cut -d " " -f 2)
217            umount "$mountdir"
218            rm -r "$mountdir"
219        fi
220
221        ubirmvol "/dev/${vol}" -N "$rmname"
222    fi
223}
224
225ubi_cleanup() {
226    # When ubi_cleanup is run, it expects one or no active version.
227    activeVersion=$(busctl --list --no-pager tree \
228            xyz.openbmc_project.Software.BMC.Updater | \
229            grep /xyz/openbmc_project/software/ | tail -c 9)
230
231    if [[ -z "$activeVersion" ]]; then
232        vols=$(ubinfo -a | grep "rofs-" | cut -c 14-)
233        vols=(${vols})
234    else
235        vols=$(ubinfo -a | grep "rofs-" | \
236                grep -v "$activeVersion" | cut -c 14-)
237        vols=(${vols})
238    fi
239
240    for (( index=0; index<${#vols[@]}; index++ )); do
241         ubi_remove ${vols[index]}
242    done
243}
244
245mount_alt_rwfs() {
246  altNum="$(findmtdnum "alt-bmc")"
247  if [ ! -z "${altNum}" ]; then
248    altRwfs=$(ubinfo -a -d ${altNum} | grep -w "rwfs") || true
249    if [ ! -z "${altRwfs}" ]; then
250      altVarMount="/media/alt/var"
251      mkdir -p "${altVarMount}"
252      if mount ubi"${altNum}":rwfs "${altVarMount}" -t ubifs -o defaults; then
253        mkdir -p "${altVarMount}"/persist/etc
254      fi
255    fi
256  fi
257}
258
259remount_ubi() {
260  bmcmtd="$(findmtd "bmc")"
261  altbmcmtd="$(findmtd "alt-bmc")"
262  mtds="${bmcmtd: -1}","${altbmcmtd: -1}"
263
264  IFS=',' read -r -a mtds <<< "$mtds"
265  mtds=($(echo "${mtds[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
266  for mtd in ${mtds[@]}; do
267    # Get information on all ubi volumes
268    ubinfo=$(ubinfo -d ${mtd})
269    presentVolumes=${ubinfo##*:}
270    IFS=', ' read -r -a array <<< "$presentVolumes"
271    for element in ${array[@]}; do
272      elementProperties=$(ubinfo -d $mtd -n $element)
273      # Get ubi volume name by getting rid of additional properties
274      name=${elementProperties#*Name:}
275      name="${name%Character*}"
276      name="$(echo -e "${name}" | tr -d '[:space:]')"
277
278      if [[ ${name} == rofs-* ]]; then
279        mountdir="/media/${name}"
280
281        if [ ! -d ${mountdir} ]; then
282          mkdir -p "${mountdir}"
283          # U-Boot will create the ubiblock for the running version, but not
284          # for the version on the other chip
285          if [ ! -e "/dev/ubiblock${mtd}_${element}" ]; then
286            ubiblock --create /dev/ubi${mtd}_${element}
287          fi
288          mount -t squashfs -o ro "/dev/ubiblock${mtd}_${element}" "${mountdir}"
289        fi
290      fi
291    done
292  done
293
294  set_wdt2bite
295}
296
297# Read the current env variable and set it on the alternate boot env
298copy_env_var_to_alt() {
299  varName=$1
300  value="$(fw_printenv -n "${varName}")"
301  fw_setenv -c /etc/alt_fw_env.config "${varName}" "${value}"
302}
303
304# When the alternate bmc chip boots, u-boot thinks its the primary mtdX.
305# Therefore need to swap the chip numbers when copying the ubiblock and root to
306# alternate bmc u-boot environment.
307copy_ubiblock_to_alt() {
308  value="$(fw_printenv -n ubiblock)"
309  bmcNum="$(findmtdnum "bmc")"
310  altNum="$(findmtdnum "alt-bmc")"
311  replaceAlt="${value/${altNum},/${bmcNum},}"
312
313  if [[ "${value}" == "${replaceAlt}" ]]; then
314    replaceBmc="${value/${bmcNum},/${altNum},}"
315    value=${replaceBmc}
316  else
317    value=${replaceAlt}
318  fi
319
320  fw_setenv -c /etc/alt_fw_env.config ubiblock "${value}"
321}
322
323copy_root_to_alt() {
324  value="$(fw_printenv -n root)"
325  bmcNum="$(findmtdnum "bmc")"
326  altNum="$(findmtdnum "alt-bmc")"
327  replaceAlt="${value/${altNum}_/${bmcNum}_}"
328
329  if [[ "${value}" == "${replaceAlt}" ]]; then
330    replaceBmc="${value/${bmcNum}_/${altNum}_}"
331    value=${replaceBmc}
332  else
333    value=${replaceAlt}
334  fi
335
336  fw_setenv -c /etc/alt_fw_env.config root "${value}"
337}
338
339ubi_setenv() {
340    # The U-Boot environment maintains two banks of environment variables.
341    # The banks need to be consistent with each other to ensure that these
342    # variables can reliably be read from file. In order to guarantee that the
343    # banks are both correct, we need to run fw_setenv twice.
344    variable=$1
345    if [[ "$variable" == *"="* ]]; then
346        varName="${variable%=*}"
347        value="${variable##*=}"
348        # Write only if var is not set already to the requested value
349        currentValue="$(fw_printenv -n "${varName}" 2>/dev/null)" || true
350        if [[ "${currenValue}" != "${value}" ]]; then
351          fw_setenv "$varName" "$value"
352          fw_setenv "$varName" "$value"
353        fi
354    else
355        fw_setenv "$variable"
356        fw_setenv "$variable"
357    fi
358}
359
360mtd_write() {
361  flashmtd="$(findmtd "${reqmtd}")"
362  img="/tmp/images/${version}/${imgfile}"
363  flashcp -v ${img} /dev/${flashmtd}
364}
365
366backup_env_vars() {
367  copy_env_var_to_alt kernelname
368  copy_ubiblock_to_alt
369  copy_root_to_alt
370}
371
372update_env_vars() {
373  vol="$(findubi rofs-"${version}")"
374  if [ -z "${vol}" ]; then
375    return 1
376  fi
377  ubidevid="${vol#ubi}"
378  block="/dev/ubiblock${ubidevid}"
379  if [ ! -e "${block}" ]; then
380    return 1
381  fi
382  ubi_setenv "kernelname=kernel-${version}"
383  ubi_setenv "ubiblock=$(echo "${ubidevid}" | sed 's/_/,/')"
384  ubi_setenv "root=${block}"
385}
386
387#TODO: Replace the implementation with systemd-inhibitors lock
388#      once systemd/systemd#949 is resolved
389rebootguardenable() {
390  dir="/run/systemd/system/"
391  file="reboot-guard.conf"
392  units=("reboot" "poweroff" "halt")
393
394  for unit in "${units[@]}"; do
395    mkdir -p ${dir}${unit}.target.d
396    echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
397  done
398}
399
400#TODO: Replace the implementation with systemd-inhibitors lock
401#      once systemd/systemd#949 is resolved
402rebootguarddisable() {
403  dir="/run/systemd/system/"
404  file="reboot-guard.conf"
405  units=("reboot" "poweroff" "halt")
406
407  for unit in "${units[@]}"; do
408    rm -rf ${dir}${unit}.target.d/${file}
409  done
410}
411
412# Create a copy in the alt mtd
413create_vol_in_alt() {
414  alt="alt-bmc"
415  altmtd="$(findmtd "${alt}")"
416  if [ ! -z "${altmtd}" ]; then
417    reqmtd="${alt}"
418    reqmtd2="${alt}"
419    ubi_ro
420    ubi_updatevol
421  fi
422}
423
424# Copy contents of one MTD device to another
425mtd_copy() {
426  in=$1
427  out=$2
428
429  # Must erase MTD first to prevent corruption
430  flash_eraseall "${out}"
431  dd if="${in}" of="${out}"
432}
433
434mirroruboot() {
435  bmc="$(findmtd "u-boot")"
436  bmcdev="/dev/${bmc}"
437  alt="$(findmtd "alt-u-boot")"
438  altdev="/dev/${alt}"
439
440  checksum_bmc="$(md5sum "${bmcdev}")"
441  checksum_bmc="${checksum_bmc% *}"
442  checksum_alt="$(md5sum "${altdev}")"
443  checksum_alt="${checksum_alt% *}"
444
445  if [[ "${checksum_bmc}" != "${checksum_alt}" ]]; then
446    bmcenv="$(findmtd "u-boot-env")"
447    bmcenvdev="/dev/${bmcenv}"
448    altenv="$(findmtd "alt-u-boot-env")"
449    altenvdev="/dev/${altenv}"
450
451    echo "Mirroring U-boot to alt chip"
452    mtd_copy "${bmcdev}" "${altdev}"
453    mtd_copy "${bmcenvdev}" "${altenvdev}"
454
455    copy_ubiblock_to_alt
456    copy_root_to_alt
457  fi
458}
459
460# Compare the device where u-boot resides with an image file. Specify the full
461# path to the device and image file to use for the compare. Print a value of
462# "0" if identical, "1" otherwise.
463cmp_uboot() {
464  device="$1"
465  image="$2"
466
467  # Since the image file can be smaller than the device, copy the device to a
468  # tmp file and write the image file on top, then compare the sum of each.
469  # Use cat / redirection since busybox does not have the conv=notrunc option.
470  tmpFile="$(mktemp /tmp/ubootdev.XXXXXX)"
471  dd if="${device}" of="${tmpFile}"
472  devSum="$(sha256sum ${tmpFile})"
473  cat < "${image}" 1<> "${tmpFile}"
474  imgSum="$(sha256sum ${tmpFile})"
475  rm -f "${tmpFile}"
476
477  if [ "${imgSum}" == "${devSum}" ]; then
478    echo "0";
479  else
480    echo "1";
481  fi
482}
483
484# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
485# Return the label (a or b) for the running partition.
486mmc_get_primary_label() {
487  # Get root device /dev/mmcblkpX
488  rootmatch=" on / "
489  root="$(mount | grep "${rootmatch}")"
490  root="${root%${rootmatch}*}"
491
492  # Find the device label
493  if [[ $(readlink -f /dev/disk/by-partlabel/rofs-a) == "${root}" ]]; then
494    echo "a"
495  elif [[ $(readlink -f /dev/disk/by-partlabel/rofs-b) == "${root}" ]]; then
496    echo "b"
497  else
498    echo ""
499  fi
500}
501
502# The eMMC partition labels for the kernel and rootfs are boot-a/b and rofs-a/b.
503# Return the label (a or b) for the non-running partition.
504mmc_get_secondary_label() {
505  root="$(mmc_get_primary_label)"
506  if [[ "${root}" == "a" ]]; then
507    echo "b"
508  elif [[ "${root}" == "b" ]]; then
509    echo "a"
510  else
511    echo ""
512  fi
513}
514
515mmc_update() {
516  # Update u-boot if needed
517  bootPartition="mmcblk0boot0"
518  devUBoot="/dev/${bootPartition}"
519  imgUBoot="${imgpath}/${version}/image-u-boot"
520  if [ "$(cmp_uboot "${devUBoot}" "${imgUBoot}")" != "0" ]; then
521    echo 0 > "/sys/block/${bootPartition}/force_ro"
522    dd if="${imgUBoot}" of="${devUBoot}"
523    echo 1 > "/sys/block/${bootPartition}/force_ro"
524  fi
525
526  # Update the secondary (non-running) boot and rofs partitions.
527  label="$(mmc_get_secondary_label)"
528
529  # Update the boot and rootfs partitions, restore their labels after the update
530  # by getting the partition number mmcblk0pX from their label.
531  zstd -d -c ${imgpath}/${version}/image-kernel | dd of="/dev/disk/by-partlabel/boot-${label}"
532  number="$(readlink -f /dev/disk/by-partlabel/boot-${label})"
533  number="${number##*mmcblk0p}"
534  sgdisk --change-name=${number}:boot-${label} /dev/mmcblk0 1>/dev/null
535
536  zstd -d -c ${imgpath}/${version}/image-rofs | dd of="/dev/disk/by-partlabel/rofs-${label}"
537  number="$(readlink -f /dev/disk/by-partlabel/rofs-${label})"
538  number="${number##*mmcblk0p}"
539  sgdisk --change-name=${number}:rofs-${label} /dev/mmcblk0 1>/dev/null
540
541  # Run this after sgdisk for labels to take effect.
542  partprobe
543
544  # Update hostfw
545  if [ -f ${imgpath}/${version}/image-hostfw ]; then
546    # Remove patches
547    patchdir="/usr/local/share/hostfw/alternate"
548    if [ -d "${patchdir}" ]; then
549      rm -rf "${patchdir}"/*
550    fi
551    hostfwdir=$(grep "hostfw " /proc/mounts | cut -d " " -f 2)
552    cp ${imgpath}/${version}/image-hostfw ${hostfwdir}/hostfw-${label}
553    mkdir -p ${hostfwdir}/alternate
554    mount ${hostfwdir}/hostfw-${label} ${hostfwdir}/alternate -o ro
555  fi
556
557  # Store the label where the other properties like purpose and priority are
558  # preserved via the storePriority() function in the serialize files, so that
559  # it can be used for the remove function.
560  label_dir="/var/lib/phosphor-bmc-code-mgmt/${version}"
561  label_file="${label_dir}/partlabel"
562  mkdir -p "${label_dir}"
563  echo "${label}" > "${label_file}"
564
565  set_flashid "${label}"
566}
567
568mmc_remove() {
569  # Render the filesystem unbootable by wiping out the first 1MB, this
570  # invalidates the filesystem header.
571  # If the label property does not exist, assume it's the secondary
572  # (non-running) one since the running device should not be erased.
573  label=""
574  label_file="/var/lib/phosphor-bmc-code-mgmt/${version}/partlabel"
575  if [ -f "${label_file}" ]; then
576    label="$(cat "${label_file}")"
577  else
578    label="$(mmc_get_secondary_label)"
579  fi
580  dd if=/dev/zero of=/dev/disk/by-partlabel/boot-${label} count=2048
581  dd if=/dev/zero of=/dev/disk/by-partlabel/rofs-${label} count=2048
582
583  hostfw_alt="hostfw/alternate"
584  if grep -q "${hostfw_alt}" /proc/mounts; then
585    hostfw_alt=$(grep "${hostfw_alt}" /proc/mounts | cut -d " " -f 2)
586    umount "${hostfw_alt}"
587  fi
588  hostfw_base="hostfw "
589  if grep -q "${hostfw_base}" /proc/mounts; then
590    hostfw_base=$(grep "${hostfw_base}" /proc/mounts | cut -d " " -f 2)
591    rm -f ${hostfw_base}/hostfw-${label}
592  fi
593}
594
595# Set the requested version as primary for the BMC to boot from upon reboot.
596mmc_setprimary() {
597  # Point root to the label of the requested BMC rootfs. If the label property
598  # does not exist, determine if the requested version is functional or not.
599  label=""
600  label_file="/var/lib/phosphor-bmc-code-mgmt/${version}/partlabel"
601  if [ -f "${label_file}" ]; then
602    label="$(cat "${label_file}")"
603  else
604    functional="$(busctl call xyz.openbmc_project.ObjectMapper \
605                  /xyz/openbmc_project/software/functional \
606                  org.freedesktop.DBus.Properties Get ss \
607                  xyz.openbmc_project.Association endpoints)"
608    if [[ "${functional}" =~ "${version}" ]]; then
609      label="$(mmc_get_primary_label)"
610    else
611      label="$(mmc_get_secondary_label)"
612    fi
613  fi
614  fw_setenv bootside "${label}"
615}
616
617case "$1" in
618  mtduboot)
619    reqmtd="$2"
620    version="$3"
621    imgfile="image-u-boot"
622    mtd_write
623    ;;
624  ubirw)
625    reqmtd="$2"
626    name="$3"
627    imgsize="$4"
628    ubi_rw
629    ;;
630  ubiro)
631    reqmtd="$(echo "$2" | cut -d "+" -f 1)"
632    reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
633    name="$3"
634    version="$4"
635    imgfile="image-rofs"
636    ubi_ro
637    ubi_updatevol
638    ubi_block
639    ;;
640  ubikernel)
641    reqmtd="$(echo "$2" | cut -d "+" -f 1)"
642    reqmtd2="$(echo "$2" | cut -d "+" -f 2)"
643    name="$3"
644    version="$4"
645    imgfile="image-kernel"
646    ubi_ro
647    ubi_updatevol
648    create_vol_in_alt
649    ;;
650  ubiremove)
651    name="$2"
652    ubi_remove "${name}"
653    ;;
654  ubicleanup)
655    ubi_cleanup
656    ;;
657  ubisetenv)
658    ubi_setenv "$2"
659    ;;
660  ubiremount)
661    remount_ubi
662    mount_alt_rwfs
663    ;;
664  createenvbackup)
665    backup_env_vars
666    ;;
667  updateubootvars)
668    version="$2"
669    update_env_vars
670    ;;
671  rebootguardenable)
672    rebootguardenable
673    ;;
674  rebootguarddisable)
675    rebootguarddisable
676    ;;
677  mirroruboot)
678    mirroruboot
679    ;;
680  mmc)
681    version="$2"
682    imgpath="$3"
683    mmc_update
684    ;;
685  mmc-remove)
686    version="$2"
687    mmc_remove
688    ;;
689  mmc-setprimary)
690    version="$2"
691    mmc_setprimary
692    ;;
693  *)
694    echo "Invalid argument"
695    exit 1
696    ;;
697esac
698