platform.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. REQUIRE_IMAGE_METADATA=1
  2. UBOOT_ENV_PART=3
  3. BOOT_PART=4
  4. ROOTFS_PART=5
  5. RAMFS_COPY_BIN='blockdev'
  6. export_bootdevice() {
  7. local cmdline uuid blockdev uevent line class
  8. local MAJOR MINOR DEVNAME DEVTYPE
  9. local rootpart="$(cmdline_get_var root)"
  10. case "$rootpart" in
  11. PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \
  12. PARTUUID=????????-????-????-????-??????????05)
  13. uuid="${rootpart#PARTUUID=}"
  14. uuid="${uuid%/PARTNROFF=1}"
  15. uuid="${uuid%0?}00"
  16. for disk in $(find /dev -type b); do
  17. 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"')
  18. if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
  19. uevent="/sys/class/block/${disk##*/}/uevent"
  20. break
  21. fi
  22. done
  23. ;;
  24. esac
  25. if [ -e "$uevent" ]; then
  26. while read line; do
  27. export -n "$line"
  28. done < "$uevent"
  29. export BOOTDEV_MAJOR=$MAJOR
  30. export BOOTDEV_MINOR=$MINOR
  31. return 0
  32. fi
  33. return 1
  34. }
  35. platform_check_image() {
  36. local diskdev partdev diff
  37. [ "$#" -gt 1 ] && return 1
  38. export_bootdevice && export_partdevice diskdev 0 || {
  39. v "platform_check_image: Unable to determine upgrade device"
  40. return 1
  41. }
  42. get_partitions "/dev/$diskdev" bootdisk
  43. v "Extract the boot sector from the image"
  44. get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
  45. get_partitions /tmp/image.bs image
  46. #compare tables
  47. diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
  48. rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
  49. if [ -n "$diff" ]; then
  50. echo "Partition layout has changed. Full image will be written."
  51. ask_bool 0 "Abort" && exit 1
  52. return 0
  53. fi
  54. }
  55. platform_do_upgrade() {
  56. local diskdev partdev diff partlabel
  57. export_bootdevice && export_partdevice diskdev 0 || {
  58. v "platform_do_upgrade: Unable to determine upgrade device"
  59. return 1
  60. }
  61. sync
  62. if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
  63. get_partitions "/dev/$diskdev" bootdisk
  64. v "Extract boot sector from the image"
  65. get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
  66. get_partitions /tmp/image.bs image
  67. #compare tables
  68. diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
  69. else
  70. diff=1
  71. fi
  72. if [ -n "$diff" ]; then
  73. rm -rf /tmp/ubootenv
  74. if export_partdevice partdev $UBOOT_ENV_PART; then
  75. v "Saving u-boot env (/dev/$partdev) before to write image"
  76. get_image_dd "/dev/$partdev" of=/tmp/ubootenv
  77. fi
  78. v "Writing image to /dev/$diskdev..."
  79. get_image_dd "$1" of="/dev/$diskdev" conv=fsync
  80. blockdev --rereadpt "/dev/$diskdev"
  81. [ -f /tmp/ubootenv ] && {
  82. # iterate over each partition from the image to find the
  83. # u-boot-env partition and restore u-boot env.
  84. while read part start size; do
  85. if export_partdevice partdev $part; then
  86. while read line; do
  87. eval "local l$line"
  88. done < "/sys/class/block/$partdev/uevent"
  89. [ "$lPARTNAME" = "u-boot-env" ] || continue
  90. v "Writting u-boot env to /dev/$partdev"
  91. get_image_dd /tmp/ubootenv of="/dev/$partdev" conv=fsync
  92. return 0
  93. fi
  94. done < /tmp/partmap.image
  95. }
  96. return 0
  97. fi
  98. #iterate over each partition from the image and write it to the boot disk
  99. while read part start size; do
  100. if export_partdevice partdev $part; then
  101. # do not erase u-boot env
  102. [ "$part" = "$UBOOT_ENV_PART" ] && continue
  103. v "Writing image to /dev/$partdev..."
  104. v "Normal partition, doing DD"
  105. get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
  106. count="$size" conv=fsync
  107. else
  108. v "Unable to find partition $part device, skipped."
  109. fi
  110. done < /tmp/partmap.image
  111. if export_partdevice partdev "$BOOT_PART"; then
  112. mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
  113. local partuuid="$(cmdline_get_var root)"
  114. v "Setting rootfs ${partuuid}"
  115. sed -i "s/PARTUUID=[a-f0-9-]\+/${partuuid}/ig" \
  116. /mnt/extlinux/extlinux.conf
  117. umount /mnt
  118. fi
  119. }
  120. platform_copy_config() {
  121. local partdev
  122. # Iterate over each partition from the image to find the boot partition
  123. # and copy the config tarball.
  124. # The partlabel is used to find the partition.
  125. # An hardcoded partition number cannot be used, as it could be wrong if
  126. # the partition table changed, and the full image was written.
  127. while read part start size; do
  128. # config is copied in the boot partition, as for squashfs image, the
  129. # rootfs partition is not writable.
  130. if export_partdevice partdev "$part"; then
  131. while read line; do
  132. eval "local l$line"
  133. done < "/sys/class/block/$partdev/uevent"
  134. [ "$lPARTNAME" = "boot" ] || continue
  135. mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
  136. cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
  137. umount /mnt
  138. return 0
  139. else
  140. v "ERROR: Unable to find partition to copy config data to"
  141. fi
  142. done < /tmp/partmap.image
  143. }