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 <russell@personaltelco.net>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
owl
Jo-Philipp Wich 2016-05-24 12:07:02 +02:00
parent 3193053df7
commit 1012701014
3 changed files with 55 additions and 26 deletions

View 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

View 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

View 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