|
|
151578 |
From 54c42d18d82ae4c5c0562600b47a7710a583ea07 Mon Sep 17 00:00:00 2001
|
|
|
151578 |
From: Pavel Butsykin <pbutsykin@virtuozzo.com>
|
|
|
151578 |
Date: Tue, 2 May 2017 15:35:06 +0300
|
|
|
151578 |
Subject: [PATCH] v2v: bootloaders: search grub config for all distributions
|
|
|
151578 |
|
|
|
151578 |
This patch improves the search of grub config on EFI partition. This
|
|
|
151578 |
means that the config will be found not only for rhel but also for
|
|
|
151578 |
many other distributions. Tests were performed on the following
|
|
|
151578 |
distributions: centos, fedora, ubuntu, suse. In all cases, the config
|
|
|
151578 |
path was /boot/efi/EFI/*distname*/grub.cfg
|
|
|
151578 |
|
|
|
151578 |
The main purpose of the patch is to improve support for converting of
|
|
|
151578 |
vm with UEFI for most distributions. Unfortunately this patch does not
|
|
|
151578 |
solve the problem for all distributions, for example Debian does not
|
|
|
151578 |
store grub config on the EFI partition, therefore for such
|
|
|
151578 |
distributions another solution is necessary.
|
|
|
151578 |
|
|
|
151578 |
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
|
|
|
151578 |
(cherry picked from commit a76e9040b20f97eb5c9accbefcbf55999554dc48)
|
|
|
151578 |
---
|
|
|
151578 |
v2v/linux_bootloaders.ml | 76 ++++++++++++++++++++++++++++++------------------
|
|
|
151578 |
1 file changed, 48 insertions(+), 28 deletions(-)
|
|
|
151578 |
|
|
|
151578 |
diff --git a/v2v/linux_bootloaders.ml b/v2v/linux_bootloaders.ml
|
|
|
151578 |
index c3fd09ca8..25dab02fe 100644
|
|
|
151578 |
--- a/v2v/linux_bootloaders.ml
|
|
|
151578 |
+++ b/v2v/linux_bootloaders.ml
|
|
|
151578 |
@@ -49,6 +49,13 @@ let remove_hd_prefix path =
|
|
|
151578 |
|
|
|
151578 |
(* Grub1 (AKA grub-legacy) representation. *)
|
|
|
151578 |
class bootloader_grub1 (g : G.guestfs) inspect grub_config =
|
|
|
151578 |
+ let () =
|
|
|
151578 |
+ (* Apply the "grub" lens if it is not handling the file
|
|
|
151578 |
+ * already -- Augeas < 1.7.0 will error out otherwise.
|
|
|
151578 |
+ *)
|
|
|
151578 |
+ if g#aug_ls ("/files" ^ grub_config) = [||] then
|
|
|
151578 |
+ g#aug_transform "grub" grub_config in
|
|
|
151578 |
+
|
|
|
151578 |
(* Grub prefix? Usually "/boot". *)
|
|
|
151578 |
let grub_prefix =
|
|
|
151578 |
let mounts = g#inspect_get_mountpoints inspect.i_root in
|
|
|
151578 |
@@ -345,33 +352,46 @@ object (self)
|
|
|
151578 |
end
|
|
|
151578 |
|
|
|
151578 |
let detect_bootloader (g : G.guestfs) inspect =
|
|
|
151578 |
- let config_file, typ =
|
|
|
151578 |
- let locations = [
|
|
|
151578 |
- "/boot/grub2/grub.cfg", Grub2;
|
|
|
151578 |
- "/boot/grub/grub.cfg", Grub2;
|
|
|
151578 |
- "/boot/grub/menu.lst", Grub1;
|
|
|
151578 |
- "/boot/grub/grub.conf", Grub1;
|
|
|
151578 |
- ] in
|
|
|
151578 |
- let locations =
|
|
|
151578 |
- match inspect.i_firmware with
|
|
|
151578 |
- | I_UEFI _ ->
|
|
|
151578 |
- [
|
|
|
151578 |
- "/boot/efi/EFI/redhat/grub.cfg", Grub2;
|
|
|
151578 |
- "/boot/efi/EFI/redhat/grub.conf", Grub1;
|
|
|
151578 |
- ] @ locations
|
|
|
151578 |
- | I_BIOS -> locations in
|
|
|
151578 |
- try
|
|
|
151578 |
- List.find (
|
|
|
151578 |
- fun (config_file, _) -> g#is_file ~followsymlinks:true config_file
|
|
|
151578 |
- ) locations
|
|
|
151578 |
- with
|
|
|
151578 |
- Not_found ->
|
|
|
151578 |
- error (f_"no bootloader detected") in
|
|
|
151578 |
+ (* Where to start searching for bootloaders. *)
|
|
|
151578 |
+ let mp =
|
|
|
151578 |
+ match inspect.i_firmware with
|
|
|
151578 |
+ | I_BIOS -> "/boot"
|
|
|
151578 |
+ | I_UEFI _ -> "/boot/efi/EFI" in
|
|
|
151578 |
|
|
|
151578 |
- match typ with
|
|
|
151578 |
- | Grub1 ->
|
|
|
151578 |
- if config_file = "/boot/efi/EFI/redhat/grub.conf" then
|
|
|
151578 |
- g#aug_transform "grub" "/boot/efi/EFI/redhat/grub.conf";
|
|
|
151578 |
+ (* Find all paths below the mountpoint, then filter them to find
|
|
|
151578 |
+ * the grub config file.
|
|
|
151578 |
+ *)
|
|
|
151578 |
+ let paths =
|
|
|
151578 |
+ try List.map ((^) mp) (Array.to_list (g#find mp))
|
|
|
151578 |
+ with G.Error msg ->
|
|
|
151578 |
+ error (f_"could not find bootloader mount point (%s): %s") mp msg in
|
|
|
151578 |
|
|
|
151578 |
- new bootloader_grub1 g inspect config_file
|
|
|
151578 |
- | Grub2 -> new bootloader_grub2 g config_file
|
|
|
151578 |
+ (* We can determine if the bootloader config file is grub 1 or
|
|
|
151578 |
+ * grub 2 just by looking at the filename.
|
|
|
151578 |
+ *)
|
|
|
151578 |
+ let bootloader_type_of_filename path =
|
|
|
151578 |
+ match last_part_of path '/' with
|
|
|
151578 |
+ | Some "grub.cfg" -> Some Grub2
|
|
|
151578 |
+ | Some ("grub.conf" | "menu.lst") -> Some Grub1
|
|
|
151578 |
+ | Some _
|
|
|
151578 |
+ | None -> None
|
|
|
151578 |
+ in
|
|
|
151578 |
+
|
|
|
151578 |
+ let grub_config, typ =
|
|
|
151578 |
+ let rec loop = function
|
|
|
151578 |
+ | [] -> error (f_"no bootloader detected")
|
|
|
151578 |
+ | path :: paths ->
|
|
|
151578 |
+ match bootloader_type_of_filename path with
|
|
|
151578 |
+ | None -> loop paths
|
|
|
151578 |
+ | Some typ ->
|
|
|
151578 |
+ if not (g#is_file ~followsymlinks:true path) then loop paths
|
|
|
151578 |
+ else path, typ
|
|
|
151578 |
+ in
|
|
|
151578 |
+ loop paths in
|
|
|
151578 |
+
|
|
|
151578 |
+ let bl =
|
|
|
151578 |
+ (match typ with
|
|
|
151578 |
+ | Grub1 -> new bootloader_grub1 g inspect grub_config
|
|
|
151578 |
+ | Grub2 -> new bootloader_grub2 g grub_config) in
|
|
|
151578 |
+ debug "detected bootloader %s at %s" bl#name grub_config;
|
|
|
151578 |
+ bl
|
|
|
151578 |
--
|
|
|
151578 |
2.14.3
|
|
|
151578 |
|