From ad37e2b6b43b2c3389356d892b04f3873d8f6b93 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 2 Mar 2017 12:49:16 +0100 Subject: [PATCH] x86: backport more sysupgrade patches Should fix sysupgrades on disks with 4k block size. --- ...ove-sysupgrade.tgz-only-if-it-exists.patch | 32 +++ ...tform-upgrade-functions-to-common.sh.patch | 253 ++++++++++++++++++ ...upgrades-on-disks-with-4k-block-size.patch | 46 ++++ 3 files changed, 331 insertions(+) create mode 100644 patches/openwrt/0094-x86-move-sysupgrade.tgz-only-if-it-exists.patch create mode 100644 patches/openwrt/0095-base-files-export-x86-platform-upgrade-functions-to-common.sh.patch create mode 100644 patches/openwrt/0096-x86-fix-sysupgrades-on-disks-with-4k-block-size.patch diff --git a/patches/openwrt/0094-x86-move-sysupgrade.tgz-only-if-it-exists.patch b/patches/openwrt/0094-x86-move-sysupgrade.tgz-only-if-it-exists.patch new file mode 100644 index 00000000..55a237f0 --- /dev/null +++ b/patches/openwrt/0094-x86-move-sysupgrade.tgz-only-if-it-exists.patch @@ -0,0 +1,32 @@ +From: Yousong Zhou +Date: Sun, 1 Jan 2017 01:06:29 +0800 +Subject: x86: move sysupgrade.tgz only if it exists + +To squash error messages at boot time + + mv: can't rename '/mnt/sysupgrade.tgz': No such file or directory + +Signed-off-by: Yousong Zhou + +Backport of LEDE fa37bdc05a3e8ebab7de293d059959b2efc99581 + +diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config +index 5ac81cb90d1c15782a9c4f271720cfa66d6d03a9..37954f0236faafca657a05a3c1efc7df2e162bfc 100644 +--- a/target/linux/x86/base-files/lib/preinit/79_move_config ++++ b/target/linux/x86/base-files/lib/preinit/79_move_config +@@ -7,9 +7,12 @@ move_config() { + . /lib/upgrade/platform.sh + + if platform_export_bootdevice && platform_export_partdevice partdev 1; then +- mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt +- mv -f /mnt/sysupgrade.tgz / +- umount /mnt ++ if mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt; then ++ if [ -f /mnt/sysupgrade.tgz ]; then ++ mv -f /mnt/sysupgrade.tgz / ++ fi ++ umount /mnt ++ fi + fi + } + diff --git a/patches/openwrt/0095-base-files-export-x86-platform-upgrade-functions-to-common.sh.patch b/patches/openwrt/0095-base-files-export-x86-platform-upgrade-functions-to-common.sh.patch new file mode 100644 index 00000000..a0dd25d8 --- /dev/null +++ b/patches/openwrt/0095-base-files-export-x86-platform-upgrade-functions-to-common.sh.patch @@ -0,0 +1,253 @@ +From: Yousong Zhou +Date: Sun, 1 Jan 2017 01:06:37 +0800 +Subject: base-files: export x86 platform upgrade functions to common.sh + +Signed-off-by: Yousong Zhou + +Backport of LEDE 6f61d8511eccf2736fd7f430aff2c98c595fa4b9 + +diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh +index 14684959dd46d04b1c4b72213dbe06943ae64686..2064adf775c491725dbff5826b94bd6132d8d060 100644 +--- a/package/base-files/files/lib/upgrade/common.sh ++++ b/package/base-files/files/lib/upgrade/common.sh +@@ -203,6 +203,96 @@ get_magic_long() { + (get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null + } + ++export_bootdevice() { ++ local cmdline uuid disk uevent ++ local MAJOR MINOR DEVNAME DEVTYPE ++ ++ if read cmdline < /proc/cmdline; then ++ case "$cmdline" in ++ *block2mtd=*) ++ disk="${cmdline##*block2mtd=}" ++ disk="${disk%%,*}" ++ ;; ++ *root=*) ++ disk="${cmdline##*root=}" ++ disk="${disk%% *}" ++ ;; ++ esac ++ ++ case "$disk" in ++ PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02) ++ uuid="${disk#PARTUUID=}" ++ uuid="${uuid%-02}" ++ for disk in $(find /dev -type b); do ++ set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "') ++ if [ "$4$3$2$1" = "$uuid" ]; then ++ uevent="/sys/class/block/${disk##*/}/uevent" ++ break ++ fi ++ done ++ ;; ++ /dev/*) ++ uevent="/sys/class/block/${disk##*/}/uevent" ++ ;; ++ esac ++ ++ if [ -e "$uevent" ]; then ++ . "$uevent" ++ ++ export BOOTDEV_MAJOR=$MAJOR ++ export BOOTDEV_MINOR=$MINOR ++ return 0 ++ fi ++ fi ++ ++ return 1 ++} ++ ++export_partdevice() { ++ local var="$1" offset="$2" ++ local uevent MAJOR MINOR DEVNAME DEVTYPE ++ ++ for uevent in /sys/class/block/*/uevent; do ++ . "$uevent" ++ if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then ++ export "$var=$DEVNAME" ++ return 0 ++ fi ++ done ++ ++ return 1 ++} ++ ++get_partitions() { # ++ local disk="$1" ++ local filename="$2" ++ ++ if [ -b "$disk" -o -f "$disk" ]; then ++ v "Reading partition table from $filename..." ++ ++ local magic="$(hexdump -v -n 2 -s 0x1FE -e '1/2 "0x%04X"' "$disk")" ++ if [ "$magic" != 0xAA55 ]; then ++ v "Invalid partition table on $disk" ++ exit ++ fi ++ ++ rm -f "/tmp/partmap.$filename" ++ ++ local part ++ for part in 1 2 3 4; do ++ set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") ++ ++ local type="$(($1 % 256))" ++ local lba="$(($2))" ++ local num="$(($3))" ++ ++ [ $type -gt 0 ] || continue ++ ++ printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" ++ done ++ fi ++} ++ + jffs2_copy_config() { + if grep rootfs_data /proc/mtd >/dev/null; then + # squashfs+jffs2 +diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config +index 37954f0236faafca657a05a3c1efc7df2e162bfc..143ca5147b5693a5b8068dc10eb71b5066777160 100644 +--- a/target/linux/x86/base-files/lib/preinit/79_move_config ++++ b/target/linux/x86/base-files/lib/preinit/79_move_config +@@ -4,9 +4,9 @@ + move_config() { + local partdev + +- . /lib/upgrade/platform.sh ++ . /lib/upgrade/common.sh + +- if platform_export_bootdevice && platform_export_partdevice partdev 1; then ++ if export_bootdevice && export_partdevice partdev 1; then + if mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt; then + if [ -f /mnt/sysupgrade.tgz ]; then + mv -f /mnt/sysupgrade.tgz / +diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh +index c8bc3f7f608fc82ee3afc049b64af3a740fd2c37..8850917062618985126b5086dccfe11506ed1fbb 100644 +--- a/target/linux/x86/base-files/lib/upgrade/platform.sh ++++ b/target/linux/x86/base-files/lib/upgrade/platform.sh +@@ -1,64 +1,3 @@ +-platform_export_partdevice() { +- local var="$1" offset="$2" +- local uevent MAJOR MINOR DEVNAME DEVTYPE +- +- for uevent in /sys/class/block/*/uevent; do +- . "$uevent" +- if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then +- export "$var=$DEVNAME" +- return 0 +- fi +- done +- +- return 1 +-} +- +-platform_export_bootdevice() { +- local cmdline uuid disk uevent +- local MAJOR MINOR DEVNAME DEVTYPE +- +- if read cmdline < /proc/cmdline; then +- case "$cmdline" in +- *block2mtd=*) +- disk="${cmdline##*block2mtd=}" +- disk="${disk%%,*}" +- ;; +- *root=*) +- disk="${cmdline##*root=}" +- disk="${disk%% *}" +- ;; +- esac +- +- case "$disk" in +- PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02) +- uuid="${disk#PARTUUID=}" +- uuid="${uuid%-02}" +- for disk in $(find /dev -type b); do +- set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "') +- if [ "$4$3$2$1" = "$uuid" ]; then +- uevent="/sys/class/block/${disk##*/}/uevent" +- break +- fi +- done +- ;; +- /dev/*) +- uevent="/sys/class/block/${disk##*/}/uevent" +- ;; +- esac +- +- if [ -e "$uevent" ]; then +- . "$uevent" +- +- export BOOTDEV_MAJOR=$MAJOR +- export BOOTDEV_MINOR=$MINOR +- +- return 0 +- fi +- fi +- +- return 1 +-} +- + platform_check_image() { + [ "$#" -gt 1 ] && return 1 + +@@ -74,47 +13,17 @@ platform_check_image() { + platform_copy_config() { + local partdev + +- if platform_export_partdevice partdev 1; then ++ if export_partdevice partdev 1; then + mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt + cp -af "$CONF_TAR" /mnt/ + umount /mnt + fi + } + +-get_partitions() { # +- local disk="$1" +- local filename="$2" +- +- if [ -b "$disk" -o -f "$disk" ]; then +- echo "Reading partition table from $filename..." +- +- local magic="$(hexdump -v -n 2 -s 0x1FE -e '1/2 "0x%04X"' "$disk")" +- if [ "$magic" != 0xAA55 ]; then +- echo "Invalid partition table on $disk" +- exit +- fi +- +- rm -f "/tmp/partmap.$filename" +- +- local part +- for part in 1 2 3 4; do +- set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") +- +- local type="$(($1 % 256))" +- local lba="$(($2))" +- local num="$(($3))" +- +- [ $type -gt 0 ] || continue +- +- printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" +- done +- fi +-} +- + platform_do_upgrade() { + local diskdev partdev ibs diff + +- if platform_export_bootdevice && platform_export_partdevice diskdev 0; then ++ if export_bootdevice && export_partdevice diskdev 0; then + sync + if [ "$SAVE_PARTITIONS" = "1" ]; then + get_partitions "/dev/$diskdev" bootdisk +@@ -143,7 +52,7 @@ platform_do_upgrade() { + + #iterate over each partition from the image and write it to the boot disk + while read part start size; do +- if platform_export_partdevice partdev $part; then ++ if export_partdevice partdev $part; then + echo "Writing image to /dev/$partdev..." + get_image "$@" | dd of="/dev/$partdev" ibs="$ibs" obs=1M skip="$start" count="$size" conv=fsync + else diff --git a/patches/openwrt/0096-x86-fix-sysupgrades-on-disks-with-4k-block-size.patch b/patches/openwrt/0096-x86-fix-sysupgrades-on-disks-with-4k-block-size.patch new file mode 100644 index 00000000..c2d38071 --- /dev/null +++ b/patches/openwrt/0096-x86-fix-sysupgrades-on-disks-with-4k-block-size.patch @@ -0,0 +1,46 @@ +From: Felix Fietkau +Date: Wed, 25 Jan 2017 08:13:11 +0100 +Subject: x86: fix sysupgrades on disks with 4k block size + +Even when the disk uses 4k blocks, the partition table still uses units +of 512 byte sectors. Always use ibs=512 for the offsets + +Signed-off-by: Felix Fietkau + +Backport of LEDE e9ecb228c9d80605884058d7653e2eb56ba64051 + +diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh +index 8850917062618985126b5086dccfe11506ed1fbb..d3e9f360aadedad0995da55205364940c9884ba4 100644 +--- a/target/linux/x86/base-files/lib/upgrade/platform.sh ++++ b/target/linux/x86/base-files/lib/upgrade/platform.sh +@@ -21,20 +21,13 @@ platform_copy_config() { + } + + platform_do_upgrade() { +- local diskdev partdev ibs diff ++ local diskdev partdev diff + + if export_bootdevice && export_partdevice diskdev 0; then + sync + if [ "$SAVE_PARTITIONS" = "1" ]; then + get_partitions "/dev/$diskdev" bootdisk + +- #get block size +- if [ -f "/sys/block/$diskdev/queue/physical_block_size" ]; then +- ibs="$(cat "/sys/block/$diskdev/queue/physical_block_size")" +- else +- ibs=512 +- fi +- + #extract the boot sector from the image + get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b + +@@ -54,7 +47,7 @@ platform_do_upgrade() { + while read part start size; do + if export_partdevice partdev $part; then + echo "Writing image to /dev/$partdev..." +- get_image "$@" | dd of="/dev/$partdev" ibs="$ibs" obs=1M skip="$start" count="$size" conv=fsync ++ get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync + else + echo "Unable to find partition $part device, skipped." + fi