in-place: Add new -O option to write inspector XML

resolves: RHEL-58032
This commit is contained in:
Richard W.M. Jones 2024-12-09 19:10:22 +00:00
parent d43c5a3af1
commit 88802688a4
15 changed files with 4592 additions and 3 deletions

View File

@ -0,0 +1,32 @@
From a794e7936064812540f0bb8b37827fa562a6fba4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Oct 2024 15:39:31 +0000
Subject: [PATCH] in-place: Add a warning about checking the exit code
(cherry picked from commit 8b768fd9b17412ee8893447dc0f1e75bc612df58)
---
docs/virt-v2v-in-place.pod | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod
index b7384210..4057dae5 100644
--- a/docs/virt-v2v-in-place.pod
+++ b/docs/virt-v2v-in-place.pod
@@ -35,6 +35,17 @@ If the guest has been copied to local libvirt then:
virt-v2v-in-place -i libvirt guest
+=head2 Exit code
+
+If virt-v2v-in-place fails it will return a non-zero (error) exit
+code. In this case, the disk image will be in an B<unknown, possibly
+corrupted state>.
+
+If the image contains important information you should ensure you have
+a backup before trying a virt-v2v-in-place conversion. And you should
+check the exit code is zero before using the disk image after a
+conversion.
+
=head1 EXAMPLES
=head1 OPTIONS

View File

@ -0,0 +1,30 @@
From 669acaf0f56ffdb85a1d72fb37ff2958600003cc Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 15 Nov 2024 14:00:07 +0000
Subject: [PATCH] -i libvirt: Trim whitespace around name
In -i libvirt / -i libvirtxml we didn't trim whitespace
around the name, so:
<name> foo </name>
would set the input name to the literal string " foo ".
(cherry picked from commit 9cb76069040543ce25003ac8c620aff3724964fc)
---
input/parse_libvirt_xml.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/input/parse_libvirt_xml.ml b/input/parse_libvirt_xml.ml
index 4d0fcdf3..8009a05a 100644
--- a/input/parse_libvirt_xml.ml
+++ b/input/parse_libvirt_xml.ml
@@ -78,7 +78,7 @@ let parse_libvirt_xml ?conn xml =
match xpath_string "/domain/name/text()" with
| None | Some "" ->
error (f_"in the libvirt XML metadata, <name> is missing or empty")
- | Some s -> s in
+ | Some s -> String.trim s in
let genid =
match xpath_string "/domain/genid/text()" with
| None | Some "" -> None

View File

@ -0,0 +1,962 @@
From faf29e12e7928345ca0178923f468fee34d067e8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 15 Nov 2024 11:49:26 +0000
Subject: [PATCH] -o qemu: Replace hard-coded UEFI paths
Update the qemu shell script to simply find the UEFI paths as
required.
Remove lib/uefi.ml:find_uefi_firmware as this function is no longer
needed.
Remove common/mlv2v/ everywhere. This contained a list of UEFI code
and NVRAM files which is no longer used.
Update common submodule. This pulls in:
Richard W.M. Jones (5):
mlcustomize/customize_run.ml: Move 'in' to new line
mlstdutils/guestfs_config: Define host_os
mlcustomize, mltools: Check guest OS is compatible before allowing --run
Remove mlv2v/ subdirectory
qemuopts: Add ability to add raw, unquoted output to qemu scripts
qemuopts: Fix missing break statement
(cherry picked from commit 69b4e83935b03e10c5da9b93f987eb8ddd2cde31)
---
Makefile.am | 1 -
common | 2 +-
configure.ac | 1 -
convert/Makefile.am | 2 -
in-place/Makefile.am | 4 +-
input/Makefile.am | 2 -
inspector/Makefile.am | 4 +-
lib/Makefile.am | 1 -
lib/utils.ml | 20 -------
lib/utils.mli | 4 --
ocaml-dep.sh.in | 1 -
output/Makefile.am | 2 -
output/output_qemu.ml | 121 +++++++++++++++++++++++-------------------
output/qemuopts-c.c | 12 +++++
output/qemuopts.ml | 1 +
output/qemuopts.mli | 4 ++
po/POTFILES-ml | 1 -
v2v/Makefile.am | 5 +-
18 files changed, 87 insertions(+), 101 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 51370188..4cc87324 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,7 +37,6 @@ SUBDIRS += common/mlxml
SUBDIRS += common/mltools
SUBDIRS += common/mlcustomize
SUBDIRS += common/mldrivers
-SUBDIRS += common/mlv2v
SUBDIRS += lib
SUBDIRS += input
SUBDIRS += output
Submodule common 2d42128e..faee2645:
diff --git a/common/.gitignore b/common/.gitignore
index 49915e31..44f49eb6 100644
--- a/common/.gitignore
+++ b/common/.gitignore
@@ -58,7 +58,6 @@ Makefile.in
/mlutils/.depend
/mlutils/c_utils_unit_tests
/mlutils/oUnit-*
-/mlv2v/.depend
/mlvisit/.depend
/mlvisit/visit_tests
/mlxml/.depend
diff --git a/common/mlcustomize/customize_run.ml b/common/mlcustomize/customize_run.ml
index 1d7c13ea..5ec5ed11 100644
--- a/common/mlcustomize/customize_run.ml
+++ b/common/mlcustomize/customize_run.ml
@@ -44,21 +44,13 @@ let run (g : G.guestfs) root (ops : ops) =
let debug_logfile () =
try g#download logfile "/dev/stderr"
with exn ->
- warning (f_"log file %s: %s (ignored)") logfile (Printexc.to_string exn) in
+ warning (f_"log file %s: %s (ignored)") logfile (Printexc.to_string exn)
+ in
(* Useful wrapper for scripts. *)
let do_run ~display ?(warn_failed_no_network = false) cmd =
- let incompatible_fn () =
- let guest_arch = g#inspect_get_arch root in
- error (f_"host cpu (%s) and guest arch (%s) are not compatible, \
- so you cannot use command line options that involve \
- running commands in the guest. Use --firstboot scripts \
- instead.")
- Guestfs_config.host_cpu guest_arch
- in
-
try
- run_in_guest_command g root ~logfile ~incompatible_fn cmd
+ run_in_guest_command g root ~logfile cmd
with
G.Error msg ->
debug_logfile ();
diff --git a/common/mlstdutils/guestfs_config.ml.in b/common/mlstdutils/guestfs_config.ml.in
index 0ab95bd9..84929581 100644
--- a/common/mlstdutils/guestfs_config.ml.in
+++ b/common/mlstdutils/guestfs_config.ml.in
@@ -22,4 +22,5 @@ let package_version = "@PACKAGE_VERSION@"
let package_version_full = "@PACKAGE_VERSION_FULL@"
let prefix = "@prefix@"
let datadir = prefix ^ "/share"
+let host_os = "@host_os@"
let host_cpu = "@host_cpu@"
diff --git a/common/mlstdutils/guestfs_config.mli b/common/mlstdutils/guestfs_config.mli
index 78df3040..70161c01 100644
--- a/common/mlstdutils/guestfs_config.mli
+++ b/common/mlstdutils/guestfs_config.mli
@@ -31,5 +31,8 @@ val prefix : string
val datadir : string
(** The configure value [@datadir@] *)
+val host_os : string
+(** The configure value [@host_os@] *)
+
val host_cpu : string
(** The configure value [@host_cpu@] *)
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
index 23f16c51..1ff72ff3 100644
--- a/common/mltools/tools_utils.ml
+++ b/common/mltools/tools_utils.ml
@@ -737,11 +737,21 @@ let run_in_guest_command g root ?logfile ?incompatible_fn cmd =
(* Is the host_cpu compatible with the guest arch? ie. Can we
* run commands in this guest?
*)
+ let guest_os = g#inspect_get_type root in
+ let guest_os_compatible =
+ String.is_prefix Guestfs_config.host_os "linux" &&
+ guest_os = "linux" in
let guest_arch = g#inspect_get_arch root in
let guest_arch_compatible = guest_arch_compatible guest_arch in
- if not guest_arch_compatible then (
+ if not guest_os_compatible || not guest_arch_compatible then (
match incompatible_fn with
- | None -> ()
+ | None ->
+ error (f_"host (%s/%s) and guest (%s/%s) are not compatible, \
+ so you cannot use command line options that involve \
+ running commands in the guest. Use --firstboot scripts \
+ instead.")
+ Guestfs_config.host_os Guestfs_config.host_cpu
+ guest_os guest_arch
| Some fn -> fn ()
)
else (
diff --git a/common/mltools/tools_utils.mli b/common/mltools/tools_utils.mli
index 193ba7b6..4d627676 100644
--- a/common/mltools/tools_utils.mli
+++ b/common/mltools/tools_utils.mli
@@ -233,9 +233,15 @@ val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
val run_in_guest_command : Guestfs.guestfs -> string -> ?logfile:string -> ?incompatible_fn:(unit -> unit) -> string -> unit
(** [run_in_guest_command g root ?incompatible_archs_fn cmd]
runs a command in the guest, which is already mounted for the
- specified [root]. The command is run directly in case the
- architecture of the host and the guest are compatible, optionally
- calling [?incompatible_fn] in case they are not.
+ specified [root].
+
+ The command is run directly in the case that the host and guest
+ are compatible.
+
+ If they are not compatible, the command is not run and an error
+ is printed. However you can override the error by setting
+ [?incompatible_fn], which is called so you can do something else
+ (like install a firstboot script).
[?logfile] is an optional file in the guest to where redirect
stdout and stderr of the command. *)
diff --git a/common/mlv2v/Makefile.am b/common/mlv2v/Makefile.am
deleted file mode 100644
index 945f9813..00000000
--- a/common/mlv2v/Makefile.am
+++ /dev/null
@@ -1,91 +0,0 @@
-# libguestfs OCaml virt-v2v generated code
-# Copyright (C) 2011-2019 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.
-
-include $(top_srcdir)/subdir-rules.mk
-
-EXTRA_DIST = \
- $(generator_built) \
- $(SOURCES_MLI) \
- $(SOURCES_ML) \
- $(SOURCES_C)
-
-generator_built = \
- uefi.mli \
- uefi.ml
-
-SOURCES_MLI = \
- uefi.mli
-
-SOURCES_ML = \
- uefi.ml
-
-SOURCES_C = \
- dummy.c
-
-# We pretend that we're building a C library. automake handles the
-# compilation of the C sources for us. At the end we take the C
-# objects and OCaml objects and link them into the OCaml library.
-# This C library is never used.
-
-noinst_LIBRARIES = libmlv2v.a
-
-if !HAVE_OCAMLOPT
-MLV2V_CMA = mlv2v.cma
-else
-MLV2V_CMA = mlv2v.cmxa
-endif
-
-noinst_DATA = $(MLV2V_CMA)
-
-libmlv2v_a_SOURCES = $(SOURCES_C)
-libmlv2v_a_CPPFLAGS = \
- -DCAML_NAME_SPACE \
- -I. \
- -I$(top_builddir) \
- -I$(shell $(OCAMLC) -where)
-libmlv2v_a_CFLAGS = \
- $(WARN_CFLAGS) $(WERROR_CFLAGS) \
- -fPIC
-
-BOBJECTS = $(SOURCES_ML:.ml=.cmo)
-XOBJECTS = $(BOBJECTS:.cmo=.cmx)
-
-OCAMLPACKAGES = \
- -package str,unix \
- -I $(builddir)
-OCAMLPACKAGES_TESTS = $(MLV2V_CMA)
-
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
-
-if !HAVE_OCAMLOPT
-OBJECTS = $(BOBJECTS)
-else
-OBJECTS = $(XOBJECTS)
-endif
-
-libmlv2v_a_DEPENDENCIES = $(OBJECTS)
-
-$(MLV2V_CMA): $(OBJECTS) libmlv2v.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
- $(OBJECTS) $(libmlv2v_a_OBJECTS) -o mlv2v
-
-# OCaml dependencies.
-.depend: $(srcdir)/*.mli $(srcdir)/*.ml
- $(top_builddir)/ocaml-dep.sh $^
--include .depend
-
-.PHONY: docs
diff --git a/common/mlv2v/dummy.c b/common/mlv2v/dummy.c
deleted file mode 100644
index ebab6198..00000000
--- a/common/mlv2v/dummy.c
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Dummy source, to be used for OCaml-based tools with no C sources. */
-enum { foo = 1 };
diff --git a/common/mlv2v/uefi.ml b/common/mlv2v/uefi.ml
deleted file mode 100644
index 7a2610f2..00000000
--- a/common/mlv2v/uefi.ml
+++ /dev/null
@@ -1,71 +0,0 @@
-(* libguestfs generated file
- * WARNING: THIS FILE IS GENERATED
- * from the code in the generator/ subdirectory.
- * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
- *
- * Copyright (C) 2009-2023 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.
- *)
-
-type uefi_firmware = {
- code : string;
- code_debug : string option;
- vars : string;
- flags : uefi_flags;
-}
-and uefi_flags = uefi_flag list
-and uefi_flag = UEFI_FLAG_SECURE_BOOT_REQUIRED
-
-let uefi_aarch64_firmware = [
- { code = "/usr/share/AAVMF/AAVMF_CODE.fd";
- code_debug = Some "/usr/share/AAVMF/AAVMF_CODE.verbose.fd";
- vars = "/usr/share/AAVMF/AAVMF_VARS.fd";
- flags = [];
- };
- { code = "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw";
- code_debug = None;
- vars = "/usr/share/edk2/aarch64/vars-template-pflash.raw";
- flags = [];
- };
-]
-
-let uefi_x86_64_firmware = [
- { code = "/usr/share/OVMF/OVMF_CODE.fd";
- code_debug = None;
- vars = "/usr/share/OVMF/OVMF_VARS.fd";
- flags = [];
- };
- { code = "/usr/share/OVMF/OVMF_CODE.secboot.fd";
- code_debug = None;
- vars = "/usr/share/OVMF/OVMF_VARS.fd";
- flags = [UEFI_FLAG_SECURE_BOOT_REQUIRED];
- };
- { code = "/usr/share/edk2/ovmf/OVMF_CODE.fd";
- code_debug = None;
- vars = "/usr/share/edk2/ovmf/OVMF_VARS.fd";
- flags = [];
- };
- { code = "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd";
- code_debug = None;
- vars = "/usr/share/edk2/ovmf/OVMF_VARS.fd";
- flags = [UEFI_FLAG_SECURE_BOOT_REQUIRED];
- };
- { code = "/usr/share/qemu/ovmf-x86_64-code.bin";
- code_debug = None;
- vars = "/usr/share/qemu/ovmf-x86_64-vars.bin";
- flags = [];
- };
-]
diff --git a/common/mlv2v/uefi.mli b/common/mlv2v/uefi.mli
deleted file mode 100644
index 33789979..00000000
--- a/common/mlv2v/uefi.mli
+++ /dev/null
@@ -1,35 +0,0 @@
-(* libguestfs generated file
- * WARNING: THIS FILE IS GENERATED
- * from the code in the generator/ subdirectory.
- * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.
- *
- * Copyright (C) 2009-2023 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.
- *)
-
-(** UEFI paths. *)
-
-type uefi_firmware = {
- code : string; (** code file *)
- code_debug : string option; (** code debug file *)
- vars : string; (** vars template file *)
- flags : uefi_flags; (** flags *)
-}
-and uefi_flags = uefi_flag list
-and uefi_flag = UEFI_FLAG_SECURE_BOOT_REQUIRED
-
-val uefi_aarch64_firmware : uefi_firmware list
-val uefi_x86_64_firmware : uefi_firmware list
diff --git a/common/qemuopts/qemuopts.c b/common/qemuopts/qemuopts.c
index b12fe38f..7dd9136d 100644
--- a/common/qemuopts/qemuopts.c
+++ b/common/qemuopts/qemuopts.c
@@ -76,13 +76,14 @@ enum qopt_type {
QOPT_FLAG,
QOPT_ARG,
QOPT_ARG_NOQUOTE,
+ QOPT_RAW,
QOPT_ARG_LIST,
};
struct qopt {
enum qopt_type type;
char *flag; /* eg. "-m" */
- char *value; /* Value, for QOPT_ARG, QOPT_ARG_NOQUOTE. */
+ char *value; /* Value, for QOPT_ARG, QOPT_ARG_NOQUOTE, QOPT_RAW */
char **values; /* List of values, for QOPT_ARG_LIST. */
};
@@ -353,6 +354,27 @@ qemuopts_add_arg_noquote (struct qemuopts *qopts, const char *flag,
return 0;
}
+int
+qemuopts_add_raw (struct qemuopts *qopts, const char *str)
+{
+ struct qopt *qopt;
+ char *value_copy;
+
+ value_copy = strdup (str);
+ if (value_copy == NULL)
+ return -1;
+
+ if ((qopt = extend_options (qopts)) == NULL) {
+ free (value_copy);
+ return -1;
+ }
+
+ qopt->type = QOPT_RAW;
+ qopt->value = value_copy;
+
+ return 0;
+}
+
/**
* Start an argument that takes a comma-separated list of fields.
*
@@ -724,6 +746,12 @@ qemuopts_to_channel (struct qemuopts *qopts, FILE *fp)
shell_and_comma_quote (qopts->options[i].values[j], fp);
}
break;
+
+ case QOPT_RAW:
+ fprintf (fp, "%s%s",
+ nl, qopts->options[i].value);
+ break;
+
}
}
fputc ('\n', fp);
@@ -769,6 +797,12 @@ qemuopts_to_argv (struct qemuopts *qopts)
case QOPT_ARG:
case QOPT_ARG_LIST:
n += 2;
+ break;
+
+ /* Raw is incompatible with using argv. */
+ case QOPT_RAW:
+ errno = EINVAL;
+ return NULL;
}
}
@@ -845,6 +879,10 @@ qemuopts_to_argv (struct qemuopts *qopts)
}
ret[n][len] = '\0';
n++;
+ break;
+
+ case QOPT_RAW:
+ abort ();
}
}
@@ -924,7 +962,8 @@ qemuopts_to_config_channel (struct qemuopts *qopts, FILE *fp)
return -1;
case QOPT_ARG_NOQUOTE:
- /* arg_noquote is incompatible with this function. */
+ case QOPT_RAW:
+ /* arg_noquote and raw are incompatible with this function. */
errno = EINVAL;
return -1;
@@ -960,6 +999,7 @@ qemuopts_to_config_channel (struct qemuopts *qopts, FILE *fp)
case QOPT_FLAG:
case QOPT_ARG_NOQUOTE:
case QOPT_ARG:
+ case QOPT_RAW:
abort ();
case QOPT_ARG_LIST:
diff --git a/common/qemuopts/qemuopts.h b/common/qemuopts/qemuopts.h
index 08efcd9a..29f81475 100644
--- a/common/qemuopts/qemuopts.h
+++ b/common/qemuopts/qemuopts.h
@@ -31,6 +31,7 @@ extern int qemuopts_add_flag (struct qemuopts *qopts, const char *flag);
extern int qemuopts_add_arg (struct qemuopts *qopts, const char *flag, const char *value);
extern int qemuopts_add_arg_format (struct qemuopts *qopts, const char *flag, const char *fs, ...) __attribute__((format (printf,3,4)));
extern int qemuopts_add_arg_noquote (struct qemuopts *qopts, const char *flag, const char *value);
+extern int qemuopts_add_raw (struct qemuopts *qopts, const char *str);
extern int qemuopts_start_arg_list (struct qemuopts *qopts, const char *flag);
extern int qemuopts_append_arg_list (struct qemuopts *qopts, const char *value);
extern int qemuopts_append_arg_list_format (struct qemuopts *qopts, const char *fs, ...) __attribute__((format (printf,2,3)));
diff --git a/configure.ac b/configure.ac
index 0c8473bd..8d6a506b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,7 +137,6 @@ AC_CONFIG_FILES([Makefile
common/mlstdutils/guestfs_config.ml
common/mltools/Makefile
common/mlutils/Makefile
- common/mlv2v/Makefile
common/mlxml/Makefile
common/qemuopts/Makefile
common/utils/Makefile
diff --git a/convert/Makefile.am b/convert/Makefile.am
index 2d34fe7c..2809c555 100644
--- a/convert/Makefile.am
+++ b/convert/Makefile.am
@@ -83,7 +83,6 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/common/mltools \
-I $(top_builddir)/common/mldrivers \
- -I $(top_builddir)/common/mlv2v \
-I $(top_builddir)/common/mlxml
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -113,7 +112,6 @@ OCAMLLINKFLAGS = \
mltools.$(MLARCHIVE) \
mlcustomize.$(MLARCHIVE) \
mldrivers.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
diff --git a/in-place/Makefile.am b/in-place/Makefile.am
index 2217ff40..2fecb3a7 100644
--- a/in-place/Makefile.am
+++ b/in-place/Makefile.am
@@ -64,8 +64,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlxml \
-I $(top_builddir)/common/mltools \
-I $(top_builddir)/common/mlcustomize \
- -I $(top_builddir)/common/mldrivers \
- -I $(top_builddir)/common/mlv2v
+ -I $(top_builddir)/common/mldrivers
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
endif
@@ -101,7 +100,6 @@ OCAMLLINKFLAGS = \
mllibvirt.$(MLARCHIVE) \
mlcustomize.$(MLARCHIVE) \
mldrivers.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
mlconvert.$(MLARCHIVE) \
mlinput.$(MLARCHIVE) \
diff --git a/input/Makefile.am b/input/Makefile.am
index 4153f878..75bee624 100644
--- a/input/Makefile.am
+++ b/input/Makefile.am
@@ -104,7 +104,6 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlgettext \
-I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/common/mltools \
- -I $(top_builddir)/common/mlv2v \
-I $(top_builddir)/common/mlxml
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -132,7 +131,6 @@ OCAMLLINKFLAGS = \
mlxml.$(MLARCHIVE) \
mltools.$(MLARCHIVE) \
mllibvirt.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 51ac71f9..172b2dc0 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -64,8 +64,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlxml \
-I $(top_builddir)/common/mltools \
-I $(top_builddir)/common/mlcustomize \
- -I $(top_builddir)/common/mldrivers \
- -I $(top_builddir)/common/mlv2v
+ -I $(top_builddir)/common/mldrivers
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
endif
@@ -101,7 +100,6 @@ OCAMLLINKFLAGS = \
mllibvirt.$(MLARCHIVE) \
mlcustomize.$(MLARCHIVE) \
mldrivers.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
mlconvert.$(MLARCHIVE) \
mlinput.$(MLARCHIVE) \
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a8776019..5cec771c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -87,7 +87,6 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mltools \
-I $(top_builddir)/common/mlutils \
- -I $(top_builddir)/common/mlv2v \
-I $(top_builddir)/common/mlxml
OCAMLPACKAGES_TESTS = $(MLV2VLIB_CMA)
diff --git a/lib/utils.ml b/lib/utils.ml
index 4c9b7415..c4cfd89b 100644
--- a/lib/utils.ml
+++ b/lib/utils.ml
@@ -69,26 +69,6 @@ let qemu_supports_sound_card = function
| Types.USBAudio
-> false
-(* Find the UEFI firmware. *)
-let find_uefi_firmware guest_arch =
- let files =
- (* The lists of firmware are actually defined in common/utils/uefi.c. *)
- match guest_arch with
- | "x86_64" -> Uefi.uefi_x86_64_firmware
- | "aarch64" -> Uefi.uefi_aarch64_firmware
- | arch ->
- error (f_"dont know how to convert UEFI guests for architecture %s")
- guest_arch in
- let rec loop = function
- | [] ->
- error (f_"cannot find firmware for UEFI guests.\n\nYou probably \
- need to install OVMF (x86-64), or AAVMF (aarch64)")
- | ({ Uefi.code; vars = vars_template } as ret) :: rest ->
- if Sys.file_exists code && Sys.file_exists vars_template then ret
- else loop rest
- in
- loop files
-
let compare_app2_versions app1 app2 =
let i = compare app1.Guestfs.app2_epoch app2.Guestfs.app2_epoch in
if i <> 0 then i
diff --git a/lib/utils.mli b/lib/utils.mli
index 46d05306..afe61a4e 100644
--- a/lib/utils.mli
+++ b/lib/utils.mli
@@ -36,10 +36,6 @@ val kvm_arch : string -> string
val qemu_supports_sound_card : Types.source_sound_model -> bool
(** Does qemu support the given sound card? *)
-val find_uefi_firmware : string -> Uefi.uefi_firmware
-(** Find the UEFI firmware for the guest architecture.
- This cannot return an error, it calls [error] and fails instead. *)
-
val compare_app2_versions : Guestfs.application2 -> Guestfs.application2 -> int
(** Compare two app versions. *)
diff --git a/ocaml-dep.sh.in b/ocaml-dep.sh.in
index 7f3130e5..565f880f 100755
--- a/ocaml-dep.sh.in
+++ b/ocaml-dep.sh.in
@@ -41,7 +41,6 @@ common/mlprogress
common/mlstdutils
common/mltools
common/mlutils
-common/mlv2v
common/mlvisit
common/mlxml
lib
diff --git a/output/Makefile.am b/output/Makefile.am
index 1e6799c3..f736d52d 100644
--- a/output/Makefile.am
+++ b/output/Makefile.am
@@ -157,7 +157,6 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlgettext \
-I $(top_builddir)/common/mlpcre \
-I $(top_builddir)/common/mltools \
- -I $(top_builddir)/common/mlv2v \
-I $(top_builddir)/common/mlxml
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
@@ -188,7 +187,6 @@ OCAMLLINKFLAGS = \
mlxml.$(MLARCHIVE) \
mltools.$(MLARCHIVE) \
mllibvirt.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
$(LINK_CUSTOM_OCAMLC_ONLY)
diff --git a/output/output_qemu.ml b/output/output_qemu.ml
index b6f24565..fd0182d6 100644
--- a/output/output_qemu.ml
+++ b/output/output_qemu.ml
@@ -105,30 +105,56 @@ module QEMU = struct
let { guestcaps; target_buses; target_firmware } = target_meta in
+ (* Start the shell script. Write it to a temporary file
+ * which we rename at the end.
+ *)
let file = output_storage // output_name ^ ".sh" in
+ let tmpfile = file ^ ".tmp" in
+ On_exit.unlink tmpfile;
- let uefi_firmware =
- match target_firmware with
- | TargetBIOS -> None
- | TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in
- let machine, secure_boot_required =
- match guestcaps.gcaps_machine, uefi_firmware with
- | _, Some { Uefi.flags }
- when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags ->
- (* Force machine type to Q35 because PC does not support
- * secure boot. We must remove this when we get the
- * correct machine type from libosinfo in future. XXX
- *)
- Q35, true
- | machine, _ ->
- machine, false in
- let smm = secure_boot_required in
+ let chan = open_out tmpfile in
+ let fpf fs = fprintf chan fs in
+ fpf "#!/bin/sh -\n";
+ fpf "\n";
- let machine_str =
- match machine with
- | I440FX -> "pc"
- | Q35 -> "q35"
- | Virt -> "virt" in
+ (* Allow the user to override our choice of machine type. *)
+ let () =
+ let machine_str =
+ match guestcaps.gcaps_machine with
+ | I440FX -> "pc"
+ | Q35 -> "q35"
+ | Virt -> "virt" in
+ fpf "machine=%s\n" machine_str;
+ fpf "\n" in
+
+ (* If the firmware is UEFI, locate the OVMF files. *)
+ (match target_firmware with
+ | TargetBIOS -> ()
+ | TargetUEFI ->
+ let prefix =
+ match guestcaps.gcaps_arch with
+ | "x86_64" ->
+ fpf "uefi_dir=/usr/share/OVMF\n"; "OVMF"
+ | "aarch64" ->
+ fpf "uefi_dir=/usr/share/AAVMF\n"; "AAVMF"
+ | arch ->
+ error (f_"dont know how to convert UEFI guests \
+ for architecture %s")
+ arch in
+ fpf "uefi_code=\"$( \
+ find $uefi_dir -name '%s_CODE*.fd' -print -quit )\"\n"
+ prefix;
+ fpf "uefi_vars_template=\"$( \
+ find $uefi_dir -name '%s_VARS.fd' -print -quit )\"\n"
+ prefix;
+ fpf "\n";
+ fpf "# Make a copy of the UEFI variables template\n";
+ fpf "uefi_vars=\"$(mktemp)\"\n";
+ fpf "cp \"$uefi_vars_template\" \"$uefi_vars\"\n";
+ fpf "\n";
+ fpf "# You may need to set this 'on' to use secure boot\n";
+ fpf "smm=off\n";
+ );
(* Construct the command line. Note that the [Qemuopts]
* module deals with shell and qemu comma quoting.
@@ -152,20 +178,17 @@ module QEMU = struct
if not guestcaps.gcaps_rtc_utc then arg "-rtc" "base=localtime";
- arg_list "-machine" (machine_str ::
- (if smm then ["smm=on"] else []) @
- ["accel=kvm:tcg"]);
+ arg_noquote "-machine" "$machine${smm:+,smm=$smm},accel=kvm:tcg";
- (match uefi_firmware with
- | None -> ()
- | Some { Uefi.code } ->
- if secure_boot_required then
- arg_list "-global"
- ["driver=cfi.pflash01"; "property=secure"; "value=on"];
- arg_list "-drive"
- ["if=pflash"; "format=raw"; "file=" ^ code; "readonly=on"];
- arg_noquote "-drive" "if=pflash,format=raw,file=\"$uefi_vars\"";
- );
+ fpf "if [ \"$uefi_code\" != \"\" ]; then\n";
+ fpf " uefi_args=\"\\\n";
+ fpf " -global driver=cfi.pflash01,property=secure,value=$smm \\\n";
+ fpf " -drive if=pflash,format=raw,file=$uefi_code,readonly=on \\\n";
+ fpf " -drive if=pflash,format=raw,file=$uefi_vars \\\n";
+ fpf " \"\n";
+ fpf "fi\n";
+ fpf "\n";
+ Qemuopts.raw cmd "$uefi_args";
arg "-m" (Int64.to_string (source.s_memory /^ 1024L /^ 1024L));
@@ -209,7 +232,7 @@ module QEMU = struct
Array.exists floppy_filter target_buses.target_floppy_bus in
if ide_ctrl_needed then (
- match machine with
+ match guestcaps.gcaps_machine with
| I440FX -> ()
(* The PC machine has a built-in controller of type "piix3-ide"
* providing buses "ide.0" and "ide.1", with each bus fitting two
@@ -232,7 +255,7 @@ module QEMU = struct
arg_list "-device" [ "virtio-scsi-pci"; "id=scsi0" ];
if floppy_ctrl_needed then (
- match machine with
+ match guestcaps.gcaps_machine with
| I440FX -> ()
(* The PC machine has a built-in controller of type "isa-fdc"
* providing bus "floppy-bus.0", fitting two devices.
@@ -283,7 +306,7 @@ module QEMU = struct
*)
let backend_name = sprintf "drive-ide-%d" frontend_ctr
and ide_bus, ide_unit =
- match machine with
+ match guestcaps.gcaps_machine with
| I440FX -> frontend_ctr / 2, frontend_ctr mod 2
| Q35 -> frontend_ctr, 0
| Virt -> 0, 0 (* should never happen, see warning above *) in
@@ -450,25 +473,13 @@ module QEMU = struct
if inspect.i_type = "linux" then
arg "-serial" "stdio";
- (* Write the qemu script. *)
- with_open_out file (
- fun chan ->
- let fpf fs = fprintf chan fs in
- fpf "#!/bin/sh -\n";
- fpf "\n";
-
- (match uefi_firmware with
- | None -> ()
- | Some { Uefi.vars = vars_template } ->
- fpf "# Make a copy of the UEFI variables template\n";
- fpf "uefi_vars=\"$(mktemp)\"\n";
- fpf "cp %s \"$uefi_vars\"\n" (quote vars_template);
- fpf "\n"
- );
-
- Qemuopts.to_chan cmd chan
- );
+ (* Write the qemu command. *)
+ Qemuopts.to_chan cmd chan;
+ (* Finish off by renaming the temporary file to the final file
+ * and making it executable.
+ *)
+ Unix.rename tmpfile file;
Unix.chmod file 0o755;
(* If -oo qemu-boot option was specified then we should boot the guest. *)
diff --git a/output/qemuopts-c.c b/output/qemuopts-c.c
index 03c40206..1d080737 100644
--- a/output/qemuopts-c.c
+++ b/output/qemuopts-c.c
@@ -176,6 +176,18 @@ guestfs_int_qemuopts_arg_list (value qoptsv, value flagv, value valuesv)
CAMLreturn (Val_unit);
}
+value
+guestfs_int_qemuopts_raw (value qoptsv, value strv)
+{
+ CAMLparam2 (qoptsv, strv);
+ struct qemuopts *qopts = Qopts_val (qoptsv);
+
+ if (qemuopts_add_raw (qopts, String_val (strv)) == -1)
+ unix_error (errno, (char *) "qemuopts_add_raw", strv);
+
+ CAMLreturn (Val_unit);
+}
+
value
guestfs_int_qemuopts_to_script (value qoptsv, value strv)
{
diff --git a/output/qemuopts.ml b/output/qemuopts.ml
index 1ba57dba..bc4e33d7 100644
--- a/output/qemuopts.ml
+++ b/output/qemuopts.ml
@@ -25,6 +25,7 @@ external flag : t -> string -> unit = "guestfs_int_qemuopts_flag"
external arg : t -> string -> string -> unit = "guestfs_int_qemuopts_arg"
external arg_noquote : t -> string -> string -> unit = "guestfs_int_qemuopts_arg_noquote"
external arg_list : t -> string -> string list -> unit = "guestfs_int_qemuopts_arg_list"
+external raw : t -> string -> unit = "guestfs_int_qemuopts_raw"
external to_script : t -> string -> unit = "guestfs_int_qemuopts_to_script"
external _to_chan : t -> Unix.file_descr -> unit = "guestfs_int_qemuopts_to_chan"
diff --git a/output/qemuopts.mli b/output/qemuopts.mli
index 5c39a32f..bd65405f 100644
--- a/output/qemuopts.mli
+++ b/output/qemuopts.mli
@@ -53,6 +53,10 @@ val arg_list : t -> string -> string list -> unit
This does both qemu comma-quoting and shell-quoting as required. *)
+val raw : t -> string -> unit
+(** [raw "stuff"] adds [stuff] to the command line completely
+ unquoted. Use with care. *)
+
val to_script : t -> string -> unit
(** [to_script t "./file.sh"] writes the resulting command line to
a file. The file begins with [#!/bin/sh] and is chmod 0755. *)
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index e88a18b0..7f1d1cdb 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -42,7 +42,6 @@ common/mltools/urandom.ml
common/mltools/xpath_helpers.ml
common/mlutils/c_utils.ml
common/mlutils/unix_utils.ml
-common/mlv2v/uefi.ml
common/mlxml/xml.ml
in-place/in_place.ml
input/OVA.ml
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index d609ab02..9378eb89 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -67,8 +67,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/common/mlxml \
-I $(top_builddir)/common/mltools \
-I $(top_builddir)/common/mlcustomize \
- -I $(top_builddir)/common/mldrivers \
- -I $(top_builddir)/common/mlv2v
+ -I $(top_builddir)/common/mldrivers
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
endif
@@ -104,7 +103,6 @@ OCAMLLINKFLAGS = \
mllibvirt.$(MLARCHIVE) \
mlcustomize.$(MLARCHIVE) \
mldrivers.$(MLARCHIVE) \
- mlv2v.$(MLARCHIVE) \
mlv2vlib.$(MLARCHIVE) \
mlconvert.$(MLARCHIVE) \
mlinput.$(MLARCHIVE) \
@@ -164,7 +162,6 @@ v2v_unit_tests_DEPENDENCIES = \
../common/mltools/mltools.$(MLARCHIVE) \
../common/mlcustomize/mlcustomize.$(MLARCHIVE) \
../common/mldrivers/mldrivers.$(MLARCHIVE) \
- ../common/mlv2v/mlv2v.$(MLARCHIVE) \
$(top_srcdir)/ocaml-link.sh
v2v_unit_tests_LINK = \
$(top_srcdir)/ocaml-link.sh -cclib '$(OCAMLCLIBS)' -- \

View File

@ -0,0 +1,32 @@
From f43d92473d3da0a5f6a2da6e44ca8416ad824d8f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 15 Nov 2024 14:04:48 +0000
Subject: [PATCH] -o qemu: Add set -e, -x at the top of the output script
This adds:
set -e
#set -x
The second command is commented so that users can enable it if they
want to see the output.
(cherry picked from commit e09aaad7e787803ff5e383fa6b5276c888b42ef5)
---
output/output_qemu.ml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/output/output_qemu.ml b/output/output_qemu.ml
index fd0182d6..b0c2ff01 100644
--- a/output/output_qemu.ml
+++ b/output/output_qemu.ml
@@ -116,6 +116,9 @@ module QEMU = struct
let fpf fs = fprintf chan fs in
fpf "#!/bin/sh -\n";
fpf "\n";
+ fpf "set -e\n";
+ fpf "#set -x\n";
+ fpf "\n";
(* Allow the user to override our choice of machine type. *)
let () =

View File

@ -0,0 +1,276 @@
From 037a603c2d5cf9d2d5f8157116dbf14945277dc2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 2 Dec 2024 15:22:43 +0000
Subject: [PATCH] v2v: Implement --parallel=N for parallel disk copies
When set, run up to N copies of nbdcopy in parallel. This only
applies for guests with multiple disks.
The default, as for all older versions of virt-v2v, is to copy disks
one at a time.
(cherry picked from commit fd1148f79581b148525eb12154aef7603ccf0baa)
---
docs/virt-v2v.pod | 13 +++++++
lib/utils.ml | 6 ++++
lib/utils.mli | 4 +++
tests/Makefile.am | 2 ++
tests/test-v2v-i-disk-parallel.sh | 54 +++++++++++++++++++++++++++++
v2v/v2v.ml | 56 +++++++++++++++++++++++++------
6 files changed, 125 insertions(+), 10 deletions(-)
create mode 100755 tests/test-v2v-i-disk-parallel.sh
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 74581463..216e617d 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -749,6 +749,19 @@ C<root>.
You will get an error if virt-v2v is unable to mount/write to the
Export Storage Domain.
+=item B<--parallel> N
+
+Enable parallel copying if the guest has multiple disks. I<N> is the
+maximum number of parallel L<nbdcopy(1)> instances to run.
+
+The default is to run at most one instance of nbdcopy
+(ie. I<--parallel=1>). All versions of virt-v2v E<le> 2.7.2 also did
+disk copies one at a time.
+
+Within each guest disk, nbdcopy tries to copy in parallel if the
+underlying endpoints support that. This is not affected by this
+command line option. See the L<nbdcopy(1)> manual page for details.
+
=item B<--print-source>
Print information about the source guest and stop. This option is
diff --git a/lib/utils.ml b/lib/utils.ml
index c4cfd89b..f2da9e80 100644
--- a/lib/utils.ml
+++ b/lib/utils.ml
@@ -29,6 +29,12 @@ let large_tmpdir =
try Sys.getenv "VIRT_V2V_TMPDIR"
with Not_found -> (open_guestfs ())#get_cachedir ()
+let string_of_process_status = function
+ | Unix.WEXITED 0 -> s_"success"
+ | WEXITED i -> sprintf (f_"exited with non-zero error code %d") i
+ | WSIGNALED i -> sprintf (f_"signalled by signal %d") i
+ | WSTOPPED i -> sprintf (f_"stopped by signal %d") i
+
(* Is SELinux enabled and enforcing on the host? *)
let have_selinux =
0 = Sys.command "getenforce 2>/dev/null | grep -isq Enforcing"
diff --git a/lib/utils.mli b/lib/utils.mli
index afe61a4e..e7ee13d1 100644
--- a/lib/utils.mli
+++ b/lib/utils.mli
@@ -23,6 +23,10 @@ val large_tmpdir : string
such as overlays in this directory. Small temporary files can
use the default behaviour eg. of {!Filename.temp_file} *)
+val string_of_process_status : Unix.process_status -> string
+(** Convert a process status (such as returned by {!Unix.wait}) into
+ a printable string. *)
+
val have_selinux : bool
(** True if SELinux is enabled and enforcing on the host. *)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8a710b99..fa5bb4f1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -76,6 +76,7 @@ TESTS = \
test-v2v-cdrom.sh \
test-v2v-floppy.sh \
test-v2v-i-disk.sh \
+ test-v2v-i-disk-parallel.sh \
test-v2v-i-ova.sh \
test-v2v-inspector.sh \
test-v2v-mac.sh \
@@ -189,6 +190,7 @@ EXTRA_DIST += \
test-v2v-floppy.expected \
test-v2v-floppy.sh \
test-v2v-i-disk.sh \
+ test-v2v-i-disk-parallel.sh \
test-v2v-i-ova-as-root.ovf \
test-v2v-i-ova-as-root.sh \
test-v2v-i-ova-bad-sha1.sh \
diff --git a/tests/test-v2v-i-disk-parallel.sh b/tests/test-v2v-i-disk-parallel.sh
new file mode 100755
index 00000000..a6470fdd
--- /dev/null
+++ b/tests/test-v2v-i-disk-parallel.sh
@@ -0,0 +1,54 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014-2024 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.
+
+# Test --parallel option.
+
+set -e
+
+source ./functions.sh
+set -e
+set -x
+
+skip_if_skipped
+windows=../test-data/phony-guests/windows.img
+requires test -f $windows
+
+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
+
+d=test-v2v-i-disk-parallel.d
+rm -rf $d
+cleanup_fn rm -rf $d
+mkdir $d
+
+truncate -s $((100*1024*1024)) $d/disk-2.img $d/disk-3.img $d/disk-4.img
+
+$VG virt-v2v --debug-gc \
+ --parallel=2 \
+ -i disk \
+ $windows \
+ $d/disk-2.img \
+ $d/disk-3.img \
+ $d/disk-4.img \
+ -o local -os $d
+
+# Test the libvirt XML metadata and output disks were created.
+test -f $d/windows.xml
+test -f $d/windows-sda
+test -f $d/windows-sdb
+test -f $d/windows-sdc
+test -f $d/windows-sdd
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 2fdaf40b..68502884 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -79,6 +79,7 @@ let rec main () =
)
in
+ let parallel = ref 1 in
let network_map = Networks.create () in
let static_ips = ref [] in
let rec add_network str =
@@ -263,6 +264,8 @@ let rec main () =
s_"Set output storage location";
[ L"password-file" ], Getopt.String ("filename", set_string_option_once "-ip" input_password),
s_"Same as -ip filename";
+ [ L"parallel" ], Getopt.Set_int ("N", parallel),
+ s_"Run up to N instances of nbdcopy in parallel";
[ L"print-source" ], Getopt.Set print_source,
s_"Print source and stop";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
@@ -365,6 +368,7 @@ read the man page virt-v2v(1).
| `Preallocated -> Types.Preallocated in
let output_mode = !output_mode in
let output_name = !output_name in
+ let parallel = !parallel in
let print_source = !print_source in
let root_choice = !root_choice in
let static_ips = !static_ips in
@@ -386,6 +390,7 @@ read the man page virt-v2v(1).
pr "mac-option\n";
pr "bandwidth-option\n";
pr "mac-ip-option\n";
+ pr "parallel-option\n";
pr "customize-ops\n";
pr "input:disk\n";
pr "input:libvirt\n";
@@ -583,12 +588,15 @@ read the man page virt-v2v(1).
else
List.rev acc
in
- let disks = loop [] 0 in
- let nr_disks = List.length disks in
+ let disks = ref (loop [] 0) in
+ let nr_disks = List.length !disks in
(* Copy the disks. *)
- List.iter (
- fun (i, input_socket, output_socket) ->
+ let nbdcopy_pids = ref [] in
+ let rec copy_loop () =
+ if List.length !nbdcopy_pids < parallel && !disks <> [] then (
+ (* Schedule another nbdcopy process. *)
+ let i, input_socket, output_socket = List.pop_front disks in
message (f_"Copying disk %d/%d") (i+1) nr_disks;
let request_size = Output_module.request_size
@@ -608,8 +616,33 @@ read the man page virt-v2v(1).
flush Stdlib.stderr
);
- nbdcopy ?request_size output_alloc input_uri output_uri
- ) disks;
+ let pid = nbdcopy ?request_size output_alloc input_uri output_uri in
+ List.push_front pid nbdcopy_pids;
+
+ copy_loop ();
+ )
+ else if !nbdcopy_pids <> [] then (
+ (* Wait for one nbdcopy instance to exit. *)
+ let pid, status = wait () in
+ (* If this internal error turns up in real world scenarios then
+ * we may need to change the [wait] above so it only waits on
+ * the nbdcopy PIDs.
+ *)
+ if not (List.mem pid !nbdcopy_pids) then
+ error (f_"internal error: wait returned unexpected \
+ process ID %d status \"%s\"")
+ pid (string_of_process_status status);
+ nbdcopy_pids := List.filter ((<>) pid) !nbdcopy_pids;
+ (match status with
+ | WEXITED 0 -> copy_loop ()
+ | WEXITED _ | WSIGNALED _ | WSTOPPED _ ->
+ error "nbdcopy %s" (string_of_process_status status)
+ );
+ )
+ in
+ copy_loop ();
+ assert (!disks == []);
+ assert (!nbdcopy_pids == []);
(* End of copying phase. *)
unlink (v2vdir // "copy");
@@ -647,6 +680,7 @@ and check_host_free_space () =
\"Minimum free space check in the host\".")
large_tmpdir (human_size free_space)
+(* Start nbdcopy as a background process, returning the PID. *)
and nbdcopy ?request_size output_alloc input_uri output_uri =
(* XXX It's possible that some output modes know whether
* --target-is-zero which would be a useful optimization.
@@ -674,10 +708,12 @@ and nbdcopy ?request_size output_alloc input_uri output_uri =
if not (quiet ()) then List.push_back cmd "--progress";
if output_alloc = Types.Preallocated then List.push_back cmd "--allocated";
- let cmd = !cmd in
-
- if run_command cmd <> 0 then
- error (f_"nbdcopy command failed, see earlier error messages")
+ let args = Array.of_list !cmd in
+ match fork () with
+ | 0 ->
+ (* Child process (nbdcopy). *)
+ execvp "nbdcopy" args
+ | pid -> pid
(* Run nbdinfo on a URI and collect the information. However don't
* fail if nbdinfo is not installed since this is just used for debugging.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,272 @@
From a9d2eb43fdd5f1d115cc5b048a4b252a533d72cd Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 15:19:15 +0000
Subject: [PATCH] tests: Sort the tests into alphabetical order
The list of tests had grown organically over a very long time.
Also rename the "odd one out" rhbz* to test-rhbz*.
(cherry picked from commit d80c05a27098c6affaca4363372cae2354d9bc4f)
---
.gitignore | 2 +-
configure.ac | 2 +-
tests/Makefile.am | 70 +++++++++----------
tests/rhbz1232192.xml | 26 +++++++
tests/{rhbz1232192.sh => test-rhbz1232192.sh} | 2 +-
...1232192.xml.in => test-rhbz1232192.xml.in} | 0
6 files changed, 64 insertions(+), 38 deletions(-)
create mode 100644 tests/rhbz1232192.xml
rename tests/{rhbz1232192.sh => test-rhbz1232192.sh} (95%)
rename tests/{rhbz1232192.xml.in => test-rhbz1232192.xml.in} (100%)
diff --git a/.gitignore b/.gitignore
index b8abc3f8..9dcd4611 100644
--- a/.gitignore
+++ b/.gitignore
@@ -121,13 +121,13 @@ Makefile.in
/test-data/phony-guests/windows-system
/tests/functions.sh
/tests/libvirt-is-version
-/tests/rhbz1232192.xml
/tests/test-cdrom.xml
/tests/test-conversion-of-*.sh
/tests/test-floppy.xml
/tests/test-mac.xml
/tests/test-networks-and-bridges.xml
/tests/test-print-source.xml
+/tests/test-rhbz1232192.xml
/tests/test-sound.xml
/tests/windows.vmdk
/v2v/.depend
diff --git a/configure.ac b/configure.ac
index 300b421e..623c634d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -163,12 +163,12 @@ AC_CONFIG_FILES([Makefile
test-data/phony-guests/guests.xml
tests/functions.sh
tests/Makefile
- tests/rhbz1232192.xml
tests/test-cdrom.xml
tests/test-floppy.xml
tests/test-mac.xml
tests/test-networks-and-bridges.xml
tests/test-print-source.xml
+ tests/test-rhbz1232192.xml
tests/test-sound.xml
v2v/Makefile])
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4c4a8e55..0dd5927b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -56,6 +56,17 @@ libvirt_is_version_CFLAGS = \
TESTS_ENVIRONMENT = $(top_builddir)/run --test
TESTS = \
+ test-bad-networks-and-bridges.sh \
+ test-cdrom.sh \
+ test-customize.sh \
+ test-fedora-btrfs-conversion.sh \
+ test-fedora-conversion.sh \
+ test-fedora-luks-on-lvm-conversion.sh \
+ test-fedora-lvm-on-luks-conversion.sh \
+ test-fedora-md-conversion.sh \
+ test-floppy.sh \
+ test-i-disk-parallel.sh \
+ test-i-disk.sh \
test-i-ova-bad-sha1.sh \
test-i-ova-bad-sha256.sh \
test-i-ova-directory.sh \
@@ -68,18 +79,11 @@ TESTS = \
test-i-ova-subfolders.sh \
test-i-ova-tar.sh \
test-i-ova-two-disks.sh \
- test-i-vmx.sh \
- test-it-vddk-io-query.sh \
- test-o-rhv-upload-oo-query.sh \
- test-o-vdsm-oo-query.sh \
- test-bad-networks-and-bridges.sh \
- test-cdrom.sh \
- test-floppy.sh \
- test-i-disk.sh \
- test-i-disk-parallel.sh \
test-i-ova.sh \
+ test-i-vmx.sh \
test-in-place.sh \
test-inspector.sh \
+ test-it-vddk-io-query.sh \
test-mac.sh \
test-machine-readable.sh \
test-networks-and-bridges.sh \
@@ -91,24 +95,20 @@ TESTS = \
test-o-null.sh \
test-o-openstack.sh \
test-o-qemu.sh \
- test-o-rhv.sh \
+ test-o-rhv-upload-oo-query.sh \
test-o-rhv-upload.sh \
+ test-o-rhv.sh \
+ test-o-vdsm-oo-query.sh \
test-o-vdsm-options.sh \
test-oa-option-qcow2.sh \
test-oa-option-raw.sh \
test-of-option.sh \
test-on-option.sh \
test-print-source.sh \
+ test-rhbz1232192.sh \
test-sound.sh \
test-virtio-win-iso.sh \
- test-fedora-conversion.sh \
- test-fedora-btrfs-conversion.sh \
- test-fedora-luks-on-lvm-conversion.sh \
- test-fedora-lvm-on-luks-conversion.sh \
- test-fedora-md-conversion.sh \
test-windows-conversion.sh \
- test-customize.sh \
- rhbz1232192.sh \
$(SLOW_TESTS) \
$(ROOT_TESTS)
@@ -184,16 +184,17 @@ EXTRA_DIST += \
test-bad-networks-and-bridges.sh \
test-cdrom.expected \
test-cdrom.sh \
+ test-conversion-of.sh \
test-customize.sh \
- test-fedora-conversion.sh \
test-fedora-btrfs-conversion.sh \
+ test-fedora-conversion.sh \
test-fedora-luks-on-lvm-conversion.sh \
test-fedora-lvm-on-luks-conversion.sh \
test-fedora-md-conversion.sh \
test-floppy.expected \
test-floppy.sh \
- test-i-disk.sh \
test-i-disk-parallel.sh \
+ test-i-disk.sh \
test-i-ova-as-root.ovf \
test-i-ova-as-root.sh \
test-i-ova-bad-sha1.sh \
@@ -228,46 +229,46 @@ EXTRA_DIST += \
test-i-ova.ovf \
test-i-ova.sh \
test-i-ova.xml \
- test-i-vmx.sh \
test-i-vmx-1.expected \
- test-i-vmx-2.expected \
- test-i-vmx-3.expected \
- test-i-vmx-4.expected \
- test-i-vmx-5.expected \
- test-i-vmx-6.expected \
- test-i-vmx-7.expected \
test-i-vmx-1.vmx \
+ test-i-vmx-2.expected \
test-i-vmx-2.vmx \
+ test-i-vmx-3.expected \
test-i-vmx-3.vmx \
+ test-i-vmx-4.expected \
test-i-vmx-4.vmx \
+ test-i-vmx-5.expected \
test-i-vmx-5.vmx \
+ test-i-vmx-6.expected \
test-i-vmx-6.vmx \
+ test-i-vmx-7.expected \
test-i-vmx-7.vmx \
+ test-i-vmx.sh \
test-in-place.sh \
test-inspector.sh \
test-it-vddk-io-query.sh \
- test-machine-readable.sh \
test-mac-expected.xml \
test-mac.sh \
- test-networks-and-bridges.sh \
+ test-machine-readable.sh \
test-networks-and-bridges-expected.xml \
+ test-networks-and-bridges.sh \
test-o-glance.sh \
test-o-kubevirt-fedora.sh \
- test-o-kubevirt-windows.sh \
test-o-kubevirt-fedora.yaml.expected \
+ test-o-kubevirt-windows.sh \
test-o-kubevirt-windows.yaml.expected \
test-o-libvirt.sh \
test-o-local-qcow2-compressed.sh \
test-o-null.sh \
test-o-openstack.sh \
test-o-qemu.sh \
- test-o-rhv.ovf.expected \
- test-o-rhv.sh \
- test-o-rhv-upload.sh \
test-o-rhv-upload-module/imageio.py \
test-o-rhv-upload-module/ovirtsdk4/__init__.py \
test-o-rhv-upload-module/ovirtsdk4/types.py \
test-o-rhv-upload-oo-query.sh \
+ test-o-rhv-upload.sh \
+ test-o-rhv.ovf.expected \
+ test-o-rhv.sh \
test-o-vdsm-oo-query.sh \
test-o-vdsm-options.ovf.expected \
test-o-vdsm-options.sh \
@@ -277,9 +278,8 @@ EXTRA_DIST += \
test-on-option.sh \
test-print-source.expected \
test-print-source.sh \
- test-conversion-of.sh \
+ test-rhbz1232192.sh \
test-sound.sh \
test-trim.sh \
test-virtio-win-iso.sh \
- test-windows-conversion.sh \
- rhbz1232192.sh
+ test-windows-conversion.sh
diff --git a/tests/rhbz1232192.xml b/tests/rhbz1232192.xml
new file mode 100644
index 00000000..cf0d7a45
--- /dev/null
+++ b/tests/rhbz1232192.xml
@@ -0,0 +1,26 @@
+<domain type='kvm'>
+ <name>rhbz1232192</name>
+ <memory>1048576</memory>
+ <vcpu>2</vcpu>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/home/rjones/d/virt-v2v-rhel-9.6/test-data/phony-guests/windows.img'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/home/rjones/d/virt-v2v-rhel-9.6/test-data/phony-guests/blank-disk.img'/>
+ <target dev='hdb' bus='ide'/>
+ </disk>
+ </devices>
+</domain>
diff --git a/tests/rhbz1232192.sh b/tests/test-rhbz1232192.sh
similarity index 95%
rename from tests/rhbz1232192.sh
rename to tests/test-rhbz1232192.sh
index d2180439..21eb2dbd 100755
--- a/tests/rhbz1232192.sh
+++ b/tests/test-rhbz1232192.sh
@@ -32,4 +32,4 @@ requires test -f ../test-data/phony-guests/blank-disk.img
export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
-virt-v2v -i libvirtxml rhbz1232192.xml -o null
+virt-v2v -i libvirtxml test-rhbz1232192.xml -o null
diff --git a/tests/rhbz1232192.xml.in b/tests/test-rhbz1232192.xml.in
similarity index 100%
rename from tests/rhbz1232192.xml.in
rename to tests/test-rhbz1232192.xml.in

View File

@ -0,0 +1,26 @@
From 66a6afb741d32f998633b121c2fb9813e5195820 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 13:35:24 +0000
Subject: [PATCH] docs: Embolden whole "-O -"
Since this is typed literally make sure the whole string is
emboldened, according to our usual style.
(cherry picked from commit 3b81441fdb9e43eae3619c247e0d945d143fc92f)
---
docs/virt-v2v-inspector.pod | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/virt-v2v-inspector.pod b/docs/virt-v2v-inspector.pod
index 6b2ba2a9..8201fcf9 100644
--- a/docs/virt-v2v-inspector.pod
+++ b/docs/virt-v2v-inspector.pod
@@ -138,7 +138,7 @@ Display help.
Write the output to a file called F<output.xml>.
-=item B<-O> -
+=item B<-O ->
Write the output to stdout. This is also the default if the I<-O>
option is omitted.

View File

@ -0,0 +1,26 @@
From 900641084045a53f9c59e099e7d49dbb43bda3eb Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 17:17:25 +0000
Subject: [PATCH] in-place: Fix name of program in the --help output
(cherry picked from commit 00bd17ceb1ce0ff1f837b7621596d3b1e16ccc65)
---
in-place/in_place.ml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 9d24de78..42075139 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -194,9 +194,9 @@ let rec main () =
Note this program modifies the guest in-place with no backup.
Normally you should use virt-v2v.
-virt-v2v -i libvirtxml guest-domain.xml
+virt-v2v-in-place -i libvirtxml guest-domain.xml
-virt-v2v -i disk disk.img
+virt-v2v-in-place -i disk disk.img
A short summary of the options is given below. For detailed help please
read the man page virt-v2v-in-place(1).

View File

@ -0,0 +1,28 @@
From 908f4148d8479c0f5e74ec21471adc57696eed55 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 17:27:38 +0000
Subject: [PATCH] inspector: Reorder -O option in alphabetical order
Updates: commit 0805ea93796b8b57e7c9f0bc04f83ea76a9820a5
(cherry picked from commit 8efb3ac06467f32901fa0447176311ff71aa53f9)
---
inspector/inspector.ml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/inspector/inspector.ml b/inspector/inspector.ml
index 1ad67bbc..aeddbec6 100644
--- a/inspector/inspector.ml
+++ b/inspector/inspector.ml
@@ -178,10 +178,10 @@ let rec main () =
s_"Map NIC to network or bridge or assign static IP";
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),
s_"Map network in to out";
- [ L"root" ], Getopt.String ("ask|... ", set_root_choice),
- s_"How to choose root filesystem";
[ S 'O' ], Getopt.String ("output.xml", set_output_file_option),
s_"Set the output filename";
+ [ L"root" ], Getopt.String ("ask|... ", set_root_choice),
+ s_"How to choose root filesystem";
] in
(* Append virt-customize options. *)

View File

@ -0,0 +1,24 @@
From b242c331e0e3a3d04369aaefe7e910c978491368 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 7 Dec 2024 11:13:09 +0000
Subject: [PATCH] v2v: Ensure --parallel >= 1
Fixes: commit fd1148f79581b148525eb12154aef7603ccf0baa
(cherry picked from commit 755ce5dc08929ef4ef9dc0b0290d380574cb1235)
---
v2v/v2v.ml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 68502884..e56462a5 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -369,6 +369,8 @@ read the man page virt-v2v(1).
let output_mode = !output_mode in
let output_name = !output_name in
let parallel = !parallel in
+ if parallel < 1 then
+ error (f_"--parallel parameter must be >= 1");
let print_source = !print_source in
let root_choice = !root_choice in
let static_ips = !static_ips in

View File

@ -0,0 +1,403 @@
From 479f2cc10e74304e2d6202ad13dd99bdc9a6923d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 13:26:43 +0000
Subject: [PATCH] inspector: Move the code that creates XML output to a
separate file
Simple code motion, so that we can reuse this code in
virt-v2v-in-place.
(cherry picked from commit 3d2d65a04ae75716c084063b572ff916fa83fd1b)
---
inspector/Makefile.am | 2 +
inspector/create_inspector_xml.ml | 167 +++++++++++++++++++++++++++++
inspector/create_inspector_xml.mli | 22 ++++
inspector/inspector.ml | 144 +------------------------
4 files changed, 193 insertions(+), 142 deletions(-)
create mode 100644 inspector/create_inspector_xml.ml
create mode 100644 inspector/create_inspector_xml.mli
diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 172b2dc0..15f8cc34 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -23,9 +23,11 @@ EXTRA_DIST = \
$(SOURCES_C)
SOURCES_MLI = \
+ create_inspector_xml.mli \
inspector.mli
SOURCES_ML = \
+ create_inspector_xml.ml \
inspector.ml
SOURCES_C = \
diff --git a/inspector/create_inspector_xml.ml b/inspector/create_inspector_xml.ml
new file mode 100644
index 00000000..a3281d46
--- /dev/null
+++ b/inspector/create_inspector_xml.ml
@@ -0,0 +1,167 @@
+(* virt-v2v-inspector
+ * Copyright (C) 2009-2022 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 Std_utils
+open Tools_utils
+
+open Types
+open Utils
+open DOM
+
+(* This is where we construct the final XML document based on
+ * these inputs:
+ * - Global configuration like the version of v2v etc.
+ * - The NBD input sockets: v2vdir // "in0", "in1", etc
+ * - The inspection data (Types.inspect)
+ *)
+let rec create_inspector_xml v2vdir inspect target_meta =
+ let body = ref [] in
+
+ (* Record the version of virt-v2v etc, mainly for debugging. *)
+ List.push_back_list body [
+ Comment generated_by;
+ e "program" [] [PCData "virt-v2v-inspector"];
+ e "package" [] [PCData Config.package_name];
+ e "version" [] [PCData Config.package_version];
+ ];
+
+ (* The disks. *)
+ let disks = ref [] in
+
+ List.iter (
+ fun (i, virtual_size) ->
+ let elems = ref [] in
+ List.push_back elems (e "virtual-size" []
+ [PCData (Int64.to_string virtual_size)]);
+ (match get_input_disk_allocated v2vdir i with
+ | None -> ()
+ | Some real_size ->
+ List.push_back elems (e "allocated" [ "estimated", "true" ]
+ [PCData (Int64.to_string real_size)])
+ );
+
+ List.push_back disks (e "disk" [ "index", string_of_int i ] !elems)
+ ) (get_disks v2vdir);
+ List.push_back body (e "disks" [] !disks);
+
+ (* The <firmware> field is outside the <operatingsystem> element,
+ * since firmware is not part of the OS, and also because this is
+ * consistent with virt-drivers output.
+ *)
+ List.push_back body
+ (e "firmware"
+ ["type",
+ string_of_target_firmware target_meta.target_firmware]
+ []);
+
+ (* The inspection data. *)
+ (* NB: Keep these field names compatible with virt-inspector! *)
+ let os = ref [] in
+ List.push_back os (e "name" [] [PCData inspect.i_type]);
+ List.push_back os (e "distro" [] [PCData inspect.i_distro]);
+ List.push_back os (e "osinfo" [] [PCData inspect.i_osinfo]);
+ List.push_back os (e "arch" [] [PCData inspect.i_arch]);
+ List.push_back os (e "major_version" []
+ [PCData (string_of_int inspect.i_major_version)]);
+ List.push_back os (e "minor_version" []
+ [PCData (string_of_int inspect.i_minor_version)]);
+ if inspect.i_package_format <> "" then
+ List.push_back os (e "package_format" []
+ [PCData inspect.i_package_format]);
+ if inspect.i_package_management <> "" then
+ List.push_back os (e "package_management" []
+ [PCData inspect.i_package_management]);
+ if inspect.i_product_name <> "" then
+ List.push_back os (e "product_name" [] [PCData inspect.i_product_name]);
+ if inspect.i_product_variant <> "" then
+ List.push_back os (e "product_variant" []
+ [PCData inspect.i_product_variant]);
+
+ if inspect.i_windows_systemroot <> "" then
+ List.push_back os (e "windows_systemroot" []
+ [PCData inspect.i_windows_systemroot]);
+ if inspect.i_windows_software_hive <> "" then
+ List.push_back os (e "windows_software_hive" []
+ [PCData inspect.i_windows_software_hive]);
+ if inspect.i_windows_systemroot <> "" then
+ List.push_back os (e "windows_system_hive" []
+ [PCData inspect.i_windows_system_hive]);
+ if inspect.i_windows_current_control_set <> "" then
+ List.push_back os (e "windows_current_control_set" []
+ [PCData inspect.i_windows_current_control_set]);
+
+ List.push_back os (e "root" [] [PCData inspect.i_root]);
+ let mps = ref [] in
+ List.iter (
+ fun (fs, dev) ->
+ List.push_back mps (e "mountpoint" [ "dev", dev ] [PCData fs])
+ ) inspect.i_mountpoints;
+ List.push_back os (e "mountpoints" [] !mps);
+
+ List.push_back body (e "operatingsystem" [] !os);
+
+ (* Construct the final document. *)
+ (doc "v2v-inspection" [] !body : DOM.doc)
+
+
+(* This is a copy of {!Output.get_disks}. *)
+and get_disks dir =
+ let rec loop acc i =
+ let socket = sprintf "%s/in%d" dir i in
+ if Sys.file_exists socket then (
+ let size = Utils.with_nbd_connect_unix ~socket NBD.get_size in
+ loop ((i, size) :: acc) (i+1)
+ )
+ else
+ List.rev acc
+ in
+ loop [] 0
+
+(* This is like {!Utils.get_disk_allocated} but works on the input disks. *)
+and get_input_disk_allocated dir i =
+ let socket = sprintf "%s/in%d" dir i
+ and alloc_ctx = "base:allocation" in
+ with_nbd_connect_unix ~socket ~meta_contexts:[alloc_ctx]
+ (fun nbd ->
+ if NBD.can_meta_context nbd alloc_ctx then (
+ (* Get the list of extents, using a 2GiB chunk size as hint. *)
+ let size = NBD.get_size nbd
+ and allocated = ref 0_L
+ and fetch_offset = ref 0_L in
+ while !fetch_offset < size do
+ let remaining = size -^ !fetch_offset in
+ let fetch_size = min 0x8000_0000_L remaining in
+ NBD.block_status nbd fetch_size !fetch_offset
+ (fun ctx offset entries err ->
+ assert (ctx = alloc_ctx);
+ for i = 0 to Array.length entries / 2 - 1 do
+ let len = entries.(i * 2)
+ and typ = entries.(i * 2 + 1) in
+ assert (len > 0_L);
+ if typ &^ 1_L = 0_L then
+ allocated := !allocated +^ len;
+ fetch_offset := !fetch_offset +^ len
+ done;
+ 0
+ )
+ done;
+ Some !allocated
+ ) else None
+ )
diff --git a/inspector/create_inspector_xml.mli b/inspector/create_inspector_xml.mli
new file mode 100644
index 00000000..4f09269c
--- /dev/null
+++ b/inspector/create_inspector_xml.mli
@@ -0,0 +1,22 @@
+(* virt-v2v-in-place
+ * Copyright (C) 2009-2024 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.
+ *)
+
+val create_inspector_xml : string -> Types.inspect -> Types.target_meta ->
+ DOM.doc
+(** Create the XML output of virt-v2v-inspector which contains the
+ post-conversion metadata. *)
diff --git a/inspector/inspector.ml b/inspector/inspector.ml
index aeddbec6..ac26146f 100644
--- a/inspector/inspector.ml
+++ b/inspector/inspector.ml
@@ -27,7 +27,7 @@ open Getopt.OptionName
open Types
open Utils
-open DOM
+open Create_inspector_xml
(* Matches --mac command line parameters. *)
let mac_re = PCRE.compile "^([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)$"
@@ -368,7 +368,7 @@ read the man page virt-v2v-inspector(1).
);
(* Dump out the information. *)
- let doc = inspector_xml v2vdir inspect target_meta in
+ let doc = create_inspector_xml v2vdir inspect target_meta in
let chan =
match output_file with
| None -> Stdlib.stdout
@@ -404,144 +404,4 @@ and check_host_free_space () =
\"Minimum free space check in the host\".")
large_tmpdir (human_size free_space)
-(* This is a copy of {!Output.get_disks}. *)
-and get_disks dir =
- let rec loop acc i =
- let socket = sprintf "%s/in%d" dir i in
- if Sys.file_exists socket then (
- let size = Utils.with_nbd_connect_unix ~socket NBD.get_size in
- loop ((i, size) :: acc) (i+1)
- )
- else
- List.rev acc
- in
- loop [] 0
-
-(* This is like {!Utils.get_disk_allocated} but works on the input disks. *)
-and get_input_disk_allocated dir i =
- let socket = sprintf "%s/in%d" dir i
- and alloc_ctx = "base:allocation" in
- with_nbd_connect_unix ~socket ~meta_contexts:[alloc_ctx]
- (fun nbd ->
- if NBD.can_meta_context nbd alloc_ctx then (
- (* Get the list of extents, using a 2GiB chunk size as hint. *)
- let size = NBD.get_size nbd
- and allocated = ref 0_L
- and fetch_offset = ref 0_L in
- while !fetch_offset < size do
- let remaining = size -^ !fetch_offset in
- let fetch_size = min 0x8000_0000_L remaining in
- NBD.block_status nbd fetch_size !fetch_offset
- (fun ctx offset entries err ->
- assert (ctx = alloc_ctx);
- for i = 0 to Array.length entries / 2 - 1 do
- let len = entries.(i * 2)
- and typ = entries.(i * 2 + 1) in
- assert (len > 0_L);
- if typ &^ 1_L = 0_L then
- allocated := !allocated +^ len;
- fetch_offset := !fetch_offset +^ len
- done;
- 0
- )
- done;
- Some !allocated
- ) else None
- )
-
-(* This is where we construct the final XML document based on
- * these inputs:
- * - Global configuration like the version of v2v etc.
- * - The NBD input sockets: v2vdir // "in0", "in1", etc
- * - The inspection data (Types.inspect)
- *)
-and inspector_xml v2vdir inspect target_meta =
- let body = ref [] in
-
- (* Record the version of virt-v2v etc, mainly for debugging. *)
- List.push_back_list body [
- Comment generated_by;
- e "program" [] [PCData "virt-v2v-inspector"];
- e "package" [] [PCData Config.package_name];
- e "version" [] [PCData Config.package_version];
- ];
-
- (* The disks. *)
- let disks = ref [] in
-
- List.iter (
- fun (i, virtual_size) ->
- let elems = ref [] in
- List.push_back elems (e "virtual-size" []
- [PCData (Int64.to_string virtual_size)]);
- (match get_input_disk_allocated v2vdir i with
- | None -> ()
- | Some real_size ->
- List.push_back elems (e "allocated" [ "estimated", "true" ]
- [PCData (Int64.to_string real_size)])
- );
-
- List.push_back disks (e "disk" [ "index", string_of_int i ] !elems)
- ) (get_disks v2vdir);
- List.push_back body (e "disks" [] !disks);
-
- (* The <firmware> field is outside the <operatingsystem> element,
- * since firmware is not part of the OS, and also because this is
- * consistent with virt-drivers output.
- *)
- List.push_back body
- (e "firmware"
- ["type",
- string_of_target_firmware target_meta.target_firmware]
- []);
-
- (* The inspection data. *)
- (* NB: Keep these field names compatible with virt-inspector! *)
- let os = ref [] in
- List.push_back os (e "name" [] [PCData inspect.i_type]);
- List.push_back os (e "distro" [] [PCData inspect.i_distro]);
- List.push_back os (e "osinfo" [] [PCData inspect.i_osinfo]);
- List.push_back os (e "arch" [] [PCData inspect.i_arch]);
- List.push_back os (e "major_version" []
- [PCData (string_of_int inspect.i_major_version)]);
- List.push_back os (e "minor_version" []
- [PCData (string_of_int inspect.i_minor_version)]);
- if inspect.i_package_format <> "" then
- List.push_back os (e "package_format" []
- [PCData inspect.i_package_format]);
- if inspect.i_package_management <> "" then
- List.push_back os (e "package_management" []
- [PCData inspect.i_package_management]);
- if inspect.i_product_name <> "" then
- List.push_back os (e "product_name" [] [PCData inspect.i_product_name]);
- if inspect.i_product_variant <> "" then
- List.push_back os (e "product_variant" []
- [PCData inspect.i_product_variant]);
-
- if inspect.i_windows_systemroot <> "" then
- List.push_back os (e "windows_systemroot" []
- [PCData inspect.i_windows_systemroot]);
- if inspect.i_windows_software_hive <> "" then
- List.push_back os (e "windows_software_hive" []
- [PCData inspect.i_windows_software_hive]);
- if inspect.i_windows_systemroot <> "" then
- List.push_back os (e "windows_system_hive" []
- [PCData inspect.i_windows_system_hive]);
- if inspect.i_windows_current_control_set <> "" then
- List.push_back os (e "windows_current_control_set" []
- [PCData inspect.i_windows_current_control_set]);
-
- List.push_back os (e "root" [] [PCData inspect.i_root]);
- let mps = ref [] in
- List.iter (
- fun (fs, dev) ->
- List.push_back mps (e "mountpoint" [ "dev", dev ] [PCData fs])
- ) inspect.i_mountpoints;
- List.push_back os (e "mountpoints" [] !mps);
-
- List.push_back body (e "operatingsystem" [] !os);
-
- (* Construct the final document. *)
- (doc "v2v-inspection" [] !body : DOM.doc)
-
let () = run_main_and_handle_errors main

View File

@ -0,0 +1,33 @@
From e6f1a170002bff5db70aa8a8b6987ef1122d61e1 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 15:28:38 +0000
Subject: [PATCH] build: Define MLOBJECT (OCaml object file) as either cmo or
cmx
This macro expands to either cmo or cmx depending on whether we are
compiling for bytecode or native code.
This is a natural extension of the existing MLARCHIVE macro.
(cherry picked from commit 7b43b226eb3af18a5bd58b2664fb064832404a47)
---
subdir-rules.mk | 2 ++
1 file changed, 2 insertions(+)
diff --git a/subdir-rules.mk b/subdir-rules.mk
index e969f357..05221b95 100644
--- a/subdir-rules.mk
+++ b/subdir-rules.mk
@@ -47,10 +47,12 @@ $(top_builddir)/generator/generator:
if !HAVE_OCAMLOPT
MLARCHIVE = cma
+MLOBJECT = cmo
LINK_CUSTOM_OCAMLC_ONLY = -output-complete-exe
BEST = c
else
MLARCHIVE = cmxa
+MLOBJECT = cmx
BEST = opt
endif

View File

@ -0,0 +1,284 @@
From 3dc5eb5c76fd6be2108c5b3907d9d31bbacd00a5 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 5 Dec 2024 13:36:29 +0000
Subject: [PATCH] in-place: Add new -O option to write inspector XML
When using virt-v2v-in-place there is no easy way to get the
post-conversion metadata, such as the operating system and firmware
that virt-v2v detected inside the guest.
This commit adds new, optional '-O output.xml' to write this
information out to a file. The format is identical to
virt-v2v-inspector (and roughly a superset of virt-inspector).
Fixes: https://issues.redhat.com/browse/RHEL-58032
Thanks: Martin Necas
(cherry picked from commit 2f0958e5ac5c3442c2771518c5b73d6ebcd5bd4a)
---
docs/virt-v2v-in-place.pod | 18 +++++++++
in-place/Makefile.am | 2 +
in-place/in_place.ml | 39 +++++++++++++-----
tests/Makefile.am | 2 +
tests/test-in-place-xml.sh | 81 ++++++++++++++++++++++++++++++++++++++
5 files changed, 132 insertions(+), 10 deletions(-)
create mode 100755 tests/test-in-place-xml.sh
diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod
index 4057dae5..34e99cf0 100644
--- a/docs/virt-v2v-in-place.pod
+++ b/docs/virt-v2v-in-place.pod
@@ -7,10 +7,12 @@ virt-v2v-in-place - Convert a guest to use KVM in-place
virt-v2v-in-place -i disk [other -i* options]
[virt-customize options]
filename
+ [-O output.xml]
virt-v2v-in-place -i libvirt|libvirtxml [other -i* options]
[virt-customize options]
guest
+ [-O output.xml]
=head1 DESCRIPTION
@@ -35,6 +37,14 @@ If the guest has been copied to local libvirt then:
virt-v2v-in-place -i libvirt guest
+=head2 Output XML
+
+Optionally use the I<-O> option to write post-conversion metadata
+about the guest to an XML file. This is in the same format as
+L<virt-v2v-inspector(1)>. This can be used, for example, to find out
+what operating system and firmware was found inside the guest during
+conversion.
+
=head2 Exit code
If virt-v2v-in-place fails it will return a non-zero (error) exit
@@ -205,6 +215,14 @@ are mapped to C<out>.
See L<virt-v2v(1)/Networks and bridges>.
+=item B<-O> output.xml
+
+=item B<-O ->
+
+If this option is present, write post-conversion metadata about the
+guest to the named XML file, or to stdout if I<-O -> is used. This is
+in the same format as L<virt-v2v-inspector(1)>.
+
=item B<--print-source>
Print information about the source guest and stop. This option is
diff --git a/in-place/Makefile.am b/in-place/Makefile.am
index 2fecb3a7..89e3f5f3 100644
--- a/in-place/Makefile.am
+++ b/in-place/Makefile.am
@@ -57,6 +57,7 @@ OCAMLPACKAGES = \
-I $(top_builddir)/lib \
-I $(top_builddir)/input \
-I $(top_builddir)/convert \
+ -I $(top_builddir)/inspector \
-I $(top_builddir)/common/mlstdutils \
-I $(top_builddir)/common/mlutils \
-I $(top_builddir)/common/mlgettext \
@@ -103,6 +104,7 @@ OCAMLLINKFLAGS = \
mlv2vlib.$(MLARCHIVE) \
mlconvert.$(MLARCHIVE) \
mlinput.$(MLARCHIVE) \
+ create_inspector_xml.$(MLOBJECT) \
$(LINK_CUSTOM_OCAMLC_ONLY)
virt_v2v_in_place_DEPENDENCIES = \
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 42075139..c77533e7 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -28,6 +28,12 @@ open Getopt.OptionName
open Types
open Utils
+open Create_inspector_xml
+
+type output_xml_option =
+ | No_output_xml | Output_xml_to_stdout
+ | Output_xml_to_file of string
+
(* Matches --mac command line parameters. *)
let mac_re = PCRE.compile "^([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)$"
let mac_ip_re = PCRE.compile "^([[:xdigit:]]|:|\\.)+$"
@@ -61,6 +67,13 @@ let rec main () =
in
let network_map = Networks.create () in
+
+ let output_xml = ref No_output_xml in
+ let set_output_xml_option filename =
+ if filename = "-" then output_xml := Output_xml_to_stdout
+ else output_xml := Output_xml_to_file filename
+ in
+
let static_ips = ref [] in
let rec add_network str =
match String.split ":" str with
@@ -172,6 +185,8 @@ let rec main () =
s_"Map NIC to network or bridge or assign static IP";
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),
s_"Map network in to out";
+ [ S 'O' ], Getopt.String ("output.xml", set_output_xml_option),
+ s_"Set the output filename";
[ L"print-source" ], Getopt.Set print_source,
s_"Print source and stop";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
@@ -228,6 +243,7 @@ read the man page virt-v2v-in-place(1).
let customize_ops = get_customize_ops () in
let input_conn = !input_conn in
let input_mode = !input_mode in
+ let output_xml = !output_xml in
let print_source = !print_source in
let root_choice = !root_choice in
let static_ips = !static_ips in
@@ -246,6 +262,7 @@ read the man page virt-v2v-in-place(1).
pr "mac-option\n";
pr "mac-ip-option\n";
pr "customize-ops\n";
+ pr "output-xml-option\n";
pr "input:disk\n";
pr "input:libvirt\n";
pr "input:libvirtxml\n";
@@ -348,16 +365,18 @@ read the man page virt-v2v-in-place(1).
ignore (Sys.command cmd)
);
- (* XXX Should we create target metadata and if so where?
- *
- * If the input mode is libvirt, there is an argument for
- * updating the libvirt XML of the guest. If the input
- * mode is disk, maybe we should write <guestname>.xml.
- *
- * For the moment we just ignore the output from the
- * conversion step.
- *)
- ignore (inspect, target_meta);
+ (* Write the post-conversion metadata, if asked. *)
+ let chan =
+ match output_xml with
+ | No_output_xml -> None
+ | Output_xml_to_stdout -> Some Stdlib.stdout
+ | Output_xml_to_file filename -> Some (open_out filename) in
+ Option.iter (
+ fun chan ->
+ let doc = create_inspector_xml v2vdir inspect target_meta in
+ DOM.doc_to_chan chan doc;
+ Stdlib.flush chan
+ ) chan;
message (f_"Finishing off");
(* As the last thing, write a file indicating success before
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0dd5927b..4d46daf9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -82,6 +82,7 @@ TESTS = \
test-i-ova.sh \
test-i-vmx.sh \
test-in-place.sh \
+ test-in-place-xml.sh \
test-inspector.sh \
test-it-vddk-io-query.sh \
test-mac.sh \
@@ -245,6 +246,7 @@ EXTRA_DIST += \
test-i-vmx-7.vmx \
test-i-vmx.sh \
test-in-place.sh \
+ test-in-place-xml.sh \
test-inspector.sh \
test-it-vddk-io-query.sh \
test-mac-expected.xml \
diff --git a/tests/test-in-place-xml.sh b/tests/test-in-place-xml.sh
new file mode 100755
index 00000000..e9580006
--- /dev/null
+++ b/tests/test-in-place-xml.sh
@@ -0,0 +1,81 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014-2024 Red Hat Inc.
+# Copyright (C) 2015 Parallels IP Holdings GmbH.
+#
+# 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.
+
+# Test virt-v2v-in-place -O option.
+
+unset CDPATH
+export LANG=C
+set -e
+
+source ./functions.sh
+set -e
+set -x
+
+skip_if_skipped
+requires test -f ../test-data/phony-guests/windows.img
+
+img_base="$abs_top_builddir/test-data/phony-guests/windows.img"
+
+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
+export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win"
+
+d=$PWD/test-v2v-in-place-xml.d
+rm -rf $d
+cleanup_fn rm -r $d
+mkdir $d
+
+img="$d/test.qcow2"
+qemu-img convert -f raw $img_base -O qcow2 $img
+
+out="$d/out.xml"
+
+libvirt_xml="$d/test.xml"
+rm -f $libvirt_xml
+n=windows
+cat > $libvirt_xml <<EOF
+<node>
+ <domain type='test'>
+ <name>$n</name>
+ <memory>1048576</memory>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='$img'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ </devices>
+ </domain>
+</node>
+EOF
+
+$VG virt-v2v-in-place --debug-gc -i libvirt -ic "test://$libvirt_xml" \
+ $n -O $out
+cat $out
+
+# Expect certain elements to be present.
+grep '^<v2v-inspection' $out
+grep '<program>virt-v2v-inspector</program>' $out
+grep '<disks>' $out
+grep "<disk index='0'>" $out
+grep '<distro>windows</distro>' $out
+grep '<osinfo>win2k22</osinfo>' $out

View File

@ -8,7 +8,7 @@
Name: virt-v2v
Epoch: 1
Version: 2.7.1
Release: 1%{?dist}
Release: 2%{?dist}
Summary: Convert a virtual machine to run on KVM
License: GPL-2.0-or-later AND LGPL-2.0-or-later
@ -42,6 +42,20 @@ Patch0011: 0011-RHEL-9-oo-compressed-Remove-nbdcopy-version-check-an.patch
Patch0012: 0012-RHEL-9-tests-Remove-btrfs-test.patch
Patch0013: 0013-RHEL-9-Remove-block-driver-option.patch
Patch0014: 0014-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0015: 0015-in-place-Add-a-warning-about-checking-the-exit-code.patch
Patch0016: 0016-i-libvirt-Trim-whitespace-around-name.patch
Patch0017: 0017-o-qemu-Replace-hard-coded-UEFI-paths.patch
Patch0018: 0018-o-qemu-Add-set-e-x-at-the-top-of-the-output-script.patch
Patch0019: 0019-v2v-Implement-parallel-N-for-parallel-disk-copies.patch
Patch0020: 0020-tests-Rename-all-test-v2v-to-test.patch
Patch0021: 0021-tests-Sort-the-tests-into-alphabetical-order.patch
Patch0022: 0022-docs-Embolden-whole-O.patch
Patch0023: 0023-in-place-Fix-name-of-program-in-the-help-output.patch
Patch0024: 0024-inspector-Reorder-O-option-in-alphabetical-order.patch
Patch0025: 0025-v2v-Ensure-parallel-1.patch
Patch0026: 0026-inspector-Move-the-code-that-creates-XML-output-to-a.patch
Patch0027: 0027-build-Define-MLOBJECT-OCaml-object-file-as-either-cm.patch
Patch0028: 0028-in-place-Add-new-O-option-to-write-inspector-XML.patch
%if !0%{?rhel}
# libguestfs hasn't been built on i686 for a while since there is no
@ -296,7 +310,7 @@ done
# "windows.vmdk", regardless of the TESTS we want to run. The real
# target we need to make here is "fedora-luks-on-lvm.img".
make -C test-data/phony-guests windows.img fedora-luks-on-lvm.img
make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
make -C tests TESTS=test-fedora-luks-on-lvm-conversion.sh check
%endif
@ -343,13 +357,15 @@ make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
%changelog
* Wed Oct 30 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.7.1-1
* Mon Dec 09 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.7.1-2
- Rebase to upstream development version 2.7.1
resolves: RHEL-56813
- Replace Jansson with json-c
resolves: RHEL-65296
- Find drivers for win2025 guests
resolves: RHEL-65010
- in-place: Add new -O option to write inspector XML
resolves: RHEL-58032
* Thu Sep 05 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.5.9-1
- Rebase to upstream development version 2.5.9