[PATCH] v2v: linux: simplify RPM database cleaning
by Pino Toscano
Iterate on the array directly, instead of converting it to a list to do
the same; also, avoid a temporary variable for it.
---
v2v/convert_linux.ml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index f9aa334..9941750 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -85,9 +85,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
Linux.augeas_init g;
(* Clean RPM database. This must be done early to avoid RHBZ#1143866. *)
- let dbfiles = g#glob_expand "/var/lib/rpm/__db.00?" in
- let dbfiles = Array.to_list dbfiles in
- List.iter g#rm_f dbfiles;
+ Array.iter g#rm_f (g#glob_expand "/var/lib/rpm/__db.00?");
(* What grub is installed? *)
let grub_config, grub =
--
2.7.4
8 years, 2 months
[PATCH] v2v: Use OVMF secure boot file (RHBZ#1367615).
by Richard W.M. Jones
This is only lightly tested. In particularly I only tested that the
non-secure-boot path still works. I didn't test it on RHEL 7.3 yet
because I haven't got enough free disk space for these giant source
*.ova files :-( Will try to give that a go later.
Rich.
8 years, 2 months
[PATCH 1/2] v2v: Make fstrim warning clearer (RHBZ#1366456).
by Richard W.M. Jones
This reverts the change made for RHBZ#1168144. The warning is now
always displayed.
It would be nice to make the warning actionable, but there is not a
lot that end users can do since fstrim is such a complex topic
interacting with all filesystem and storage layers.
---
v2v/v2v.ml | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index e221f29..8365aae 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -397,11 +397,7 @@ and do_fstrim g inspect =
if mounted then (
try g#fstrim "/"
with G.Error msg ->
- (* Only emit this warning when debugging, because otherwise
- * it causes distress (RHBZ#1168144).
- *)
- if verbose () then
- warning (f_"%s (ignored)") msg
+ warning (f_"fstrim on guest filesystem %s failed. This may mean that conversion takes longer than normal. Usually you can ignore this as fstrim is just an optimization. Not all filesystems support trimming, and it can depend on specific details of the filesystem, alignment and backing storage. Original message: %s") dev msg
)
) fses
--
2.7.4
8 years, 2 months
[PATCH v2] v2v: factor out bootloader handling
by Pino Toscano
Create an object hierarchy to represent different bootloaders for Linux
guests, moving the separate handling of grub1 and grub2 in different
classes: this isolates the code for each type of bootloader together,
instead of scattering it all around.
This is mostly code refactoring, with no actual behaviour change.
---
po/POTFILES-ml | 1 +
v2v/Makefile.am | 2 +
v2v/bootloaders.ml | 317 +++++++++++++++++++++++++++++++++++++++++++++++++++
v2v/bootloaders.mli | 44 +++++++
v2v/convert_linux.ml | 284 ++-------------------------------------------
5 files changed, 376 insertions(+), 272 deletions(-)
create mode 100644 v2v/bootloaders.ml
create mode 100644 v2v/bootloaders.mli
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index b7b39fa..35325d9 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -105,6 +105,7 @@ sysprep/sysprep_operation_utmp.ml
sysprep/sysprep_operation_yum_uuid.ml
v2v/DOM.ml
v2v/OVF.ml
+v2v/bootloaders.ml
v2v/changeuid.ml
v2v/cmdline.ml
v2v/convert_linux.ml
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 008c5ba..9a997e9 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -27,6 +27,7 @@ EXTRA_DIST = \
CLEANFILES = *~ *.annot *.cmi *.cmo *.cmx *.cmxa *.o virt-v2v
SOURCES_MLI = \
+ bootloaders.mli \
changeuid.mli \
cmdline.mli \
convert_linux.mli \
@@ -79,6 +80,7 @@ SOURCES_ML = \
input_libvirt_xen_ssh.ml \
input_libvirt.ml \
input_ova.ml \
+ bootloaders.ml \
convert_linux.ml \
convert_windows.ml \
output_null.ml \
diff --git a/v2v/bootloaders.ml b/v2v/bootloaders.ml
new file mode 100644
index 0000000..689d7b4
--- /dev/null
+++ b/v2v/bootloaders.ml
@@ -0,0 +1,317 @@
+(* virt-v2v
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Printf
+
+open Common_gettext.Gettext
+open Common_utils
+
+open Types
+open Utils
+
+module G = Guestfs
+
+class virtual bootloader = object
+ method virtual name : string
+ method virtual augeas_device_patterns : string list
+ method virtual list_kernels : unit -> string list
+ method virtual set_default_kernel : string -> unit
+ method set_augeas_configuration () = false
+ method virtual configure_console : unit -> unit
+ method virtual remove_console : unit -> unit
+ method update () = ()
+end
+
+(* Helper type used in detect_bootloader. *)
+type bootloader_type =
+ | Grub1
+ | Grub2
+
+(* Helper function for SUSE: remove (hdX,X) prefix from a path. *)
+let remove_hd_prefix path =
+ let rex = Str.regexp "^(hd.*)\\(.*\\)" in
+ Str.replace_first rex "\\1" path
+
+(* Grub1 (AKA grub-legacy) representation. *)
+class bootloader_grub1 (g : G.guestfs) inspect grub_config =
+ (* Grub prefix? Usually "/boot". *)
+ let grub_prefix =
+ let mounts = g#inspect_get_mountpoints inspect.i_root in
+ try
+ List.find (
+ fun path -> List.mem_assoc path mounts
+ ) [ "/boot/grub"; "/boot" ]
+ with Not_found -> "" in
+object
+ inherit bootloader
+
+ method name = "grub1"
+
+ method augeas_device_patterns = [
+ "/files" ^ grub_config ^ "/*/kernel/root";
+ "/files" ^ grub_config ^ "/*/kernel/resume";
+ "/files/boot/grub/device.map/*[label() != \"#comment\"]";
+ "/files/etc/sysconfig/grub/boot";
+ ]
+
+ method list_kernels () =
+ let paths =
+ let expr = sprintf "/files%s/title/kernel" grub_config in
+ let paths = g#aug_match expr in
+ let paths = Array.to_list paths in
+
+ (* Remove duplicates. *)
+ let paths = remove_duplicates paths in
+
+ (* Get the default kernel from grub if it's set. *)
+ let default =
+ let expr = sprintf "/files%s/default" grub_config in
+ try
+ let idx = g#aug_get expr in
+ let idx = int_of_string idx in
+ (* Grub indices are zero-based, augeas is 1-based. *)
+ let expr =
+ sprintf "/files%s/title[%d]/kernel" grub_config (idx+1) in
+ Some expr
+ with G.Error msg
+ when String.find msg "aug_get: no matching node" >= 0 ->
+ None in
+
+ (* If a default kernel was set, put it at the beginning of the paths
+ * list. If not set, assume the first kernel always boots (?)
+ *)
+ match default with
+ | None -> paths
+ | Some p -> p :: List.filter ((<>) p) paths in
+
+ (* Resolve the Augeas paths to kernel filenames. *)
+ let vmlinuzes = List.map g#aug_get paths in
+
+ (* Make sure kernel does not begin with (hdX,X). *)
+ let vmlinuzes = List.map remove_hd_prefix vmlinuzes in
+
+ (* Prepend grub filesystem. *)
+ List.map ((^) grub_prefix) vmlinuzes
+
+ method set_default_kernel vmlinuz =
+ if not (String.is_prefix vmlinuz grub_prefix) then
+ error (f_"kernel %s is not under grub tree %s")
+ vmlinuz grub_prefix;
+ let kernel_under_grub_prefix =
+ let prefix_len = String.length grub_prefix in
+ let kernel_len = String.length vmlinuz in
+ String.sub vmlinuz prefix_len (kernel_len - prefix_len) in
+
+ (* Find the grub entry for the given kernel. *)
+ let paths = g#aug_match (sprintf "/files%s/title/kernel[. = '%s']"
+ grub_config kernel_under_grub_prefix) in
+ let paths = Array.to_list paths in
+ if paths = [] then
+ error (f_"didn't find grub entry for kernel %s") vmlinuz;
+ let path = List.hd paths in
+ let rex = Str.regexp ".*/title\\[\\([1-9][0-9]*\\)\\]/kernel" in
+ if not (Str.string_match rex path 0) then
+ error (f_"internal error: regular expression did not match '%s'")
+ path;
+ let index = int_of_string (Str.matched_group 1 path) - 1 in
+ g#aug_set (sprintf "/files%s/default" grub_config) (string_of_int index);
+ g#aug_save ()
+
+ method set_augeas_configuration () =
+ let incls = g#aug_match "/augeas/load/Grub/incl" in
+ let incls = Array.to_list incls in
+ let incls_contains_conf =
+ List.exists (fun incl -> g#aug_get incl = grub_config) incls in
+ if not incls_contains_conf then (
+ g#aug_set "/augeas/load/Grub/incl[last()+1]" grub_config;
+ true;
+ ) else false
+
+ method configure_console () =
+ let rex = Str.regexp "\\(.*\\)\\b\\([xh]vc0\\)\\b\\(.*\\)" in
+ let expr = sprintf "/files%s/title/kernel/console" grub_config in
+
+ let paths = g#aug_match expr in
+ let paths = Array.to_list paths in
+ List.iter (
+ fun path ->
+ let console = g#aug_get path in
+ if Str.string_match rex console 0 then (
+ let console = Str.global_replace rex "\\1ttyS0\\3" console in
+ g#aug_set path console
+ )
+ ) paths;
+
+ g#aug_save ()
+
+ method remove_console () =
+ let rex = Str.regexp "\\(.*\\)\\b\\([xh]vc0\\)\\b\\(.*\\)" in
+ let expr = sprintf "/files%s/title/kernel/console" grub_config in
+
+ let rec loop = function
+ | [] -> ()
+ | path :: paths ->
+ let console = g#aug_get path in
+ if Str.string_match rex console 0 then (
+ ignore (g#aug_rm path);
+ (* All the paths are invalid, restart the loop. *)
+ let paths = g#aug_match expr in
+ let paths = Array.to_list paths in
+ loop paths
+ )
+ else
+ loop paths
+ in
+ let paths = g#aug_match expr in
+ let paths = Array.to_list paths in
+ loop paths;
+
+ g#aug_save ()
+end
+
+(* Grub2 representation. *)
+class bootloader_grub2 (g : G.guestfs) grub_config =
+ let grub2_update_console ~remove =
+ let rex = Str.regexp "\\(.*\\)\\bconsole=[xh]vc0\\b\\(.*\\)" in
+
+ let paths = [
+ "/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX";
+ "/files/etc/default/grub/GRUB_CMDLINE_LINUX";
+ "/files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT"
+ ] in
+ let paths = List.map g#aug_match paths in
+ let paths = List.map Array.to_list paths in
+ let paths = List.flatten paths in
+ match paths with
+ | [] ->
+ if not remove then
+ warning (f_"could not add grub2 serial console (ignored)")
+ else
+ warning (f_"could not remove grub2 serial console (ignored)")
+ | path :: _ ->
+ let grub_cmdline = g#aug_get path in
+ if Str.string_match rex grub_cmdline 0 then (
+ let new_grub_cmdline =
+ if not remove then
+ Str.global_replace rex "\\1console=ttyS0\\2" grub_cmdline
+ else
+ Str.global_replace rex "\\1\\2" grub_cmdline in
+ g#aug_set path new_grub_cmdline;
+ g#aug_save ();
+
+ try
+ ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |])
+ with
+ G.Error msg ->
+ warning (f_"could not rebuild grub2 configuration file (%s). This may mean that grub output will not be sent to the serial port, but otherwise should be harmless. Original error message: %s")
+ grub_config msg
+ ) in
+object
+ inherit bootloader
+
+ method name = "grub2"
+
+ method augeas_device_patterns = [
+ "/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX";
+ "/files/etc/default/grub/GRUB_CMDLINE_LINUX";
+ "/files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT";
+ "/files/boot/grub2/device.map/*[label() != \"#comment\"]";
+ ]
+
+ method list_kernels () =
+ let get_default_image () =
+ let cmd =
+ if g#exists "/sbin/grubby" then
+ [| "grubby"; "--default-kernel" |]
+ else
+ [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; "
+ InitLibrary();
+ my $default = Bootloader::Tools::GetDefaultSection();
+ print $default->{image};
+ " |] in
+ match g#command cmd with
+ | "" -> None
+ | k ->
+ let len = String.length k in
+ let k =
+ if len > 0 && k.[len-1] = '\n' then
+ String.sub k 0 (len-1)
+ else k in
+ Some (remove_hd_prefix k)
+ in
+
+ let vmlinuzes =
+ (match get_default_image () with
+ | None -> []
+ | Some k -> [k]) @
+ (* This is how the grub2 config generator enumerates kernels. *)
+ Array.to_list (g#glob_expand "/boot/kernel-*") @
+ Array.to_list (g#glob_expand "/boot/vmlinuz-*") @
+ Array.to_list (g#glob_expand "/vmlinuz-*") in
+ let rex = Str.regexp ".*\\.\\(dpkg-.*|rpmsave|rpmnew\\)$" in
+ let vmlinuzes = List.filter (
+ fun file -> not (Str.string_match rex file 0)
+ ) vmlinuzes in
+ vmlinuzes
+
+ method set_default_kernel vmlinuz =
+ let cmd =
+ if g#exists "/sbin/grubby" then
+ [| "grubby"; "--set-default"; vmlinuz |]
+ else
+ [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; sprintf "
+ InitLibrary();
+ my @sections = GetSectionList(type=>image, image=>\"%s\");
+ my $section = GetSection(@sections);
+ my $newdefault = $section->{name};
+ SetGlobals(default, \"$newdefault\");
+ " vmlinuz |] in
+ ignore (g#command cmd)
+
+ method configure_console () =
+ grub2_update_console ~remove:false
+
+ method remove_console () =
+ grub2_update_console ~remove:true
+
+ method update () =
+ ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |])
+end
+
+let detect_bootloader (g : G.guestfs) inspect =
+ let config_file, typ =
+ let locations = [
+ "/boot/grub2/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) :: locations
+ | I_BIOS -> locations in
+ try
+ List.find (
+ fun (grub_config, _) -> g#is_file ~followsymlinks:true grub_config
+ ) locations
+ with
+ Not_found ->
+ error (f_"no bootloader detected") in
+
+ match typ with
+ | Grub1 -> new bootloader_grub1 g inspect config_file
+ | Grub2 -> new bootloader_grub2 g config_file
diff --git a/v2v/bootloaders.mli b/v2v/bootloaders.mli
new file mode 100644
index 0000000..477312b
--- /dev/null
+++ b/v2v/bootloaders.mli
@@ -0,0 +1,44 @@
+(* virt-v2v
+ * Copyright (C) 2009-2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+class virtual bootloader : object
+ method virtual name : string
+ (** The name of the bootloader. *)
+ method virtual augeas_device_patterns : string list
+ (** A list of augeas patterns to search for device names. *)
+ method virtual list_kernels : unit -> string list
+ (** Lists all the kernels configured in the bootloader. *)
+ method virtual set_default_kernel : string -> unit
+ (** Sets the specified vmlinuz path as default bootloader entry. *)
+ method set_augeas_configuration : unit -> bool
+ (** Checks whether augeas is reading the configuration file
+ of the bootloader, and if not then add it.
+
+ Returns whether augeas needs to be reloaded. *)
+ method virtual configure_console : unit -> unit
+ (** Sets up the console for the available kernels. *)
+ method virtual remove_console : unit -> unit
+ (** Removes the console in all the available kernels. *)
+ method update : unit -> unit
+ (** Update the bootloader. *)
+end
+(** Encapsulates a UNIX boot loader as object. *)
+
+val detect_bootloader : Guestfs.guestfs -> Types.inspect -> bootloader
+(** Detects the bootloader on the guest, and creates the object
+ representing it. *)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index f9aa334..77d9d8e 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -89,36 +89,8 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let dbfiles = Array.to_list dbfiles in
List.iter g#rm_f dbfiles;
- (* What grub is installed? *)
- let grub_config, grub =
- let locations = [
- "/boot/grub2/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) :: locations
- | I_BIOS -> locations in
- try
- List.find (
- fun (grub_config, _) -> g#is_file ~followsymlinks:true grub_config
- ) locations
- with
- Not_found ->
- error (f_"no grub1/grub-legacy or grub2 configuration file was found") in
-
- (* Grub prefix? Usually "/boot". *)
- let grub_prefix =
- match grub with
- | `Grub2 -> ""
- | `Grub1 ->
- let mounts = g#inspect_get_mountpoints inspect.i_root in
- try
- List.find (
- fun path -> List.mem_assoc path mounts
- ) [ "/boot/grub"; "/boot" ]
- with Not_found -> "" in
+ (* Detect the installed bootloader. *)
+ let bootloader = Bootloaders.detect_bootloader g inspect in
(* What kernel/kernel-like packages are installed on the current guest? *)
let installed_kernels : kernel_info list =
@@ -269,88 +241,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
* list is the default booting kernel.
*)
let grub_kernels : kernel_info list =
- (* Helper function for SUSE: remove (hdX,X) prefix from a path. *)
- let remove_hd_prefix =
- let rex = Str.regexp "^(hd.*)\\(.*\\)" in
- Str.replace_first rex "\\1"
- in
-
- let vmlinuzes =
- match grub with
- | `Grub1 ->
- let paths =
- let expr = sprintf "/files%s/title/kernel" grub_config in
- let paths = g#aug_match expr in
- let paths = Array.to_list paths in
-
- (* Remove duplicates. *)
- let paths = remove_duplicates paths in
-
- (* Get the default kernel from grub if it's set. *)
- let default =
- let expr = sprintf "/files%s/default" grub_config in
- try
- let idx = g#aug_get expr in
- let idx = int_of_string idx in
- (* Grub indices are zero-based, augeas is 1-based. *)
- let expr =
- sprintf "/files%s/title[%d]/kernel" grub_config (idx+1) in
- Some expr
- with G.Error msg
- when String.find msg "aug_get: no matching node" >= 0 ->
- None in
-
- (* If a default kernel was set, put it at the beginning of the paths
- * list. If not set, assume the first kernel always boots (?)
- *)
- match default with
- | None -> paths
- | Some p -> p :: List.filter ((<>) p) paths in
-
- (* Resolve the Augeas paths to kernel filenames. *)
- let vmlinuzes = List.map g#aug_get paths in
-
- (* Make sure kernel does not begin with (hdX,X). *)
- let vmlinuzes = List.map remove_hd_prefix vmlinuzes in
-
- (* Prepend grub filesystem. *)
- List.map ((^) grub_prefix) vmlinuzes
-
- | `Grub2 ->
- let get_default_image () =
- let cmd =
- if g#exists "/sbin/grubby" then
- [| "grubby"; "--default-kernel" |]
- else
- [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; "
- InitLibrary();
- my $default = Bootloader::Tools::GetDefaultSection();
- print $default->{image};
- " |] in
- match g#command cmd with
- | "" -> None
- | k ->
- let len = String.length k in
- let k =
- if len > 0 && k.[len-1] = '\n' then
- String.sub k 0 (len-1)
- else k in
- Some (remove_hd_prefix k)
- in
-
- let vmlinuzes =
- (match get_default_image () with
- | None -> []
- | Some k -> [k]) @
- (* This is how the grub2 config generator enumerates kernels. *)
- Array.to_list (g#glob_expand "/boot/kernel-*") @
- Array.to_list (g#glob_expand "/boot/vmlinuz-*") @
- Array.to_list (g#glob_expand "/vmlinuz-*") in
- let rex = Str.regexp ".*\\.\\(dpkg-.*|rpmsave|rpmnew\\)$" in
- let vmlinuzes = List.filter (
- fun file -> not (Str.string_match rex file 0)
- ) vmlinuzes in
- vmlinuzes in
+ let vmlinuzes = bootloader#list_kernels () in
(* Map these to installed kernels. *)
filter_map (
@@ -389,21 +280,8 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* Conversion step. *)
let rec augeas_grub_configuration () =
- match grub with
- | `Grub1 ->
- (* Ensure Augeas is reading the grub configuration file, and if not
- * then add it.
- *)
- let incls = g#aug_match "/augeas/load/Grub/incl" in
- let incls = Array.to_list incls in
- let incls_contains_conf =
- List.exists (fun incl -> g#aug_get incl = grub_config) incls in
- if not incls_contains_conf then (
- g#aug_set "/augeas/load/Grub/incl[last()+1]" grub_config;
- Linux.augeas_reload g;
- )
-
- | `Grub2 -> () (* Not necessary for grub2. *)
+ if bootloader#set_augeas_configuration () then
+ Linux.augeas_reload g
and unconfigure_xen () =
(* Remove kmod-xenpv-* (RHEL 3). *)
@@ -733,7 +611,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let kernels = List.rev kernels (* so best is first *) in
List.hd kernels in
if best_kernel <> List.hd grub_kernels then
- grub_set_bootable best_kernel;
+ bootloader#set_default_kernel best_kernel.ki_vmlinuz;
(* Does the best/bootable kernel support virtio? *)
let virtio = best_kernel.ki_supports_virtio in
@@ -751,46 +629,6 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
best_kernel, virtio
- and grub_set_bootable kernel =
- match grub with
- | `Grub1 ->
- if not (String.is_prefix kernel.ki_vmlinuz grub_prefix) then
- error (f_"kernel %s is not under grub tree %s")
- kernel.ki_vmlinuz grub_prefix;
- let kernel_under_grub_prefix =
- let prefix_len = String.length grub_prefix in
- let kernel_len = String.length kernel.ki_vmlinuz in
- String.sub kernel.ki_vmlinuz prefix_len (kernel_len - prefix_len) in
-
- (* Find the grub entry for the given kernel. *)
- let paths = g#aug_match (sprintf "/files%s/title/kernel[. = '%s']"
- grub_config kernel_under_grub_prefix) in
- let paths = Array.to_list paths in
- if paths = [] then
- error (f_"didn't find grub entry for kernel %s") kernel.ki_vmlinuz;
- let path = List.hd paths in
- let rex = Str.regexp ".*/title\\[\\([1-9][0-9]*\\)\\]/kernel" in
- if not (Str.string_match rex path 0) then
- error (f_"internal error: regular expression did not match '%s'")
- path;
- let index = int_of_string (Str.matched_group 1 path) - 1 in
- g#aug_set (sprintf "/files%s/default" grub_config) (string_of_int index);
- g#aug_save ()
-
- | `Grub2 ->
- let cmd =
- if g#exists "/sbin/grubby" then
- [| "grubby"; "--set-default"; kernel.ki_vmlinuz |]
- else
- [| "/usr/bin/perl"; "-MBootloader::Tools"; "-e"; sprintf "
- InitLibrary();
- my @sections = GetSectionList(type=>image, image=>\"%s\");
- my $section = GetSection(@sections);
- my $newdefault = $section->{name};
- SetGlobals(default, \"$newdefault\");
- " kernel.ki_vmlinuz |] in
- ignore (g#command cmd)
-
(* Even though the kernel was already installed (this version of
* virt-v2v does not install new kernels), it could have an
* initrd that does not have support virtio. Therefore rebuild
@@ -956,28 +794,6 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
g#aug_save ()
- and grub_configure_console () =
- match grub with
- | `Grub1 ->
- let rex = Str.regexp "\\(.*\\)\\b\\([xh]vc0\\)\\b\\(.*\\)" in
- let expr = sprintf "/files%s/title/kernel/console" grub_config in
-
- let paths = g#aug_match expr in
- let paths = Array.to_list paths in
- List.iter (
- fun path ->
- let console = g#aug_get path in
- if Str.string_match rex console 0 then (
- let console = Str.global_replace rex "\\1ttyS0\\3" console in
- g#aug_set path console
- )
- ) paths;
-
- g#aug_save ()
-
- | `Grub2 ->
- grub2_update_console ~remove:false
-
(* If the target doesn't support a serial console, we want to remove
* all references to it instead.
*)
@@ -1006,71 +822,6 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
g#aug_save ()
- and grub_remove_console () =
- match grub with
- | `Grub1 ->
- let rex = Str.regexp "\\(.*\\)\\b\\([xh]vc0\\)\\b\\(.*\\)" in
- let expr = sprintf "/files%s/title/kernel/console" grub_config in
-
- let rec loop = function
- | [] -> ()
- | path :: paths ->
- let console = g#aug_get path in
- if Str.string_match rex console 0 then (
- ignore (g#aug_rm path);
- (* All the paths are invalid, restart the loop. *)
- let paths = g#aug_match expr in
- let paths = Array.to_list paths in
- loop paths
- )
- else
- loop paths
- in
- let paths = g#aug_match expr in
- let paths = Array.to_list paths in
- loop paths;
-
- g#aug_save ()
-
- | `Grub2 ->
- grub2_update_console ~remove:true
-
- and grub2_update_console ~remove =
- let rex = Str.regexp "\\(.*\\)\\bconsole=[xh]vc0\\b\\(.*\\)" in
-
- let paths = [
- "/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX";
- "/files/etc/default/grub/GRUB_CMDLINE_LINUX";
- "/files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT"
- ] in
- let paths = List.map g#aug_match paths in
- let paths = List.map Array.to_list paths in
- let paths = List.flatten paths in
- match paths with
- | [] ->
- if not remove then
- warning (f_"could not add grub2 serial console (ignored)")
- else
- warning (f_"could not remove grub2 serial console (ignored)")
- | path :: _ ->
- let grub_cmdline = g#aug_get path in
- if Str.string_match rex grub_cmdline 0 then (
- let new_grub_cmdline =
- if not remove then
- Str.global_replace rex "\\1console=ttyS0\\2" grub_cmdline
- else
- Str.global_replace rex "\\1\\2" grub_cmdline in
- g#aug_set path new_grub_cmdline;
- g#aug_save ();
-
- try
- ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |])
- with
- G.Error msg ->
- warning (f_"could not rebuild grub2 configuration file (%s). This may mean that grub output will not be sent to the serial port, but otherwise should be harmless. Original error message: %s")
- grub_config msg
- )
-
and supports_acpi () =
(* ACPI known to cause RHEL 3 to fail. *)
if family = `RHEL_family && inspect.i_major_version == 3 then
@@ -1296,19 +1047,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let paths = [
(* /etc/fstab *)
"/files/etc/fstab/*/spec";
-
- (* grub-legacy config *)
- "/files" ^ grub_config ^ "/*/kernel/root";
- "/files" ^ grub_config ^ "/*/kernel/resume";
- "/files/boot/grub/device.map/*[label() != \"#comment\"]";
- "/files/etc/sysconfig/grub/boot";
-
- (* grub2 config *)
- "/files/etc/sysconfig/grub/GRUB_CMDLINE_LINUX";
- "/files/etc/default/grub/GRUB_CMDLINE_LINUX";
- "/files/etc/default/grub/GRUB_CMDLINE_LINUX_DEFAULT";
- "/files/boot/grub2/device.map/*[label() != \"#comment\"]";
] in
+ (* Bootloader config *)
+ let paths = paths @ bootloader#augeas_device_patterns in
(* Which of these paths actually exist? *)
let paths =
@@ -1386,9 +1127,8 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
if !changed then (
g#aug_save ();
- (* If it's grub2, we have to regenerate the config files. *)
- if grub = `Grub2 then
- ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |]);
+ (* Make sure the bootloader is up-to-date. *)
+ bootloader#update ();
Linux.augeas_reload g
);
@@ -1418,10 +1158,10 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
if keep_serial_console then (
configure_console ();
- grub_configure_console ();
+ bootloader#configure_console ();
) else (
remove_console ();
- grub_remove_console ();
+ bootloader#remove_console ();
);
let acpi = supports_acpi () in
--
2.7.4
8 years, 2 months
[PATCH] p2v: Fix s/is/are/ in GUI message.
by Richard W.M. Jones
I reordered the 'and' clause to make it sound a bit more natural.
Thanks: Junqin Zhou.
---
p2v/gui.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/p2v/gui.c b/p2v/gui.c
index 58310bf..3ef1e77 100644
--- a/p2v/gui.c
+++ b/p2v/gui.c
@@ -1754,8 +1754,8 @@ set_log_dir (gpointer user_data)
CLEANUP_FREE char *msg;
if (asprintf (&msg,
- _("Log files and debug information "
- "is saved to this directory "
+ _("Debug information and log files "
+ "are saved to this directory "
"on the conversion server:\n"
"%s"),
remote_dir ? remote_dir : "") == -1)
--
2.7.4
8 years, 2 months
[PATCH 2/2] v2v: ilnux: detect name of grub2-mkconfig
by Tomáš Golembiovský
On Debian family of OSes Grub2 tools are prefixed with 'grub-', not with
'grub2-'. We have to detect the correct name of the tool to use it.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
---
v2v/convert_linux.ml | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 103728b..1f5f12c 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -109,6 +109,23 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
Not_found ->
error (f_"no grub1/grub-legacy or grub2 configuration file was found") in
+ let grub2_mkconfig_cmd =
+ if grub = `Grub2 then
+ try
+ (* Red Hat and Suse families *)
+ ignore (g#command [| "grub2-mkconfig"; "--version" |]);
+ "grub2-mkconfig"
+ with G.Error _ ->
+ try
+ (* Debian family *)
+ ignore (g#command [| "grub-mkconfig"; "--version" |]);
+ "grub-mkconfig"
+ with G.Error _ ->
+ error (f_"failed to find grub2-mkconfig binary (but Grub2 was detected on guest)")
+ else
+ ""
+ in
+
(* Grub prefix? Usually "/boot". *)
let grub_prefix =
match grub with
@@ -1109,7 +1126,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
g#aug_save ();
try
- ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |])
+ ignore (g#command [| grub2_mkconfig_cmd; "-o"; grub_config |])
with
G.Error msg ->
warning (f_"could not rebuild grub2 configuration file (%s). This may mean that grub output will not be sent to the serial port, but otherwise should be harmless. Original error message: %s")
@@ -1431,7 +1448,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
(* If it's grub2, we have to regenerate the config files. *)
if grub = `Grub2 then
- ignore (g#command [| "grub2-mkconfig"; "-o"; grub_config |]);
+ ignore (g#command [| grub2_mkconfig_cmd; "-o"; grub_config |]);
Linux.augeas_reload g
);
--
2.9.2
8 years, 2 months
[PATCH v2] v2v: linux: accept 'sr' devices in fstab
by Richard W.M. Jones
From: Tomáš Golembiovský <tgolembi(a)redhat.com>
Do not print warning for 'sr' devices when converting fstab. Not all
systems create the /dev/cdrom symlink for SCSI CD-ROM devices. Moreover,
on systems with multiple CD-ROMs, having entries for /dev/sr* devices
may be inevitable.
RWMJ: Use String.is_prefix instead of String.find, to more accurately
match on the device name.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
Signed-off-by: Richard W.M. Jones <rjones(a)redhat.com>
---
v2v/convert_linux.ml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 4b1ce99..f9aa334 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -1329,8 +1329,10 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
let replace device =
try List.assoc device map
with Not_found ->
- if String.find device "md" = -1 && String.find device "fd" = -1 &&
- device <> "cdrom" then
+ if not (String.is_prefix device "md") &&
+ not (String.is_prefix device "fd") &&
+ not (String.is_prefix device "sr") &&
+ device <> "cdrom" then
warning (f_"%s references unknown device \"%s\". You may have to fix this entry manually after conversion.")
path device;
device
--
2.7.4
8 years, 2 months
[PATCH] v2v: linux: accept 'sr' devices is fstab
by Tomáš Golembiovský
Do not print warning for 'sr' devices when converting fstab. Not all
systems create the /dev/cdrom symlink for SCSI CD-ROM devices. Moreover,
on systems with multiple CD-ROMs, having entries for /dev/sr* devices
may be inevitable.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
---
v2v/convert_linux.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 06943cd..9bc0271 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -1330,7 +1330,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
try List.assoc device map
with Not_found ->
if String.find device "md" = -1 && String.find device "fd" = -1 &&
- device <> "cdrom" then
+ String.find device "sr" = -1 && device <> "cdrom" then
warning (f_"%s references unknown device \"%s\". You may have to fix this entry manually after conversion.")
path device;
device
--
2.9.2
8 years, 2 months
[PATCH 1/2] v2v: linux: correctly reconfigure the initrd on Debian
by Tomáš Golembiovský
Using update-initramfs is the native way of updating initrd on Debian
based systems.
Signed-off-by: Tomáš Golembiovský <tgolembi(a)redhat.com>
---
v2v/convert_linux.ml | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index 47fec9e..103728b 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -865,6 +865,15 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
ignore (g#command (Array.of_list args))
in
+ let run_update_initramfs_command () =
+ let args =
+ "/usr/sbin/update-initramfs" ::
+ (if verbose () then [ "-v" ] else [])
+ @ [ "-c"; "-k"; mkinitrd_kv ]
+ in
+ ignore (g#command (Array.of_list args))
+ in
+
if g#is_file ~followsymlinks:true "/sbin/dracut" then
run_dracut_command "/sbin/dracut"
else if g#is_file ~followsymlinks:true "/usr/bin/dracut" then
@@ -878,6 +887,18 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
"-k"; kernel.ki_vmlinuz |]
)
)
+ else if family = `Debian_family then (
+ if not (g#is_file ~followsymlinks:true "/usr/sbin/update-initramfs") then
+ error (f_"unable to rebuild initrd (%s) because update-initramfs was not found in the guest")
+ initrd;
+
+ (* The modules to add to initrd are defined in a file. *)
+ let modules = String.concat "\n" modules in
+ let modules = "#\n# Added by virt-v2v\n" ^ modules ^ "\n" in
+ ignore (g#write_append "/etc/initramfs-tools/modules" modules);
+
+ run_update_initramfs_command ()
+ )
else if g#is_file ~followsymlinks:true "/sbin/mkinitrd" then (
let module_args = List.map (sprintf "--with=%s") modules in
let args =
--
2.9.2
8 years, 2 months
[PATCH 0/2] More on the topic of Debian/Ubuntu conversion
by Tomáš Golembiovský
Adding couple more bits to the conversion of systems based on Debian.
It does not mean we can convert it yet, but we will get there eventually.
Tomáš Golembiovský (2):
v2v: linux: correctly reconfigure the initrd on Debian
v2v: ilnux: detect name of grub2-mkconfig
v2v/convert_linux.ml | 42 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
--
2.9.2
8 years, 2 months