Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | |
| 3 | echo update: "$@" |
| 4 | |
Milton Miller | a5d44e4 | 2016-06-15 18:47:38 -0500 | [diff] [blame] | 5 | echoerr() { |
| 6 | echo 1>&2 "ERROR: $@" |
| 7 | } |
| 8 | |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 9 | cd / |
| 10 | if ! test -r /proc/mounts || ! test -f /proc/mounts |
| 11 | then |
| 12 | mkdir -p /proc |
| 13 | mount -t proc proc proc |
| 14 | fi |
| 15 | if ! test -d /sys/class |
| 16 | then |
| 17 | mkdir -p /sys |
| 18 | mount -t sysfs sys sys |
| 19 | fi |
| 20 | if ! test -c /dev/null |
| 21 | then |
| 22 | mkdir -p /dev |
| 23 | mount -t devtmpfs dev dev |
| 24 | fi |
Milton Miller | c88f927 | 2016-05-23 16:00:19 -0500 | [diff] [blame] | 25 | |
Milton Miller | 7dcd160 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 26 | # mtd number N with mtd name Name can be mounted via mtdN, or mtd:Name |
| 27 | # (with a mtd aware fs) or by /dev/mtdblockN (with a mtd or block fs). |
| 28 | mtdismounted() { |
| 29 | m=${1##mtd} |
| 30 | if grep -s "mtdblock$m " /proc/mounts || grep -s "mtd$m " /proc/mounts |
| 31 | then |
| 32 | return 0 |
| 33 | fi |
| 34 | n=$(cat /sys/class/mtd/mtd$m/name) |
| 35 | if test -n "$n" && grep -s "mtd:$n " /proc/mounts |
| 36 | then |
| 37 | return 0 |
| 38 | fi |
| 39 | return 1 |
| 40 | } |
| 41 | |
| 42 | # Detect child partitions when the whole flash is to be updated. |
| 43 | # Ignore mtdNro and mtdblockN names in the class subsystem directory. |
| 44 | childmtds() { |
| 45 | for m in /sys/class/mtd/$1/mtd* |
| 46 | do |
| 47 | m=${m##*/} |
| 48 | if test "${m%ro}" = "${m#mtdblock}" |
| 49 | then |
| 50 | echo $m |
| 51 | fi |
| 52 | done |
| 53 | } |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 54 | |
Milton Miller | 7a7ee9c | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 55 | toobig() { |
| 56 | if test $(stat -L -c "%s" "$1") -gt $(cat /sys/class/mtd/"$2"/size) |
| 57 | then |
| 58 | return 0 |
| 59 | fi |
| 60 | return 1 |
| 61 | } |
| 62 | |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 63 | findmtd() { |
| 64 | m=$(grep -xl "$1" /sys/class/mtd/*/name) |
| 65 | m=${m%/name} |
| 66 | m=${m##*/} |
| 67 | echo $m |
| 68 | } |
| 69 | |
Andrew Jeffery | acc2c85 | 2016-02-23 23:47:23 +1030 | [diff] [blame] | 70 | blkid_fs_type() { |
| 71 | # Emulate util-linux's `blkid -s TYPE -o value $1` |
| 72 | # Example busybox blkid output: |
| 73 | # # blkid /dev/mtdblock5 |
| 74 | # /dev/mtdblock5: TYPE="squashfs" |
| 75 | # Process output to extract TYPE value "squashfs". |
| 76 | blkid $1 | sed -e 's/^.*TYPE="//' -e 's/".*$//' |
| 77 | } |
| 78 | |
| 79 | probe_fs_type() { |
| 80 | fst=$(blkid_fs_type $1) |
| 81 | echo ${fst:=jffs2} |
| 82 | } |
| 83 | |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 84 | rwfs=$(findmtd rwfs) |
| 85 | |
Milton Miller | 54d882e | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 86 | rwdev=/dev/mtdblock${rwfs#mtd} |
Milton Miller | 54d882e | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 87 | rwopts=rw |
| 88 | rorwopts=ro${rwopts#rw} |
| 89 | |
Milton D. Miller II | 8ad2be5 | 2016-02-28 16:07:46 -0600 | [diff] [blame] | 90 | rwdir=/run/initramfs/rw |
Milton Miller | 54d882e | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 91 | upper=$rwdir/cow |
Milton D. Miller II | 07b26cd | 2016-02-29 10:32:58 -0600 | [diff] [blame] | 92 | save=/run/save/${upper##*/} |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 93 | |
Milton D. Miller II | 01fe134 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 94 | mounted= |
Milton Miller | 3d44540 | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 95 | doflash=y |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 96 | doclean= |
Milton D. Miller II | 08afa53 | 2016-02-29 23:11:27 -0600 | [diff] [blame] | 97 | dosave=y |
| 98 | dorestore=y |
Milton D. Miller II | 20b647e | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 99 | toram= |
Milton Miller | 7a7ee9c | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 100 | checksize=y |
Milton Miller | 7dcd160 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 101 | checkmount=y |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 102 | |
Milton D. Miller II | 1790e04 | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 103 | whitelist=/run/initramfs/whitelist |
| 104 | image=/run/initramfs/image- |
Milton Miller | b76fb9b | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 105 | imglist= |
Milton D. Miller II | 1790e04 | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 106 | |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 107 | while test "$1" != "${1#-}" |
| 108 | do |
| 109 | case "$1" in |
Milton Miller | d717486 | 2016-06-15 16:02:23 -0500 | [diff] [blame] | 110 | --help) |
| 111 | cat <<HERE |
| 112 | Usage: $0 [options] -- Write images in /run/initramfs to flash (/dev/mtd*) |
| 113 | --help Show this message |
| 114 | --no-flash Don't attempt to write images to flash |
| 115 | --ignore-size Don't compare image size to mtd device size |
| 116 | --ignore-mount Don't check if destination is mounted |
| 117 | --save-files Copy whitelisted files to save directory in RAM |
| 118 | --no-save-files Don't copy whitelisted files to save directory |
| 119 | --copy-files Copy files from save directory to rwfs mountpoint |
| 120 | --restore-files Restore files from save directory to rwfs layer |
| 121 | --no-restore-files Don't restore saved files from ram to rwfs layer |
| 122 | --clean-saved-files Delete saved whitelisted files from RAM |
| 123 | --no-clean-saved-files Retain saved whitelisted files in RAM |
| 124 | HERE |
| 125 | |
| 126 | exit 0 ;; |
| 127 | |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 128 | --no-clean-saved-files) |
| 129 | doclean= |
| 130 | shift ;; |
| 131 | --clean-saved-files) |
| 132 | doclean=y |
| 133 | shift ;; |
Milton D. Miller II | 08afa53 | 2016-02-29 23:11:27 -0600 | [diff] [blame] | 134 | --no-save-files) |
| 135 | dosave= |
| 136 | shift ;; |
| 137 | --save-files) |
| 138 | dosave=y |
| 139 | shift ;; |
| 140 | --no-restore-files) |
| 141 | dorestore= |
| 142 | shift ;; |
| 143 | --restore-files) |
| 144 | dorestore=y |
| 145 | shift ;; |
Milton Miller | 3d44540 | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 146 | --no-flash) |
| 147 | doflash= |
| 148 | shift ;; |
Milton Miller | 7a7ee9c | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 149 | --ignore-size) |
| 150 | checksize= |
| 151 | shift ;; |
Milton Miller | 7dcd160 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 152 | --ignore-mount) |
| 153 | checkmount= |
| 154 | doflash= |
| 155 | shift ;; |
Milton D. Miller II | 20b647e | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 156 | --copy-files) |
| 157 | toram=y |
| 158 | shift ;; |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 159 | *) |
Milton Miller | d717486 | 2016-06-15 16:02:23 -0500 | [diff] [blame] | 160 | echoerr "Unknown option $1. Try $0 --help." |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 161 | exit 1 ;; |
| 162 | esac |
| 163 | done |
| 164 | |
Milton D. Miller II | 01fe134 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 165 | if test "x$dosave" = xy |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 166 | then |
Milton D. Miller II | 01fe134 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 167 | if test ! -d $upper -a -n "$rwfs" |
| 168 | then |
| 169 | mkdir -p $rwdir |
| 170 | mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rorwopts |
| 171 | mounted=$rwdir |
| 172 | fi |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 173 | |
| 174 | while read f |
| 175 | do |
Milton Miller | 5522ffe | 2016-06-16 16:58:21 -0500 | [diff] [blame^] | 176 | # Entries shall start with /, no trailing /.. or embedded /../ |
| 177 | if test "/${f#/}" != "$f" -o "${f%/..}" != "${f#*/../}" |
| 178 | then |
| 179 | echo 1>&2 "WARNING: Skipping bad whitelist entry $f." |
| 180 | continue |
| 181 | fi |
| 182 | if ! test -e "$upper/$f" |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 183 | then |
| 184 | continue |
| 185 | fi |
Milton Miller | 54d882e | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 186 | d="$save/$f" |
Milton Miller | 5522ffe | 2016-06-16 16:58:21 -0500 | [diff] [blame^] | 187 | while test "${d%/}" != "${d%/.}" |
| 188 | do |
| 189 | d="${d%/.}" |
| 190 | d="${d%/}" |
| 191 | done |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 192 | mkdir -p "${d%/*}" |
Milton Miller | 5522ffe | 2016-06-16 16:58:21 -0500 | [diff] [blame^] | 193 | cp -rp "$upper/$f" "${d%/*}/" |
Milton D. Miller II | 1790e04 | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 194 | done < $whitelist |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 195 | |
Milton D. Miller II | 01fe134 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 196 | if test -n "$mounted" |
| 197 | then |
| 198 | umount $mounted |
| 199 | fi |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 200 | fi |
| 201 | |
Milton Miller | b76fb9b | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 202 | imglist=$(echo $image*) |
| 203 | if test "$imglist" = "$image*" -a ! -e "$imglist" |
| 204 | then |
| 205 | # shell didn't expand the wildcard, so no files exist |
| 206 | echo "No images found to update." |
| 207 | imglist= |
| 208 | fi |
| 209 | |
| 210 | for f in $imglist |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 211 | do |
Milton Miller | d93b48e | 2016-02-05 11:19:58 -0600 | [diff] [blame] | 212 | m=$(findmtd ${f#$image}) |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 213 | if test -z "$m" |
| 214 | then |
Milton Miller | a5d44e4 | 2016-06-15 18:47:38 -0500 | [diff] [blame] | 215 | echoerr "Unable to find mtd partiton for ${f##*/}." |
Milton Miller | c88f927 | 2016-05-23 16:00:19 -0500 | [diff] [blame] | 216 | exit 1 |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 217 | fi |
Milton Miller | 7a7ee9c | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 218 | if test -n "$checksize" && toobig "$f" "$m" |
| 219 | then |
| 220 | echoerr "Image ${f##*/} too big for $m." |
| 221 | exit 1 |
| 222 | fi |
Milton Miller | 7dcd160 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 223 | for s in $m $(childmtds $m) |
| 224 | do |
| 225 | if test -n "$checkmount" && mtdismounted $s |
| 226 | then |
| 227 | echoerr "Device $s is mounted, ${f##*/} is busy." |
| 228 | exit 1 |
| 229 | fi |
| 230 | done |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 231 | done |
| 232 | |
Milton Miller | 3d44540 | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 233 | if test -n "$doflash" |
| 234 | then |
Milton Miller | b76fb9b | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 235 | for f in $imglist |
Milton Miller | 3d44540 | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 236 | do |
| 237 | if test ! -s $f |
| 238 | then |
| 239 | echo "Skipping empty update of ${f#$image}." |
| 240 | rm $f |
| 241 | continue |
| 242 | fi |
| 243 | m=$(findmtd ${f#$image}) |
| 244 | echo "Updating ${f#$image}..." |
| 245 | flashcp -v $f /dev/$m && rm $f |
| 246 | done |
| 247 | fi |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 248 | |
Milton Miller | 0210448 | 2016-05-23 18:35:21 -0500 | [diff] [blame] | 249 | if test -d $save -a "x$toram" = xy |
Milton D. Miller II | 20b647e | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 250 | then |
| 251 | mkdir -p $upper |
| 252 | cp -rp $save/. $upper/ |
| 253 | fi |
| 254 | |
Milton D. Miller II | 08afa53 | 2016-02-29 23:11:27 -0600 | [diff] [blame] | 255 | if test -d $save -a "x$dorestore" = xy |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 256 | then |
Milton D. Miller II | d6e2584 | 2016-02-28 16:20:19 -0600 | [diff] [blame] | 257 | odir=$rwdir |
| 258 | rwdir=/run/rw |
| 259 | upper=$rwdir${upper#$odir} |
| 260 | |
| 261 | mkdir -p $rwdir |
Andrew Jeffery | acc2c85 | 2016-02-23 23:47:23 +1030 | [diff] [blame] | 262 | mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rwopts |
Milton D. Miller II | 10aee81 | 2016-02-28 18:17:02 -0600 | [diff] [blame] | 263 | mkdir -p $upper |
Milton Miller | 54d882e | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 264 | cp -rp $save/. $upper/ |
| 265 | umount $rwdir |
Milton D. Miller II | d6e2584 | 2016-02-28 16:20:19 -0600 | [diff] [blame] | 266 | rmdir $rwdir |
Milton D. Miller II | d89d5e0 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 267 | fi |
| 268 | |
Milton D. Miller II | 30ef963 | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 269 | if test "x$doclean" = xy |
| 270 | then |
| 271 | rm -rf $save |
| 272 | fi |
| 273 | |
Milton Miller | 39b6faa | 2016-02-05 13:56:18 -0600 | [diff] [blame] | 274 | exit |