x86: add bootloader upgrade on sysupgrade
[oweals/openwrt.git] / target / linux / x86 / base-files / lib / upgrade / platform.sh
1 RAMFS_COPY_BIN='grub-bios-setup'
2
3 platform_check_image() {
4         local diskdev partdev diff
5         [ "$#" -gt 1 ] && return 1
6
7         case "$(get_magic_word "$1")" in
8                 eb48|eb63) ;;
9                 *)
10                         echo "Invalid image type"
11                         return 1
12                 ;;
13         esac
14
15         export_bootdevice && export_partdevice diskdev 0 || {
16                 echo "Unable to determine upgrade device"
17                 return 1
18         }
19
20         get_partitions "/dev/$diskdev" bootdisk
21
22         #extract the boot sector from the image
23         get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
24
25         get_partitions /tmp/image.bs image
26
27         #compare tables
28         diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
29
30         rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
31
32         if [ -n "$diff" ]; then
33                 echo "Partition layout has changed. Full image will be written."
34                 ask_bool 0 "Abort" && exit 1
35                 return 0
36         fi
37 }
38
39 platform_copy_config() {
40         local partdev
41
42         if export_partdevice partdev 1; then
43                 mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
44                 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
45                 umount /mnt
46         fi
47 }
48
49 platform_do_bootloader_upgrade() {
50         local bootpart
51         local diskdev="$1"
52
53         if export_partdevice bootpart 1; then
54                 mkdir -p /tmp/boot
55                 mount -o rw,noatime "/dev/$bootpart" /tmp/boot
56                 echo "(hd0) /dev/$diskdev" > /tmp/device.map
57
58                 echo "Upgrading bootloader on /dev/$diskdev..."
59                 grub-bios-setup \
60                         -m "/tmp/device.map" \
61                         -d "/tmp/boot/boot/grub" \
62                         -r "hd0,msdos1" \
63                         "/dev/$diskdev"
64
65                 umount /tmp/boot
66         fi
67 }
68
69 platform_do_upgrade() {
70         local diskdev partdev diff
71
72         export_bootdevice && export_partdevice diskdev 0 || {
73                 echo "Unable to determine upgrade device"
74                 return 1
75         }
76
77         sync
78
79         if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
80                 get_partitions "/dev/$diskdev" bootdisk
81
82                 #extract the boot sector from the image
83                 get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
84
85                 get_partitions /tmp/image.bs image
86
87                 #compare tables
88                 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
89         else
90                 diff=1
91         fi
92
93         if [ -n "$diff" ]; then
94                 get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
95
96                 # Separate removal and addtion is necessary; otherwise, partition 1
97                 # will be missing if it overlaps with the old partition 2
98                 partx -d - "/dev/$diskdev"
99                 partx -a - "/dev/$diskdev"
100
101                 return 0
102         fi
103
104         #iterate over each partition from the image and write it to the boot disk
105         while read part start size; do
106                 if export_partdevice partdev $part; then
107                         echo "Writing image to /dev/$partdev..."
108                         get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
109                 else
110                         echo "Unable to find partition $part device, skipped."
111                 fi
112         done < /tmp/partmap.image
113
114         #copy partition uuid
115         echo "Writing new UUID to /dev/$diskdev..."
116         get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
117
118         platform_do_bootloader_upgrade "$diskdev"
119 }