x86: fix grub-bios-setup fail during 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=63 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 parttype=ext4
41
42         if export_partdevice partdev 1; then
43                 part_magic_fat "/dev/$partdev" && parttype=vfat
44                 mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
45                 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
46                 umount /mnt
47         fi
48 }
49
50 platform_do_bootloader_upgrade() {
51         local bootpart parttable=msdos
52         local diskdev="$1"
53
54         if export_partdevice bootpart 1; then
55                 mkdir -p /tmp/boot
56                 mount -o rw,noatime "/dev/$bootpart" /tmp/boot
57                 echo "(hd0) /dev/$diskdev" > /tmp/device.map
58                 part_magic_efi "/dev/$diskdev" && parttable=gpt
59
60                 echo "Upgrading bootloader on /dev/$diskdev..."
61                 grub-bios-setup \
62                         -m "/tmp/device.map" \
63                         -d "/tmp/boot/boot/grub" \
64                         -r "hd0,${parttable}1" \
65                         "/dev/$diskdev" \
66                 && touch /tmp/boot/grub/upgraded
67
68                 umount /tmp/boot
69         fi
70 }
71
72 platform_do_upgrade() {
73         local diskdev partdev diff
74
75         export_bootdevice && export_partdevice diskdev 0 || {
76                 echo "Unable to determine upgrade device"
77                 return 1
78         }
79
80         sync
81
82         if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
83                 get_partitions "/dev/$diskdev" bootdisk
84
85                 #extract the boot sector from the image
86                 get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b >/dev/null
87
88                 get_partitions /tmp/image.bs image
89
90                 #compare tables
91                 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
92         else
93                 diff=1
94         fi
95
96         if [ -n "$diff" ]; then
97                 get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
98
99                 # Separate removal and addtion is necessary; otherwise, partition 1
100                 # will be missing if it overlaps with the old partition 2
101                 partx -d - "/dev/$diskdev"
102                 partx -a - "/dev/$diskdev"
103
104                 return 0
105         fi
106
107         #iterate over each partition from the image and write it to the boot disk
108         while read part start size; do
109                 if export_partdevice partdev $part; then
110                         echo "Writing image to /dev/$partdev..."
111                         get_image "$@" | dd of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync
112                 else
113                         echo "Unable to find partition $part device, skipped."
114                 fi
115         done < /tmp/partmap.image
116
117         #copy partition uuid
118         echo "Writing new UUID to /dev/$diskdev..."
119         get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
120
121         platform_do_bootloader_upgrade "$diskdev"
122         local parttype=ext4
123         part_magic_efi "/dev/$diskdev" || return 0
124
125         if export_partdevice partdev 1; then
126                 part_magic_fat "/dev/$partdev" && parttype=vfat
127                 mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
128                 set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
129                 sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg
130                 umount /mnt
131         fi
132
133 }