OLD | NEW |
1 #!/bin/bash | 1 #!/bin/bash |
2 | 2 |
3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # This is the autoupdater for Memento. When called it consults Omaha to see | 7 # This is the autoupdater for Memento. When called it consults Omaha to see |
8 # if there's an update available. If so, it downloads it to the other | 8 # if there's an update available. If so, it downloads it to the other |
9 # partition on the Memento USB stick, then alters the MBR and partitions | 9 # partition on the Memento USB stick, then alters the MBR and partitions |
10 # as needed so the next reboot will boot into the newly installed partition. | 10 # as needed so the next reboot will boot into the newly installed partition. |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 if [[ -z "$IMG_URL" || -z "$CHECKSUM" ]] | 98 if [[ -z "$IMG_URL" || -z "$CHECKSUM" ]] |
99 then | 99 then |
100 log no update | 100 log no update |
101 exit 0 | 101 exit 0 |
102 fi | 102 fi |
103 # TODO(adlr): make sure we have enough space for the download. we are | 103 # TODO(adlr): make sure we have enough space for the download. we are |
104 # already correct if we don't have space, but it would be nice to fail | 104 # already correct if we don't have space, but it would be nice to fail |
105 # fast. | 105 # fast. |
106 log Update Found: $IMG_URL checksum: $CHECKSUM | 106 log Update Found: $IMG_URL checksum: $CHECKSUM |
107 | 107 |
108 # figure out which device i'm on, and which to download to. | 108 # Figure out which partition I'm on, and which to download to. |
109 ROOT_ARG=$(cat /proc/cmdline | tr ' ' '\n' | grep ^root= | cut -d = -f 2-) | 109 LOCAL_DEV=$(rootdev) |
110 LOCAL_DEV="$ROOT_ARG" | |
111 # do some device sanity checks | |
112 if expr match "$ROOT_ARG" '^UUID=' > /dev/null | |
113 then | |
114 LOCAL_DEV=$(readlink -f /dev/disk/by-uuid/${ROOT_ARG#UUID=}) | |
115 elif expr match "$ROOT_ARG" '^LABEL=' > /dev/null | |
116 then | |
117 LOCAL_DEV=$(readlink -f /dev/disk/by-label/${ROOT_ARG#LABEL=}) | |
118 fi | |
119 | 110 |
120 # we install onto the other dev. so if we end in 1, other ends in 2, and | 111 # We install onto the other partition so if we end in 3, other ends in 5, and |
121 # vice versa | 112 # vice versa |
122 INSTALL_DEV=$(echo $LOCAL_DEV | tr '1234' '2143') | 113 INSTALL_DEV=$(echo $LOCAL_DEV | tr '35' '53') |
| 114 NEW_PART_NUM=${INSTALL_DEV##*/*[a-z]} |
| 115 # The kernel needs to be installed to its own partition. We'll handle that in |
| 116 # the postinst script (from the new rootfs). partitions 2&3 are image A, |
| 117 # partitions 4&5 are image B. |
| 118 KINSTALL_DEV=$(echo $INSTALL_DEV | tr '35' '24') |
123 | 119 |
124 ROOT_DEV=$(echo $LOCAL_DEV | tr -d '1234') # strip trailing number | 120 # Find whole disk device. |
| 121 ROOT_DEV=${LOCAL_DEV%%[0-9]*} |
125 | 122 |
126 # do some device sanity checks | 123 # Do some device sanity checks. |
127 if ! expr match "$LOCAL_DEV" '^/dev/[a-z][a-z]*[1234]$' > /dev/null | 124 if ! expr match "$LOCAL_DEV" '^/dev/[a-z][a-z]*[12345]$' > /dev/null |
128 then | 125 then |
129 log "didnt find good local device. local: $LOCAL_DEV install: $INSTALL_DEV" | 126 log "didnt find good local device. local: $LOCAL_DEV install: $INSTALL_DEV" |
130 exit 1 | 127 exit 1 |
131 fi | 128 fi |
132 if ! expr match "$INSTALL_DEV" '^/dev/[a-z][a-z]*[1234]$' > /dev/null | 129 if ! expr match "$INSTALL_DEV" '^/dev/[a-z][a-z]*[12345]$' > /dev/null |
133 then | 130 then |
134 log "didnt find good install device. local: $LOCAL_DEV install: $INSTALL_DEV" | 131 log "didnt find good install device. local: $LOCAL_DEV install: $INSTALL_DEV" |
135 exit 1 | 132 exit 1 |
136 fi | 133 fi |
137 if [ "$LOCAL_DEV" == "$INSTALL_DEV" ] | 134 if [ "$LOCAL_DEV" == "$INSTALL_DEV" ] |
138 then | 135 then |
139 log local and installation device are the same: "$LOCAL_DEV" | 136 log local and installation device are the same: "$LOCAL_DEV" |
140 exit 1 | 137 exit 1 |
141 fi | 138 fi |
142 | 139 |
143 log Booted from "$LOCAL_DEV" and installing onto "$INSTALL_DEV" | 140 log Booted from "$LOCAL_DEV" and installing onto "$INSTALL_DEV" |
144 | 141 |
145 # make sure installation device is unmounted | 142 # Make sure installation device is unmounted. |
146 if [ "$INSTALL_DEV" == ""$(grep "^$INSTALL_DEV " /proc/mounts | \ | 143 if [ "$INSTALL_DEV" == ""$(grep "^$INSTALL_DEV " /proc/mounts | \ |
147 cut -d ' ' -f 1 | uniq) ] | 144 cut -d ' ' -f 1 | uniq) ] |
148 then | 145 then |
149 # drive is mounted. must unmount | 146 # Drive is mounted, must unmount. |
150 log unmounting "$INSTALL_DEV" | 147 log unmounting "$INSTALL_DEV" |
151 umount "$INSTALL_DEV" | 148 umount "$INSTALL_DEV" |
152 # check if it's still mounted for some strange reason | 149 # Check if it's still mounted for some strange reason. |
153 if [ "$INSTALL_DEV" == ""$(grep "^$INSTALL_DEV " /proc/mounts | \ | 150 if [ "$INSTALL_DEV" == ""$(grep "^$INSTALL_DEV " /proc/mounts | \ |
154 cut -d ' ' -f 1 | uniq) ] | 151 cut -d ' ' -f 1 | uniq) ] |
155 then | 152 then |
156 log unable to unmount "$INSTALL_DEV", which is where i need to write to | 153 log unable to unmount "$INSTALL_DEV", which is where i need to write to |
157 exit 1 | 154 exit 1 |
158 fi | 155 fi |
159 fi | 156 fi |
160 | 157 |
161 # download file to the device | 158 # Download file to the device. |
162 log downloading image. this may take a while | 159 log downloading image. this may take a while |
163 | 160 |
164 # wget - fetch file, send to stdout | 161 # wget - fetch file, send to stdout |
165 # tee - save a copy off to device, also send to stdout | 162 # tee - save a copy off to device, also send to stdout |
166 # openssl - calculate the sha1 hash of stdin, send checksum to stdout | 163 # openssl - calculate the sha1 hash of stdin, send checksum to stdout |
167 # tr - convert trailing newline to a space | 164 # tr - convert trailing newline to a space |
168 # pipestatus - append return codes for all prior commands. should all be 0 | 165 # pipestatus - append return codes for all prior commands. should all be 0 |
169 | 166 |
170 CHECKSUM_FILE="/tmp/memento_autoupdate_checksum" | 167 CHECKSUM_FILE="/tmp/memento_autoupdate_checksum" |
171 RETURNED_CODES=$(wget -O - --load-cookies <(echo "$COOKIES") \ | 168 RETURNED_CODES=$(wget -O - --load-cookies <(echo "$COOKIES") \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 if [ "$ForceUpdate" != "yes" ] && | 226 if [ "$ForceUpdate" != "yes" ] && |
230 version_number_greater_than "$APP_VERSION" "$NEW_VERSION" | 227 version_number_greater_than "$APP_VERSION" "$NEW_VERSION" |
231 then | 228 then |
232 log "Can't upgrade to older version: " "$NEW_VERSION" | 229 log "Can't upgrade to older version: " "$NEW_VERSION" |
233 umount "$MOUNTPOINT" | 230 umount "$MOUNTPOINT" |
234 rmdir "$MOUNTPOINT" | 231 rmdir "$MOUNTPOINT" |
235 exit 1 | 232 exit 1 |
236 fi | 233 fi |
237 fi | 234 fi |
238 | 235 |
239 "$MOUNTPOINT"/postinst "$INSTALL_DEV" 2>&1 | cat >> "$MEMENTO_AU_LOG"; \ | 236 "$MOUNTPOINT"/postinst "$INSTALL_DEV" "$KINSTALL_DEV" 2>&1 | \ |
240 [ "${PIPESTATUS[*]}" = "0 0" ] | 237 cat >> "$MEMENTO_AU_LOG" |
| 238 [ "${PIPESTATUS[*]}" = "0 0" ] |
241 POSTINST_RETURN_CODE=$? | 239 POSTINST_RETURN_CODE=$? |
242 umount "$MOUNTPOINT" | 240 umount "$MOUNTPOINT" |
243 rmdir "$MOUNTPOINT" | 241 rmdir "$MOUNTPOINT" |
244 | 242 |
245 # $1 is return code, $2 is command | 243 # $1 is return code, $2 is command |
246 function abort_update_if_cmd_failed_long { | 244 function abort_update_if_cmd_failed_long { |
247 if [ "$1" -ne "0" ] | 245 if [ "$1" -ne "0" ] |
248 then | 246 then |
249 log "$2 failed with error code $1 . aborting update" | 247 log "$2 failed with error code $1 . aborting update" |
250 exit 1 | 248 exit 1 |
251 fi | 249 fi |
252 } | 250 } |
253 | 251 |
254 function abort_update_if_cmd_failed { | 252 function abort_update_if_cmd_failed { |
255 abort_update_if_cmd_failed_long "$?" "!!" | 253 abort_update_if_cmd_failed_long "$?" "!!" |
256 } | 254 } |
257 | 255 |
258 # if it failed, don't update MBR but just to be safe, zero out a page of | 256 # If it failed, don't update MBR but just to be safe, zero out a page of |
259 # install device | 257 # install device. |
260 abort_update_if_cmd_failed_long "$POSTINST_RETURN_CODE" "$MOUNTPOINT"/postinst | 258 abort_update_if_cmd_failed_long "$POSTINST_RETURN_CODE" "$MOUNTPOINT"/postinst |
261 | 259 |
262 # postinstall on new partition succeeded. | 260 # postinstall on new partition succeeded. |
263 # fix up MBR and make our own partition not something casper will find | 261 # fix up MBR and make our own partition not something casper will find |
264 | 262 |
265 # update MBR to make the other partition bootable | 263 # update MBR to make the other partition bootable |
266 # the slash-magic converts '/' -> '\/' so it's valid in a regex | 264 # the slash-magic converts '/' -> '\/' so it's valid in a regex |
267 log updating MBR of usb device | 265 log updating MBR of usb device |
268 | 266 |
269 # flush linux caches; seems to be necessary | 267 # flush linux caches; seems to be necessary |
270 sync | 268 sync |
271 echo 3 > /proc/sys/vm/drop_caches | 269 echo 3 > /proc/sys/vm/drop_caches |
272 | 270 # Configure the PMBR to boot the new image. |
273 LAYOUT_FILE=/tmp/new_partition_layout | 271 # TODO: ChromeOS EFI BIOS will need a different command to set the GPT |
274 sfdisk -d $ROOT_DEV | sed -e "s/${INSTALL_DEV//\//\\/} .*[^e]$/&, bootable/" \ | 272 # partition attributes bits to mark the new image as bootable. |
275 -e "s/\(${LOCAL_DEV//\//\\/} .*\), bootable/\1/" \ | 273 # NOTE: This won't work for ARM, because we'll need to regenerate the U-Boot |
276 > "$LAYOUT_FILE" | 274 # script when the kernel size and location are changed. Luckily it won't |
277 sfdisk --force $ROOT_DEV < "$LAYOUT_FILE" 2>&1 | cat >> "$MEMENTO_AU_LOG" | 275 # matter because we'll ship with the GPT-based selection process. The U-Boot |
| 276 # script is just a temporary hack for bringup. |
| 277 # FIX: The current gpt tool requires a -b arg to specify the PMBR bootcode. We |
| 278 # don't want to change the code, so we have to extract it, then put it back. |
| 279 # We'll fix this RSN. |
| 280 dd if=${ROOT_DEV} bs=512 count=1 of=/tmp/oldpmbr.bin |
| 281 gpt -S boot -i $NEW_PART_NUM -b /tmp/oldpmbr.bin ${ROOT_DEV} 2>&1 | \ |
| 282 cat >> "$MEMENTO_AU_LOG" |
278 abort_update_if_cmd_failed | 283 abort_update_if_cmd_failed |
279 | 284 |
280 # mark update as complete so we don't try to update again | 285 # mark update as complete so we don't try to update again |
281 touch "$UPDATED_COMPLETED_FILE" | 286 touch "$UPDATED_COMPLETED_FILE" |
282 | 287 |
283 # tell user to reboot | 288 # tell user to reboot |
284 log Autoupdate applied. You should now reboot | 289 log Autoupdate applied. You should now reboot |
285 echo UPDATED | 290 echo UPDATED |
OLD | NEW |