bee999dd90
Fixes #961
136 lines
4.9 KiB
Diff
136 lines
4.9 KiB
Diff
From: Jo-Philipp Wich <jow@openwrt.org>
|
|
Date: Tue, 9 Feb 2016 12:33:17 +0000
|
|
Subject: 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@countercultured.net>
|
|
|
|
Backport of OpenWrt r48682
|
|
|
|
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
|
|
index 761b4c17957e2cf63b88025520b6fba59c890255..dc865544f65c16399dcced55b8b09c671b31b5d1 100644
|
|
--- a/package/base-files/files/lib/upgrade/common.sh
|
|
+++ b/package/base-files/files/lib/upgrade/common.sh
|
|
@@ -67,6 +67,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 ef83c4b00f1a88ae5d68fc70adf51a6af3dc109c..759c841e131a415c8009995c372cce1f55fb78a0 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 ba733c02480b248aa95331da2bcd8fee3e25f812..29a232296a02b253344927a61eecb40503473d59 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 rdc 64
|
|
MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
|
|
|
|
+DEFAULT_PACKAGES += partx-utils
|
|
+
|
|
KERNEL_PATCHVER:=3.18
|
|
|
|
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 adc119c897ed840aef17c2041a48244d0922564e..c21f1a7e5feba553110f138c14977daaa472da70 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
|
|
}
|