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