source: trunk/package/base-files/files/sbin/sysupgrade

Last change on this file was 48682, checked in by jow, 8 months ago

x86: preserve partition table on sysupgrade

With this patch sysupgrade will write directly to the partitions
instead of to the main disk. The UUID is copied from the image
to the MBR as well. This prevents the mbr from being completely
overwritten and losing the partition table. The -p option has
been added to maintain the original behavior and overwite the
entire disk with the new image. Tests have been added to ensure
that the image partitions match up with the active partitions.

Signed-off-by: Rob Mosher <nyt-openwrt@…>

  • Property svn:executable set to *
File size: 6.1 KB
Line 
1#!/bin/sh
2. /lib/functions.sh
3. /lib/functions/system.sh
4
5# initialize defaults
6RAMFS_COPY_BIN=""       # extra programs for temporary ramfs root
7RAMFS_COPY_DATA=""      # extra data files
8export MTD_CONFIG_ARGS=""
9export INTERACTIVE=0
10export VERBOSE=1
11export SAVE_CONFIG=1
12export SAVE_OVERLAY=0
13export SAVE_PARTITIONS=1
14export DELAY=
15export CONF_IMAGE=
16export CONF_BACKUP_LIST=0
17export CONF_BACKUP=
18export CONF_RESTORE=
19export NEED_IMAGE=
20export HELP=0
21export FORCE=0
22export TEST=0
23
24# parse options
25while [ -n "$1" ]; do
26        case "$1" in
27                -i) export INTERACTIVE=1;;
28                -d) export DELAY="$2"; shift;;
29                -v) export VERBOSE="$(($VERBOSE + 1))";;
30                -q) export VERBOSE="$(($VERBOSE - 1))";;
31                -n) export SAVE_CONFIG=0;;
32                -c) export SAVE_OVERLAY=1;;
33                -p) export SAVE_PARTITIONS=0;;
34                -b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
35                -r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
36                -l|--list-backup) export CONF_BACKUP_LIST=1; break;;
37                -f) export CONF_IMAGE="$2"; shift;;
38                -F|--force) export FORCE=1;;
39                -T|--test) export TEST=1;;
40                -h|--help) export HELP=1; break;;
41                -*)
42                        echo "Invalid option: $1"
43                        exit 1
44                ;;
45                *) break;;
46        esac
47        shift;
48done
49
50export CONFFILES=/tmp/sysupgrade.conffiles
51export CONF_TAR=/tmp/sysupgrade.tgz
52
53export ARGV="$*"
54export ARGC="$#"
55
56[ -z "$ARGV" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && {
57        cat <<EOF
58Usage: $0 [<upgrade-option>...] <image file or URL>
59       $0 [-q] [-i] <backup-command> <file>
60
61upgrade-option:
62        -d <delay>   add a delay before rebooting
63        -f <config>  restore configuration from .tar.gz (file or url)
64        -i           interactive mode
65        -c           attempt to preserve all changed files in /etc/
66        -n           do not save configuration over reflash
67        -p           do not attempt to restore the partition table after flash.
68        -T | --test
69                     Verify image and config .tar.gz but do not actually flash.
70        -F | --force
71                     Flash image even if image checks fail, this is dangerous!
72        -q           less verbose
73        -v           more verbose
74        -h | --help  display this help
75
76backup-command:
77        -b | --create-backup <file>
78                     create .tar.gz of files specified in sysupgrade.conf
79                     then exit. Does not flash an image. If file is '-',
80                     i.e. stdout, verbosity is set to 0 (i.e. quiet).
81        -r | --restore-backup <file>
82                     restore a .tar.gz created with sysupgrade -b
83                     then exit. Does not flash an image. If file is '-',
84                     the archive is read from stdin.
85        -l | --list-backup
86                     list the files that would be backed up when calling
87                     sysupgrade -b. Does not create a backup file.
88
89EOF
90        exit 1
91}
92
93[ -n "$ARGV" -a -n "$NEED_IMAGE" ] && {
94        cat <<-EOF
95                -b|--create-backup and -r|--restore-backup do not perform a firmware upgrade.
96                Do not specify both -b|-r and a firmware image.
97        EOF
98        exit 1
99}
100
101# prevent messages from clobbering the tarball when using stdout
102[ "$CONF_BACKUP" = "-" ] && export VERBOSE=0
103
104add_uci_conffiles() {
105        local file="$1"
106        ( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
107                /etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
108                -type f -o -type l 2>/dev/null;
109          opkg list-changed-conffiles ) | sort -u > "$file"
110        return 0
111}
112
113add_overlayfiles() {
114        local file="$1"
115        if [ -d /overlay/upper ]; then
116                local overlaydir="/overlay/upper"
117        else
118                local overlaydir="/overlay"
119        fi
120        find $overlaydir/etc/ -type f -o -type l | sed \
121                -e 's,^/overlay\/upper/,/,' \
122                -e 's,^/overlay/,/,' \
123                -e '\,/META_[a-zA-Z0-9]*$,d' \
124                -e '\,/functions.sh$,d' \
125                -e '\,/[^/]*-opkg$,d' \
126        > "$file"
127        return 0
128}
129
130# hooks
131sysupgrade_image_check="platform_check_image"
132[ $SAVE_OVERLAY = 0 -o ! -d /overlay/etc ] && \
133        sysupgrade_init_conffiles="add_uci_conffiles" || \
134        sysupgrade_init_conffiles="add_overlayfiles"
135
136include /lib/upgrade
137
138[ "$1" = "nand" ] && nand_upgrade_stage2 $@
139
140do_save_conffiles() {
141        local conf_tar="${1:-$CONF_TAR}"
142
143        [ -z "$(rootfs_type)" ] && {
144                echo "Cannot save config while running from ramdisk."
145                ask_bool 0 "Abort" && exit
146                return 0
147        }
148        run_hooks "$CONFFILES" $sysupgrade_init_conffiles
149        ask_bool 0 "Edit config file list" && vi "$CONFFILES"
150
151        v "Saving config files..."
152        [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
153        tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null
154
155        rm -f "$CONFFILES"
156}
157
158if [ $CONF_BACKUP_LIST -eq 1 ]; then
159        add_uci_conffiles "$CONFFILES"
160        cat "$CONFFILES"
161        rm -f "$CONFFILES"
162        exit 0
163fi
164
165if [ -n "$CONF_BACKUP" ]; then
166        do_save_conffiles "$CONF_BACKUP"
167        exit $?
168fi
169
170if [ -n "$CONF_RESTORE" ]; then
171        if [ "$CONF_RESTORE" != "-" ] && [ ! -f "$CONF_RESTORE" ]; then
172                echo "Backup archive '$CONF_RESTORE' not found."
173                exit 1
174        fi
175
176        [ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
177        tar -C / -x${TAR_V}zf "$CONF_RESTORE"
178        exit $?
179fi
180
181type platform_check_image >/dev/null 2>/dev/null || {
182        echo "Firmware upgrade is not implemented for this platform."
183        exit 1
184}
185
186for check in $sysupgrade_image_check; do
187        ( eval "$check \"\$ARGV\"" ) || {
188                if [ $FORCE -eq 1 ]; then
189                        echo "Image check '$check' failed but --force given - will update anyway!"
190                        break
191                else
192                        echo "Image check '$check' failed."
193                        exit 1
194                fi
195        }
196done
197
198if [ -n "$CONF_IMAGE" ]; then
199        case "$(get_magic_word $CONF_IMAGE cat)" in
200                # .gz files
201                1f8b) ;;
202                *)
203                        echo "Invalid config file. Please use only .tar.gz files"
204                        exit 1
205                ;;
206        esac
207        get_image "$CONF_IMAGE" "cat" > "$CONF_TAR"
208        export SAVE_CONFIG=1
209elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
210        [ $TEST -eq 1 ] || do_save_conffiles
211        export SAVE_CONFIG=1
212else
213        export SAVE_CONFIG=0
214fi
215
216if [ $TEST -eq 1 ]; then
217        exit 0
218fi
219
220run_hooks "" $sysupgrade_pre_upgrade
221
222# Some platforms/devices may want different sysupgrade process, e.g. without
223# killing processes yet or calling ubus system upgrade method.
224# This is needed e.g. on NAND devices where we just want to trigger stage1 at
225# this point.
226if type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
227        platform_pre_upgrade "$ARGV"
228fi
229
230ubus call system upgrade
231touch /tmp/sysupgrade
232
233if [ ! -f /tmp/failsafe ] ; then
234        kill_remaining TERM
235        sleep 3
236        kill_remaining KILL
237fi
238
239if [ -n "$(rootfs_type)" ]; then
240        v "Switching to ramdisk..."
241        run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade'
242else
243        do_upgrade
244fi
Note: See TracBrowser for help on using the repository browser.