Richard W.M. Jones
2016-Nov-02 15:01 UTC
[Libguestfs] [PATCH v4 1/2] v2v: bootloaders: search grub config for all distributions
From: Pavel Butsykin <pbutsykin@virtuozzo.com> This patch improves the search of grub config on EFI partition. This means that the config will be found not only for rhel but also for many other distributions. Tests were performed on the following distributions: centos, fedora, ubuntu, suse. In all cases, the config path was /boot/efi/EFI/*distname*/grub.cfg The main purpose of the patch is to improve support for converting of vm with UEFI for most distributions. Unfortunately this patch does not solve the problem for all distributions, for example Debian does not store grub config on the EFI partition, therefore for such distributions another solution is necessary. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> Signed-off-by: Richard W.M. Jones <rjones@redhat.com> --- v2v/linux_bootloaders.ml | 83 ++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml index e03d22b..9160dcc 100644 --- a/v2v/linux_bootloaders.ml +++ b/v2v/linux_bootloaders.ml @@ -42,6 +42,10 @@ type bootloader_type | Grub1 | Grub2 +let string_of_bootloader_type = function + | Grub1 -> "Grub1" + | Grub2 -> "Grub2" + (* Helper function for SUSE: remove (hdX,X) prefix from a path. *) let remove_hd_prefix path let rex = Str.regexp "^(hd.*)\\(.*\\)" in @@ -49,6 +53,10 @@ let remove_hd_prefix path (* Grub1 (AKA grub-legacy) representation. *) class bootloader_grub1 (g : G.guestfs) inspect grub_config + let () + if grub_config = "/boot/efi/EFI/redhat/grub.conf" then + g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf" in + (* Grub prefix? Usually "/boot". *) let grub_prefix let mounts = g#inspect_get_mountpoints inspect.i_root in @@ -191,7 +199,7 @@ type default_kernel_method | MethodNone (** No known way. *) (* Grub2 representation. *) -class bootloader_grub2 (g : G.guestfs) grub_config +class bootloader_grub2 (g : G.guestfs) inspect grub_config let grub2_mkconfig_cmd let elems = [ @@ -334,33 +342,46 @@ object (self) end let detect_bootloader (g : G.guestfs) inspect - let config_file, typ - let locations = [ - "/boot/grub2/grub.cfg", Grub2; - "/boot/grub/grub.cfg", Grub2; - "/boot/grub/menu.lst", Grub1; - "/boot/grub/grub.conf", Grub1; - ] in - let locations - match inspect.i_firmware with - | I_UEFI _ -> - [ - "/boot/efi/EFI/redhat/grub.cfg", Grub2; - "/boot/efi/EFI/redhat/grub.conf", Grub1; - ] @ locations - | I_BIOS -> locations in - try - List.find ( - fun (config_file, _) -> g#is_file ~followsymlinks:true config_file - ) locations - with - Not_found -> - error (f_"no bootloader detected") in - - match typ with - | Grub1 -> - if config_file = "/boot/efi/EFI/redhat/grub.conf" then - g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf"; - - new bootloader_grub1 g inspect config_file - | Grub2 -> new bootloader_grub2 g config_file + (* Where to start searching for bootloaders. *) + let mp + match inspect.i_firmware with + | I_BIOS -> "/boot" + | I_UEFI _ -> "/boot/efi/EFI" in + + (* Find all paths below the mountpoint, then filter them to find + * the grub config file. + *) + let paths + try List.map ((^) mp) (Array.to_list (g#find mp)) + with G.Error msg -> + error (f_"could not find bootloader mount point (%s): %s") mp msg in + + (* We can determine if the bootloader config file is grub 1 or + * grub 2 just by looking at the filename. + *) + let bootloader_type_of_filename path + match last_part_of path '/' with + | Some "grub.cfg" -> Some Grub2 + | Some ("grub.conf" | "menu.lst") -> Some Grub1 + | Some _ + | None -> None + in + + let grub_config, typ + let rec loop = function + | [] -> error (f_"no bootloader detected") + | path :: paths -> + match bootloader_type_of_filename path with + | None -> loop paths + | Some typ -> + if not (g#is_file ~followsymlinks:true path) then loop paths + else path, typ + in + loop paths in + + debug "detected bootloader %s at %s" + (string_of_bootloader_type typ) grub_config; + + (match typ with + | Grub1 -> new bootloader_grub1 + | Grub2 -> new bootloader_grub2) g inspect grub_config -- 2.9.3
Richard W.M. Jones
2016-Nov-02 15:01 UTC
[Libguestfs] [PATCH v4 2/2] v2v: bootloaders: Remove call to g#aug_transform.
Let's fix this in Augeas upstream instead of hacking around it in libguestfs. --- v2v/linux_bootloaders.ml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml index 9160dcc..ec32715 100644 --- a/v2v/linux_bootloaders.ml +++ b/v2v/linux_bootloaders.ml @@ -53,10 +53,6 @@ let remove_hd_prefix path (* Grub1 (AKA grub-legacy) representation. *) class bootloader_grub1 (g : G.guestfs) inspect grub_config - let () - if grub_config = "/boot/efi/EFI/redhat/grub.conf" then - g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf" in - (* Grub prefix? Usually "/boot". *) let grub_prefix let mounts = g#inspect_get_mountpoints inspect.i_root in -- 2.9.3
Pino Toscano
2016-Nov-02 16:42 UTC
Re: [Libguestfs] [PATCH v4 1/2] v2v: bootloaders: search grub config for all distributions
On Wednesday, 2 November 2016 15:01:08 CET Richard W.M. Jones wrote:> From: Pavel Butsykin <pbutsykin@virtuozzo.com> > > This patch improves the search of grub config on EFI partition. This > means that the config will be found not only for rhel but also for > many other distributions. Tests were performed on the following > distributions: centos, fedora, ubuntu, suse. In all cases, the config > path was /boot/efi/EFI/*distname*/grub.cfg > > The main purpose of the patch is to improve support for converting of > vm with UEFI for most distributions. Unfortunately this patch does not > solve the problem for all distributions, for example Debian does not > store grub config on the EFI partition, therefore for such > distributions another solution is necessary. > > Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> > Signed-off-by: Richard W.M. Jones <rjones@redhat.com> > ---Mostly LGTM (it was the approach I suggested, after all) -- just one note below.> (* Grub1 (AKA grub-legacy) representation. *) > class bootloader_grub1 (g : G.guestfs) inspect grub_config > + let () > + if grub_config = "/boot/efi/EFI/redhat/grub.conf" then > + g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf" inI guess this could be changed to be: if String.is_prefix grub_config "/boot/efi/EFI/" then g#aug_transform "grub" grub_config so even if we keep it around for a while, it will work fine also for other distros than RH-based. Thanks, -- Pino Toscano
Richard W.M. Jones
2016-Nov-03 08:58 UTC
Re: [Libguestfs] [PATCH v4 1/2] v2v: bootloaders: search grub config for all distributions
On Wed, Nov 02, 2016 at 05:42:28PM +0100, Pino Toscano wrote:> On Wednesday, 2 November 2016 15:01:08 CET Richard W.M. Jones wrote: > > From: Pavel Butsykin <pbutsykin@virtuozzo.com> > > > > This patch improves the search of grub config on EFI partition. This > > means that the config will be found not only for rhel but also for > > many other distributions. Tests were performed on the following > > distributions: centos, fedora, ubuntu, suse. In all cases, the config > > path was /boot/efi/EFI/*distname*/grub.cfg > > > > The main purpose of the patch is to improve support for converting of > > vm with UEFI for most distributions. Unfortunately this patch does not > > solve the problem for all distributions, for example Debian does not > > store grub config on the EFI partition, therefore for such > > distributions another solution is necessary. > > > > Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> > > Signed-off-by: Richard W.M. Jones <rjones@redhat.com> > > --- > > Mostly LGTM (it was the approach I suggested, after all) -- just one > note below. > > > (* Grub1 (AKA grub-legacy) representation. *) > > class bootloader_grub1 (g : G.guestfs) inspect grub_config > > + let () > > + if grub_config = "/boot/efi/EFI/redhat/grub.conf" then > > + g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf" in > > I guess this could be changed to be: > > if String.is_prefix grub_config "/boot/efi/EFI/" then > g#aug_transform "grub" grub_config > > so even if we keep it around for a while, it will work fine also for > other distros than RH-based.The problem I found is that if the path is included in the Augeas lens and this code is in libguestfs at the same time, then you get the error noted before about: augeas failed to parse [path to grub.conf]: error "Lenses @Grub and grub.lns could be used to load this file" I think we should just set Augeas 1.7.0 (released tomorrow) as the minimum version for virt-v2v users, and then the problem largely goes away. I was also looking at whether it is possible to detect if the file has a transform already using Augeas APIs. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Richard W.M. Jones
2016-Nov-03 14:28 UTC
Re: [Libguestfs] [PATCH v4 1/2] v2v: bootloaders: search grub config for all distributions
On Wed, Nov 02, 2016 at 09:52:20PM +0300, Pavel Butsykin wrote:> But there is another point, we added a search for grub.conf/menu.lst in > /boot dir. This means that in some rare cases we can find the grub.conf > in non-standard locations(that will not be added to augeas). Can we > somehow handle the error aug_transform? Because if we could know that > augeas already contains the config path, it would simplify the issue.I posted a question related to this on augeas-devel: https://www.redhat.com/archives/augeas-devel/2016-November/msg00004.html Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
Apparently Analagous Threads
- [PATCH v3] v2v: bootloaders: search grub config for all distributions
- [PATCH] v2v: bootloaders: search grub config for all distributions
- [PATCH v5 0/3] v2v and augeas
- [PATCH v5 1/3] v2v: bootloaders: search grub config for all distributions
- Re: [PATCH v6 1/1] v2v: bootloaders: search grub config for all distributions