On Mon, Aug 03, 2026 at 01:45:44PM +0530, Srihari Parimi via Libguestfs wrote:
Hi Richard,
This is a more comprehensive description of the problem, where I respond to the
specific issue and questions that you brought up during the discussion last
week. I also cover the proposed solution towards the end. Kindly bear with the
somewhat longish one
• [Comment 1] - Specific behaviors of the GRUB bootloader when encountering
"Linux 16" versus "Linux EFI" directives.
□ linux16 - Directive in GRUB boot loader to load the Linux Kernel image.
It is documented in the GNU GRUB documentation - linux16
☆ The linux16 command forces GRUB load Linux Kernel image by using
legacy 16-bit real-mode boot protocol.
☆ GRUB hands control to the kernel while the CPU is still in 16-bit
Real Mode.
☆ This allows the kernel's real-mode setup code to perform early
hardware initialization using BIOS services (e.g., querying video
modes, memory map)"
☆ The Linux Kernel switches itself into 32-bit protected mode.
☆ initrd16 loads the initramfs and is paired with linux16
□ linuxefi - downstream GRUB2 bootloader directives specific to RHEL 7
for UEFI systems. Documented in RHEL 7 System Administrator Guide
☆ Directive specific to RHEL 7. These directives are deprecated in
RHEL 8 upwards which use standard GRUB directives linux, initrd
instead and these work uniformly across BIOS or UEFI systems.
☆ linuxefi and initrdefi directives use UEFI boot services to load
the Linux Kernel image and initramfs respectively.
I think this was the context I was missing. So these are RHEL 7 only
directives that allow a kernel/initramfs to be loaded either in 16 bit
mode or as an EFI binary.
Are all RHEL 7 kernels compatible with either boot method?
If these directives were deprecated or removed in RHEL 8+ then that is
a justification for only implementing the change specifically in RHEL
7 guests.
□ Based on the boot mode of the system
☆ These GRUB configuration files are created using scripts in /etc/
grub.d/ - primary script which generates the kernel image,
initramfs boot loader commands is /etc/grub.d/10_linux.
○ RHEL 7.9 VM in BIOS Mode - GRUB reads the file /boot/grub2/
grub.cfg which has the directives {linux16, initrd16}
[root@localhost ~]# cat /boot/grub2/grub.cfg | egrep "linux16|initrd16"
linux16 /vmlinuz-3.10.0-1160.el7.x86_64
root=UUID=b635e330-0173-4866-9e5e-693086760507
ro crashkernel=auto rhgb quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-1160.el7.x86_64.img
linux16 /vmlinuz-0-rescue-bb246b817b814a44b5e960404fdc7ae3
root=UUID=b635e330-0173-4866
-9e5e-693086760507 ro crashkernel=auto rhgb quiet
initrd16 /initramfs-0-rescue-bb246b817b814a44b5e960404fdc7ae3.img
• RHEL 7.9 VM in UEFI Mode - GRUB reads the file /boot/efi/EFI/redhat/
grub.cfg which has the directives {linux16, initrd16}
ITYM linuxefi, initrdefi?
[root@localhost ~]# cat /boot/efi/EFI/redhat/grub.cfg | egrep
"linuxefi|initrdefi"
linuxefi /vmlinuz-3.10.0-1160.el7.x86_64 root=/dev/mapper/rhel-root ro
crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet
initrdefi /initramfs-3.10.0-1160.el7.x86_64.img
linuxefi /vmlinuz-0-rescue-6e4e30972e924630b169d78059b932d2
root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap
rhgb quiet
initrdefi /initramfs-0-rescue-6e4e30972e924630b169d78059b932d2.img
• Code snippet from /etc/grub.d/10_linux for RHEL9 and RHEL7. The root device
UUID passed to the kernel (e.g., root=UUID=...) is dynamically queried and
formatted by helper routines in /usr/share/grub/grub-mkconfig_lib using
grub-probe .
□ Code snippet from /etc/grub.d/10_linux in RHEL9
if [ -d /sys/firmware/efi ]; then
bootefi_device="`${grub_probe} --target=device /boot/efi/`"
prepare_grub_to_access_device_with_variable boot ${bootefi_device}
else
boot_device="`${grub_probe} --target=device /boot/`"
prepare_grub_to_access_device_with_variable boot ${boot_device}
fi
• Code snippet from /etc/grub.d/10_linux in RHEL7
if [ -d /sys/firmware/efi ]; then
sed "s/^/$submenu_indentation/" << EOF
${linuxefi} ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro
${args}
EOF
else
sed "s/^/$submenu_indentation/" << EOF
linux${sixteenbit} ${rel_dirname}/${basename}
root=${linux_root_device_thisversion} ro ${args}
EOF
fi
Jeeez ... Grub is so complicated & over-engineered ...
• [Comment 2] Confirming that the virtual machine Linux file format
is fully compatible with the new directive
I'm not clear that the text below does confirm this.
□ Based on the analysis done for the previous comment, we can
safely conclude that this problem is very specific to RHEL 7 only. Further, the problem
occurs when following conditions are met
☆ Source VM must be in UEFI boot mode
☆ In the /etc/fstab, the /boot and /boot/efi partitions must be identified by
the corresponding /dev/sd* files instead of the UUIDs (default) generated during FS
creation.
□ The second condition forces virt-v2v conversion to configure GRUB.
☆ As the grub configuration executes in context of libguestfs appliance (BIOS
mode), it is generated with linux16, initrd16 whereas the VM is configured to boot in
UEFI.
☆ The VM powers up with UEFI firmware, but the linux16 directive switches the
CPU into 16-bit real mode and look for BIOS services (/boot/grub2/i386-pc) which are
absent.
As ever I can only review what's in the pull request, and currently
the pull request is the same as it always was, so we're no closer to
actually merging anything.
Also, all the justifications must be in the final commit message, not
random comments spread over github and mailing lists.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages.
http://libguestfs.org