import CS virt-v2v-2.7.1-5.el9

This commit is contained in:
eabdullin 2025-03-11 08:18:30 +00:00
parent ec0e840c16
commit 26811d9634
47 changed files with 5586 additions and 745 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
SOURCES/libguestfs.keyring
SOURCES/virt-v2v-2.5.6.tar.gz
SOURCES/virt-v2v-2.7.1.tar.gz

View File

@ -1,2 +1,2 @@
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
7c49844a2ffb54d6fcb58eca1dbf57b110d5d47e SOURCES/virt-v2v-2.5.6.tar.gz
e25884dd89561fc32072849c1cbc7b020ce75b34 SOURCES/virt-v2v-2.7.1.tar.gz

View File

@ -1,28 +0,0 @@
From 7800049c5612e6ffb30be7f8862d147d82976ae8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 31 Jul 2024 10:09:50 +0100
Subject: [PATCH] docs: Note that --mac len field is now optional
Reported-by: Ming Xie
Updates: commit 159fda411d2f75b087106e7293d273ae142c9fbe
---
docs/virt-v2v.pod | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index b53face6..dfe92d77 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -394,9 +394,9 @@ Force a particular interface (controlled by its MAC address) to have a
static IP address after boot.
The fields in the parameter are: C<ipaddr> is the IP address. C<gw>
-is the optional gateway IP address. C<len> is the subnet mask length
-(an integer). The final parameters are zero or more nameserver IP
-addresses.
+is the optional gateway IP address. C<len> is the optional subnet
+mask length (an integer). The final parameters are zero or more
+nameserver IP addresses.
This option can be supplied zero or more times.

View File

@ -0,0 +1,60 @@
From 8dd5577174fe23ace5ecba7a81d2516315a0b301 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Oct 2024 10:16:35 +0000
Subject: [PATCH] lib: OVF: Add preliminary support for Windows Server 2025
Unfortunately support has not yet been added to oVirt. However I have
inferred the correct ostype value based on existing entries.
Also pull in the following commit from the common submodule:
Richard W.M. Jones (1):
mlcustomize: Add heuristic support for Windows Server 2025
Related: https://issues.redhat.com/browse/RHEL-65009
Related: https://issues.redhat.com/browse/RHEL-65010
Reported-by: Ming Xie
---
common | 2 +-
lib/create_ovf.ml | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
Submodule common e9eea65a..2d42128e:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 88c1c8cf..7e46f318 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -522,6 +522,8 @@ and virtio_iso_path_matches_guest_os t path =
(10, 0, not_client, ((=) "win2k19"))
else if pathelem "2k22" || pathelem "win2022" then
(10, 0, not_client, ((=) "win2k22"))
+ else if pathelem "2k25" || pathelem "win2025" then
+ (10, 0, not_client, ((=) "win2k25"))
else
raise Not_found in
diff --git a/lib/create_ovf.ml b/lib/create_ovf.ml
index f0b32e01..e2c19b08 100644
--- a/lib/create_ovf.ml
+++ b/lib/create_ovf.ml
@@ -242,10 +242,11 @@ and get_ostype = function
| "win2k16" -> "windows_2016x64"
| "win2k19" -> "windows_2019x64"
| "win2k22" -> "windows_2022"
+ | "win2k25" -> "windows_2025"
| _ ->
warning (f_"unknown Windows 10 variant: %s (%s)")
osinfo product;
- "windows_2022"
+ "windows_2025"
)
| { i_type = typ; i_distro = distro;
@@ -448,6 +449,7 @@ and get_ovirt_osid = function
| "win2k16" -> (* windows_2016x64 *) 29
| "win2k19" -> (* windows_2019x64 *) 31
| "win2k22" -> (* windows_2022 *) 37
+ (*| "win2k25" -> (* windows_2025 *) not yet known - 2024/10 *)
| _ ->
warning (f_"unknown Windows 10 variant: %s (%s)")
osinfo product;

View File

@ -1,4 +1,4 @@
From ed515103ba0d4054c7000568b39df42abb503f3c Mon Sep 17 00:00:00 2001
From 76d765ce4b8ea64a9b2c36b68ceacd1517c62aa7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 28 Sep 2014 19:14:43 +0100
Subject: [PATCH] RHEL: v2v: Select correct qemu binary for -o qemu mode

View File

@ -1,207 +0,0 @@
From c57ec4fd5d4942d2320aec4a6b01977dabb87f83 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Aug 2024 09:01:47 +0100
Subject: [PATCH] convert: More robust qemu-ga installation, change paths
Add a commit from the common submodule to attempt to make qemu-ga
installation more robust on Windows.
Rename network configuration Powershell script from "v2vnetcf" to
"network-configuration". I also dropped the ".ps1" extension as the
modified Firstboot.add_firstboot_powershell function now adds this.
Update the common submodule to get these changes:
Richard W.M. Jones (3):
mlcustomize: Use Start-Process -Wait to run qemu-ga installer
mlcustomize: Add Firstboot.firstboot_dir function
mlcustomize: Place powershell scripts into <firstboot_dir>\Temp
---
common | 2 +-
convert/convert_windows.ml | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
Submodule common ae639ba3..d489469f:
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 4b9b910b..3bbba714 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -239,7 +239,22 @@ WantedBy=%s
end
module Windows = struct
- let rec install_service (g : Guestfs.guestfs) root =
+ (* Create and return the firstboot directory. *)
+ let create_firstboot_dir (g : Guestfs.guestfs) =
+ let rec loop firstboot_dir firstboot_dir_win = function
+ | [] -> firstboot_dir, firstboot_dir_win
+ | dir :: path ->
+ let firstboot_dir =
+ if firstboot_dir = "" then "/" ^ dir else firstboot_dir // dir in
+ let firstboot_dir_win = firstboot_dir_win ^ "\\" ^ dir in
+ let firstboot_dir = g#case_sensitive_path firstboot_dir in
+ g#mkdir_p firstboot_dir;
+ loop firstboot_dir firstboot_dir_win path
+ in
+ loop "" "C:" ["Program Files"; "Guestfs"; "Firstboot"]
+
+ let rec install_service (g : Guestfs.guestfs) root
+ firstboot_dir firstboot_dir_win =
(* Either rhsrvany.exe or pvvxsvc.exe must exist.
*
* (Check also that it's not a dangling symlink but a real file).
@@ -254,20 +269,7 @@ module Windows = struct
error (f_"One of rhsrvany.exe or pvvxsvc.exe is missing in %s. One of them is required in order to install Windows firstboot scripts. You can get one by building rhsrvany (https://github.com/rwmjones/rhsrvany)")
(virt_tools_data_dir ()) in
- (* Create a directory for firstboot files in the guest. *)
- let firstboot_dir, firstboot_dir_win =
- let rec loop firstboot_dir firstboot_dir_win = function
- | [] -> firstboot_dir, firstboot_dir_win
- | dir :: path ->
- let firstboot_dir =
- if firstboot_dir = "" then "/" ^ dir else firstboot_dir // dir in
- let firstboot_dir_win = firstboot_dir_win ^ "\\" ^ dir in
- let firstboot_dir = g#case_sensitive_path firstboot_dir in
- g#mkdir_p firstboot_dir;
- loop firstboot_dir firstboot_dir_win path
- in
- loop "" "C:" ["Program Files"; "Guestfs"; "Firstboot"] in
-
+ (* Create a directory for firstboot scripts in the guest. *)
g#mkdir_p (firstboot_dir // "scripts");
(* Copy pvvxsvc or rhsrvany to the guest. *)
@@ -339,11 +341,25 @@ echo uninstalling firstboot service
"PWD", REG_SZ firstboot_dir_win ];
] in
reg_import reg regedits
- );
-
- firstboot_dir
+ )
end
+let firstboot_dir (g : Guestfs.guestfs) root =
+ let typ = g#inspect_get_type root in
+
+ match typ with
+ | "linux" ->
+ let dir = Linux.firstboot_dir in
+ g#mkdir_p dir;
+ dir, None
+
+ | "windows" ->
+ let dir, dir_win = Windows.create_firstboot_dir g in
+ dir, Some dir_win
+
+ | _ ->
+ error (f_"guest type %s is not supported") typ
+
let script_count = ref 0
let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name
@@ -363,7 +379,8 @@ let add_firstboot_script (g : Guestfs.guestfs) root ?(prio = 5000) name
g#chmod 0o755 filename
| "windows", _ ->
- let firstboot_dir = Windows.install_service g root in
+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in
+ Windows.install_service g root firstboot_dir firstboot_dir_win;
let filename = firstboot_dir // "scripts" // filename ^ ".bat" in
g#write filename (String.unix2dos content)
@@ -382,15 +399,18 @@ let add_firstboot_powershell g root ?prio name code =
*)
assert (g#inspect_get_type root = "windows");
- let windows_systemroot = g#inspect_get_windows_systemroot root in
-
- (* Create the temporary directory to put the Powershell file. *)
- let tempdir = sprintf "%s/Temp" windows_systemroot in
+ (* Place the Powershell script into firstboot_dir/Temp *)
+ let firstboot_dir, firstboot_dir_win = Windows.create_firstboot_dir g in
+ let tempdir = sprintf "%s/Temp" firstboot_dir in
g#mkdir_p tempdir;
- let ps_path = sprintf "%s/%s" tempdir name in
+
+ let ps_path = sprintf "%s/%s.ps1" tempdir name in
+ let ps_path_win = sprintf "%s\\Temp\\%s.ps1" firstboot_dir_win name in
let code = String.concat "\r\n" code ^ "\r\n" in
g#write ps_path code;
- let fb = sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file %s"
- ps_path in
+ (* Create a regular firstboot bat that just invokes powershell *)
+ let fb =
+ sprintf "powershell.exe -ExecutionPolicy ByPass -NoProfile -file \"%s\""
+ ps_path_win in
add_firstboot_script g root ?prio name fb
diff --git a/common/mlcustomize/firstboot.mli b/common/mlcustomize/firstboot.mli
index 8231af65..34ff0690 100644
--- a/common/mlcustomize/firstboot.mli
+++ b/common/mlcustomize/firstboot.mli
@@ -16,6 +16,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
+val firstboot_dir : Guestfs.guestfs -> string -> string * string option
+(** [firstboot_dir g root]
+ returns the path of the firstboot directory, creating it in
+ the guest if necessary.
+
+ This returns the name of the directory as a guestfs path, and
+ optionally the name as a Windows path (only for Windows guests).
+
+ For Linux this could be [/usr/lib/virt-sysprep, None]
+
+ For Windows this could be ["/Program Files/Guestfs/Firstboot",
+ Some "C:\Program Files\Guestfs\Firstboot"]
+
+ Additional files that are used during firstboot can be placed
+ in this directory, but be careful not to conflict with files
+ and scripts added by the firstboot process itself. *)
+
val add_firstboot_script : Guestfs.guestfs -> string -> ?prio:int -> string ->
string -> unit
(** [add_firstboot_script g root prio name content] adds a firstboot
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index eee93669..b04a3b38 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -592,11 +592,11 @@ and configure_qemu_ga t files =
add "# Run qemu-ga installers";
List.iter (
fun msi_path ->
- add (sprintf "C:\\%s /norestart /qn /l+*vx C:\\%s.log"
+ add (sprintf "Start-Process -Wait -FilePath \"C:\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"C:\\%s.log\""
msi_path msi_path)
) files;
- Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga.ps1" !script
+ Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script
and configure_blnsvr t blnsvr =
let cmd = sprintf "\
diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
index 2d6e2059..52ca5bbe 100644
--- a/convert/convert_windows.ml
+++ b/convert/convert_windows.ml
@@ -397,7 +397,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
%systemroot%\\Sysnative\\PnPutil -i -a \
%systemroot%\\Drivers\\Virtio\\*.inf" in
- (* Set priority higher than that of "v2vnetcf.ps1" firstboot script. *)
+ (* Set priority higher than that of "network-configure" firstboot script. *)
Firstboot.add_firstboot_script g inspect.i_root ~prio:2000
"pnputil install drivers" fb_script;
@@ -674,7 +674,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
* Powershell script which runs at boot.
*)
if static_ips <> [] then (
- let psh_filename = "v2vnetcf.ps1" in
+ let psh_filename = "network-configure" in
let psh = ref [] in
let add = List.push_back psh in

View File

@ -1,4 +1,4 @@
From 84afa8cb6933daee1585facc00557826f1fd2273 Mon Sep 17 00:00:00 2001
From efba6c869424b27fc5946acc230dd486906e721a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 30 Sep 2014 10:50:27 +0100
Subject: [PATCH] RHEL: v2v: Disable the --qemu-boot / -oo qemu-boot option
@ -44,10 +44,10 @@ index d2a1c270..0be37f5e 100644
=item B<-o null>
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 346be606..81a4b45a 100644
index 5345a6c9..a1e8fb30 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -146,11 +146,6 @@ Since F<guest-domain.xml> contains the path(s) to the guest disk
@@ -157,11 +157,6 @@ Since F<guest-domain.xml> contains the path(s) to the guest disk
image(s) you do not need to specify the name of the disk image on the
command line.
@ -59,7 +59,7 @@ index 346be606..81a4b45a 100644
=head1 OPTIONS
=over 4
@@ -522,9 +517,6 @@ This is similar to I<-o local>, except that a shell script is written
@@ -533,9 +528,6 @@ This is similar to I<-o local>, except that a shell script is written
which you can use to boot the guest in qemu. The converted disks and
shell script are written to the directory specified by I<-os>.
@ -69,7 +69,7 @@ index 346be606..81a4b45a 100644
=item B<-o> B<rhev>
This is the same as I<-o rhv>.
@@ -607,11 +599,6 @@ For I<-o openstack> (L<virt-v2v-output-openstack(1)>) only, set a guest ID
@@ -618,11 +610,6 @@ For I<-o openstack> (L<virt-v2v-output-openstack(1)>) only, set a guest ID
which is saved on each Cinder volume in the C<virt_v2v_guest_id>
volume property.
@ -81,7 +81,7 @@ index 346be606..81a4b45a 100644
=item B<-oo verify-server-certificate>
=item B<-oo verify-server-certificate=>C<true|false>
@@ -782,10 +769,6 @@ Print information about the source guest and stop. This option is
@@ -793,10 +780,6 @@ Print information about the source guest and stop. This option is
useful when you are setting up network and bridge maps.
See L</Networks and bridges>.
@ -107,7 +107,7 @@ index 07dae8c2..b6f24565 100644
let output_storage =
match options.output_storage with
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 48c8cfba..fca5f6e9 100644
index 194e6233..6baa111f 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -277,8 +277,6 @@ let rec main () =

View File

@ -1,116 +0,0 @@
From 168eacf977ca49e96bc63ddc4109c27515ac0277 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 1 Aug 2024 10:36:52 +0100
Subject: [PATCH] common: mlcustomize: Inject qemu-ga & blnsvr into
<firstboot_dir>/Temp
Update common submodule to pick up this further change which should
mean that for all Windows conversions, everything is confined to
C:\Program Files\Guestfs\Firstboot (except the virtio drivers
themselves).
Richard W.M. Jones (1):
mlcustomize: Inject qemu-ga & blnsvr into <firstboot_dir>/Temp
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common d489469f..04116678:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index b04a3b38..2981bff5 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -263,14 +263,28 @@ let rec inject_virtio_win_drivers ({ g } as t) reg =
}
)
-and inject_qemu_ga t =
- let msi_files = copy_qemu_ga t in
+and inject_qemu_ga ({ g; root } as t) =
+ (* Copy the qemu-ga MSI(s) to the guest. *)
+ let dir, dir_win = Firstboot.firstboot_dir g root in
+ let dir_win = Option.value dir_win ~default:dir in
+ let tempdir = sprintf "%s/Temp" dir in
+ let tempdir_win = sprintf "%s\\Temp" dir_win in
+ g#mkdir_p tempdir;
+
+ let msi_files = copy_qemu_ga t tempdir in
if msi_files <> [] then
- configure_qemu_ga t msi_files;
+ configure_qemu_ga t tempdir_win msi_files;
msi_files <> [] (* return true if we found some qemu-ga MSI files *)
-and inject_blnsvr t =
- let files = copy_blnsvr t in
+and inject_blnsvr ({ g; root } as t) =
+ (* Copy the files to the guest. *)
+ let dir, dir_win = Firstboot.firstboot_dir g root in
+ let dir_win = Option.value dir_win ~default:dir in
+ let tempdir = sprintf "%s/Temp" dir in
+ let tempdir_win = sprintf "%s\\Temp" dir_win in
+ g#mkdir_p tempdir;
+
+ let files = copy_blnsvr t tempdir in
match files with
| [] -> false (* Didn't find or install anything. *)
@@ -278,7 +292,7 @@ and inject_blnsvr t =
* drivers/by-driver). Pick the first.
*)
| blnsvr :: _ ->
- configure_blnsvr t blnsvr;
+ configure_blnsvr t tempdir_win blnsvr;
true
and add_guestor_to_registry t ((g, root) as reg) drv_name drv_pciid =
@@ -360,13 +374,13 @@ and copy_drivers t driverdir =
(fun () ->
error (f_"root directory / is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
-and copy_qemu_ga t =
- copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_qemu_ga t)
+and copy_qemu_ga t tempdir =
+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_qemu_ga t)
(fun () ->
error (f_"root directory / is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
-and copy_blnsvr t =
- copy_from_virtio_win t "/" "/" (virtio_iso_path_matches_blnsvr t)
+and copy_blnsvr t tempdir =
+ copy_from_virtio_win t "/" tempdir (virtio_iso_path_matches_blnsvr t)
(fun () ->
error (f_"root directory / is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
@@ -578,7 +592,7 @@ and copy_from_libosinfo { g; i_osinfo; i_arch } destdir =
(* Install qemu-ga. [files] is the non-empty list of possible qemu-ga
* installers we detected.
*)
-and configure_qemu_ga t files =
+and configure_qemu_ga t tempdir_win files =
let script = ref [] in
let add = List.push_back script in
@@ -591,16 +605,17 @@ and configure_qemu_ga t files =
add "";
add "# Run qemu-ga installers";
List.iter (
- fun msi_path ->
- add (sprintf "Start-Process -Wait -FilePath \"C:\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"C:\\%s.log\""
- msi_path msi_path)
+ fun msi ->
+ (* [`] is an escape char for quotes *)
+ add (sprintf "Start-Process -Wait -FilePath \"%s\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"`\"%s\\%s.log`\"\""
+ tempdir_win msi tempdir_win msi)
) files;
Firstboot.add_firstboot_powershell t.g t.root "install-qemu-ga" !script
-and configure_blnsvr t blnsvr =
+and configure_blnsvr t tempdir_win blnsvr =
let cmd = sprintf "\
@echo off\n\
echo Installing %s\n\
- c:\\%s -i\n" blnsvr blnsvr in
- Firstboot.add_firstboot_script t.g t.root (sprintf "install-%s" blnsvr) cmd
+ \"%s\\%s\" -i\n" blnsvr tempdir_win blnsvr in
+ Firstboot.add_firstboot_script t.g t.root "install-blnsvr" cmd

View File

@ -1,4 +1,4 @@
From abab56cf74a5005b33e962bb3d42db3d5b39e6d3 Mon Sep 17 00:00:00 2001
From f43f6b4a5ab2387f192a871c366598194a5c1e43 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 24 Apr 2015 09:45:41 -0400
Subject: [PATCH] RHEL: Fix list of supported sound cards to match RHEL qemu

View File

@ -1,45 +0,0 @@
From c952f310c902e438a8b0b5240a4b486b698bede8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 5 Aug 2024 10:08:34 +0100
Subject: [PATCH] docs: Add a note about removal of VMware Tools on Windows
We use VMware's recommended method for removal, but we know from
experience that this rarely works. The alternate method being
proposed involves making very invasive changes to the Registry and
filesystem, which are inappropriate for virt-v2v to do and highly
risky. Therefore simply document this, with notes for the virt-v2v
user if they want to try the risky method.
Fixes: https://issues.redhat.com/browse/RHEL-51169
Thanks: Yan Vugenfirer
Reported-by: Ming Xie
---
docs/virt-v2v.pod | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index dfe92d77..92941026 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1299,6 +1299,21 @@ B<N.B.> Take care not to interrupt the automatic driver installation
process when logging in to the guest for the first time, as this may
prevent the guest from subsequently booting correctly.
+=head3 Removing VMware Tools from Windows guests
+
+Virt-v2v attempts to remove VMware Tools. For Windows guests this is
+supposed to happen during the first boot after conversion.
+
+We use VMware's recommended uninstallation method as that is the
+safest choice. However our experience has shown that this method
+usually fails. If so, VMware Tools must be removed by some other
+method.
+
+One possible method is described here:
+L<https://gist.github.com/broestls/f872872a00acee2fca02017160840624>
+You should carefully check this script since it makes very invasive
+changes to the Windows Registry and filesystem.
+
=head2 Free space for conversion
=head3 Free space in the guest

View File

@ -1,4 +1,4 @@
From 2039580744223840a09b8aab7ff2fbf94a563a6c Mon Sep 17 00:00:00 2001
From 0d6280e2be92bef1246adc70830a6ae18359f121 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 30 Aug 2015 03:21:57 -0400
Subject: [PATCH] RHEL: Fixes for libguestfs-winsupport.
@ -18,10 +18,10 @@ https://bugzilla.redhat.com/show_bug.cgi?id=2187961#c1
6 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/convert/convert.ml b/convert/convert.ml
index 344c5858..ecc48ad4 100644
index 64b36c97..604902d1 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -52,6 +52,7 @@ let rec convert dir options source =
@@ -53,6 +53,7 @@ let rec convert dir options source =
message (f_"Opening the source");
let g = open_guestfs ~identifier:"v2v" () in
@ -30,7 +30,7 @@ index 344c5858..ecc48ad4 100644
(* Setting the number of vCPUs allows parallel mkinitrd, but make
* sure this is not too large because each vCPU consumes guest RAM.
diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
index 30908a91..73cf5144 100755
index 501c2a93..28b2744f 100755
--- a/test-data/phony-guests/make-windows-img.sh
+++ b/test-data/phony-guests/make-windows-img.sh
@@ -37,6 +37,7 @@ fi
@ -85,7 +85,7 @@ index 4373f140..2b31b0bb 100755
# Test the base image remained untouched
diff --git a/tests/test-v2v-virtio-win-iso.sh b/tests/test-v2v-virtio-win-iso.sh
index 69f6f414..b9b806fb 100755
index 68fb879b..2e133034 100755
--- a/tests/test-v2v-virtio-win-iso.sh
+++ b/tests/test-v2v-virtio-win-iso.sh
@@ -82,6 +82,12 @@ mktest ()

View File

@ -1,25 +0,0 @@
From 7bc9b115baba6df2969451cd6907e2d7543ef22d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 5 Aug 2024 10:18:31 +0100
Subject: [PATCH] Update common submodule
Richard W.M. Jones (1):
mlcustomize: Write qemu-ga log file name to log.txt
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 04116678..7b84a370:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index 2981bff5..afec1e45 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -606,6 +606,8 @@ and configure_qemu_ga t tempdir_win files =
add "# Run qemu-ga installers";
List.iter (
fun msi ->
+ add (sprintf "Write-Host \"Writing log to %s\\%s.log\""
+ tempdir_win msi);
(* [`] is an escape char for quotes *)
add (sprintf "Start-Process -Wait -FilePath \"%s\\%s\" -ArgumentList \"/norestart\",\"/qn\",\"/l+*vx\",\"`\"%s\\%s.log`\"\""
tempdir_win msi tempdir_win msi)

View File

@ -1,78 +0,0 @@
From 50f005f8b7034916588855c15b10a0195bf54b23 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 8 Aug 2024 10:40:24 +0100
Subject: [PATCH] Pull in a fix to make Windows firstboot more reliable.
Update the common submodule to get:
Richard W.M. Jones (2):
mlcustomize: Add some comments to firstboot batch file
mlcustomize: Reboot Windows between each firstboot script
Document that Windows may now reboot several times after conversion.
---
common | 2 +-
docs/virt-v2v.pod | 9 ++++++---
2 files changed, 7 insertions(+), 4 deletions(-)
Submodule common 7b84a370..a7883967:
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 3bbba714..52e76401 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -278,6 +278,9 @@ module Windows = struct
(* Write a firstboot.bat control script which just runs the other
* scripts in the directory. Note we need to use CRLF line endings
* in this script.
+ *
+ * XXX It would be better to use powershell here. For some ideas see
+ * https://github.com/HCK-CI/HLK-Setup-Scripts/
*)
let firstboot_script = sprintf "\
@echo off
@@ -299,6 +302,7 @@ if not exist \"%%scripts_done%%\" (
mkdir \"%%scripts_done%%\"
)
+:: Pick the next script to run.
for %%%%f in (\"%%scripts%%\"\\*.bat) do (
echo running \"%%%%f\"
move \"%%%%f\" \"%%scripts_done%%\"
@@ -307,8 +311,17 @@ for %%%%f in (\"%%scripts%%\"\\*.bat) do (
set elvl=!errorlevel!
echo .... exit code !elvl!
popd
+
+ :: Reboot the computer. This is necessary to free any locked
+ :: files which may prevent later scripts from running.
+ shutdown /r /t 0 /y
+
+ :: Exit the script (in case shutdown returns before rebooting).
+ :: On next boot, the whole firstboot service will be called again.
+ exit /b
)
+:: Fallthrough here if there are no scripts.
echo uninstalling firstboot service
\"%%firstboot%%\\%s\" -s firstboot uninstall
" firstboot_dir_win srvany in
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 92941026..587b4604 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1295,9 +1295,12 @@ The guest will be bootable after the offline conversion stage, but
will not yet have all necessary drivers installed to work correctly.
These will be installed automatically the first time the guest boots.
-B<N.B.> Take care not to interrupt the automatic driver installation
-process when logging in to the guest for the first time, as this may
-prevent the guest from subsequently booting correctly.
+B<N.B.> Windows may reboot 4 or more times the first time after
+conversion. This is required to install the required drivers, guest
+agents, remove VMware Tools, and configure the network. Take care not
+to interrupt the automatic driver installation process when logging in
+to the guest for the first time, as this may prevent the guest from
+subsequently booting correctly.
=head3 Removing VMware Tools from Windows guests

View File

@ -1,4 +1,4 @@
From 13970ce5d6be475cf6e06185636a730584303a6e Mon Sep 17 00:00:00 2001
From 421a6ec290e90add03f9ddf4ca8436fdf80f885c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 2 Mar 2017 14:21:37 +0100
Subject: [PATCH] RHEL: v2v: -i disk: force VNC as display (RHBZ#1372671)

View File

@ -1,4 +1,4 @@
From 98a14fe2f8a428ed4bba85aba3889467d48a5743 Mon Sep 17 00:00:00 2001
From 8e52f84563cf8f6eaa68ed60d1f46b39c9b73b50 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Wed, 8 Mar 2017 11:03:40 +0100
Subject: [PATCH] RHEL: v2v: do not mention SUSE Xen hosts (RHBZ#1430203)

View File

@ -1,30 +0,0 @@
From e9c0d63b22bcb4c31cfaac00fc1271713c8bd3b3 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 8 Aug 2024 10:56:16 +0100
Subject: [PATCH] docs: Restate position on removal of VMware Tools
With the "reboot after every step" change made in the previous commit,
it seems removal of VMware Tools is now more reliable. Update the
notes about this.
Updates: commit c952f310c902e438a8b0b5240a4b486b698bede8
---
docs/virt-v2v.pod | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 587b4604..346be606 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1308,9 +1308,8 @@ Virt-v2v attempts to remove VMware Tools. For Windows guests this is
supposed to happen during the first boot after conversion.
We use VMware's recommended uninstallation method as that is the
-safest choice. However our experience has shown that this method
-usually fails. If so, VMware Tools must be removed by some other
-method.
+safest choice. If this fails, VMware Tools must be manually removed
+by some other method.
One possible method is described here:
L<https://gist.github.com/broestls/f872872a00acee2fca02017160840624>

View File

@ -1,17 +1,17 @@
From be45d1e5bca42148c295da10c27c485c72de28c3 Mon Sep 17 00:00:00 2001
From dc02d123d578511f9c4dffd3df5d797af14a1f3b Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Tue, 26 Mar 2019 09:42:25 +0100
Subject: [PATCH] RHEL: point to KB for supported v2v hypervisors/guests
---
docs/virt-v2v-support.pod | 104 ++------------------------------------
1 file changed, 4 insertions(+), 100 deletions(-)
docs/virt-v2v-support.pod | 96 ++-------------------------------------
1 file changed, 4 insertions(+), 92 deletions(-)
diff --git a/docs/virt-v2v-support.pod b/docs/virt-v2v-support.pod
index 8b64a5ea..1ffc0f9d 100644
index e6415692..1ffc0f9d 100644
--- a/docs/virt-v2v-support.pod
+++ b/docs/virt-v2v-support.pod
@@ -8,106 +8,10 @@ systems and guests in virt-v2v
@@ -8,98 +8,10 @@ systems and guests in virt-v2v
This page documents which foreign hypervisors, virtualization
management systems and guest types that L<virt-v2v(1)> can support.
@ -84,9 +84,9 @@ index 8b64a5ea..1ffc0f9d 100644
-
-=over 4
-
-=item Red Hat Enterprise Linux 4, 5, 6, 7
-=item Red Hat Enterprise Linux 4, 5, 6, 7, 8, 9, 10
-
-=item CentOS 4, 5, 6, 7
-=item CentOS 4, 5, 6, 7, 8, 9, 10
-
-=item Scientific Linux 4, 5, 6, 7
-
@ -104,15 +104,7 @@ index 8b64a5ea..1ffc0f9d 100644
-
-=item Ubuntu 10.04, 12.04, 14.04, 16.04, and up
-
-=item Windows XP to Windows 10 / Windows Server 2016
-
-We use Windows internal version numbers, see
-L<https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions>
-
-Currently NT 5.2 to NT 6.3 are supported.
-
-See L</WINDOWS> below for additional notes on converting Windows
-guests.
-=item Windows XP to Windows 11 / Windows Server 2025
-
-=back
+For more information on supported hypervisors, and guest types in

View File

@ -1,4 +1,4 @@
From b0386851d539e414302cb646567836717fd027d9 Mon Sep 17 00:00:00 2001
From 6593a1970703eee10c3ef9f41279d80a133a611d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Jun 2021 11:15:52 +0100
Subject: [PATCH] RHEL: Disable -o glance
@ -98,10 +98,10 @@ index cd4862b1..54cd276e 100644
=head1 AUTHOR
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 81a4b45a..7c7069df 100644
index a1e8fb30..b89a08a3 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -435,14 +435,6 @@ See L</Networks and bridges> below.
@@ -446,14 +446,6 @@ See L</Networks and bridges> below.
This is the same as I<-o local>.
@ -116,7 +116,7 @@ index 81a4b45a..7c7069df 100644
=item B<-o> B<kubevirt>
Set the output method to I<kubevirt>. B<Note the way this mode works
@@ -1191,11 +1183,6 @@ and output methods may use disk space, as outlined in the table below.
@@ -1206,11 +1198,6 @@ and output methods may use disk space, as outlined in the table below.
This temporarily places a full copy of the uncompressed source disks
in C<$VIRT_V2V_TMPDIR> (or F</var/tmp>).
@ -128,7 +128,7 @@ index 81a4b45a..7c7069df 100644
=item I<-o local>
=item I<-o qemu>
@@ -1398,13 +1385,6 @@ See also L</Starting the libvirt system instance>.
@@ -1413,13 +1400,6 @@ See also L</Starting the libvirt system instance>.
Because of how Cinder volumes are presented as F</dev> block devices,
using I<-o openstack> normally requires that virt-v2v is run as root.
@ -167,7 +167,7 @@ index c0db9115..074b5e16 100755
set -e
set -x
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index fca5f6e9..4148fa50 100644
index 6baa111f..427d35d4 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -197,7 +197,6 @@ let rec main () =
@ -187,7 +187,7 @@ index fca5f6e9..4148fa50 100644
s_"Set output mode (default: libvirt)";
[ M"oa" ], Getopt.String ("sparse|preallocated", set_output_alloc),
s_"Set output allocation mode";
@@ -325,8 +324,6 @@ virt-v2v -i libvirtxml guest-domain.xml -o local -os /var/tmp
@@ -333,8 +332,6 @@ virt-v2v -i libvirtxml guest-domain.xml -o local -os /var/tmp
virt-v2v -i disk disk.img -o local -os /var/tmp
@ -196,7 +196,7 @@ index fca5f6e9..4148fa50 100644
There is a companion front-end called \"virt-p2v\" which comes as an
ISO or CD image that can be booted on physical machines.
@@ -401,7 +398,6 @@ read the man page virt-v2v(1).
@@ -412,7 +409,6 @@ read the man page virt-v2v(1).
pr "input:libvirtxml\n";
pr "input:ova\n";
pr "input:vmx\n";
@ -204,7 +204,7 @@ index fca5f6e9..4148fa50 100644
pr "output:kubevirt\n";
pr "output:libvirt\n";
pr "output:local\n";
@@ -498,7 +494,6 @@ read the man page virt-v2v(1).
@@ -509,7 +505,6 @@ read the man page virt-v2v(1).
| `Disk -> (module Output_disk.Disk)
| `Null -> (module Output_null.Null)
| `QEmu -> (module Output_qemu.QEMU)

View File

@ -1,4 +1,4 @@
From 7cbdcc0d3acf0bc50e331ad994987c26c5917b63 Mon Sep 17 00:00:00 2001
From efc69fffda1c881099a30077e70335cf381765eb Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 2 Dec 2021 11:56:05 +0000
Subject: [PATCH] RHEL: Remove the --in-place option
@ -12,10 +12,10 @@ wish to support in RHEL.
3 files changed, 17 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 7c7069df..9da6c851 100644
index b89a08a3..8f096d0c 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -24,9 +24,6 @@ virtualize those machines (physical to virtual, or p2v).
@@ -25,9 +25,6 @@ virtualize those machines (physical to virtual, or p2v).
To estimate the disk space needed before conversion, see
L<virt-v2v-inspector(1)>.
@ -25,7 +25,7 @@ index 7c7069df..9da6c851 100644
=head2 Input and Output
You normally run virt-v2v with several I<-i*> options controlling the
@@ -39,10 +36,6 @@ The input and output sides of virt-v2v are separate and unrelated.
@@ -40,10 +37,6 @@ The input and output sides of virt-v2v are separate and unrelated.
Virt-v2v can read from any input and write to any output. Therefore
these sides of virt-v2v are documented separately in this manual.
@ -33,10 +33,10 @@ index 7c7069df..9da6c851 100644
-mode". In this case the source guest is always left unchanged.
-In-place conversions may be done using L<virt-v2v-in-place(1)>.
-
=head2 Other virt-v2v topics
=head2 Customization
L<virt-v2v-support(1)> — Supported hypervisors, virtualization
@@ -1666,7 +1659,6 @@ L<https://rwmj.wordpress.com/2015/09/18/importing-kvm-guests-to-ovirt-or-rhev/#c
Virt-v2v can also customize the guest during conversion, using the
@@ -1681,7 +1674,6 @@ L<https://rwmj.wordpress.com/2015/09/18/importing-kvm-guests-to-ovirt-or-rhev/#c
L<virt-p2v(1)>,
L<virt-v2v-inspector(1)>,
@ -45,7 +45,7 @@ index 7c7069df..9da6c851 100644
L<virt-df(1)>,
L<virt-filesystems(1)>,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 723a6506..4bfa1c7a 100644
index 1c3d6064..cee516c4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,6 @@ TESTS = \
@ -57,7 +57,7 @@ index 723a6506..4bfa1c7a 100644
test-v2v-inspector.sh \
test-v2v-mac.sh \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 4148fa50..834f023d 100644
index 427d35d4..3604e396 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -219,12 +219,6 @@ let rec main () =

View File

@ -1,4 +1,4 @@
From f98822497a4a60a56cb4da2d5609d30150bdd718 Mon Sep 17 00:00:00 2001
From 077fa5f47c842f7ac1613e061c0893745febd0f7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 5 Jul 2022 11:56:54 +0100
Subject: [PATCH] RHEL 9: -oo compressed: Remove nbdcopy version check and test
@ -34,7 +34,7 @@ index 53d4bb1b..14288bdc 100644
let g = open_guestfs () in
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4bfa1c7a..f38342f0 100644
index cee516c4..e4c5cdb9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -86,7 +86,6 @@ TESTS = \

View File

@ -1,4 +1,4 @@
From 28311593d57777fd4d19a9ce93b4b06502a154be Mon Sep 17 00:00:00 2001
From a10fdcb822886c5fac37bd21dc7b214d93b95670 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 5 Jul 2022 11:58:09 +0100
Subject: [PATCH] RHEL 9: tests: Remove btrfs test
@ -9,7 +9,7 @@ RHEL does not have btrfs so this test always fails.
1 file changed, 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f38342f0..810b5b50 100644
index e4c5cdb9..fc846ee7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -100,7 +100,6 @@ TESTS = \

View File

@ -1,4 +1,4 @@
From 9b289e8d0f03c9d98d2b950feb889cad883779ea Mon Sep 17 00:00:00 2001
From 8b57ac179cdcdb221a537fd51750e94fdc96ef97 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 28 Apr 2023 12:28:19 +0100
Subject: [PATCH] RHEL 9: Remove --block-driver option
@ -16,10 +16,10 @@ Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2190387
5 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod
index ce57e229..6e1c5363 100644
index 4304c0d6..b7384210 100644
--- a/docs/virt-v2v-in-place.pod
+++ b/docs/virt-v2v-in-place.pod
@@ -47,16 +47,6 @@ Display help.
@@ -51,16 +51,6 @@ Display help.
See I<--network> below.
@ -37,10 +37,10 @@ index ce57e229..6e1c5363 100644
=item B<--colours>
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 9da6c851..d3406be0 100644
index 8f096d0c..74581463 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -197,16 +197,6 @@ The options are silently ignored for other input methods.
@@ -208,16 +208,6 @@ The options are silently ignored for other input methods.
See I<--network> below.
@ -58,7 +58,7 @@ index 9da6c851..d3406be0 100644
=item B<--colours>
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 1fbd29d3..1c690a54 100644
index 8286dbc5..2dc406e2 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -43,7 +43,6 @@ let rec main () =
@ -78,7 +78,7 @@ index 1fbd29d3..1c690a54 100644
[ S 'i' ], Getopt.String ("disk|libvirt|libvirtxml|ova|vmx", set_input_mode),
s_"Set input mode (default: libvirt)";
[ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn),
@@ -216,12 +213,6 @@ read the man page virt-v2v-in-place(1).
@@ -225,12 +222,6 @@ read the man page virt-v2v-in-place(1).
(* Dereference the arguments. *)
let args = List.rev !args in
@ -88,10 +88,10 @@ index 1fbd29d3..1c690a54 100644
- | Some "virtio-scsi" -> Virtio_SCSI
- | Some driver ->
- error (f_"unknown block driver --block-driver %s") driver in
let customize_ops = get_customize_ops () in
let input_conn = !input_conn in
let input_mode = !input_mode in
let print_source = !print_source in
@@ -305,7 +296,7 @@ read the man page virt-v2v-in-place(1).
@@ -316,7 +307,7 @@ read the man page virt-v2v-in-place(1).
(* Get the conversion options. *)
let conv_options = {
@ -101,7 +101,7 @@ index 1fbd29d3..1c690a54 100644
ks = opthandle.ks;
network_map;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 810b5b50..03c71882 100644
index fc846ee7..8a710b99 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,6 @@ TESTS = \
@ -113,7 +113,7 @@ index 810b5b50..03c71882 100644
test-v2v-mac.sh \
test-v2v-machine-readable.sh \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 834f023d..be5a66e2 100644
index 3604e396..2fdaf40b 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -48,7 +48,6 @@ let rec main () =
@ -133,7 +133,7 @@ index 834f023d..be5a66e2 100644
[ L"compressed" ], Getopt.Unit (fun () -> set_output_option_compat "compressed" ""),
s_"Compress output file (-of qcow2 only)";
[ S 'i' ], Getopt.String ("disk|libvirt|libvirtxml|ova|vmx", set_input_mode),
@@ -343,12 +340,6 @@ read the man page virt-v2v(1).
@@ -352,12 +349,6 @@ read the man page virt-v2v(1).
(* Dereference the arguments. *)
let args = List.rev !args in
@ -143,10 +143,10 @@ index 834f023d..be5a66e2 100644
- | Some "virtio-scsi" -> Virtio_SCSI
- | Some driver ->
- error (f_"unknown block driver --block-driver %s") driver in
let customize_ops = get_customize_ops () in
let input_conn = !input_conn in
let input_mode = !input_mode in
let input_transport =
@@ -520,7 +511,7 @@ read the man page virt-v2v(1).
@@ -531,7 +522,7 @@ read the man page virt-v2v(1).
(* Get the conversion options. *)
let conv_options = {

View File

@ -1,4 +1,4 @@
From 1dec94e52974e45fd3962dcbd51882fde7e9c306 Mon Sep 17 00:00:00 2001
From 308738b0d2a41427c1aac6a912c92a2f711f7d1a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 9 Jul 2024 11:30:09 +0100
Subject: [PATCH] RHEL: Add warning about virt-v2v-in-place not being supported
@ -9,10 +9,10 @@ Fixes: https://issues.redhat.com/browse/RHEL-40903
1 file changed, 3 insertions(+)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 1c690a54..a70e812b 100644
index 2dc406e2..9d24de78 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -197,6 +197,9 @@ read the man page virt-v2v-in-place(1).
@@ -206,6 +206,9 @@ read the man page virt-v2v-in-place(1).
let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true ~machine_readable:true usage_msg in
Getopt.parse opthandle.getopt;

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

@ -1,93 +0,0 @@
From d26ed76801f9d3ce5d3863ca09dfa653b4bcd1b2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 27 Aug 2024 12:36:41 +0100
Subject: [PATCH] convert: windows: Online all virtio disks at first boot
Windows 2022 (and possibly earlier versions back to around 2019) will
force offline any non-boot disks which change bus, apparently as a
security mitigation. The effect of this is that although the system
drive (C:) is present after conversion, other drives may seem to
disappear.
Running a Powershell script to bring all disks online seems risky.
The compromise is to bring online only virtio disks at first boot.
To further reduce risk, we only do this if there are non-system disks
(ie. > 1 disks in total), and only if we installed virtio drivers.
Fixes: https://issues.redhat.com/browse/RHEL-55763
Fixes: https://issues.redhat.com/browse/RHEL-55837
Related: https://issues.redhat.com/browse/MTV-1299
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1662286
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Thanks: Martin Necas
Acked-by: Martin Necas
(cherry picked from commit cb56f6f94dc153051515fc7aa0d9ca646f5e2340)
---
convert/convert_windows.ml | 39 +++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
index 52ca5bbe..352e1218 100644
--- a/convert/convert_windows.ml
+++ b/convert/convert_windows.ml
@@ -38,7 +38,8 @@ module G = Guestfs
* time the Windows VM is booted on KVM.
*)
-let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
+let convert (g : G.guestfs) source inspect i_firmware
+ block_driver _ static_ips =
(*----------------------------------------------------------------------*)
(* Inspect the Windows guest. *)
@@ -272,6 +273,8 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
Registry.with_hive_write g inspect.i_windows_software_hive
update_software_hive;
+ configure_online_disks block_driver;
+
configure_network_interfaces net_driver;
fix_ntfs_heads ();
@@ -668,6 +671,40 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips =
warning (f_"could not find registry key \
HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion")
+ and configure_online_disks block_driver =
+ (* If there are > 1 disks, run a script which will force Windows
+ * to bring them all online. Windows 2022 will offline non-boot disks
+ * where the bus changes as some sort of "security" mitigation.
+ * https://issues.redhat.com/browse/RHEL-55837
+ * https://issues.redhat.com/browse/MTV-1299
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1662286
+ *)
+ let virtio_installed =
+ match block_driver with
+ | Inject_virtio_win.Virtio_blk | Virtio_SCSI -> true
+ | IDE -> false in
+ let more_than_one_disk = List.length source.s_disks > 1 in
+
+ if virtio_installed && more_than_one_disk then (
+ let psh_filename = "online-disks" in
+ let psh = ref [] in
+ let add = List.push_back psh in
+
+ add "# Uncomment this line for lots of debug output.";
+ add "# Set-PSDebug -Trace 1";
+ add "";
+ add "Write-Host \"Online all virtio disks\"";
+ add "";
+ add "Get-Disk | Where { $_.FriendlyName -like '*VirtIO*' } | % {";
+ add " Write-Host (' - ' + $_.Number + ': ' + $_.FriendlyName + '(' + [math]::Round($_.Size/1GB,2) + 'GB)')";
+ add " $_ | Set-Disk -IsOffline $false";
+ add " $_ | Set-Disk -IsReadOnly $false";
+ add "}";
+
+ (* Install the Powershell script to run late at firstboot. *)
+ Firstboot.add_firstboot_powershell g inspect.i_root psh_filename !psh
+ )
+
and configure_network_interfaces net_driver =
(* If we were asked to force network interfaces to have particular
* static IP addresses then it is done here by installing a

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

@ -0,0 +1,49 @@
From 2c1aee0f2a33ae9a7653dcd6e827038976d4121f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 2 Jan 2025 11:11:46 +0000
Subject: [PATCH] convert: Mention "operating system" in error message
A member of Red Hat's support team mentioned that the error "source
guest" is confusing. Since this refers to the operating system inside
the source guest, say that.
(cherry picked from commit f58b02a64f4238d7e2ddec45082a6f9b2c98a0c8)
---
convert/inspect_source.ml | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/convert/inspect_source.ml b/convert/inspect_source.ml
index 78447193..218e517a 100644
--- a/convert/inspect_source.ml
+++ b/convert/inspect_source.ml
@@ -141,11 +141,11 @@ let rec inspect_source root_choice g =
and choose_root root_choice g = function
| [] ->
error (f_"inspection could not detect the source guest \
- (or physical machine).\n\nAssuming that you are \
- running virt-v2v/virt-p2v on a source which is \
- supported (and not, for example, a blank disk), \
- then this should not happen.\n\nNo root device \
- found in this operating system image.");
+ (or physical machine) operating system.\n\n\
+ Assuming that you are running virt-v2v/virt-p2v \
+ on a source which is supported (and not, for example, \
+ a blank disk), then this should not happen.\n\n\
+ No root device found in this operating system image.");
| [root] -> root (* only one root, so return it *)
| roots ->
(* If there are multiple roots, use the [--root] option supplied
@@ -254,8 +254,9 @@ and sanity_check_inspection inspect =
and error_if_unknown fieldname value =
if value = "unknown" then
error (f_"inspection could not detect the source guest (or \
- physical machine).\n\nAssuming that you are running \
- virt-v2v/virt-p2v on a source which is supported (and \
- not, for example, a blank disk), then this should not \
- happen.\n\nInspection field %s was unknown.")
+ physical machine) operating system.\n\n\
+ Assuming that you are running virt-v2v/virt-p2v \
+ on a source which is supported (and not, for example, \
+ a blank disk), then this should not happen.\n\n\
+ Inspection field %s was unknown.")
fieldname

View File

@ -0,0 +1,189 @@
From 60785259a8bea65663da270b25ea6f46be42aa0f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 9 Feb 2025 17:35:14 +0000
Subject: [PATCH] Update common submodule
Pulls in the following fix:
commit 38315604596ac747e44e38db79496610efee49f8
Author: Richard W.M. Jones <rjones@redhat.com>
Date: Thu Feb 6 08:04:38 2025 +0000
mldrivers/linux_bootloaders.ml: Don't overwrite EFI grub2 wrapper
Fedora 34+ and RHEL 9.0+ unified BIOS and UEFI grub configuration into
a single file. This leaves /boot/efi/EFI/<OS>/grub.cfg as a so-called
"wrapper" which just loads the real grub2 configuration at
/boot/grub2/grub.cfg.
Running '/sbin/grub2-mkconfig -o /boot/efi/EFI/<OS>/grub.cfg'
overwrites the wrapper instead of the real configuration file.
RHEL 9.5 added a hard error if you try to do this, which broke
virt-v2v. The error message was:
commandrvf: /sbin/grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
Running `grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg' will
overwrite the GRUB wrapper. Please run `grub2-mkconfig -o
/boot/grub2/grub.cfg' instead to update grub.cfg.
Try to detect this situation and substitute the real grub
configuration file instead.
Reported-by: Robert Knipp, Fabian Deutsch
Thanks: Nijin Ashok, Marta Lewandowska
Fixes: https://issues.redhat.com/browse/RHEL-77989
Related: https://issues.redhat.com/browse/RHEL-32099
Related: https://fedoraproject.org/wiki/Changes/UnifyGrubConfig
Fixes: https://issues.redhat.com/browse/RHEL-77989
Related: https://issues.redhat.com/browse/RHEL-32099
(cherry picked from commit 17610d1c9b37424fec55c39fbf83c971a843f45f)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common faee2645..2bb8c83c:
diff --git a/common/mldrivers/linux_bootloaders.ml b/common/mldrivers/linux_bootloaders.ml
index 91c5ab9e..a821a3f3 100644
--- a/common/mldrivers/linux_bootloaders.ml
+++ b/common/mldrivers/linux_bootloaders.ml
@@ -375,8 +375,7 @@ let detect_bootloader (g : G.guestfs) root i_firmware =
with G.Error msg ->
error (f_"could not find bootloader mount point (%s): %s") mp msg in
- (*
- * Workaround for older UEFI-based Debian which may not have
+ (* Workaround for older UEFI-based Debian which may not have
* /boot/efi/EFI/debian/grub.cfg.
*)
let paths =
@@ -410,6 +409,28 @@ let detect_bootloader (g : G.guestfs) root i_firmware =
in
loop paths in
+ (* If we found a grub2 boot config called /boot/efi/EFI/<OS>/grub.cfg
+ * check if it's a "wrapper" that redirects to /boot/grub2/grub.cfg.
+ * This is needed for Fedora 34+ and RHEL 9.0+. See:
+ * https://issues.redhat.com/browse/RHEL-32099
+ * https://issues.redhat.com/browse/RHEL-77989
+ * https://github.com/libguestfs/libguestfs-common/pull/6
+ *)
+ let grub_config =
+ match typ with
+ | Grub1 -> grub_config
+ | Grub2 ->
+ let grub2_efi_rex = PCRE.compile "^/boot/efi/EFI/.*/grub.cfg$" in
+ let grub2_real = "/boot/grub2/grub.cfg" in
+
+ if PCRE.matches grub2_efi_rex grub_config &&
+ (* does it look like the "wrapper"? *)
+ g#grep "configfile \\$prefix/grub\\.cfg" grub_config <> [||] &&
+ g#exists grub2_real then
+ grub2_real
+ else
+ grub_config in
+
let bl =
match typ with
| Grub1 -> new bootloader_grub1 g root grub_config
diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c
index ad9c6d11..3959fd56 100644
--- a/common/mlpcre/pcre-c.c
+++ b/common/mlpcre/pcre-c.c
@@ -39,19 +39,6 @@
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-/* Replacement if caml_alloc_initialized_string is missing, added
- * to OCaml runtime in 2017.
- */
-#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
-static inline value
-caml_alloc_initialized_string (mlsize_t len, const char *p)
-{
- value sv = caml_alloc_string (len);
- memcpy ((char *) String_val (sv), p, len);
- return sv;
-}
-#endif
-
/* Data on the most recent match is stored in this thread-local
* variable. It is freed either by the next call to PCRE.matches or
* by (clean) thread exit.
diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
index 86b21a7c..5be358de 100644
--- a/common/mlstdutils/std_utils.ml
+++ b/common/mlstdutils/std_utils.ml
@@ -392,21 +392,6 @@ module List = struct
let push_front_list xs xsp = xsp := xs @ !xsp
end
-module Option = struct
- let iter f = function
- | None -> ()
- | Some x -> f x
-
- let map f = function
- | None -> None
- | Some x -> Some (f x)
-
- let value x ~default =
- match x with
- | None -> default
- | Some x -> x
-end
-
let (//) = Filename.concat
let quote = Filename.quote
diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
index a39ac5f3..c320b877 100644
--- a/common/mlstdutils/std_utils.mli
+++ b/common/mlstdutils/std_utils.mli
@@ -290,21 +290,6 @@ module List : sig
end
(** Override the List module from stdlib. *)
-module Option : sig
- val iter : ('a -> unit) -> 'a option -> unit
- (** [iter f o] is [f v] if [o] is [Some v] and [()] otherwise *)
-
- val map : ('a -> 'b) -> 'a option -> 'b option
- (** [map f (Some x)] returns [Some (f x)]. [map f None] returns [None]. *)
-
- val value : 'a option -> default:'a -> 'a
- (** [value o ~default] is [v] if [o] is [Some v] and [default] otherwise. *)
-end
-(** Functions for dealing with option types.
-
- This module will be removed when we can use baseline OCaml 4.08
- since that version introduces a compatible [Option] module. *)
-
val ( // ) : string -> string -> string
(** Concatenate directory and filename. *)
diff --git a/common/mlxml/xml-c.c b/common/mlxml/xml-c.c
index e024bd8a..9259314f 100644
--- a/common/mlxml/xml-c.c
+++ b/common/mlxml/xml-c.c
@@ -41,19 +41,6 @@
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-/* Replacement if caml_alloc_initialized_string is missing, added
- * to OCaml runtime in 2017.
- */
-#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
-static inline value
-caml_alloc_initialized_string (mlsize_t len, const char *p)
-{
- value sv = caml_alloc_string (len);
- memcpy ((char *) String_val (sv), p, len);
- return sv;
-}
-#endif
-
/* xmlDocPtr type */
#define docptr_val(v) (*((xmlDocPtr *)Data_custom_val(v)))

View File

@ -0,0 +1,86 @@
From 1d3017a30a2f831ee1461c1828c63c9a196805dd Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 10 Feb 2025 10:53:00 -0500
Subject: [PATCH] convert: Use yum/apt/... for package removals, not rpm/dpkg
Current package removal implementation uses `rpm -e`, which will
fail if anything depends on the package we are trying to remove.
Like when `spausedd` is dependent on `open-vm-tools`.
Reuse the package uninstall logic from virt-customize, which
will handle this no problem.
Just print a warning when package removal goes sideways.
Fixes: https://issues.redhat.com/browse/RHEL-71522
Signed-off-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit b3268a13beca4da218e7ffe4648a18420296103a)
---
convert/convert_linux.ml | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml
index 3d0e2b88..cbae5e3d 100644
--- a/convert/convert_linux.ml
+++ b/convert/convert_linux.ml
@@ -131,6 +131,23 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ =
(*----------------------------------------------------------------------*)
(* Conversion step. *)
+ let uninstall_packages pkgs =
+ if pkgs <> [] then (
+ let cmd =
+ try Guest_packages.uninstall_command pkgs inspect.i_package_management
+ with
+ | Guest_packages.Unknown_package_manager msg
+ | Guest_packages.Unimplemented_package_manager msg ->
+ error "%s" msg
+ in
+ (try ignore (g#sh cmd)
+ with G.Error msg ->
+ warning (f_"could not uninstall packages %s: %s (ignored)")
+ (String.concat " " pkgs) msg
+ )
+ )
+ in
+
let rec do_convert () =
augeas_grub_configuration ();
@@ -237,7 +254,7 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ =
else
None
) inspect.i_apps in
- Linux.remove g inspect.i_root xenmods;
+ uninstall_packages xenmods;
(* Undo related nastiness if kmod-xenpv was installed. *)
if xenmods <> [] then (
@@ -310,7 +327,7 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ =
fun { G.app2_name = name } -> name = package_name
) inspect.i_apps in
if has_guest_additions then
- Linux.remove g inspect.i_root [package_name];
+ uninstall_packages [package_name];
(* Guest Additions might have been installed from a tarball. The
* above code won't detect this case. Look for the uninstall tool
@@ -455,8 +472,7 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ =
)
);
- let remove = !remove in
- Linux.remove g inspect.i_root remove;
+ uninstall_packages !remove;
(* VMware Tools may have been installed from a tarball, so the
* above code won't remove it. Look for the uninstall tool and run
@@ -503,7 +519,7 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ =
let pkgs = List.map (fun { G.app2_name = name } -> name) pkgs in
if pkgs <> [] then (
- Linux.remove g inspect.i_root pkgs;
+ uninstall_packages pkgs;
(* Installing these guest utilities automatically unconfigures
* ttys in /etc/inittab if the system uses it. We need to put

View File

@ -0,0 +1,141 @@
From 453e38ce02118fc81fe9ec9ca8f81ae341c93fe7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 19 Feb 2025 15:15:30 +0000
Subject: [PATCH] test-data: phony fedora: Add simple static /bin/sh
This is able to do enough to run commands via g#sh and related calls
inside the phony Fedora image.
(cherry picked from
guestfs-tools commit 4c5854f54e1da0d96807acb1b047bbf34694a0bb)
(cherry picked from commit de073524ec9fbfa179f2721c36013b2bb312e73f)
---
test-data/phony-guests/fedora.c | 76 +++++++++++++++++++++--
test-data/phony-guests/make-fedora-img.pl | 6 +-
2 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/test-data/phony-guests/fedora.c b/test-data/phony-guests/fedora.c
index c74976d6..0e324d21 100644
--- a/test-data/phony-guests/fedora.c
+++ b/test-data/phony-guests/fedora.c
@@ -16,13 +16,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* This is "just enough" of a binary to look like RPM and dracut, as
- * far as virt-v2v is concerned.
+/* This is "just enough" of a binary to look like /bin/sh, RPM and
+ * dracut, as far as virt-v2v is concerned.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
/* NB: This is also defined in make-fedora-img.pl */
#define KVER "5.19.0-0.rc1.14.fc37.x86_64"
@@ -34,6 +35,27 @@ get_basename (const char *str)
return ret == NULL ? str : ret + 1;
}
+static void
+add_str (char ***argv, size_t *argc, char *str)
+{
+ (*argc)++;
+ (*argv) = realloc (*argv, *argc * sizeof (char *));
+ (*argv)[*argc-1] = str;
+}
+
+static void
+add_null (char ***argv, size_t *argc)
+{
+ add_str (argv, argc, NULL);
+}
+
+static void
+add (char ***argv, size_t *argc, const char *s, size_t len)
+{
+ char *copy = strndup (s, len);
+ add_str (argv, argc, copy);
+}
+
int
main (int argc, char *argv[])
{
@@ -57,10 +79,54 @@ main (int argc, char *argv[])
strcmp (get_basename (argv[0]), "dracut") == 0) {
// do nothing, pretend to rebuild the initramfs
}
+ else if (argc == 3 &&
+ strcmp (get_basename (argv[0]), "sh") == 0 &&
+ strcmp (argv[1], "-c") == 0) {
+ /* Split the command and execute it. Only handles trivial cases. */
+ char *cmd = argv[2];
+ char **cmdv = NULL;
+ size_t i, cmdvlen = 0, n;
+ const size_t len = strlen (cmd);
+
+ for (i = 0; i < len;) {
+ switch (cmd[i]) {
+ case ' ': case '\t':
+ i++;
+ continue;
+
+ case '"':
+ n = strcspn (&cmd[i+1], "\"");
+ add (&cmdv, &cmdvlen, &cmd[i+1], n);
+ i += n+2;
+ break;
+
+ case '\'':
+ n = strcspn (&cmd[i+1], "'");
+ add (&cmdv, &cmdvlen, &cmd[i+1], n);
+ i += n+2;
+ break;
+
+ default:
+ n = strcspn (&cmd[i], " \t");
+ add (&cmdv, &cmdvlen, &cmd[i], n);
+ i += n;
+ }
+ }
+ add_null (&cmdv, &cmdvlen);
+
+ execvp (cmdv[0], cmdv);
+ perror (cmdv[0]);
+ exit (EXIT_FAILURE);
+ }
else {
- fprintf (stderr, "phony Fedora: unknown command\n");
- exit (1);
+ int i;
+
+ fprintf (stderr, "ERROR: test-data/phony-guests/fedora.c: "
+ "unexpected command:\n");
+ for (i = 0; i < argc; ++i)
+ fprintf (stderr, "argv[%d] = %s\n", i, argv[i]);
+ exit (EXIT_FAILURE);
}
- exit (0);
+ exit (EXIT_SUCCESS);
}
diff --git a/test-data/phony-guests/make-fedora-img.pl b/test-data/phony-guests/make-fedora-img.pl
index 188cdd75..f661e8ec 100755
--- a/test-data/phony-guests/make-fedora-img.pl
+++ b/test-data/phony-guests/make-fedora-img.pl
@@ -369,8 +369,10 @@ $g->ln_s ('/bin/test1', '/bin/test5');
$g->mkfifo (0777, '/bin/test6');
$g->mknod (0777, 10, 10, '/bin/test7');
-# Virt-v2v needs an RPM command, or at least something which acts
-# similarly, and also a dracut command.
+# Virt-v2v needs a /bin/sh, an RPM command and a dracut command, or at
+# least something which acts similarly to those.
+$g->upload ('fedora-static-bin', '/bin/sh');
+$g->chmod (0777, '/bin/sh');
$g->upload ('fedora-static-bin', '/bin/rpm');
$g->chmod (0777, '/bin/rpm');
$g->upload ('fedora-static-bin', '/sbin/dracut');

View File

@ -0,0 +1,342 @@
From 0a5fb62a2816d16cbdd7452c8bd95a8fcd2d4a02 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 19 Feb 2025 14:16:13 +0000
Subject: [PATCH] convert: Handle large output from 'rpm -ql' command
This requires the new guestfs_sh_out API from libguestfs 1.55.6.
Update common submodule to include:
Richard W.M. Jones (3):
mlstdutils: Reimplement String.find, add String.find_from
mlstdutils: Reimplement String.nsplit tail recursively
mldrivers: Handle large output from 'rpm -ql' command
Fixes: https://issues.redhat.com/browse/RHEL-80080
Reported-by: Nijin Ashok
(cherry picked from commit 5dfe62885bc7d81c7d3c9260ba6def5cb477b5fd)
---
common | 2 +-
m4/guestfs-libraries.m4 | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
Submodule common 2bb8c83c..18310179:
diff --git a/common/mldrivers/linux.ml b/common/mldrivers/linux.ml
index 4e30a8e1..0dec1549 100644
--- a/common/mldrivers/linux.ml
+++ b/common/mldrivers/linux.ml
@@ -58,76 +58,84 @@ and do_remove g root packages =
let file_list_of_package (g : Guestfs.guestfs) root app =
let package_format = g#inspect_get_package_format root in
- match package_format with
- | "deb" ->
- let cmd = [| "dpkg"; "-L"; app.G.app2_name |] in
- debug "%s" (String.concat " " (Array.to_list cmd));
- let files = g#command_lines cmd in
- let files = Array.to_list files in
+
+ let cmd =
+ match package_format with
+ | "deb" -> sprintf "dpkg -L %s" (quote app.G.app2_name)
+
+ | "rpm" ->
+ (* Since RPM allows multiple packages installed with the same
+ * name, always check the full NEVR here (RHBZ#1161250).
+ *
+ * In RPM < 4.11 query commands that use the epoch number in the
+ * package name did not work.
+ *
+ * For example:
+ * RHEL 6 (rpm 4.8.0):
+ * $ rpm -q tar-2:1.23-11.el6.x86_64
+ * package tar-2:1.23-11.el6.x86_64 is not installed
+ * Fedora 20 (rpm 4.11.2):
+ * $ rpm -q tar-2:1.26-30.fc20.x86_64
+ * tar-1.26-30.fc20.x86_64
+ *)
+ let is_rpm_lt_4_11 () =
+ let ver =
+ try
+ (* Since we're going to run 'rpm' below anyway, seems safe
+ * to run it here and assume the binary works.
+ *)
+ let cmd = [| "rpm"; "--version" |] in
+ debug "%s" (String.concat " " (Array.to_list cmd));
+ let ver = g#command_lines cmd in
+ let ver =
+ if Array.length ver > 0 then ver.(0) else raise Not_found in
+ debug "%s" ver;
+ let ver = String.nsplit " " ver in
+ let ver =
+ match ver with
+ | [ "RPM"; "version"; ver ] -> ver
+ | _ -> raise Not_found in
+ if not (PCRE.matches re_version ver) then raise Not_found;
+ (int_of_string (PCRE.sub 1), int_of_string (PCRE.sub 2))
+ with Not_found ->
+ (* 'rpm' not installed? Hmm... *)
+ (0, 0) in
+ ver < (4, 11)
+ in
+ let pkg_name =
+ if app.G.app2_epoch = Int32.zero || is_rpm_lt_4_11 () then
+ sprintf "%s-%s-%s" app.G.app2_name app.G.app2_version
+ app.G.app2_release
+ else
+ sprintf "%s-%ld:%s-%s" app.G.app2_name app.G.app2_epoch
+ app.G.app2_version app.G.app2_release in
+ sprintf "rpm -ql %s" (quote pkg_name)
+
+ | format ->
+ error (f_"dont know how to get list of files from package using %s")
+ format in
+
+ debug "file_list_of_package: running: %s" cmd;
+
+ (* Some packages have a lot of files, too many to list without
+ * breaking the maximum message size assumption in libguestfs.
+ * To cope with this, use guestfs_sh_out, added in 1.55.6.
+ * https://issues.redhat.com/browse/RHEL-80080
+ *)
+ let tmpfile = Filename.temp_file "v2vcmd" ".out" in
+ On_exit.unlink tmpfile;
+ g#sh_out cmd tmpfile;
+ let files = read_whole_file tmpfile in
+
+ (* RPM prints "(contains no files)" on stdout when a package
+ * has no files in it:
+ * https://github.com/rpm-software-management/rpm/issues/962
+ *)
+ if String.is_prefix files "(contains no files)" then []
+ else (
+ let files = String.nsplit "\n" files in
List.sort compare files
-
- | "rpm" ->
- (* Since RPM allows multiple packages installed with the same
- * name, always check the full NEVR here (RHBZ#1161250).
- *
- * In RPM < 4.11 query commands that use the epoch number in the
- * package name did not work.
- *
- * For example:
- * RHEL 6 (rpm 4.8.0):
- * $ rpm -q tar-2:1.23-11.el6.x86_64
- * package tar-2:1.23-11.el6.x86_64 is not installed
- * Fedora 20 (rpm 4.11.2):
- * $ rpm -q tar-2:1.26-30.fc20.x86_64
- * tar-1.26-30.fc20.x86_64
- *)
- let is_rpm_lt_4_11 () =
- let ver =
- try
- (* Since we're going to run 'rpm' below anyway, seems safe
- * to run it here and assume the binary works.
- *)
- let cmd = [| "rpm"; "--version" |] in
- debug "%s" (String.concat " " (Array.to_list cmd));
- let ver = g#command_lines cmd in
- let ver = if Array.length ver > 0 then ver.(0) else raise Not_found in
- debug "%s" ver;
- let ver = String.nsplit " " ver in
- let ver =
- match ver with
- | [ "RPM"; "version"; ver ] -> ver
- | _ -> raise Not_found in
- if not (PCRE.matches re_version ver) then raise Not_found;
- (int_of_string (PCRE.sub 1), int_of_string (PCRE.sub 2))
- with Not_found ->
- (* 'rpm' not installed? Hmm... *)
- (0, 0) in
- ver < (4, 11)
- in
- let pkg_name =
- if app.G.app2_epoch = Int32.zero || is_rpm_lt_4_11 () then
- sprintf "%s-%s-%s" app.G.app2_name app.G.app2_version
- app.G.app2_release
- else
- sprintf "%s-%ld:%s-%s" app.G.app2_name app.G.app2_epoch
- app.G.app2_version app.G.app2_release in
- let cmd = [| "rpm"; "-ql"; pkg_name |] in
- debug "%s" (String.concat " " (Array.to_list cmd));
- let files = g#command_lines cmd in
- (* RPM prints "(contains no files)" on stdout when a package
- * has no files in it:
- * https://github.com/rpm-software-management/rpm/issues/962
- *)
- if files = [| "(contains no files)" |] then
- []
- else (
- let files = Array.to_list files in
- List.sort compare files
- )
-
- | format ->
- error (f_"dont know how to get list of files from package using %s")
- format
+ )
let is_file_owned (g : G.guestfs) root path =
let package_format = g#inspect_get_package_format root in
diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
index 5be358de..212a1513 100644
--- a/common/mlstdutils/std_utils.ml
+++ b/common/mlstdutils/std_utils.ml
@@ -98,24 +98,27 @@ module String = struct
and len = length str in
len >= sufflen && sub str (len - sufflen) sufflen = suffix
- let rec find s sub =
- let len = length s in
+ let find_from str pos sub =
let sublen = length sub in
- let rec loop i =
- if i <= len-sublen then (
- let rec loop2 j =
- if j < sublen then (
- if s.[i+j] = sub.[j] then loop2 (j+1)
- else -1
- ) else
- i (* found *)
- in
- let r = loop2 0 in
- if r = -1 then loop (i+1) else r
- ) else
- -1 (* not found *)
- in
- loop 0
+ if sublen = 0 then
+ 0
+ else (
+ let found = ref 0 in
+ let len = length str in
+ try
+ for i = pos to len - sublen do
+ let j = ref 0 in
+ while unsafe_get str (i + !j) = unsafe_get sub !j do
+ incr j;
+ if !j = sublen then begin found := i; raise Exit; end;
+ done;
+ done;
+ -1
+ with
+ Exit -> !found
+ )
+
+ let find str sub = find_from str 0 sub
let rec replace s s1 s2 =
let len = length s in
@@ -145,7 +148,7 @@ module String = struct
else if n >= len then str, ""
else sub str 0 n, sub str n (len-n)
- let rec split sep str =
+ let split sep str =
let seplen = length sep in
let strlen = length str in
let i = find str sep in
@@ -154,20 +157,36 @@ module String = struct
sub str 0 i, sub str (i + seplen) (strlen - i - seplen)
)
- and nsplit ?(max = 0) sep str =
+ let nsplit ?(max = 0) sep str =
if max < 0 then
invalid_arg "String.nsplit: max parameter should not be negative";
- (* If we reached the limit, OR if the pattern does not match the string
- * at all, return the rest of the string as a single element list.
- *)
- if max = 1 || find str sep = -1 then
- [str]
- else (
- let s1, s2 = split sep str in
- let max = if max = 0 then 0 else max - 1 in
- s1 :: nsplit ~max sep s2
- )
+ let len = String.length str in
+ let seplen = String.length sep in
+
+ let rec loop iters posn acc =
+ (* If we reached the limit, OR if the pattern does not match
+ * the string at all, return the rest of the string.
+ *)
+ if max > 0 && iters = max then (
+ let rest =
+ if posn = 0 then str else String.sub str posn (len-posn) in
+ List.rev (rest :: acc)
+ )
+ else (
+ let end_ = find_from str posn sep in
+ if end_ = -1 then (
+ let rest =
+ if posn = 0 then str else String.sub str posn (len-posn) in
+ List.rev (rest :: acc)
+ )
+ else (
+ let acc = String.sub str posn (end_-posn) :: acc in
+ loop (iters+1) (end_+seplen) acc
+ )
+ )
+ in
+ loop 1 0 []
let rec lines_split str =
let buf = Buffer.create 16 in
diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
index c320b877..72a2d44c 100644
--- a/common/mlstdutils/std_utils.mli
+++ b/common/mlstdutils/std_utils.mli
@@ -82,6 +82,10 @@ module String : sig
val find : string -> string -> int
(** [find str sub] searches for [sub] as a substring of [str]. If
found it returns the index. If not found, it returns [-1]. *)
+ val find_from : string -> int -> string -> int
+ (** [find_from str start sub] searches for [sub] as a substring of [str],
+ starting at index [start]. If found it returns the index.
+ If not found, it returns [-1]. *)
val replace : string -> string -> string -> string
(** [replace str s1 s2] replaces all instances of [s1] appearing in
[str] with [s2]. *)
diff --git a/common/mlstdutils/std_utils_tests.ml b/common/mlstdutils/std_utils_tests.ml
index 3f5bb1a8..4e368152 100644
--- a/common/mlstdutils/std_utils_tests.ml
+++ b/common/mlstdutils/std_utils_tests.ml
@@ -113,13 +113,19 @@ let test_string_nsplit ctx =
assert_equal_stringlist [""] (String.nsplit " " "");
assert_equal_stringlist ["abc"] (String.nsplit " " "abc");
assert_equal_stringlist ["a"; "b"; "c"] (String.nsplit " " "a b c");
+ assert_equal_stringlist ["abc"; "d"; "e"] (String.nsplit " " "abc d e");
assert_equal_stringlist ["a"; "b"; "c"; ""] (String.nsplit " " "a b c ");
assert_equal_stringlist [""; "a"; "b"; "c"] (String.nsplit " " " a b c");
assert_equal_stringlist [""; "a"; "b"; "c"; ""] (String.nsplit " " " a b c ");
assert_equal_stringlist ["a b c d"] (String.nsplit ~max:1 " " "a b c d");
assert_equal_stringlist ["a"; "b c d"] (String.nsplit ~max:2 " " "a b c d");
assert_equal_stringlist ["a"; "b"; "c d"] (String.nsplit ~max:3 " " "a b c d");
- assert_equal_stringlist ["a"; "b"; "c"; "d"] (String.nsplit ~max:10 " " "a b c d")
+ assert_equal_stringlist ["a"; "b"; "c"; "d"] (String.nsplit ~max:10 " " "a b c d");
+
+ (* Test that nsplit can handle large strings. *)
+ let xs = Array.to_list (Array.make 10_000_000 "xyz") in
+ let xs_concat = String.concat " " xs in
+ assert_equal_stringlist xs (String.nsplit " " xs_concat)
(* Test Std_utils.String.lines_split. *)
let test_string_lines_split ctx =
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
index f0cad0f5..3cb3cabd 100644
--- a/m4/guestfs-libraries.m4
+++ b/m4/guestfs-libraries.m4
@@ -18,7 +18,9 @@
dnl Any C libraries required by virt-v2v.
dnl Of course we need libguestfs.
-PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.44])
+dnl
+dnl We need libguestfs >= 1:1.54.0-4.el9_6 for guestfs_sh_out.
+PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.54.0])
dnl And libnbd.
PKG_CHECK_MODULES([LIBNBD], [libnbd >= 1.10])

View File

@ -7,7 +7,7 @@ set -e
# ./copy-patches.sh
project=virt-v2v
rhel_version=9.5
rhel_version=9.6
# Check we're in the right directory.
if [ ! -f $project.spec ]; then

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmapDYsRHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKATow//dAt+/eD4WANTgt82gOK5VLuhlp/il6/L
IsErVntOsmAlr1Ukag6lAFmrQrxDHbRo1g9w+P3dabEbedqeAy0vlyE7feifbzfn
8dAGAYJBPqyhG5w5Y1YKU/ZfJF5OjxuD9kjn5YTBNmNNva2wqrb4vQqLfmfhpMlx
hf3xMlqJ3plXvaqPFk69BzSgA1hKP9Z/f522RQs9lRq+aSP00zatLX9DK5oXynas
6DbInkrfUjbMaENoYcuUzC1w45DUcTcq6Or36+h86G78yIkQpfwlS82G0/f4wVnv
QlD5pC6dCmowuCrr5/xMoYt5ah7L+qcEUIRJ4uB0xQgQtQV32eLIFjpcHsN973ot
ji2ievMtoM5Ncu2Hq1R02Hvx5PUvVZamEpEWf+HzqJl2VATw2F63CMALLjxR6mw4
WORi90ZLQWtbt7lJgZEI29WOabuBWGG/cn+01gWLh8swqQpAgkGsbJhCxNXLiUfy
0PE7K+zoWVZzSiuOVeIh1Gn2p75gSTRQXfY+l+IfPPfOUBOuNN+w1J5HRUaT7ZAk
zBbPGFA2Y6x2zR9TD5n87QftXF6LPhf715qh5URI4Wl0pE+C9gxhQk+nf1aMKJ5J
/fOAtU8N+PtZPUm95NTaQxpkraspwHmhLRygWzA7wUGANmVUiX0fE3qgxW9NE2bI
paYjGigt040=
=FGlR
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAmcX1vARHHJpY2hAYW5u
ZXhpYS5vcmcACgkQkXOPc+G3aKAx9xAAgHsZ9z7uoEC70+xxZIS3UVVzfSb/4Vik
lMgZr1+lTsFRT7cFwog+7xl/KCAfxSpNyBCfmLH3IKSSiKzVJjw4CwfbIDmRsc+5
dJeaFJaOFeaANhqxStYWwXwG9WdmPGghM3tLJZhoeYBieZ80ei2wZrh3H+cK3/hl
0mzFonLLmKFAR0AhuiLDmITGRg/SCSEZuopLLvL9n8LKQ+v8LCf0pKjZjinD4IGY
J0sSbHF9e4hwaHKpOqerEnMZgkKaKG6JtKf9cj5uTdANIT3e5xfCkYjsPIDzhOpg
7irOa2zpQJoVzqiYavSdxKdp/Uvw6+Zkb54rjwAxZSlPTSWHMFQfRSs1aY8o+mkQ
YkEo2jiDDzB9PdrJre062kiA/J+aSvHwy5AivJxX/N7pMoida5H9ERfV4h79NHgA
Vy/jQ237lO0DE/Fn4O1mchxWKozbFuwajo7a+/XocskrJNpOgBhukl8fQiNfqFHp
LP1KshvRlXljw2f0yuTm2gb2NNN2axu+1QzBp37V5MmA4WEbJwuMRILn8ntK0979
pQjtVGkYdA1aBOAX1ZJaaz6xEjwk2h9eNlY4Uu+eIUdIVgtUk7pfatOMApETmbUf
ilLiPhWZrFCqLNHAe9uG+wEbYcf7Glx1jP5wpHXR7DSVl2ZLydNpFC/YHttIXoF5
sJbNDeHwEVU=
=FH7a
-----END PGP SIGNATURE-----

View File

@ -3,11 +3,11 @@
%global verify_tarball_signature 1
# The source directory.
%global source_directory 2.5-development
%global source_directory 2.7-development
Name: virt-v2v
Epoch: 1
Version: 2.5.6
Version: 2.7.1
Release: 5%{?dist}
Summary: Convert a virtual machine to run on KVM
@ -25,30 +25,42 @@ Source2: libguestfs.keyring
Source3: copy-patches.sh
# Patches are maintained in the following repository:
# https://github.com/libguestfs/virt-v2v/commits/rhel-9.5
# https://github.com/libguestfs/virt-v2v/commits/rhel-9.6
# Patches.
Patch0001: 0001-docs-Note-that-mac-len-field-is-now-optional.patch
Patch0002: 0002-convert-More-robust-qemu-ga-installation-change-path.patch
Patch0003: 0003-common-mlcustomize-Inject-qemu-ga-blnsvr-into-firstb.patch
Patch0004: 0004-docs-Add-a-note-about-removal-of-VMware-Tools-on-Win.patch
Patch0005: 0005-Update-common-submodule.patch
Patch0006: 0006-Pull-in-a-fix-to-make-Windows-firstboot-more-reliabl.patch
Patch0007: 0007-docs-Restate-position-on-removal-of-VMware-Tools.patch
Patch0008: 0008-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch
Patch0009: 0009-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch
Patch0010: 0010-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch
Patch0011: 0011-RHEL-Fixes-for-libguestfs-winsupport.patch
Patch0012: 0012-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch
Patch0013: 0013-RHEL-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-1430203.patch
Patch0014: 0014-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch
Patch0015: 0015-RHEL-Disable-o-glance.patch
Patch0016: 0016-RHEL-Remove-the-in-place-option.patch
Patch0017: 0017-RHEL-9-oo-compressed-Remove-nbdcopy-version-check-an.patch
Patch0018: 0018-RHEL-9-tests-Remove-btrfs-test.patch
Patch0019: 0019-RHEL-9-Remove-block-driver-option.patch
Patch0020: 0020-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0021: 0021-convert-windows-Online-all-virtio-disks-at-first-boo.patch
Patch0001: 0001-lib-OVF-Add-preliminary-support-for-Windows-Server-2.patch
Patch0002: 0002-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch
Patch0003: 0003-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch
Patch0004: 0004-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch
Patch0005: 0005-RHEL-Fixes-for-libguestfs-winsupport.patch
Patch0006: 0006-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch
Patch0007: 0007-RHEL-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-1430203.patch
Patch0008: 0008-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch
Patch0009: 0009-RHEL-Disable-o-glance.patch
Patch0010: 0010-RHEL-Remove-the-in-place-option.patch
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
Patch0029: 0029-convert-Mention-operating-system-in-error-message.patch
Patch0030: 0030-Update-common-submodule.patch
Patch0031: 0031-convert-Use-yum-apt-.-for-package-removals-not-rpm-d.patch
Patch0032: 0032-test-data-phony-fedora-Add-simple-static-bin-sh.patch
Patch0033: 0033-convert-Handle-large-output-from-rpm-ql-command.patch
%if !0%{?rhel}
# libguestfs hasn't been built on i686 for a while since there is no
@ -73,12 +85,12 @@ BuildRequires: /usr/bin/pod2man
BuildRequires: gcc
BuildRequires: ocaml >= 4.04
BuildRequires: libguestfs-devel >= 1:1.49.8-1
BuildRequires: libguestfs-devel >= 1:1.54.0-4.el9
BuildRequires: augeas-devel
BuildRequires: bash-completion
BuildRequires: file-devel
BuildRequires: gettext-devel
BuildRequires: jansson-devel
BuildRequires: json-c-devel
BuildRequires: libnbd-devel
BuildRequires: libosinfo-devel
BuildRequires: libvirt-daemon-kvm
@ -117,7 +129,7 @@ BuildRequires: sqlite
BuildRequires: gnupg2
%endif
Requires: libguestfs%{?_isa} >= 1:1.49.8-1
Requires: libguestfs%{?_isa} >= 1:1.54.0-4.el9
Requires: guestfs-tools >= 1.49.7-1
# XFS is the default filesystem in Fedora and RHEL.
@ -303,7 +315,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
@ -329,9 +341,7 @@ make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
%{_mandir}/man1/virt-v2v-output-openstack.1*
%{_mandir}/man1/virt-v2v-output-rhv.1*
%{_mandir}/man1/virt-v2v-release-notes-1.42.1*
%{_mandir}/man1/virt-v2v-release-notes-2.0.1*
%{_mandir}/man1/virt-v2v-release-notes-2.2.1*
%{_mandir}/man1/virt-v2v-release-notes-2.4.1*
%{_mandir}/man1/virt-v2v-release-notes-2.*.1*
%{_mandir}/man1/virt-v2v-support.1*
%{_datadir}/virt-tools
@ -352,7 +362,28 @@ make -C tests TESTS=test-v2v-fedora-luks-on-lvm-conversion.sh check
%changelog
* Thu Aug 29 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.5.6-5
* Tue Feb 25 2025 Richard W.M. Jones <rjones@redhat.com> - 1:2.7.1-5
- 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
- mldrivers/linux_bootloaders.ml: Don't overwrite EFI grub2 wrapper
resolves: RHEL-77989
- convert: Use yum/apt/... for package removals
resolves: RHEL-71522
- Fix failure if the kernel-source package is installed in the source VM
resolves: RHEL-80080
* Thu Sep 05 2024 Richard W.M. Jones <rjones@redhat.com> - 1:2.5.9-1
- Rebase to upstream development version 2.5.9
- Fix display of incorrect Windows 11 version
resolves: RHEL-56784
- Add customization options for post-conversion modification
resolves: RHEL-55761
- convert: windows: Ignore sriov drivers on virtio-win disk
resolves: RHEL-56383