5 .
/usr
/share
/pve-kernel-helper
/scripts
/functions
7 _add_entry_to_list_file
() {
11 if [ -e "$file" ]; then
12 cp "$file" "$file.new"
14 echo "$entry" >> "$file.new"
15 sort -uo "$file.new" "$file.new"
16 mv "$file.new" "$file"
19 _remove_entry_from_list_file
() {
23 # guard against removing whole file by accident!
24 if [ -z "$entry" ]; then
25 echo "cannot remove empty entry from '$file'."
29 if [ -e "$file" ]; then
30 grep -vFx "$entry" "$file" > "$file.new" || true
31 mv "$file.new" "$file"
33 echo "'$file' does not exist.."
37 _get_partition_info
() {
38 if [ ! -e "$1" ]; then
39 warn
"E: '$1' does not exist!"
43 if [ ! -b "$bdev" ]; then
44 warn
"E: '$bdev' is not a block device!"
52 -o 'UUID,SIZE,FSTYPE,PARTTYPE,PKNAME,MOUNTPOINT' \
55 if [ -z "$bdev_info" ]; then
56 warn
"E: unable to get information about block device '$1'!"
60 count
=$
(echo "$bdev_info" |
grep -c '^')
61 if [ "$count" -ne '1' ]; then
63 warn
"E: block device '$1' has children!"
70 if [ -z "$PKNAME" ]; then
71 warn
"E: cannot determine parent device of '$1' - please provide a partition, not a full disk."
75 if [ -n "$SIZE" ] && [ "$SIZE" -lt 268435456 ]; then
76 warn
"E: '$1' is too small (<256M)."
80 if [ -n "$MOUNTPOINT" ]; then
81 warn
"E: '$1' is mounted on '$MOUNTPOINT' - exiting."
90 _get_partition_info
"$part"
92 if [ -n "$FSTYPE" ]; then
93 if [ -z "$force" ] ||
[ "$force" != '--force' ]; then
94 warn
"E: '$part' contains a filesystem ('$FSTYPE') - exiting (use --force to override)"
99 part_basename
=$
(basename "$bdev")
100 if [ -z "$part_basename" ]; then
101 if [ $part != $bdev ]; then
102 symlinkmsg
=" -> '$bdev'"
104 warn
"E: unable to determine basename of '$part'$symlinkmsg"
108 part_num
=$
(cat /sys
/block
/"$PKNAME"/"$part_basename"/partition
)
109 if [ -z "$part_num" ]; then
110 warn
"E: unable to determine partition number of '$part'"
114 if [ -z "$PARTTYPE" ] ||
[ "$PARTTYPE" != "$ESPTYPE" ]; then
115 echo "Setting partition type of '$part' to '$ESPTYPE'.."
116 sgdisk
"-t$part_num:$ESPTYPE" "/dev/$PKNAME"
117 echo "Calling 'udevadm settle'.."
118 udevadm settle
--timeout=5
121 echo "Formatting '$part' as vfat.."
122 mkfs.vfat
-F 32 "$part"
130 _get_partition_info
"$part"
132 if [ -z "$PARTTYPE" ] ||
[ "$PARTTYPE" != "$ESPTYPE" ]; then
133 warn
"E: '$part' has wrong partition type (!= $ESPTYPE)."
137 if [ -z "$FSTYPE" ] ||
[ "$FSTYPE" != 'vfat' ]; then
138 warn
"E: '$part' has wrong filesystem (!= vfat)."
142 if [ -z "$UUID" ]; then
143 warn
"E: '$part' has no UUID set, required for mounting."
147 esp_mp
="/var/tmp/espmounts/$UUID"
150 echo "Mounting '$part' on '$esp_mp'."
151 mount
-t vfat
"$part" "$esp_mp"
153 if [ -d /sys
/firmware
/efi
]; then
154 echo "Installing systemd-boot.."
155 mkdir
-p "$esp_mp/$PMX_ESP_DIR"
156 bootctl
--path "$esp_mp" install
158 echo "Configuring systemd-boot.."
159 echo "timeout 3" > "$esp_mp/$PMX_LOADER_CONF.tmp"
160 echo "default proxmox-*" >> "$esp_mp/$PMX_LOADER_CONF.tmp"
161 mv "$esp_mp/$PMX_LOADER_CONF.tmp" "$esp_mp/$PMX_LOADER_CONF"
163 echo "Installing grub i386-pc target.."
165 --boot-directory $esp_mp \
168 --bootloader-id='proxmox' \
171 echo "Unmounting '$part'."
174 echo "Adding '$part' to list of synced ESPs.."
175 _add_entry_to_list_file
"$ESP_LIST" "$UUID"
177 echo "Refreshing kernels and initrds.."
182 if [ ! -e "/dev/disk/by-uuid/" ]; then
183 warn
'E: /dev/disk/by-uuid does not exist, aborting!'
186 echo -n "Checking whether ESP '$curr_uuid' exists.. "
187 if [ -e "/dev/disk/by-uuid/$curr_uuid" ]; then
191 if [ -z "$dry_run" ] ||
[ "$dry_run" != '--dry-run' ]; then
192 _remove_entry_from_list_file
"$ESP_LIST" "$curr_uuid"
199 rm -f "$ESP_LIST".tmp
200 loop_esp_list _clean_impl
201 if [ "$?" -eq 2 ]; then
202 warn
"E: $ESP_LIST does not exist."
205 if [ -e "$ESP_LIST".tmp
]; then
206 mv "$ESP_LIST".tmp
"$ESP_LIST"
209 echo "Sorting and removing duplicate ESPs.."
210 sort -uo "$ESP_LIST".tmp
"$ESP_LIST"
211 mv "$ESP_LIST".tmp
"$ESP_LIST"
216 hookscripts
='proxmox-auto-removal zz-proxmox-boot'
218 if [ -n "$hook" ]; then
219 if echo "$hookscripts" |
grep -sqE "(^|[[:space:]]+)$hook([[:space:]]+|$)"; then
222 warn
"E: '$hook' is not a valid hook script name.";
227 for script in $hookscripts; do
228 scriptpath
="/etc/kernel/postinst.d/$script"
229 if [ -f "$scriptpath" ] && [ -x "$scriptpath" ]; then
230 echo "Running hook script '$script'.."
233 warn
"Hook script '$script' not found or not executable, skipping."
241 if [ -z "$ver" ]; then
242 warn
"E: <kernel-version> is mandatory"
247 if [ ! -e "/boot/vmlinuz-$ver" ]; then
248 warn
"E: no kernel image found in /boot for '$ver', not adding."
251 _add_entry_to_list_file
"$MANUAL_KERNEL_LIST" "$ver"
252 echo "Added kernel '$ver' to manual kernel list. Use the 'refresh' command to update the ESPs."
258 if [ -z "$ver" ]; then
259 warn
"E: <kernel-version> is mandatory"
264 if grep -sqFx "$ver" "$MANUAL_KERNEL_LIST"; then
265 _remove_entry_from_list_file
"$MANUAL_KERNEL_LIST" "$ver"
266 echo "Removed kernel '$ver' from manual kernel list. Use the 'refresh' command to update the ESPs."
268 echo "Kernel '$ver' not found in manual kernel list."
273 boot_kernels
="$(boot_kernel_list)"
275 if [ -e "$MANUAL_KERNEL_LIST" ]; then
276 manual_kernels
="$(cat "$MANUAL_KERNEL_LIST" || true)"
277 boot_kernels
="$(echo "$boot_kernels" | grep -Fxv -f "$MANUAL_KERNEL_LIST" || true)"
280 if [ -z "$manual_kernels" ]; then
281 manual_kernels
="None."
284 echo "Manually selected kernels:"
285 echo "$manual_kernels"
287 echo "Automatically selected kernels:"
292 warn
"USAGE: $0 <commands> [ARGS]"
294 warn
" $0 format <partition> [--force]"
295 warn
" $0 init <partition>"
296 warn
" $0 clean [--dry-run]"
297 warn
" $0 refresh [--hook <name>]"
298 warn
" $0 kernel <add|remove> <kernel-version>"
299 warn
" $0 kernel list"
300 warn
" $0 status [--quiet]"
305 echo "USAGE: $0 format <partition> [--force]"
307 echo " format <partition> as EFI system partition. Use --force to format even if <partition> is currently in use."
309 echo "USAGE: $0 init <partition>"
311 echo " initialize EFI system partition at <partition> for automatic synchronization of pve-kernels and their associated initrds."
313 echo "USAGE: $0 clean [--dry-run]"
315 echo " remove no longer existing EFI system partition UUIDs from $ESP_LIST. Use --dry-run to only print outdated entries instead of removing them."
317 echo "USAGE: $0 refresh [--hook <name>]"
319 echo " refresh all configured EFI system partitions. Use --hook to only run the specified hook, omit to run all."
321 echo "USAGE: $0 kernel <add|remove> <kernel-version>"
323 echo " add/remove pve-kernel with ABI <kernel-version> to list of synced kernels, in addition to automatically selected ones."
324 echo " NOTE: you need to manually run 'refresh' once you're finished with adding/removing kernels from the list"
326 echo "USAGE: $0 kernel list"
328 echo " list kernel versions currently selected for inclusion on ESPs."
330 echo "USAGE: $0 status [--quiet]"
332 echo " Print details about the ESPs configuration. Exits with 0 if any ESP is configured, else with 2."
337 if ! (echo "${curr_uuid}" |
grep -qE '[0-9a-fA-F]{4}-[0-9a-fA-F]{4}'); then
338 warn
"WARN: ${curr_uuid} read from ${ESP_LIST} does not look like a VFAT-UUID - skipping"
342 path
="/dev/disk/by-uuid/$curr_uuid"
343 if [ ! -e "${path}" ]; then
344 warn
"WARN: ${path} does not exist - clean '${ESP_LIST}'! - skipping"
348 mountpoint
="${MOUNTROOT}/${curr_uuid}"
349 mkdir
-p "${mountpoint}" || \
350 { warn
"creation of mountpoint ${mountpoint} failed - skipping"; return; }
351 mount
"${path}" "${mountpoint}" || \
352 { warn
"mount of ${path} failed - skipping"; return; }
355 if [ -f "${mountpoint}/$PMX_LOADER_CONF" ]; then
357 if [ ! -d "${mountpoint}/$PMX_ESP_DIR" ]; then
358 warn
"${path}/$PMX_ESP_DIR does not exist"
361 if [ -d "${mountpoint}/grub" ]; then
362 if [ -n "$result" ]; then
363 result
="${result},grub"
368 echo "$curr_uuid is configured with: $result"
369 umount
"${mountpoint}" || \
370 { warn
"umount of ${path} failed - failure"; exit 0; }
372 rmdir "${mountpoint}" || true
377 if [ ! -e "${ESP_LIST}" ]; then
378 if [ -z "$quiet" ]; then
379 warn
"E: $ESP_LIST does not exist."
383 if [ -z "$quiet" ]; then
384 loop_esp_list _status_detail
397 warn
"E: <partition> is mandatory."
406 reexec_in_mountns
"$@"
409 warn
"E: <partition> is mandatory."
424 if [ "$#" -eq 0 ]; then
426 elif [ "$#" -eq 2 ] && [ "$1" = "--hook" ]; then
437 warn
"E: subcommand is mandatory for 'kernel'."
457 warn
"E: invalid 'kernel' subcommand '$cmd'."
465 if [ "$#" -eq 2 ] && [ "$2" = '--quiet' ]; then
468 elif [ "$#" -eq 1 ]; then
469 reexec_in_mountns
"$@"
484 warn
"Invalid/unknown command '$1'."