x86: generalize partition discovery for sysupgrade
authorJo-Philipp Wich <jo@mein.io>
Tue, 24 May 2016 10:07:02 +0000 (12:07 +0200)
committerJo-Philipp Wich <jo@mein.io>
Tue, 24 May 2016 11:30:58 +0000 (13:30 +0200)
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 <russell@personaltelco.net>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
package/base-files/files/lib/upgrade/common.sh
target/linux/x86/base-files/lib/preinit/79_move_config
target/linux/x86/base-files/lib/upgrade/platform.sh

index 0383d25..752a61c 100644 (file)
@@ -53,7 +53,7 @@ run_ramfs() { # <command> [...]
                /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 /bin/uclient-fetch /bin/wget
        install_bin /sbin/mtd
index 1d4873d..5ac81cb 100644 (file)
@@ -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
index 29eac77..c8bc3f7 100644 (file)
@@ -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() { # <device> <filename>
 }
 
 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