Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: user_tools/linux/recovery.sh

Issue 5720007: Check for enough room in /tmp, warn about too-small USB drives. (Closed) Base URL: http://git.chromium.org/git/vboot_reference.git@master
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/sh 1 #!/bin/sh
2 # 2 #
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3 # Copyright (c) 2010 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 attempts to guide linux users through the process of putting a recovery 7 # This attempts to guide linux users through the process of putting a recovery
8 # image onto a removeable USB drive. 8 # image onto a removeable USB drive.
9 # 9 #
10 # We may not need root privileges if we have the right permissions. 10 # We may not need root privileges if we have the right permissions.
(...skipping 10 matching lines...) Expand all
21 21
22 # Where do we look for the config file? Note that we can override this by just 22 # Where do we look for the config file? Note that we can override this by just
23 # specifying the config file URL on the command line. 23 # specifying the config file URL on the command line.
24 CONFIGURL="${1:-https://dl.google.com/dl/edgedl/chromeos/recovery/recovery.conf} " 24 CONFIGURL="${1:-https://dl.google.com/dl/edgedl/chromeos/recovery/recovery.conf} "
25 25
26 # Device to put this stuff on, perhaps the user knows best? 26 # Device to put this stuff on, perhaps the user knows best?
27 DEVICE="${DEVICE:-}" 27 DEVICE="${DEVICE:-}"
28 28
29 # What version is this script? It must match the 'recovery_tool_version=' value 29 # What version is this script? It must match the 'recovery_tool_version=' value
30 # in the config file that we'll download. 30 # in the config file that we'll download.
31 MYVERSION='0.9.1' 31 MYVERSION='0.9.2'
32 32
33 33
34 ############################################################################## 34 ##############################################################################
35 # Some temporary filenames 35 # Some temporary filenames
36 debug='debug.log' 36 debug='debug.log'
37 tmpfile='tmp.txt' 37 tmpfile='tmp.txt'
38 config='config.txt' 38 config='config.txt'
39 version='version.txt' 39 version='version.txt'
40 40
41 ############################################################################## 41 ##############################################################################
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 # 101 #
102 # This also sets the following global variables to select alternative utilities 102 # This also sets the following global variables to select alternative utilities
103 # when there is more than one equivalent tool available: 103 # when there is more than one equivalent tool available:
104 # 104 #
105 # FETCH = name of utility used to download files from the web 105 # FETCH = name of utility used to download files from the web
106 # CHECK = command to invoke to generate checksums on a file 106 # CHECK = command to invoke to generate checksums on a file
107 # CHECKTYPE = type of checksum generated 107 # CHECKTYPE = type of checksum generated
108 # DISKUTIL = set if we have 'diskutil' (for Macs) 108 # DISKUTIL = set if we have 'diskutil' (for Macs)
109 # 109 #
110 require_utils() { 110 require_utils() {
111 local external 111 local extern
112 local errors 112 local errors
113 local tool 113 local tool
114 local tmp 114 local tmp
115 115
116 external='cat cut dd grep ls mkdir mount readlink sed sync umount unzip wc' 116 extern='awk cat cut dd grep ls mkdir mount readlink sed sync umount unzip wc'
117 if [ -z "$WORKDIR" ]; then 117 if [ -z "$WORKDIR" ]; then
118 external="$external mktemp" 118 extern="$extern mktemp"
119 fi 119 fi
120 errors= 120 errors=
121 121
122 for tool in $external ; do 122 for tool in $extern ; do
123 if ! type "$tool" >/dev/null 2>&1 ; then 123 if ! type "$tool" >/dev/null 2>&1 ; then
124 warn "ERROR: need \"$tool\"" 124 warn "ERROR: need \"$tool\""
125 errors=yes 125 errors=yes
126 fi 126 fi
127 done 127 done
128 128
129 # We also need to a way to fetch files from teh internets. Note that the args 129 # We also need to a way to fetch files from teh internets. Note that the args
130 # are different depending on which utility we find. We'll use two variants, 130 # are different depending on which utility we find. We'll use two variants,
131 # one to fetch fresh every time and one to try again from where we left off. 131 # one to fetch fresh every time and one to try again from where we left off.
132 FETCH= 132 FETCH=
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 openssl md5 < "$filename" 231 openssl md5 < "$filename"
232 else 232 else
233 $CHECK "$zipfile" | cut -d' ' -f1 233 $CHECK "$zipfile" | cut -d' ' -f1
234 fi 234 fi
235 } 235 }
236 236
237 237
238 ############################################################################## 238 ##############################################################################
239 # Helper functions to handle the config file and image zipfile. 239 # Helper functions to handle the config file and image zipfile.
240 240
241 # Convert bytes to MB, rounding up to determine storage needed to hold bytes.
242 roundup() {
243 local num=$1
244 local div=$(( 1024 * 1024 ))
245 local rem=$(( $num % $div ))
246
247 if [ $rem -ne 0 ]; then
248 num=$(($num + $div - $rem))
249 fi
250 echo $(( $num / $div ))
251 }
252
253
254 # Die unless the filesystem containing the current directory has enough free
255 # space. The argument is the number of MB required.
256 verify_tmp_space() {
257 local need
258 local got
259 need="$1"
260
261 # The output of "df -m ." could take two forms:
262 #
263 # Filesystem 1M-blocks Used Available Use% Mounted on
264 # /some/really/long/path/to/some/where
265 # 37546 11118 24521 32% /
266 #
267 # Filesystem 1048576-blocks Used Available Capacity Mounted on
268 # /some/short/path 37546 11118 24521 32% /
269 #
270 got=$(df -m . | awk '/^\/[^ ]+ +[0-9]/ {print $4} /^ +[0-9]/ {print $3}')
271
272 if [ "$need" -gt "$got" ]; then
273 fatal " There is not enough free space in ${WORKDIR}" \
274 "(it has ${got}MB, we need ${need}MB).
275
276 Please free up some space on that filesystem, or specify a temporary directory
277 on the commandline like so:
278
279 WORKDIR=/path/to/some/dir $0
280 "
281 fi
282 }
283
284
241 # Each paragraph in the config file should describe a new image. Let's make 285 # Each paragraph in the config file should describe a new image. Let's make
242 # sure it follows all the rules. This scans the config file and returns success 286 # sure it follows all the rules. This scans the config file and returns success
243 # if it looks valid. As a side-effect, it lists the line numbers of the start 287 # if it looks valid. As a side-effect, it lists the line numbers of the start
244 # and end of each stanza in the global variables 'start_lines' and 'end_lines' 288 # and end of each stanza in the global variables 'start_lines' and 'end_lines'
245 # and saves the total number of images in the global variable 'num_images'. 289 # and saves the total number of images in the global variable 'num_images'.
246 good_config() { 290 good_config() {
247 local line 291 local line
248 local key 292 local key
249 local val 293 local val
250 local name 294 local name
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 fi 490 fi
447 done 491 done
448 echo 492 echo
449 493
450 # global 494 # global
451 user_choice="$num" 495 user_choice="$num"
452 } 496 }
453 497
454 # Fetch and verify the user's chosen image. On success, it sets the global 498 # Fetch and verify the user's chosen image. On success, it sets the global
455 # variable 'image_file' to indicate the local name of the unpacked binary that 499 # variable 'image_file' to indicate the local name of the unpacked binary that
456 # should be written to the USB drive. 500 # should be written to the USB drive. It also sets the global variable
501 # 'disk_needed' to the minimum capacity of the USB drive required (in MB).
457 fetch_image() { 502 fetch_image() {
458 local start 503 local start
459 local end 504 local end
460 local line 505 local line
461 local key 506 local key
462 local val 507 local val
463 local file 508 local file
464 local zipfilesize 509 local zipfilesize
465 local filesize 510 local filesize
466 local url 511 local url
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 filesize) 555 filesize)
511 filesize="$val" 556 filesize="$val"
512 ;; 557 ;;
513 md5) 558 md5)
514 md5="$val" 559 md5="$val"
515 ;; 560 ;;
516 sha1) 561 sha1)
517 sha1="$val" 562 sha1="$val"
518 ;; 563 ;;
519 url) 564 url)
565 # Make sure we have enough temp space available. Die if we don't.
566 verify_tmp_space $(roundup $(( $zipfilesize + $filesize )))
520 # Try to download each url until one works. 567 # Try to download each url until one works.
521 if [ -n "$url" ]; then 568 if [ -n "$url" ]; then
522 # We've already got one (it's very nice). 569 # We've already got one (it's very nice).
523 continue; 570 continue;
524 fi 571 fi
525 warn "Downloading image zipfile from $val" 572 warn "Downloading image zipfile from $val"
526 warn "" 573 warn ""
527 zipfile=${val##*/} 574 zipfile=${val##*/}
528 if fetch_url "$val" "$zipfile" "resumeok"; then 575 if fetch_url "$val" "$zipfile" "resumeok"; then
529 # Got it. 576 # Got it.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 return 1 609 return 1
563 fi 610 fi
564 611
565 if ! ls -l "$file" | grep -q "$filesize"; then 612 if ! ls -l "$file" | grep -q "$filesize"; then
566 DEBUG "unpacked filesize is wrong" 613 DEBUG "unpacked filesize is wrong"
567 return 1 614 return 1
568 fi 615 fi
569 616
570 # global 617 # global
571 image_file="$file" 618 image_file="$file"
619 disk_needed=$(roundup "$filesize")
572 } 620 }
573 621
574 ############################################################################## 622 ##############################################################################
575 # Helper functions to manage USB drives. 623 # Helper functions to manage USB drives.
576 624
577 # Return a list of base device names ("sda sdb ...") for all USB drives 625 # Return a list of base device names ("sda sdb ...") for all USB drives
578 get_devlist() { 626 get_devlist() {
579 local dev 627 local dev
580 local t 628 local t
581 local r 629 local r
(...skipping 16 matching lines...) Expand all
598 t=$(cat "/sys/block/$dev/device/type") && 646 t=$(cat "/sys/block/$dev/device/type") &&
599 [ "$t" = "0" ] && 647 [ "$t" = "0" ] &&
600 r=$(cat "/sys/block/$dev/removable") && 648 r=$(cat "/sys/block/$dev/removable") &&
601 [ "$r" = "1" ] && 649 [ "$r" = "1" ] &&
602 readlink -f "/sys/block/$dev" | grep -q -i usb && 650 readlink -f "/sys/block/$dev" | grep -q -i usb &&
603 echo "$dev" || true 651 echo "$dev" || true
604 done 652 done
605 fi 653 fi
606 } 654 }
607 655
656 # Return the raw size in MB of each provided base device name ("sda sdb ...")
657 get_devsize() {
658 local dev
659 local bytes
660 local sectors
661
662 # Are we on a mac?
663 if [ -n "$DISKUTIL" ]; then
664 for dev in $1; do
665 bytes=$(diskutil info $dev | \
666 awk '/\([0-9]+ Bytes\)/' | sed -E 's/.*\(([0-9]+) Bytes\).*/\1/')
667 echo $(( $bytes / 1024 / 1024))
668 done
669 else
670 for dev in $1; do
671 sectors=$(cat "/sys/block/$dev/size")
672 echo $(( $sectors * 512 / 1024 / 1024 ))
673 done
674 fi
675 }
676
677
608 # Return descriptions for each provided base device name ("sda sdb ...") 678 # Return descriptions for each provided base device name ("sda sdb ...")
609 get_devinfo() { 679 get_devinfo() {
610 local dev 680 local dev
611 local v 681 local v
612 local m 682 local m
613 local s 683 local s
614 local ss 684 local ss
615 685
616 # Are we on a mac? 686 # Are we on a mac?
617 if [ -n "$DISKUTIL" ]; then 687 if [ -n "$DISKUTIL" ]; then
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 while true; do 733 while true; do
664 if [ -n "$show" ]; then 734 if [ -n "$show" ]; then
665 devlist=$(get_devlist) 735 devlist=$(get_devlist)
666 choices=$(get_choices "$devlist") 736 choices=$(get_choices "$devlist")
667 if [ -z "$devlist" ]; then 737 if [ -z "$devlist" ]; then
668 num_drives="0" 738 num_drives="0"
669 msg="I can't seem to find a valid USB drive." 739 msg="I can't seem to find a valid USB drive."
670 else 740 else
671 num_drives=$(echo "$devlist" | wc -l) 741 num_drives=$(echo "$devlist" | wc -l)
672 if [ "$num_drives" != "1" ]; then 742 if [ "$num_drives" != "1" ]; then
673 msg="I found $num_drives USB drives" 743 msg="I found $num_drives USB drives."
674 else 744 else
675 msg="I found $num_drives USB drive" 745 msg="I found $num_drives USB drive."
676 fi 746 fi
677 fi 747 fi
678 echo " 748 echo "
679 749
680 $msg 750 $msg We need one with at least ${disk_needed}MB capacity.
681 751
682 $choices 752 $choices
753
683 " 754 "
684 show= 755 show=
685 fi 756 fi
686 prompt "Tell me what to do (or just press Enter to scan again): " 757 prompt "Tell me what to do (or just press Enter to scan again): "
687 read num 758 read num
688 if [ -z "$num" ] || [ "$num" = "?" ]; then 759 if [ -z "$num" ] || [ "$num" = "?" ]; then
689 show=yes 760 show=yes
690 elif echo "$num" | grep -q '[^0-9]'; then 761 elif echo "$num" | grep -q '[^0-9]'; then
691 echo "Sorry, I didn't understand that." 762 echo "Sorry, I didn't understand that."
692 else 763 else
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 if [ -n "$DEVICE" ]; then 847 if [ -n "$DEVICE" ]; then
777 user_choice="${DEVICE#/dev/}" 848 user_choice="${DEVICE#/dev/}"
778 dev_desc="${DEVICE}" 849 dev_desc="${DEVICE}"
779 else 850 else
780 # Make the user pick a USB drive, or exit. 851 # Make the user pick a USB drive, or exit.
781 choose_drive 852 choose_drive
782 853
783 # Be sure 854 # Be sure
784 dev_desc=$(get_devinfo "$user_choice") 855 dev_desc=$(get_devinfo "$user_choice")
785 fi 856 fi
857
858 # Start asking for confirmation
859 dev_size=$(get_devsize "$user_choice")
860 if [ "$dev_size" -lt "$disk_needed" ]; then
861 echo "
862
863 WARNING: This drive seems too small (${dev_size}MB)." \
864 "The recovery image is ${disk_needed}MB."
865 fi
786 echo " 866 echo "
787 Is this the device you want to put the recovery image on? 867 Is this the device you want to put the recovery image on?
788 868
789 $dev_desc 869 $dev_desc
790 " 870 "
791 prompt "You must enter 'YES' (all uppercase) to continue: " 871 prompt "You must enter 'YES' (all uppercase) to continue: "
792 read tmp 872 read tmp
793 if [ "$tmp" != "YES" ]; then 873 if [ "$tmp" != "YES" ]; then
794 quit 874 quit
795 fi 875 fi
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 prompt "Shall I remove the temporary files now? [y/n] " 921 prompt "Shall I remove the temporary files now? [y/n] "
842 read tmp 922 read tmp
843 case $tmp in 923 case $tmp in
844 [Yy]*) 924 [Yy]*)
845 cd 925 cd
846 \rm -rf ${WORKDIR} 926 \rm -rf ${WORKDIR}
847 ;; 927 ;;
848 esac 928 esac
849 929
850 exit 0 930 exit 0
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698