I ended up with the following logic (which is pretty close to what you suggested, had to unmount sysfs first to create directories there) def update(self, g): if self.boot_type == BootType.UEFI: # On rhel7 and sles12/15 the grub config is set to non efi commands # due to a weak uefi detection algorithm which doesn't work from a # chrooted environment (checks for [ -d /sys/firmware/efi ]). # libguestfs bind-mounts the sysfs of the appliance to /sys when # invoking g.sh()/command() - Therefore, /sys/firmware/efi does # not exist. Hack around this behavior by unmount /sys and # creating /sys/firmware/efi dir before running grub2's mkconfig. g.sh(f'umount /sys && mkdir -p /sys/firmware/efi && ' f'{self.mkconfig} -o {self.config}') else: g.command([self.mkconfig, '-o', self.config]) return True I'm pretty sure that should be fixed in virt-v2v too (although I'm a bit lazy do write that OCaml equivalent of this and test it). So just a heads up on the mailing list. Sam On Thu, Aug 27, 2020 at 12:28 PM Sam Eiderman <sameid@google.com> wrote:
I see, thanks for the clarification.
On Thu, Aug 27, 2020 at 12:05 PM Richard W.M. Jones <rjones@redhat.com> wrote:
On Thu, Aug 27, 2020 at 11:24:57AM +0300, Sam Eiderman wrote:
Yes, I understand that, I am just surprised to know that we bind /sys for g.sh() commands.
However, "g.command([self.mkconfig, '-o', self.config])" shouldn't have the appliances /sys available (I looked briefly in command.c and I don't see the same bind-mount code), or maybe I'm missing something.
guestfs_sh, guestfs_sh_lines, guestfs_command, guestfs_command_lines all attempt to bind-mount /sys and other directories into the chroot while running the command. (See daemon/sh.c)
Anyway I misunderstood before - I thought you were trying to run grub to install the bootloader. Running grub2-mkconfig as done in virt-v2v should be fine since AIUI it's just concatenating some configuration files together.
I thought I could use my g.mkdir_p('/sys/firmware/efi') hack, but since it didn't work, I'm now resort to explicitly handling this failure after running the mkconfig command:
The mkdir didn't work since that directory will be covered by the bind mount when the command is running.
I'm not sure there's a good answer here, maybe something like:
g.sh (" mkdir -p /sys/firmware/efi # create some files in /sys/firmware/efi to trick grub grub2-mkconfig -o ... ")
although this may modify the appliance's real /sys.
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