123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- 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
- }
|