From: Jo-Philipp Wich Date: Tue, 24 May 2016 12:07:02 +0200 Subject: x86: generalize partition discovery for sysupgrade Generalize the partition discovery in sysupgrade in order to fix sysupgrade and config backup/recovery on MMC block devices which use a different naming scheme compared to mtdblock or sd* devices. The change also adds the find applet to the ramdisk utilities so that upgrade code can rely on it. The commit is based on the initial submission by Russell Senior at http://patchwork.ozlabs.org/patch/625440/ . Signed-off-by: Russell Senior Signed-off-by: Jo-Philipp Wich Backport of LEDE 1012701014bd944197031a3c0023527861b521b4 diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index dc865544f65c16399dcced55b8b09c671b31b5d1..14684959dd46d04b1c4b72213dbe06943ae64686 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -53,7 +53,7 @@ run_ramfs() { # [...] /bin/dd /bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump \ /bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \ /bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir \ - /bin/rm /usr/bin/basename /bin/kill /bin/chmod + /bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find install_bin /sbin/mtd install_bin /sbin/mount_root 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 1d4873d78b480cb3f11e04e6246559417b431a8a..5ac81cb90d1c15782a9c4f271720cfa66d6d03a9 100644 --- a/target/linux/x86/base-files/lib/preinit/79_move_config +++ b/target/linux/x86/base-files/lib/preinit/79_move_config @@ -2,10 +2,12 @@ # Copyright (C) 2012-2015 OpenWrt.org move_config() { + local partdev + . /lib/upgrade/platform.sh - if platform_export_bootpart; then - mount -t ext4 -o rw,noatime "$BOOTPART" /mnt + 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 fi diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh index 29eac77dfb0ae52f241696f3f62dce7d16106b20..c8bc3f7f608fc82ee3afc049b64af3a740fd2c37 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh @@ -1,5 +1,21 @@ -platform_export_bootpart() { - local cmdline uuid disk +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 @@ -17,20 +33,27 @@ platform_export_bootpart() { 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 /dev/*; do - [ -b "$disk" ] || continue + 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 - export BOOTPART="${disk}1" - return 0 + uevent="/sys/class/block/${disk##*/}/uevent" + break fi done ;; /dev/*) - export BOOTPART="${disk%[0-9]}1" - return 0 + 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 @@ -49,8 +72,10 @@ platform_check_image() { } platform_copy_config() { - if [ -b "$BOOTPART" ]; then - mount -t ext4 -o rw,noatime "$BOOTPART" /mnt + local partdev + + if platform_export_partdevice partdev 1; then + mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt cp -af "$CONF_TAR" /mnt/ umount /mnt fi @@ -87,18 +112,16 @@ get_partitions() { # } platform_do_upgrade() { - platform_export_bootpart - disk="${BOOTPART%[0-9]}" + local diskdev partdev ibs diff - if [ -b "$disk" ]; then + if platform_export_bootdevice && platform_export_partdevice diskdev 0; then sync if [ "$SAVE_PARTITIONS" = "1" ]; then - get_partitions "$disk" bootdisk - + get_partitions "/dev/$diskdev" bootdisk #get block size - if [ -f "/sys/block/${disk##*/}/queue/physical_block_size" ]; then - ibs="$(cat "/sys/block/${disk##*/}/queue/physical_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 @@ -114,21 +137,25 @@ platform_do_upgrade() { echo "Partition layout is changed. Full image will be written." ask_bool 0 "Abort" && exit - get_image "$@" | dd of="$disk" bs=4096 conv=fsync + get_image "$@" | dd of="/dev/$diskdev" 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 + if platform_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 + echo "Unable to find partition $part device, skipped." + fi done < /tmp/partmap.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 + echo "Writing new UUID to /dev/$diskdev..." + get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync else - get_image "$@" | dd of="$disk" bs=4096 conv=fsync + get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync fi sleep 1