On Wed, Aug 5, 2026 at 3:06 PM Richard W.M. Jones <rjones@redhat.com> wrote:
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?
I verified this in RHEL 7.6 too - below is snapshot. If needed we can verify it in prior RHEL 7 versions too. [root@dhcp-6-172-238 ~]# cat /etc/os-release | grep VERSION VERSION="7.6 (Maipo)" [root@dhcp-6-172-238 ~]# cat /boot/efi/EFI/redhat/grub.cfg | grep -E "linuxefi|initrdefi" linuxefi /vmlinuz-3.10.0-957.el7.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet LANG=en_US.UTF-8 initrdefi /initramfs-3.10.0-957.el7.x86_64.img linuxefi /vmlinuz-0-rescue-9d978a092fa6417ca4c724320cc009f2 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet initrdefi /initramfs-0-rescue-9d978a092fa6417ca4c724320cc009f2.img
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?
Yes - I meant 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.
- We are not using any new directive; rather, we are replacing incompatible directives {linux16, initrd16} with the compatible directives {linuxefi, initrdefi} that were natively used by the Source VM prior to virt-v2v conversion. Below is the snippet of /boot/efi/EFI/redhat/grub.cfg in the source VM before conversion. [root@localhost ~]# virt-what vmware [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 [root@localhost ~]# - Summary of the issue - Source VM is RHEL 7.9 EFI based, grub configuration has {linuxefi, initrdefi} - virt-v2v executes grub2-mkconfig because /dev/sdX is present in /etc/fstab. - grub2-mkconfig runs in the libguestfs appliance which is in BIOS boot mode, so it ends up generating the GRUB 2 bootloader configuration{linux16, initrd16} - The VM fails to boot post-conversion because these directives require BIOS firmware - I still need to update the PR to avoid using sed; I will work on that once the approach is accepted. - The unit test which I performed with the current PR - In the Source VM, I changed /etc/fstab to use device files instead of default UUIDs - Post virt-v2v conversion, the VM booted successfully with these changes.
□ 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.
As I mentioned earlier, I will update the PR once the approach is accepted.
Also, all the justifications must be in the final commit message, not random comments spread over github and mailing lists.
I agree and will put the justifications and approach in the commit message.
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