@@ -3,30 +3,35 @@ set -euo pipefail
3
3
4
4
# https://issues.redhat.com/browse/OCPBUGS-54594
5
5
6
- # This script updates the bootloader using bootupd
7
- # and also detects RAID-1 setups as those requires
8
- # extra steps.
9
- if [ -e /dev/disk/by-label/EFI-SYSTEM ]; then
10
- echo " Found ESP; calling 'bootupctl update'"
11
- bootupctl update
12
- exit
13
- fi
6
+ # This script updates the bootloader using bootupd when it's safe
7
+ # and manually otherwise. Right now bootupd doesn't support RAID-1
8
+ # setups and also not sure of the behavior if there are multiple
9
+ # EFI-SYSTEM labeled filesystems attached.
10
+
11
+ # Function that actually does the manual copy
12
+ copy_to_esp_device () {
13
+ local device=$1
14
+ mount $device /boot/efi
15
+ echo " [Before Update: ${device} ]"
16
+ find /boot/efi/ -type f | xargs md5sum
17
+ cp -rp /usr/lib/bootupd/updates/EFI /boot/efi
18
+ echo " [After Update: ${device} ]"
19
+ find /boot/efi/ -type f | xargs md5sum
20
+ umount /boot/efi
21
+ }
14
22
15
23
# Handle RAID case manually since bootupd doesn't support it.
16
24
# https://github.com/coreos/bootupd/issues/132
17
- #
18
- # First we'll find the RAID device the root filesystem is
19
- # mounted from (i.e. /dev/md127).
20
- root_raid_device=$( findmnt --json --target /sysroot \
21
- | jq -r .filesystems[0].source)
22
- echo " Detected root raid device is: $root_raid_device "
23
- # Next we'll find all the devices that are a part of that
24
- # RAID array that have an ESP (i.e. a vfat formatted partition
25
- # with a label that starts with "esp-", like "esp-1", "esp-2").
26
- # and we'll capture the device name for the partition.
27
- esp_partitions=$(
28
- lsblk --paths --fs -J | \
29
- jq --arg raid_device " ${root_raid_device} " -r '
25
+ update_raid_esp () {
26
+ local boot_raid_device=$1
27
+ local devices_json=" ${2} "
28
+ echo " Detected boot raid device is: $boot_raid_device "
29
+ # Next we'll find all the devices that are a part of that
30
+ # RAID array that have an ESP (i.e. a vfat formatted partition
31
+ # with a label that starts with "esp-", like "esp-1", "esp-2").
32
+ # and we'll capture the device name for the partition.
33
+ esp_partitions=$(
34
+ jq --arg raid_device " ${boot_raid_device} " -r '
30
35
.blockdevices[]
31
36
| select(.children[]?.children[]?.name == $raid_device)
32
37
| .children[]
@@ -35,15 +40,69 @@ esp_partitions=$(
35
40
(.label != null) and
36
41
(.label | startswith("esp"))
37
42
)
43
+ | .name' <<< " ${devices_json}" )
44
+ for part in $esp_partitions ; do
45
+ echo " Found ESP replica in ${part} ; updating"
46
+ copy_to_esp_device $part
47
+ done
48
+ }
49
+
50
+ main () {
51
+ # Grab the info about the systems disks from `lsblk`.
52
+ block_devices_json=$( lsblk --paths --fs --json)
53
+
54
+ # Find the device the boot filesystem is mounted from
55
+ # (i.e. /dev/md126 or /dev/sda3).
56
+ boot_fs_device=$( findmnt --json --target /boot | jq -r .filesystems[0].source)
57
+
58
+ # Grab the JSON for the boot partition (i.e. /dev/sda3). This partition
59
+ # could hold the filesystem directly or it could be a linux_raid_member
60
+ # in which case the $boot_fs_device will be in the "children" of this
61
+ # device. Choose .[0] here since we only need to look at the first device
62
+ # (only RAID will have more than 1 anyway).
63
+ boot_fs_partition_json=$(
64
+ jq --arg boot_fs_device " ${boot_fs_device} " -r '
65
+ [
66
+ .blockdevices[].children[]
67
+ | select(
68
+ .name == $boot_fs_device or
69
+ .children[]?.name == $boot_fs_device
70
+ )
71
+ ] | .[0]' <<< " ${block_devices_json}" )
72
+
73
+ # Grab the partition fstype (useful to determine if it's RAID)
74
+ boot_fs_partition_fstype=$( jq -r ' .fstype' <<< " ${boot_fs_partition_json}" )
75
+
76
+ # Determine how many devices are attached with filesystems
77
+ # with the "EFI-SYSTEM" label.
78
+ num_efi_system_devices=$(
79
+ jq -r '
80
+ [
81
+ .blockdevices[]
82
+ | select(.children[]?.label == "EFI-SYSTEM")
83
+ ] | length' <<< " ${block_devices_json}" )
84
+
85
+ # Now do the updates based on what situation we are in.
86
+ if [ " ${boot_fs_partition_fstype} " == ' linux_raid_member' ]; then
87
+ # If it's RAID we'll update manually.
88
+ update_raid_esp $boot_fs_device " ${block_devices_json} "
89
+ elif [ " ${num_efi_system_devices} " -gt 1 ]; then
90
+ echo " Detected more than one ESP device in a non-RAID setup"
91
+ echo " Falling back to manual copy"
92
+ # If there is more than one device with the EFI-SYSTEM label
93
+ # then we'll need to manually do this to make sure we copy
94
+ # to the right one.
95
+ esp_device=$(
96
+ jq --arg boot_fs_device " $boot_fs_device " -r '
97
+ .blockdevices[]
98
+ | select(.children[]?.name == $boot_fs_device)
99
+ | .children[]
100
+ | select(.label == "EFI-SYSTEM")
38
101
| .name' )
39
- for part in $esp_partitions ; do
40
- echo " Found ESP replica in ${part} ; updating"
41
- mount $part /boot/efi
42
- echo " [Before Update: ${part} ]"
43
- find /boot/efi/ -type f | xargs md5sum
44
- cp -rp /usr/lib/bootupd/updates/EFI /boot/efi
45
- echo " [After Update: ${part} ]"
46
- find /boot/efi/ -type f | xargs md5sum
47
- umount /boot/efi
48
- done
49
- sync
102
+ copy_to_esp_device $esp_device
103
+ else
104
+ echo " Found ESP; calling 'bootupctl update'"
105
+ bootupctl update
106
+ fi
107
+ sync # write data out to backing devices
108
+ }
0 commit comments