diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index f894f3155b5..0383d253a32 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() { # [...] 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 93f0749108e..2f441f868ba 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 e4bc0d9a50b..45bb8c7cac2 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 +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 73ab5ef0794..86696aec04d 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() { # + 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 }