x86: generalize partition discovery for sysupgrade
Backport a few patches to allow sysupgrades on mmcblk and similar block devices.
This commit is contained in:
parent
689de50c27
commit
1f08074438
@ -0,0 +1,135 @@
|
||||
From: Jo-Philipp Wich <jow@openwrt.org>
|
||||
Date: Tue, 9 Feb 2016 12:33:17 +0000
|
||||
Subject: x86: preserve partition table on sysupgrade
|
||||
|
||||
With this patch sysupgrade will write directly to the partitions
|
||||
instead of to the main disk. The UUID is copied from the image
|
||||
to the MBR as well. This prevents the mbr from being completely
|
||||
overwritten and losing the partition table. The -p option has
|
||||
been added to maintain the original behavior and overwite the
|
||||
entire disk with the new image. Tests have been added to ensure
|
||||
that the image partitions match up with the active partitions.
|
||||
|
||||
Signed-off-by: Rob Mosher <nyt-openwrt@countercultured.net>
|
||||
|
||||
Backport of OpenWrt r48682
|
||||
|
||||
diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh
|
||||
index 761b4c17957e2cf63b88025520b6fba59c890255..dc865544f65c16399dcced55b8b09c671b31b5d1 100644
|
||||
--- a/package/base-files/files/lib/upgrade/common.sh
|
||||
+++ b/package/base-files/files/lib/upgrade/common.sh
|
||||
@@ -67,6 +67,7 @@ run_ramfs() { # <command> [...]
|
||||
install_bin /usr/sbin/ubirsvol
|
||||
install_bin /usr/sbin/ubirmvol
|
||||
install_bin /usr/sbin/ubimkvol
|
||||
+ install_bin /usr/sbin/partx
|
||||
for file in $RAMFS_COPY_BIN; do
|
||||
install_bin ${file//:/ }
|
||||
done
|
||||
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
|
||||
index ef83c4b00f1a88ae5d68fc70adf51a6af3dc109c..759c841e131a415c8009995c372cce1f55fb78a0 100755
|
||||
--- a/package/base-files/files/sbin/sysupgrade
|
||||
+++ b/package/base-files/files/sbin/sysupgrade
|
||||
@@ -10,6 +10,7 @@ export INTERACTIVE=0
|
||||
export VERBOSE=1
|
||||
export SAVE_CONFIG=1
|
||||
export SAVE_OVERLAY=0
|
||||
+export SAVE_PARTITIONS=1
|
||||
export DELAY=
|
||||
export CONF_IMAGE=
|
||||
export CONF_BACKUP_LIST=0
|
||||
@@ -29,6 +30,7 @@ while [ -n "$1" ]; do
|
||||
-q) export VERBOSE="$(($VERBOSE - 1))";;
|
||||
-n) export SAVE_CONFIG=0;;
|
||||
-c) export SAVE_OVERLAY=1;;
|
||||
+ -p) export SAVE_PARTITIONS=0;;
|
||||
-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
|
||||
-r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
|
||||
-l|--list-backup) export CONF_BACKUP_LIST=1; break;;
|
||||
@@ -62,6 +64,7 @@ upgrade-option:
|
||||
-i interactive mode
|
||||
-c attempt to preserve all changed files in /etc/
|
||||
-n do not save configuration over reflash
|
||||
+ -p do not attempt to restore the partition table after flash.
|
||||
-T | --test
|
||||
Verify image and config .tar.gz but do not actually flash.
|
||||
-F | --force
|
||||
diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile
|
||||
index ba733c02480b248aa95331da2bcd8fee3e25f812..29a232296a02b253344927a61eecb40503473d59 100644
|
||||
--- a/target/linux/x86/Makefile
|
||||
+++ b/target/linux/x86/Makefile
|
||||
@@ -13,6 +13,8 @@ FEATURES:=squashfs ext4 vdi vmdk pcmcia targz
|
||||
SUBTARGETS=generic xen_domu ep80579 geode kvm_guest rdc 64
|
||||
MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
+DEFAULT_PACKAGES += partx-utils
|
||||
+
|
||||
KERNEL_PATCHVER:=3.18
|
||||
|
||||
KERNELNAME:=bzImage
|
||||
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
index adc119c897ed840aef17c2041a48244d0922564e..c21f1a7e5feba553110f138c14977daaa472da70 100644
|
||||
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
@@ -55,12 +55,59 @@ platform_copy_config() {
|
||||
fi
|
||||
}
|
||||
|
||||
+get_partitions() { # <device> <filename>
|
||||
+ local disk="$1"
|
||||
+ local filename="$2"
|
||||
+
|
||||
+ if [ -b "$disk" -o -f "$disk" ]; then
|
||||
+ echo "Reading partition table from $filename..."
|
||||
+ partx -r "$disk" -gbo NR,START,SECTORS > "/tmp/partx.$filename"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
platform_do_upgrade() {
|
||||
platform_export_bootpart
|
||||
+ disk="${BOOTPART%[0-9]}"
|
||||
|
||||
- if [ -b "${BOOTPART%[0-9]}" ]; then
|
||||
+ if [ -b "$disk" ]; then
|
||||
sync
|
||||
- get_image "$@" | dd of="${BOOTPART%[0-9]}" bs=4096 conv=fsync
|
||||
+ if [ "$SAVE_PARTITIONS" = "1" ]; then
|
||||
+ get_partitions "$disk" bootdisk
|
||||
+
|
||||
+
|
||||
+ #get block size
|
||||
+ sectors="$(partx -r $disk -gbo SECTORS --nr 1:1)"
|
||||
+ size="$(partx -r $disk -gbo SIZE --nr 1:1)"
|
||||
+ ibs="$(($size / $sectors))"
|
||||
+
|
||||
+ #extract the boot sector from the image
|
||||
+ get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
|
||||
+
|
||||
+ get_partitions /tmp/image.bs image
|
||||
+
|
||||
+ #compare tables
|
||||
+ diff="$(grep -F -x -v -f /tmp/partx.bootdisk /tmp/partx.image)"
|
||||
+ if [ -n "$diff" ]; then
|
||||
+ echo "Partition layout is changed. Full image will be written."
|
||||
+ ask_bool 0 "Abort" && exit
|
||||
+
|
||||
+ get_image "$@" | dd of="$disk" 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
|
||||
+ done < /tmp/partx.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
|
||||
+ else
|
||||
+ get_image "$@" | dd of="$disk" bs=4096 conv=fsync
|
||||
+ fi
|
||||
+
|
||||
sleep 1
|
||||
fi
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
From: Jo-Philipp Wich <jo@mein.io>
|
||||
Date: Wed, 30 Mar 2016 03:10:51 +0200
|
||||
Subject: x86: make sysupgrade work without partx
|
||||
|
||||
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
Backport of LEDE 9f422eba7c1a297a96a03b1cce05fa3cb9d71a4a
|
||||
|
||||
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
index c21f1a7e5feba553110f138c14977daaa472da70..f12deebf6484df6f3f69e453ad67688a76d57972 100644
|
||||
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
@@ -61,7 +61,27 @@ get_partitions() { # <device> <filename>
|
||||
|
||||
if [ -b "$disk" -o -f "$disk" ]; then
|
||||
echo "Reading partition table from $filename..."
|
||||
- partx -r "$disk" -gbo NR,START,SECTORS > "/tmp/partx.$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
|
||||
}
|
||||
|
||||
@@ -76,9 +96,11 @@ platform_do_upgrade() {
|
||||
|
||||
|
||||
#get block size
|
||||
- sectors="$(partx -r $disk -gbo SECTORS --nr 1:1)"
|
||||
- size="$(partx -r $disk -gbo SIZE --nr 1:1)"
|
||||
- ibs="$(($size / $sectors))"
|
||||
+ if [ -f "/sys/block/${disk##*/}/queue/physical_block_size" ]; then
|
||||
+ ibs="$(cat "/sys/block/${disk##*/}/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
|
||||
@@ -86,7 +108,7 @@ platform_do_upgrade() {
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
#compare tables
|
||||
- diff="$(grep -F -x -v -f /tmp/partx.bootdisk /tmp/partx.image)"
|
||||
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
|
||||
if [ -n "$diff" ]; then
|
||||
echo "Partition layout is changed. Full image will be written."
|
||||
ask_bool 0 "Abort" && exit
|
||||
@@ -99,7 +121,7 @@ platform_do_upgrade() {
|
||||
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
|
||||
- done < /tmp/partx.image
|
||||
+ done < /tmp/partmap.image
|
||||
|
||||
#copy partition uuid
|
||||
echo "Writing new UUID to $disk$part..."
|
@ -0,0 +1,22 @@
|
||||
From: Jo-Philipp Wich <jo@mein.io>
|
||||
Date: Wed, 30 Mar 2016 03:19:23 +0200
|
||||
Subject: x86: search PARTUUID in any block device
|
||||
|
||||
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
Backport of LEDE 924fb794bde41eca8289c6cf10322bf6683b4a80
|
||||
|
||||
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
index f12deebf6484df6f3f69e453ad67688a76d57972..29eac77dfb0ae52f241696f3f62dce7d16106b20 100644
|
||||
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
|
||||
@@ -17,7 +17,8 @@ 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/[hsv]d[a-z] /dev/xvd[a-z]; do
|
||||
+ for disk in /dev/*; do
|
||||
+ [ -b "$disk" ] || continue
|
||||
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"
|
@ -0,0 +1,182 @@
|
||||
From: Jo-Philipp Wich <jo@mein.io>
|
||||
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 <russell@personaltelco.net>
|
||||
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
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() { # <command> [...]
|
||||
/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() { # <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
|
Loading…
Reference in New Issue
Block a user