[Libguestfs] [PATCH] v2v: bootloaders: search grub config for all distributions

Richard W.M. Jones rjones at redhat.com
Tue Nov 1 10:11:39 UTC 2016


On Thu, Oct 27, 2016 at 08:22:30PM +0300, Pavel Butsykin wrote:
>    match typ with
>    | Grub1 ->
> -    if config_file = "/boot/efi/EFI/redhat/grub.conf" then
> -      g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf";
> -
> +    (match inspect.i_firmware with
> +    | I_BIOS -> ()
> +    | I_UEFI _ -> g#aug_transform "grub" config_file
> +    );
>      new bootloader_grub1 g inspect config_file
>    | Grub2 -> new bootloader_grub2 g config_file

I don't think this part of the patch is correct.  We need to use the
Augeas transform only for a particular path which is missing from the
Augeas lens.

What do you think of the attached version instead?  It's smaller and
more efficient (only makes 2 libguestfs API calls in the normal case)?

I'm still running tests on it.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
-------------- next part --------------
>From 780ef55b117b025850f323df8337e3804676b9cb Mon Sep 17 00:00:00 2001
From: Pavel Butsykin <pbutsykin at virtuozzo.com>
Date: Thu, 27 Oct 2016 20:22:30 +0300
Subject: [PATCH] v2v: bootloaders: search grub config for all distributions

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 at virtuozzo.com>
Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
---
 v2v/linux_bootloaders.ml | 54 +++++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 21 deletions(-)

diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml
index e03d22b..ec99980 100644
--- a/v2v/linux_bootloaders.ml
+++ b/v2v/linux_bootloaders.ml
@@ -333,29 +333,41 @@ object (self)
     ignore (g#command [| grub2_mkconfig_cmd; "-o"; grub_config |])
 end
 
+(* 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 =
+  if String.is_suffix path "/grub.cfg" then
+    Some Grub2
+  else if String.is_suffix path "/grub.conf" ||
+          String.is_suffix path "/menu.lst" then
+    Some Grub1
+  else
+    None
+
+(* Where to start searching for bootloaders. *)
+let bootloader_mountpoint = function
+  | { i_firmware = I_BIOS } -> "/boot"
+  | { i_firmware = I_UEFI _ } -> "/boot/efi/EFI"
+
 let detect_bootloader (g : G.guestfs) inspect =
+  let mp = bootloader_mountpoint inspect in
+  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
+
   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
+    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
 
   match typ with
   | Grub1 ->
-- 
2.9.3



More information about the Libguestfs mailing list