Skip to content

Commit

Permalink
x86: preserve partition table on sysupgrade
Browse files Browse the repository at this point in the history
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 <[email protected]>

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@48682 3c298f89-4303-0410-b956-a3cf2f4a3e73
  • Loading branch information
jow- committed Feb 9, 2016
1 parent 16cf902 commit 5c41d99
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
1 change: 1 addition & 0 deletions package/base-files/files/lib/upgrade/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ run_ramfs() { # <command> [...]
install_bin /usr/sbin/ubirsvol
install_bin /usr/sbin/ubirmvol
install_bin /usr/sbin/ubimkvol
install_bin /usr/sbin/partx
for file in $RAMFS_COPY_BIN; do
install_bin ${file//:/ }
done
Expand Down
3 changes: 3 additions & 0 deletions package/base-files/files/sbin/sysupgrade
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export INTERACTIVE=0
export VERBOSE=1
export SAVE_CONFIG=1
export SAVE_OVERLAY=0
export SAVE_PARTITIONS=1
export DELAY=
export CONF_IMAGE=
export CONF_BACKUP_LIST=0
Expand All @@ -29,6 +30,7 @@ while [ -n "$1" ]; do
-q) export VERBOSE="$(($VERBOSE - 1))";;
-n) export SAVE_CONFIG=0;;
-c) export SAVE_OVERLAY=1;;
-p) export SAVE_PARTITIONS=0;;
-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
-r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
-l|--list-backup) export CONF_BACKUP_LIST=1; break;;
Expand Down Expand Up @@ -62,6 +64,7 @@ upgrade-option:
-i interactive mode
-c attempt to preserve all changed files in /etc/
-n do not save configuration over reflash
-p do not attempt to restore the partition table after flash.
-T | --test
Verify image and config .tar.gz but do not actually flash.
-F | --force
Expand Down
2 changes: 2 additions & 0 deletions target/linux/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ FEATURES:=squashfs ext4 vdi vmdk pcmcia targz
SUBTARGETS=generic xen_domu ep80579 geode kvm_guest 64
MAINTAINER:=Felix Fietkau <[email protected]>

DEFAULT_PACKAGES += partx-utils

KERNEL_PATCHVER:=4.4

KERNELNAME:=bzImage
Expand Down
51 changes: 49 additions & 2 deletions target/linux/x86/base-files/lib/upgrade/platform.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,59 @@ platform_copy_config() {
fi
}

get_partitions() { # <device> <filename>
local disk="$1"
local filename="$2"

if [ -b "$disk" -o -f "$disk" ]; then
echo "Reading partition table from $filename..."
partx -r "$disk" -gbo NR,START,SECTORS > "/tmp/partx.$filename"
fi
}

platform_do_upgrade() {
platform_export_bootpart
disk="${BOOTPART%[0-9]}"

if [ -b "${BOOTPART%[0-9]}" ]; then
if [ -b "$disk" ]; then
sync
get_image "$@" | dd of="${BOOTPART%[0-9]}" bs=4096 conv=fsync
if [ "$SAVE_PARTITIONS" = "1" ]; then
get_partitions "$disk" bootdisk


#get block size
sectors="$(partx -r $disk -gbo SECTORS --nr 1:1)"
size="$(partx -r $disk -gbo SIZE --nr 1:1)"
ibs="$(($size / $sectors))"

#extract the boot sector from the image
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b

get_partitions /tmp/image.bs image

#compare tables
diff="$(grep -F -x -v -f /tmp/partx.bootdisk /tmp/partx.image)"
if [ -n "$diff" ]; then
echo "Partition layout is changed. Full image will be written."
ask_bool 0 "Abort" && exit

get_image "$@" | dd of="$disk" bs=4096 conv=fsync
return 0
fi

#iterate over each partition from the image and write it to the boot disk
while read part start size; do
echo "Writing image to $disk$part..."
get_image "$@" | dd of="$disk$part" ibs="$ibs" obs=1M skip="$start" count="$size" conv=fsync
done < /tmp/partx.image

#copy partition uuid
echo "Writing new UUID to $disk$part..."
get_image "$@" | dd of="$disk" bs=1 skip=440 count=4 seek=440 conv=fsync
else
get_image "$@" | dd of="$disk" bs=4096 conv=fsync
fi

sleep 1
fi
}

0 comments on commit 5c41d99

Please sign in to comment.