0089-x86-preserve-partition-table-on-sysupgrade.patch 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. From: Jo-Philipp Wich <jow@openwrt.org>
  2. Date: Tue, 9 Feb 2016 12:33:17 +0000
  3. Subject: x86: preserve partition table on sysupgrade
  4. With this patch sysupgrade will write directly to the partitions
  5. instead of to the main disk. The UUID is copied from the image
  6. to the MBR as well. This prevents the mbr from being completely
  7. overwritten and losing the partition table. The -p option has
  8. been added to maintain the original behavior and overwite the
  9. entire disk with the new image. Tests have been added to ensure
  10. that the image partitions match up with the active partitions.
  11. Signed-off-by: Rob Mosher <nyt-openwrt@countercultured.net>
  12. Backport of OpenWrt r48682
  13. diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
  14. index 761b4c17957e2cf63b88025520b6fba59c890255..dc865544f65c16399dcced55b8b09c671b31b5d1 100644
  15. --- a/package/base-files/files/lib/upgrade/common.sh
  16. +++ b/package/base-files/files/lib/upgrade/common.sh
  17. @@ -67,6 +67,7 @@ run_ramfs() { # <command> [...]
  18. install_bin /usr/sbin/ubirsvol
  19. install_bin /usr/sbin/ubirmvol
  20. install_bin /usr/sbin/ubimkvol
  21. + install_bin /usr/sbin/partx
  22. for file in $RAMFS_COPY_BIN; do
  23. install_bin ${file//:/ }
  24. done
  25. diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
  26. index ef83c4b00f1a88ae5d68fc70adf51a6af3dc109c..759c841e131a415c8009995c372cce1f55fb78a0 100755
  27. --- a/package/base-files/files/sbin/sysupgrade
  28. +++ b/package/base-files/files/sbin/sysupgrade
  29. @@ -10,6 +10,7 @@ export INTERACTIVE=0
  30. export VERBOSE=1
  31. export SAVE_CONFIG=1
  32. export SAVE_OVERLAY=0
  33. +export SAVE_PARTITIONS=1
  34. export DELAY=
  35. export CONF_IMAGE=
  36. export CONF_BACKUP_LIST=0
  37. @@ -29,6 +30,7 @@ while [ -n "$1" ]; do
  38. -q) export VERBOSE="$(($VERBOSE - 1))";;
  39. -n) export SAVE_CONFIG=0;;
  40. -c) export SAVE_OVERLAY=1;;
  41. + -p) export SAVE_PARTITIONS=0;;
  42. -b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
  43. -r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
  44. -l|--list-backup) export CONF_BACKUP_LIST=1; break;;
  45. @@ -62,6 +64,7 @@ upgrade-option:
  46. -i interactive mode
  47. -c attempt to preserve all changed files in /etc/
  48. -n do not save configuration over reflash
  49. + -p do not attempt to restore the partition table after flash.
  50. -T | --test
  51. Verify image and config .tar.gz but do not actually flash.
  52. -F | --force
  53. diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile
  54. index ba733c02480b248aa95331da2bcd8fee3e25f812..29a232296a02b253344927a61eecb40503473d59 100644
  55. --- a/target/linux/x86/Makefile
  56. +++ b/target/linux/x86/Makefile
  57. @@ -13,6 +13,8 @@ FEATURES:=squashfs ext4 vdi vmdk pcmcia targz
  58. SUBTARGETS=generic xen_domu ep80579 geode kvm_guest rdc 64
  59. MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
  60. +DEFAULT_PACKAGES += partx-utils
  61. +
  62. KERNEL_PATCHVER:=3.18
  63. KERNELNAME:=bzImage
  64. diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
  65. index adc119c897ed840aef17c2041a48244d0922564e..c21f1a7e5feba553110f138c14977daaa472da70 100644
  66. --- a/target/linux/x86/base-files/lib/upgrade/platform.sh
  67. +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
  68. @@ -55,12 +55,59 @@ platform_copy_config() {
  69. fi
  70. }
  71. +get_partitions() { # <device> <filename>
  72. + local disk="$1"
  73. + local filename="$2"
  74. +
  75. + if [ -b "$disk" -o -f "$disk" ]; then
  76. + echo "Reading partition table from $filename..."
  77. + partx -r "$disk" -gbo NR,START,SECTORS > "/tmp/partx.$filename"
  78. + fi
  79. +}
  80. +
  81. platform_do_upgrade() {
  82. platform_export_bootpart
  83. + disk="${BOOTPART%[0-9]}"
  84. - if [ -b "${BOOTPART%[0-9]}" ]; then
  85. + if [ -b "$disk" ]; then
  86. sync
  87. - get_image "$@" | dd of="${BOOTPART%[0-9]}" bs=4096 conv=fsync
  88. + if [ "$SAVE_PARTITIONS" = "1" ]; then
  89. + get_partitions "$disk" bootdisk
  90. +
  91. +
  92. + #get block size
  93. + sectors="$(partx -r $disk -gbo SECTORS --nr 1:1)"
  94. + size="$(partx -r $disk -gbo SIZE --nr 1:1)"
  95. + ibs="$(($size / $sectors))"
  96. +
  97. + #extract the boot sector from the image
  98. + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
  99. +
  100. + get_partitions /tmp/image.bs image
  101. +
  102. + #compare tables
  103. + diff="$(grep -F -x -v -f /tmp/partx.bootdisk /tmp/partx.image)"
  104. + if [ -n "$diff" ]; then
  105. + echo "Partition layout is changed. Full image will be written."
  106. + ask_bool 0 "Abort" && exit
  107. +
  108. + get_image "$@" | dd of="$disk" bs=4096 conv=fsync
  109. + return 0
  110. + fi
  111. +
  112. + #iterate over each partition from the image and write it to the boot disk
  113. + while read part start size; do
  114. + echo "Writing image to $disk$part..."
  115. + get_image "$@" | dd of="$disk$part" ibs="$ibs" obs=1M skip="$start" count="$size" conv=fsync
  116. + done < /tmp/partx.image
  117. +
  118. + #copy partition uuid
  119. + echo "Writing new UUID to $disk$part..."
  120. + get_image "$@" | dd of="$disk" bs=1 skip=440 count=4 seek=440 conv=fsync
  121. + else
  122. + get_image "$@" | dd of="$disk" bs=4096 conv=fsync
  123. + fi
  124. +
  125. sleep 1
  126. fi
  127. }