11#! /bin/bash
22#
3- # Copyright 2019 Delphix
3+ # Copyright 2019, 2025 Delphix
44#
55# Licensed under the Apache License, Version 2.0 (the "License");
66# you may not use this file except in compliance with the License.
@@ -83,15 +83,19 @@ function get_bootloader_devices() {
8383 # devices. We determine this by listing the devices used by the
8484 # rpool. Additionally, we have to filter out devices that could
8585 # be attached to the rpool, but would never be used for the
86- # bootloader. Finally, we need to strip off any parition
86+ # bootloader. Finally, we need to strip off any partition
8787 # information, since we want to install the bootloader directly
8888 # to the device, rather than to a partition of the device.
8989 #
9090 zpool list -vH rpool |
9191 awk ' ! /rpool|mirror|replacing|spare/ {print $1}' |
9292 while read -r part; do
93+ # Skip if device doesn't exist or is not a block device
94+ [[ -e " /dev/$dev " ]] || continue
95+ [[ -b " /dev/$dev " ]] || continue
96+
9397 #
94- # If the rpool is not installed a parition , we throw
98+ # If the rpool is not installed a partition , we throw
9599 # an error. We expect this to never happen, and the
96100 # calling code is likely untested in that case, so we
97101 # throw an error rather than try to handle it.
@@ -102,6 +106,44 @@ function get_bootloader_devices() {
102106 done
103107}
104108
109+ function mount_efi() {
110+ #
111+ # Find and mount the device and partition with EFI UUID
112+ #
113+ for dev in $( get_bootloader_devices) ; do
114+ for part in $( lsblk -ln -o NAME,FSTYPE,PARTTYPE " /dev/$dev " | grep vfat | awk ' {print $1}' ) ; do
115+ part_path=" /dev/$part "
116+ part_type=$( blkid -s PARTTYPE -o value " $part_path " )
117+ if [[ " $part_type " == $EFI_PARTITION_UUID ]]; then
118+ mount $part_path $EFI_DIR
119+ return
120+ fi
121+ done
122+ done
123+ }
124+
125+ function update_systemd_boot_entries() {
126+ cp " ${EFI_DIR} /loader/entries/delphix.conf" " ${EFI_DIR} /loader/entries/delphix.conf.bak"
127+ cp " ${EFI_DIR} /loader/entries/delphix-single.conf" " ${EFI_DIR} /loader/entries/delphix-single.conf.bak"
128+
129+ # Update default and single user entries
130+ source /etc/default/grub.d/override.cfg
131+ cat << -EOF >"${EFI_DIR} /loader/entries/delphix.conf"
132+ title Delphix Engine
133+ linux /vmlinuz
134+ initrd /initrd.img
135+ options root=ZFS=rpool/ROOT/${CONTAINER} /root ro $GRUB_CMDLINE_LINUX_DEFAULT
136+ EOF
137+
138+ # Single user entry
139+ cat << -EOF >"${EFI_DIR} /loader/entries/delphix-single.conf"
140+ title Delphix Engine Single User mode
141+ linux /vmlinuz
142+ initrd /initrd.img
143+ options root=ZFS=rpool/ROOT/${CONTAINER} /root ro single nomodeset dis_ucode_ldr
144+ EOF
145+ }
146+
105147function set_bootfs_not_mounted_cleanup() {
106148 umount " /var/lib/machines/$CONTAINER /mnt" ||
107149 warn " 'umount' of '/var/lib/machines/$CONTAINER /mnt' failed"
@@ -147,30 +189,33 @@ function set_bootfs_not_mounted() {
147189
148190 PLATFORM=$( get-appliance-platform)
149191
150- for dev in $( get_bootloader_devices) ; do
151- [[ -e " /dev/$dev " ]] ||
152- die " bootloader device '/dev/$dev ' not found"
153-
154- [[ -b " /dev/$dev " ]] ||
155- die " bootloader device '/dev/$dev ' not block device"
156-
157- opts=" --root-directory=/mnt"
158-
159- if [[ " $PLATFORM " == " esx" ]] || [[ " $PLATFORM " == " oci" ]]; then
160- opts+=" --debug-image=all"
161- opts+=" -v"
162- fi
192+ # If using EFI firmware, update boot entries, vmlinuz, initrd, and bootloader
193+ if is_bootmode_uefi; then
194+ mount_efi ()
195+ update_systemd_boot_entries
196+ cp " /var/lib/machines/${CONTAINER} /boot/initrd.img" " $EFI_DIR "
197+ cp " /var/lib/machines/${CONTAINER} /boot/vmlinuz" " $EFI_DIR "
198+ chroot " /var/lib/machines/$CONTAINER " bootctl update
199+ umount $EFI_DIR
200+ else
201+ for dev in $( get_bootloader_devices) ; do
202+ opts=" --root-directory=/mnt"
203+
204+ if [[ " $PLATFORM " == " esx" ]] || [[ " $PLATFORM " == " oci" ]]; then
205+ opts+=" --debug-image=all"
206+ opts+=" -v"
207+ fi
208+
209+ # shellcheck disable=SC2086
210+ chroot " /var/lib/machines/$CONTAINER " \
211+ grub-install $opts " /dev/$dev " ||
212+ die " 'grub-install' for '$dev ' failed in '$CONTAINER '"
213+ done
163214
164- # shellcheck disable=SC2086
165215 chroot " /var/lib/machines/$CONTAINER " \
166- grub-install $opts " /dev/$dev " ||
167- die " 'grub-install' for '$dev ' failed in '$CONTAINER '"
168- done
169-
170- chroot " /var/lib/machines/$CONTAINER " \
171- grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
172- die " 'grub-mkconfig' failed in '$CONTAINER '"
173-
216+ grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
217+ die " 'grub-mkconfig' failed in '$CONTAINER '"
218+ fi
174219 set_bootfs_not_mounted_cleanup
175220 trap - EXIT
176221
@@ -211,28 +256,31 @@ function set_bootfs_mounted() {
211256
212257 PLATFORM=$( get-appliance-platform)
213258
214- for dev in $( get_bootloader_devices ) ; do
215- [[ -e " /dev/ $dev " ]] ||
216- die " bootloader device '/dev/ $dev ' not found "
217-
218- [[ -b " /dev/ $dev " ]] ||
219- die " bootloader device '/dev/ $dev ' not block device "
220-
221- opts= " --root-directory=/mnt "
222-
223- if [[ " $PLATFORM " == " esx " ]] || [[ " $PLATFORM " == " oci " ]] ; then
224- opts+= " --debug-image=all "
225- opts+= " -v "
226- fi
227-
228- # shellcheck disable=SC2086
229- grub-install $opts " /dev/ $dev " ||
230- die " 'grub-install' for ' $dev ' failed in ' $CONTAINER ' "
231- done
232-
233- grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
234- die " 'grub-mkconfig' failed in ' $CONTAINER ' "
259+ # If using EFI firmware, update boot entries, vmlinuz, initrd, and bootloader
260+ if is_bootmode_uefi ; then
261+ mount_efi ()
262+ update_systemd_boot_entries
263+ cp /boot/initrd.img " $EFI_DIR "
264+ cp /boot/vmlinuz " $EFI_DIR "
265+ bootctl update
266+ umount $EFI_DIR
267+ else
268+ for dev in $( get_bootloader_devices ) ; do
269+ opts= " --root-directory=/mnt "
270+
271+ if [[ " $PLATFORM " == " esx " ]] || [[ " $PLATFORM " == " oci " ]] ; then
272+ opts+= " --debug-image=all "
273+ opts+= " -v "
274+ fi
275+
276+ # shellcheck disable=SC2086
277+ grub-install $opts " /dev/ $dev " ||
278+ die " ' grub-install' for ' $dev ' failed in ' $CONTAINER ' "
279+ done
235280
281+ grub-mkconfig -o /mnt/boot/grub/grub.cfg ||
282+ die " 'grub-mkconfig' failed in '$CONTAINER '"
283+ fi
236284 set_bootfs_mounted_cleanup
237285 trap - EXIT
238286}
@@ -367,7 +415,7 @@ set-bootfs)
367415 # We only have a single bootloader on any given appliance, so we
368416 # need to ensure that only a single process is attempting to
369417 # update the bootloader at any given time. The locking done here
370- # is to help prevent accidential corruption of the bootloader,
418+ # is to help prevent accidental corruption of the bootloader,
371419 # by ensuring only a single invocation of this script can set
372420 # the boot filesystem at any given time.
373421 #
0 commit comments