summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package/base-files/files/lib/upgrade/common.sh1
-rwxr-xr-xpackage/base-files/files/sbin/sysupgrade3
-rw-r--r--target/linux/x86/Makefile2
-rw-r--r--target/linux/x86/base-files/lib/upgrade/platform.sh51
4 files changed, 55 insertions, 2 deletions
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
index f894f3155b..0383d253a3 100644
--- a/package/base-files/files/lib/upgrade/common.sh
+++ b/package/base-files/files/lib/upgrade/common.sh
@@ -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
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index 93f0749108..2f441f868b 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -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
@@ -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;;
@@ -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
diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile
index e4bc0d9a50..45bb8c7cac 100644
--- a/target/linux/x86/Makefile
+++ b/target/linux/x86/Makefile
@@ -13,6 +13,8 @@ FEATURES:=squashfs ext4 vdi vmdk pcmcia targz
SUBTARGETS=generic xen_domu ep80579 geode kvm_guest 64
MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+DEFAULT_PACKAGES += partx-utils
+
KERNEL_PATCHVER:=4.4
KERNELNAME:=bzImage
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
index 73ab5ef079..86696aec04 100644
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
@@ -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
}