| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- REQUIRE_IMAGE_METADATA=1
- UBOOT_ENV_PART=3
- BOOT_PART=4
- ROOTFS_PART=5
- RAMFS_COPY_BIN='blockdev'
- export_bootdevice() {
- local cmdline uuid blockdev uevent line class
- local MAJOR MINOR DEVNAME DEVTYPE
- local rootpart="$(cmdline_get_var root)"
- case "$rootpart" in
- PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \
- PARTUUID=????????-????-????-????-??????????05)
- uuid="${rootpart#PARTUUID=}"
- uuid="${uuid%/PARTNROFF=1}"
- uuid="${uuid%0?}00"
- for disk in $(find /dev -type b); do
- set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
- if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
- uevent="/sys/class/block/${disk##*/}/uevent"
- break
- fi
- done
- ;;
- esac
- if [ -e "$uevent" ]; then
- while read line; do
- export -n "$line"
- done < "$uevent"
- export BOOTDEV_MAJOR=$MAJOR
- export BOOTDEV_MINOR=$MINOR
- return 0
- fi
- return 1
- }
- platform_check_image() {
- local diskdev partdev diff
- [ "$#" -gt 1 ] && return 1
- export_bootdevice && export_partdevice diskdev 0 || {
- v "platform_check_image: Unable to determine upgrade device"
- return 1
- }
- get_partitions "/dev/$diskdev" bootdisk
- v "Extract the boot sector from the image"
- get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
- get_partitions /tmp/image.bs image
- #compare tables
- diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
- rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
- if [ -n "$diff" ]; then
- echo "Partition layout has changed. Full image will be written."
- ask_bool 0 "Abort" && exit 1
- return 0
- fi
- }
- platform_do_upgrade() {
- local diskdev partdev diff partlabel
- export_bootdevice && export_partdevice diskdev 0 || {
- v "platform_do_upgrade: Unable to determine upgrade device"
- return 1
- }
- sync
- if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
- get_partitions "/dev/$diskdev" bootdisk
- v "Extract boot sector from the image"
- get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
- get_partitions /tmp/image.bs image
- #compare tables
- diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
- else
- diff=1
- fi
- if [ -n "$diff" ]; then
- rm -rf /tmp/ubootenv
- if export_partdevice partdev $UBOOT_ENV_PART; then
- v "Saving u-boot env (/dev/$partdev) before to write image"
- get_image_dd "/dev/$partdev" of=/tmp/ubootenv
- fi
- v "Writing image to /dev/$diskdev..."
- get_image_dd "$1" of="/dev/$diskdev" conv=fsync
- blockdev --rereadpt "/dev/$diskdev"
- [ -f /tmp/ubootenv ] && {
- # iterate over each partition from the image to find the
- # u-boot-env partition and restore u-boot env.
- while read part start size; do
- if export_partdevice partdev $part; then
- while read line; do
- eval "local l$line"
- done < "/sys/class/block/$partdev/uevent"
- [ "$lPARTNAME" = "u-boot-env" ] || continue
- v "Writting u-boot env to /dev/$partdev"
- get_image_dd /tmp/ubootenv of="/dev/$partdev" conv=fsync
- return 0
- fi
- done < /tmp/partmap.image
- }
- return 0
- fi
- #iterate over each partition from the image and write it to the boot disk
- while read part start size; do
- if export_partdevice partdev $part; then
- # do not erase u-boot env
- [ "$part" = "$UBOOT_ENV_PART" ] && continue
- v "Writing image to /dev/$partdev..."
- v "Normal partition, doing DD"
- get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
- count="$size" conv=fsync
- else
- v "Unable to find partition $part device, skipped."
- fi
- done < /tmp/partmap.image
- if export_partdevice partdev "$BOOT_PART"; then
- mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
- local partuuid="$(cmdline_get_var root)"
- v "Setting rootfs ${partuuid}"
- sed -i "s/PARTUUID=[a-f0-9-]\+/${partuuid}/ig" \
- /mnt/extlinux/extlinux.conf
- umount /mnt
- fi
- }
- platform_copy_config() {
- local partdev
- # Iterate over each partition from the image to find the boot partition
- # and copy the config tarball.
- # The partlabel is used to find the partition.
- # An hardcoded partition number cannot be used, as it could be wrong if
- # the partition table changed, and the full image was written.
- while read part start size; do
- # config is copied in the boot partition, as for squashfs image, the
- # rootfs partition is not writable.
- if export_partdevice partdev "$part"; then
- while read line; do
- eval "local l$line"
- done < "/sys/class/block/$partdev/uevent"
- [ "$lPARTNAME" = "boot" ] || continue
- mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
- cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
- umount /mnt
- return 0
- else
- v "ERROR: Unable to find partition to copy config data to"
- fi
- done < /tmp/partmap.image
- }
|