Compare commits

...

No commits in common. "c8-beta-stream-rhel" and "c9s" have entirely different histories.

116 changed files with 9729 additions and 5127 deletions

19
.gitignore vendored
View File

@ -1,5 +1,14 @@
SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
SOURCES/libguestfs.keyring
SOURCES/rhsrvany-fd659e77cdd9da484fdc9dcbe0605c62ec26fa30.tar.gz
SOURCES/rhsrvany.exe
SOURCES/virt-v2v-1.42.0.tar.gz
*~
# RPM target directories
/x86_64
# Version-dependent build artifacts
/.build-*.log
/virt-v2v-v*/
/virt-v2v-*.src.rpm
/results_virt-v2v/
# Source
/virt-v2v-*.tar.gz
/virt-v2v-*.tar.gz.sig

View File

@ -1,5 +0,0 @@
130adbc011dc0af736465b813c2b22a600c128c1 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
136ff75deb496e48eb448bc4ae156f3911464a90 SOURCES/rhsrvany-fd659e77cdd9da484fdc9dcbe0605c62ec26fa30.tar.gz
2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe
bdbdc7cca87735af64f7e99c050ead24fa92aa7d SOURCES/virt-v2v-1.42.0.tar.gz

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,10 +1,10 @@
From 9331544f2456f1aef7299920d0c84dff4e47d132 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 8: v2v: Select correct qemu binary for -o qemu mode
Subject: [PATCH] RHEL: v2v: Select correct qemu binary for -o qemu mode
(RHBZ#1147313).
RHEL 8 does not have qemu-system-x86_64 (etc), and in addition the
RHEL does not have qemu-system-x86_64 (etc), and in addition the
qemu binary is located in /usr/libexec. Encode the path to this
binary directly in the script.
@ -12,14 +12,14 @@ Note that we don't support people running qemu directly like this.
It's just for quick testing of converted VMs, and to help us with
support cases.
---
v2v/output_qemu.ml | 2 +-
output/output_qemu.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
index be3a3c5e..85d08265 100644
--- a/v2v/output_qemu.ml
+++ b/v2v/output_qemu.ml
@@ -81,7 +81,7 @@ object
diff --git a/output/output_qemu.ml b/output/output_qemu.ml
index 26c1ba48..07dae8c2 100644
--- a/output/output_qemu.ml
+++ b/output/output_qemu.ml
@@ -131,7 +131,7 @@ module QEMU = struct
* module deals with shell and qemu comma quoting.
*)
let cmd = Qemuopts.create () in

View File

@ -1,21 +1,23 @@
From 7df465dede750140bbc5a2579a5256061af63e03 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 8: v2v: Disable the --qemu-boot option (RHBZ#1147313).
Subject: [PATCH] RHEL: v2v: Disable the --qemu-boot / -oo qemu-boot option
(RHBZ#1147313).
This cannot work because there is no Gtk or SDL output mode
in RHEL 8's qemu-kvm.
in RHEL's qemu-kvm.
In addition you will have to edit the -display option in the
qemu script.
---
docs/virt-v2v-output-local.pod | 6 ++----
docs/virt-v2v.pod | 13 -------------
v2v/cmdline.ml | 3 ++-
3 files changed, 4 insertions(+), 18 deletions(-)
docs/virt-v2v.pod | 17 -----------------
output/output_qemu.ml | 3 +++
v2v/v2v.ml | 2 --
4 files changed, 5 insertions(+), 23 deletions(-)
diff --git a/docs/virt-v2v-output-local.pod b/docs/virt-v2v-output-local.pod
index a5f155cb..3a2e6238 100644
index d2a1c270..0be37f5e 100644
--- a/docs/virt-v2v-output-local.pod
+++ b/docs/virt-v2v-output-local.pod
@@ -9,7 +9,7 @@ or libvirt
@ -25,9 +27,9 @@ index a5f155cb..3a2e6238 100644
- virt-v2v [-i* options] -o qemu -os DIRECTORY [--qemu-boot]
+ virt-v2v [-i* options] -o qemu -os DIRECTORY
virt-v2v [-i* options] -o json -os DIRECTORY
[-oo json-disks-pattern=PATTERN]
@@ -50,12 +50,10 @@ where C<NAME> is the guest name.
virt-v2v [-i* options] -o null
@@ -47,12 +47,10 @@ where C<NAME> is the guest name.
=item B<-o qemu -os> C<DIRECTORY>
@ -39,64 +41,81 @@ index a5f155cb..3a2e6238 100644
-run, I<unless> you also add the I<--qemu-boot> option.
+run.
=item B<-o json -os> C<DIRECTORY>
=item B<-o null>
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 74934eb4..a19f0a73 100644
index 5345a6c9..a1e8fb30 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -144,11 +144,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.
-To convert a local disk image and immediately boot it in local
-qemu, do:
-
- virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot
- virt-v2v -i disk disk.img -o qemu -os /var/tmp -oo qemu-boot
-
=head1 OPTIONS
=over 4
@@ -537,9 +532,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>.
-When using this output mode, you can also specify the I<--qemu-boot>
-When using this output mode, you can also specify the I<-oo qemu-boot>
-option which boots the guest under qemu immediately.
-
=item B<-o> B<rhev>
This is the same as I<-o rhv>.
@@ -815,11 +807,6 @@ Print information about the source guest and stop. This option is
@@ -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.
-=item B<-oo qemu-boot>
-
-When using I<-o qemu> only, this boots the guest immediately after
-virt-v2v finishes.
-
=item B<-oo verify-server-certificate>
=item B<-oo verify-server-certificate=>C<true|false>
@@ -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>.
-=item B<--qemu-boot>
-
-When using I<-o qemu> only, this boots the guest immediately after
-virt-v2v finishes.
-This is the same as I<-oo qemu-boot>.
-
=item B<-q>
=item B<--quiet>
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 3b74f307..df69e2e0 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -284,7 +284,6 @@ let parse_cmdline () =
s_"Estimate size of source and stop";
[ L"print-source" ], Getopt.Set print_source,
s_"Print source and stop";
- [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
s_"How to choose root filesystem";
[ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"),
@@ -668,6 +667,8 @@ read the man page virt-v2v(1).
| Some d when not (is_directory d) ->
error (f_"-os %s: output directory does not exist or is not a directory") d
| Some d -> d in
+ if qemu_boot then
+ error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL");
Output_qemu.output_qemu os qemu_boot,
output_format, output_alloc
diff --git a/output/output_qemu.ml b/output/output_qemu.ml
index 07dae8c2..b6f24565 100644
--- a/output/output_qemu.ml
+++ b/output/output_qemu.ml
@@ -65,6 +65,9 @@ module QEMU = struct
let compressed = !compressed
and qemu_boot = !qemu_boot in
+ if qemu_boot then
+ error (f_"-o qemu: the -oo qemu-boot option cannot be used in RHEL");
+
(* -os must be set to a directory. *)
let output_storage =
match options.output_storage with
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 194e6233..6baa111f 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -277,8 +277,6 @@ let rec main () =
s_"Same as -ip filename";
[ L"print-source" ], Getopt.Set print_source,
s_"Print source and stop";
- [ L"qemu-boot" ], Getopt.Unit (fun () -> set_output_option_compat "qemu-boot" ""),
- s_"Boot in qemu (-o qemu only)";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
s_"How to choose root filesystem";
[ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"),

View File

@ -1,18 +1,18 @@
From ff5ae6613f5b344371cd8523a022af08fa6f191b 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 8: Fix list of supported sound cards to match RHEL qemu
Subject: [PATCH] RHEL: Fix list of supported sound cards to match RHEL qemu
(RHBZ#1176493).
---
v2v/utils.ml | 5 +++--
lib/utils.ml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/v2v/utils.ml b/v2v/utils.ml
index ccbb9d68..c2940582 100644
--- a/v2v/utils.ml
+++ b/v2v/utils.ml
@@ -55,13 +55,14 @@ let kvm_arch = function
diff --git a/lib/utils.ml b/lib/utils.ml
index bf010a0a..4c9b7415 100644
--- a/lib/utils.ml
+++ b/lib/utils.ml
@@ -60,13 +60,14 @@ let kvm_arch = function
(* Does qemu support the given sound card? *)
let qemu_supports_sound_card = function
| Types.AC97

View File

@ -0,0 +1,136 @@
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.
In tests we cannot use guestfish for arbitrary Windows edits.
In virt-v2v helpers we must set the program name to virt-v2v.
For RHEL 9.3 and above, see this comment:
https://bugzilla.redhat.com/show_bug.cgi?id=2187961#c1
---
convert/convert.ml | 1 +
test-data/phony-guests/make-windows-img.sh | 1 +
tests/test-v2v-block-driver.sh | 6 +++++-
tests/test-v2v-in-place.sh | 8 +++++++-
tests/test-v2v-virtio-win-iso.sh | 8 +++++++-
tests/test-v2v-windows-conversion.sh | 8 +++++++-
6 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/convert/convert.ml b/convert/convert.ml
index 64b36c97..604902d1 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -53,6 +53,7 @@ let rec convert dir options source =
message (f_"Opening the source");
let g = open_guestfs ~identifier:"v2v" () in
+ g#set_program "virt-v2v";
g#set_memsize (g#get_memsize () * 2);
(* 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 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
# Create a disk image.
guestfish <<EOF
+set-program virt-testing
sparse windows.img-t 512M
run
diff --git a/tests/test-v2v-block-driver.sh b/tests/test-v2v-block-driver.sh
index db59a2cf..a0e56bed 100755
--- a/tests/test-v2v-block-driver.sh
+++ b/tests/test-v2v-block-driver.sh
@@ -100,7 +100,11 @@ check_driver_presence ()
local virtio_dir="/Windows/Drivers/VirtIO"
- guestfish --ro -a "$img" -i >$response <<-EOM
+ guestfish >$response <<-EOM
+ add-ro $img
+ set-program virt-testing
+ run
+ mount-ro /dev/sda2 /
is-dir $virtio_dir
is-file $virtio_dir/$drv.cat
is-file $virtio_dir/$drv.inf
diff --git a/tests/test-v2v-in-place.sh b/tests/test-v2v-in-place.sh
index 4373f140..2b31b0bb 100755
--- a/tests/test-v2v-in-place.sh
+++ b/tests/test-v2v-in-place.sh
@@ -89,6 +89,12 @@ mktest ()
:> "$script"
:> "$expected"
+cat >> "$script" <<EOF
+ set-program virt-testing
+ run
+ mount /dev/sda2 /
+EOF
+
firstboot_dir="/Program Files/Guestfs/Firstboot"
mktest "is-dir \"$firstboot_dir\"" true
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
@@ -101,7 +107,7 @@ for drv in netkvm vioscsi viostor; do
done
done
-guestfish --ro -a "$img" -i < "$script" > "$response"
+guestfish --ro -a "$img" < "$script" > "$response"
diff -u "$expected" "$response"
# 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 68fb879b..2e133034 100755
--- a/tests/test-v2v-virtio-win-iso.sh
+++ b/tests/test-v2v-virtio-win-iso.sh
@@ -82,6 +82,12 @@ mktest ()
:> "$script"
:> "$expected"
+cat >> "$script" <<EOF
+ set-program virt-testing
+ run
+ mount /dev/sda2 /
+EOF
+
firstboot_dir="/Program Files/Guestfs/Firstboot"
mktest "is-dir \"$firstboot_dir\"" true
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
@@ -94,5 +100,5 @@ for drv in netkvm vioscsi viostor; do
done
done
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
diff -u "$expected" "$response"
diff --git a/tests/test-v2v-windows-conversion.sh b/tests/test-v2v-windows-conversion.sh
index a4cf191d..1ff41f6a 100755
--- a/tests/test-v2v-windows-conversion.sh
+++ b/tests/test-v2v-windows-conversion.sh
@@ -76,6 +76,12 @@ mktest ()
:> "$script"
:> "$expected"
+cat >> "$script" <<EOF
+ set-program virt-testing
+ run
+ mount /dev/sda2 /
+EOF
+
firstboot_dir="/Program Files/Guestfs/Firstboot"
mktest "is-dir \"$firstboot_dir\"" true
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
@@ -88,7 +94,7 @@ for drv in netkvm vioscsi viostor; do
done
done
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
diff -u "$expected" "$response"
# We also update the Registry several times, for firstboot, and (ONLY

View File

@ -0,0 +1,23 @@
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)
The SDL output mode is not supported in RHEL's qemu-kvm.
---
input/input_disk.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/input/input_disk.ml b/input/input_disk.ml
index cf1f811b..27fc80de 100644
--- a/input/input_disk.ml
+++ b/input/input_disk.ml
@@ -77,7 +77,7 @@ module Disk = struct
s_features = [ "acpi"; "apic"; "pae" ];
s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *)
s_display =
- Some { s_display_type = Window; s_keymap = None; s_password = None;
+ Some { s_display_type = VNC; s_keymap = None; s_password = None;
s_listen = LNoListen; s_port = None };
s_sound = None;
s_disks = s_disks;

View File

@ -1,18 +1,18 @@
From 959c084383b259ff54a247b4fdda3254e3f335db 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 8: v2v: do not mention SUSE Xen hosts (RHBZ#1430203)
Subject: [PATCH] RHEL: v2v: do not mention SUSE Xen hosts (RHBZ#1430203)
They are not supported in RHEL 8.
They are not supported in RHEL.
---
docs/virt-v2v-input-xen.pod | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/virt-v2v-input-xen.pod b/docs/virt-v2v-input-xen.pod
index 3b3cf0f0..32da2848 100644
index 4a0544f8..9c3981e1 100644
--- a/docs/virt-v2v-input-xen.pod
+++ b/docs/virt-v2v-input-xen.pod
@@ -12,7 +12,7 @@ virt-v2v-input-xen - Using virt-v2v to convert guests from Xen
@@ -11,7 +11,7 @@ virt-v2v-input-xen - Using virt-v2v to convert guests from Xen
=head1 DESCRIPTION
This page documents how to use L<virt-v2v(1)> to convert guests from

View File

@ -1,17 +1,17 @@
From 1de8532631a765c03196774e0b4a41966284bae3 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 8: point to KB for supported v2v hypervisors/guests
Subject: [PATCH] RHEL: point to KB for supported v2v hypervisors/guests
---
docs/virt-v2v-support.pod | 102 ++------------------------------------
1 file changed, 4 insertions(+), 98 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 8333366b..a5150907 100644
index e6415692..1ffc0f9d 100644
--- a/docs/virt-v2v-support.pod
+++ b/docs/virt-v2v-support.pod
@@ -8,104 +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,11 +84,11 @@ index 8333366b..a5150907 100644
-
-=over 4
-
-=item Red Hat Enterprise Linux 3, 4, 5, 6, 7
-=item Red Hat Enterprise Linux 4, 5, 6, 7, 8, 9, 10
-
-=item CentOS 3, 4, 5, 6, 7
-=item CentOS 4, 5, 6, 7, 8, 9, 10
-
-=item Scientific Linux 3, 4, 5, 6, 7
-=item Scientific Linux 4, 5, 6, 7
-
-=item Oracle Linux
-
@ -98,19 +98,13 @@ index 8333366b..a5150907 100644
-
-=item OpenSUSE 10 and up
-
-=item ALT Linux 9 and up
-
-=item Debian 6 and up
-
-=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

@ -0,0 +1,214 @@
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
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1977539
---
docs/virt-v2v-output-openstack.pod | 54 ++----------------------------
docs/virt-v2v.pod | 20 -----------
output/output_glance.mli | 2 +-
tests/test-v2v-o-glance.sh | 3 ++
v2v/v2v.ml | 7 +---
5 files changed, 7 insertions(+), 79 deletions(-)
diff --git a/docs/virt-v2v-output-openstack.pod b/docs/virt-v2v-output-openstack.pod
index cd4862b1..54cd276e 100644
--- a/docs/virt-v2v-output-openstack.pod
+++ b/docs/virt-v2v-output-openstack.pod
@@ -10,13 +10,10 @@ virt-v2v-output-openstack - Using virt-v2v to convert guests to OpenStack
[-oo verify-server-certificate=false]
[-oo os-username=admin] [-oo os-*=*]
- virt-v2v [-i* options] -o glance
-
=head1 DESCRIPTION
This page documents how to use L<virt-v2v(1)> to convert guests to run
-on OpenStack. There are two output modes you can select, but only
-I<-o openstack> should be used normally.
+on OpenStack.
=over 4
@@ -27,15 +24,6 @@ Full description: L</OUTPUT TO OPENSTACK>
This is the modern method for uploading to OpenStack via the REST API.
Guests can be directly converted into Cinder volumes.
-=item B<-o glance>
-
-Full description: L</OUTPUT TO GLANCE>
-
-This is the old method for uploading to Glance. Unfortunately Glance
-is not well suited to storing converted guests (since virt-v2v deals
-with "pets" not templated "cattle"), so this method is not recommended
-unless you really know what you are doing.
-
=back
=head1 OUTPUT TO OPENSTACK
@@ -176,48 +164,10 @@ no Cinder volume type is used.
The following options are B<not> supported with OpenStack: I<-oa>,
I<-of>.
-=head1 OUTPUT TO GLANCE
-
-Note this is a legacy option. In most cases you should use
-L</OUTPUT TO OPENSTACK> instead.
-
-To output to OpenStack Glance, use the I<-o glance> option.
-
-This runs the L<glance(1)> CLI program which must be installed on the
-virt-v2v conversion host. For authentication to work, you will need
-to set C<OS_*> environment variables. See
-L</OpenStack: Authentication> above.
-
-Virt-v2v adds metadata for the guest to Glance, describing such things
-as the guest operating system and what drivers it requires. The
-command C<glance image-show> will display the metadata as "Property"
-fields such as C<os_type> and C<hw_disk_bus>.
-
-=head2 Glance and sparseness
-
-Glance image upload doesn't appear to correctly handle sparseness.
-For this reason, using qcow2 will be faster and use less space on the
-Glance server. Use the virt-v2v S<I<-of qcow2>> option.
-
-=head2 Glance and multiple disks
-
-If the guest has a single disk, then the name of the disk in Glance
-will be the name of the guest. You can control this using the I<-on>
-option.
-
-Glance doesn't have a concept of associating multiple disks with a
-single guest, and Nova doesn't allow you to boot a guest from multiple
-Glance disks either. If the guest has multiple disks, then the first
-(assumed to be the system disk) will have the name of the guest, and
-the second and subsequent data disks will be called
-C<I<guestname>-disk2>, C<I<guestname>-disk3> etc. It may be best to
-leave the system disk in Glance, and import the data disks to Cinder.
-
=head1 SEE ALSO
L<virt-v2v(1)>,
-L<https://docs.openstack.org/python-openstackclient/latest/cli/man/openstack.html>,
-L<glance(1)>.
+L<https://docs.openstack.org/python-openstackclient/latest/cli/man/openstack.html>.
=head1 AUTHOR
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index a1e8fb30..b89a08a3 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -446,14 +446,6 @@ See L</Networks and bridges> below.
This is the same as I<-o local>.
-=item B<-o> B<glance>
-
-This is a legacy option. You should probably use I<-o openstack>
-instead.
-
-Set the output method to OpenStack Glance. In this mode the converted
-guest is uploaded to Glance. See L<virt-v2v-output-openstack(1)>.
-
=item B<-o> B<kubevirt>
Set the output method to I<kubevirt>. B<Note the way this mode works
@@ -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>).
-=item I<-o glance>
-
-This temporarily places a full copy of the output disks in
-C<$VIRT_V2V_TMPDIR> (or F</var/tmp>).
-
=item I<-o local>
=item I<-o qemu>
@@ -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.
-=item Writing to Glance
-
-This does I<not> need root (in fact it probably wont work), but may
-require either a special user and/or for you to source a script that
-sets authentication environment variables. Consult the Glance
-documentation.
-
=item Writing to block devices
This normally requires root. See the next section.
diff --git a/output/output_glance.mli b/output/output_glance.mli
index 972320a2..9befc461 100644
--- a/output/output_glance.mli
+++ b/output/output_glance.mli
@@ -18,4 +18,4 @@
(** [-o glance] output mode. *)
-module Glance : Output.OUTPUT
+(*module Glance : Output.OUTPUT*)
diff --git a/tests/test-v2v-o-glance.sh b/tests/test-v2v-o-glance.sh
index c0db9115..074b5e16 100755
--- a/tests/test-v2v-o-glance.sh
+++ b/tests/test-v2v-o-glance.sh
@@ -20,6 +20,9 @@
set -e
+# Feature is disabled in RHEL 9.
+exit 77
+
source ./functions.sh
set -e
set -x
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 6baa111f..427d35d4 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -197,7 +197,6 @@ let rec main () =
if !output_mode <> `Not_set then
error (f_"%s option used more than once on the command line") "-o";
match mode with
- | "glance" -> output_mode := `Glance
| "kubevirt" -> output_mode := `Kubevirt
| "libvirt" -> output_mode := `Libvirt
| "disk" | "local" -> output_mode := `Disk
@@ -257,7 +256,7 @@ let rec main () =
s_"Map network in to out";
[ L"no-trim" ], Getopt.String ("-", no_trim_warning),
s_"Ignored for backwards compatibility";
- [ S 'o' ], Getopt.String ("glance|kubevirt|libvirt|local|null|openstack|qemu|rhv|rhv-upload|vdsm", set_output_mode),
+ [ S 'o' ], Getopt.String ("kubevirt|libvirt|local|null|openstack|qemu|rhv|rhv-upload|vdsm", set_output_mode),
s_"Set output mode (default: libvirt)";
[ M"oa" ], Getopt.String ("sparse|preallocated", set_output_alloc),
s_"Set output allocation mode";
@@ -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
-virt-v2v -i disk disk.img -o glance
-
There is a companion front-end called \"virt-p2v\" which comes as an
ISO or CD image that can be booted on physical machines.
@@ -412,7 +409,6 @@ read the man page virt-v2v(1).
pr "input:libvirtxml\n";
pr "input:ova\n";
pr "input:vmx\n";
- pr "output:glance\n";
pr "output:kubevirt\n";
pr "output:libvirt\n";
pr "output:local\n";
@@ -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)
- | `Glance -> (module Output_glance.Glance)
| `Kubevirt -> (module Output_kubevirt.Kubevirt)
| `Openstack -> (module Output_openstack.Openstack)
| `RHV_Upload -> (module Output_rhv_upload.RHVUpload)

View File

@ -0,0 +1,84 @@
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
This disables the virt-v2v --in-place option which we do not
wish to support in RHEL.
---
docs/virt-v2v.pod | 8 --------
tests/Makefile.am | 1 -
v2v/v2v.ml | 8 --------
3 files changed, 17 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index b89a08a3..8f096d0c 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -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)>.
-For in-place conversion, there is a separate tool called
-L<virt-v2v-in-place(1)>.
-
=head2 Input and Output
You normally run virt-v2v with several I<-i*> options controlling the
@@ -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.
-Virt-v2v normally copies from the input to the output, called "copying
-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 Customization
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)>,
-L<virt-v2v-in-place(1)>,
L<virt-customize(1)>,
L<virt-df(1)>,
L<virt-filesystems(1)>,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1c3d6064..cee516c4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,6 @@ TESTS = \
test-v2v-floppy.sh \
test-v2v-i-disk.sh \
test-v2v-i-ova.sh \
- test-v2v-in-place.sh \
test-v2v-block-driver.sh \
test-v2v-inspector.sh \
test-v2v-mac.sh \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 427d35d4..3604e396 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -219,12 +219,6 @@ let rec main () =
warning (f_"the --vmtype option has been removed and now does nothing")
in
- (* Options that are errors. *)
- let in_place_error _ =
- error (f_"The --in-place option has been replaced by the \
- virt-v2v-in-place program")
- in
-
let argspec = [
[ L"bandwidth" ], Getopt.String ("bps", set_string_option_once "--bandwidth" bandwidth),
s_"Set bandwidth to bits per sec";
@@ -248,8 +242,6 @@ let rec main () =
s_"Use password from file to connect to input hypervisor";
[ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport),
s_"Input transport";
- [ L"in-place" ], Getopt.Unit in_place_error,
- s_"Use virt-v2v-in-place instead";
[ L"mac" ], Getopt.String ("mac:network|bridge|ip:out", add_mac),
s_"Map NIC to network or bridge or assign static IP";
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),

View File

@ -0,0 +1,47 @@
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
In RHEL 9 nbdcopy 1.12.4-2 will be sufficient (vs nbdcopy 1.13.5
upstream). We will enforce this through RPM dependencies and test it
separately. Thus remove the version check and test.
---
output/output.ml | 11 -----------
tests/Makefile.am | 1 -
2 files changed, 12 deletions(-)
diff --git a/output/output.ml b/output/output.ml
index 53d4bb1b..14288bdc 100644
--- a/output/output.ml
+++ b/output/output.ml
@@ -86,17 +86,6 @@ let output_to_local_file ?(changeuid = fun f -> f ()) ?(compressed = false)
if output_format <> "qcow2" then
error (f_"-oo compressed is only allowed when the output format \
is a local qcow2-format file, i.e. -of qcow2");
-
- (* Check nbdcopy is new enough. This assumes that the version of
- * libnbd is the same as the version of nbdcopy, but parsing this
- * is easier. We can remove this check when we build-depend on
- * libnbd >= 1.14.
- *)
- let version =
- NBD.create () |> NBD.get_version |>
- String.nsplit "." |> List.map int_of_string in
- if version < [1; 13; 5] then
- error (f_"-oo compressed option requires nbdcopy >= 1.13.5")
);
let g = open_guestfs () in
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cee516c4..e4c5cdb9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -86,7 +86,6 @@ TESTS = \
test-v2v-o-kubevirt-fedora.sh \
test-v2v-o-kubevirt-windows.sh \
test-v2v-o-libvirt.sh \
- test-v2v-o-local-qcow2-compressed.sh \
test-v2v-o-null.sh \
test-v2v-o-openstack.sh \
test-v2v-o-qemu.sh \

View File

@ -0,0 +1,22 @@
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
RHEL does not have btrfs so this test always fails.
---
tests/Makefile.am | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e4c5cdb9..fc846ee7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -100,7 +100,6 @@ TESTS = \
test-v2v-sound.sh \
test-v2v-virtio-win-iso.sh \
test-v2v-fedora-conversion.sh \
- test-v2v-fedora-btrfs-conversion.sh \
test-v2v-fedora-luks-on-lvm-conversion.sh \
test-v2v-fedora-lvm-on-luks-conversion.sh \
test-v2v-fedora-md-conversion.sh \

View File

@ -0,0 +1,157 @@
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
Go back to the old default of always installing virtio-blk drivers in
Windows guests.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2190387
---
docs/virt-v2v-in-place.pod | 10 ----------
docs/virt-v2v.pod | 10 ----------
in-place/in_place.ml | 11 +----------
tests/Makefile.am | 1 -
v2v/v2v.ml | 11 +----------
5 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod
index 4304c0d6..b7384210 100644
--- a/docs/virt-v2v-in-place.pod
+++ b/docs/virt-v2v-in-place.pod
@@ -51,16 +51,6 @@ Display help.
See I<--network> below.
-=item B<--block-driver> B<virtio-blk>
-
-=item B<--block-driver> B<virtio-scsi>
-
-When choosing a block driver for Windows guests, prefer C<virtio-blk> or
-C<virtio-scsi>. The default is C<virtio-blk>.
-
-Note this has no effect for Linux guests at the moment. That may be
-added in future.
-
=item B<--colors>
=item B<--colours>
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 8f096d0c..74581463 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -208,16 +208,6 @@ The options are silently ignored for other input methods.
See I<--network> below.
-=item B<--block-driver> B<virtio-blk>
-
-=item B<--block-driver> B<virtio-scsi>
-
-When choosing a block driver for Windows guests, prefer C<virtio-blk> or
-C<virtio-scsi>. The default is C<virtio-blk>.
-
-Note this has no effect for Linux guests at the moment. That may be
-added in future.
-
=item B<--colors>
=item B<--colours>
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 8286dbc5..2dc406e2 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -43,7 +43,6 @@ let rec main () =
let bandwidth = ref None in
let bandwidth_file = ref None in
- let block_driver = ref None in
let input_conn = ref None in
let input_format = ref None in
let input_password = ref None in
@@ -159,8 +158,6 @@ let rec main () =
let argspec = [
[ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge),
s_"Map bridge in to out";
- [ L"block-driver" ], Getopt.String ("driver", set_string_option_once "--block-driver" block_driver),
- s_"Prefer 'virtio-blk' or 'virtio-scsi'";
[ 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),
@@ -225,12 +222,6 @@ read the man page virt-v2v-in-place(1).
(* Dereference the arguments. *)
let args = List.rev !args in
- let block_driver =
- match !block_driver with
- | None | Some "virtio-blk" -> Virtio_blk
- | 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
@@ -316,7 +307,7 @@ read the man page virt-v2v-in-place(1).
(* Get the conversion options. *)
let conv_options = {
- Convert.block_driver = block_driver;
+ Convert.block_driver = Virtio_blk;
keep_serial_console = true;
ks = opthandle.ks;
network_map;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fc846ee7..8a710b99 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,6 @@ TESTS = \
test-v2v-floppy.sh \
test-v2v-i-disk.sh \
test-v2v-i-ova.sh \
- test-v2v-block-driver.sh \
test-v2v-inspector.sh \
test-v2v-mac.sh \
test-v2v-machine-readable.sh \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 3604e396..2fdaf40b 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -48,7 +48,6 @@ let rec main () =
let bandwidth = ref None in
let bandwidth_file = ref None in
- let block_driver = ref None in
let input_conn = ref None in
let input_format = ref None in
let input_password = ref None in
@@ -226,8 +225,6 @@ let rec main () =
s_"Set bandwidth dynamically from file";
[ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge),
s_"Map bridge in to out";
- [ L"block-driver" ], Getopt.String ("driver", set_string_option_once "--block-driver" block_driver),
- s_"Prefer 'virtio-blk' or 'virtio-scsi'";
[ 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),
@@ -352,12 +349,6 @@ read the man page virt-v2v(1).
(* Dereference the arguments. *)
let args = List.rev !args in
- let block_driver =
- match !block_driver with
- | None | Some "virtio-blk" -> Virtio_blk
- | 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
@@ -531,7 +522,7 @@ read the man page virt-v2v(1).
(* Get the conversion options. *)
let conv_options = {
- Convert.block_driver = block_driver;
+ Convert.block_driver = Virtio_blk;
keep_serial_console = not remove_serial_console;
ks = opthandle.ks;
network_map;

View File

@ -0,0 +1,24 @@
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
Fixes: https://issues.redhat.com/browse/RHEL-40903
---
in-place/in_place.ml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 2dc406e2..9d24de78 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -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;
+ warning "virt-v2v-in-place is NOT SUPPORTED for command line use. \
+ It is almost always better to use virt-v2v instead of this tool.";
+
(* Print the version, easier than asking users to tell us. *)
debug "info: %s: %s %s (%s)"
prog Config.package_name Config.package_version_full

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

@ -0,0 +1,31 @@
From b9259a577edf5532d936af491afd8789e5f7d874 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 11 Mar 2025 11:43:05 +0000
Subject: [PATCH] Update common submodule
Richard W.M. Jones (1):
mlcustomize: Remove dnf --verbose option
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2351282
(cherry picked from commit 97b73320fe8f65e48c514064e4cb1acffa8e1573)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 18310179..57c2b3f0:
diff --git a/common/mlcustomize/guest_packages.ml b/common/mlcustomize/guest_packages.ml
index 2602fc71..96614b6c 100644
--- a/common/mlcustomize/guest_packages.ml
+++ b/common/mlcustomize/guest_packages.ml
@@ -61,10 +61,7 @@ let install_command packages package_management =
apt-get $apt_opts update
apt-get $apt_opts install %s
" quoted_args
- | "dnf" ->
- sprintf "dnf%s -y install %s"
- (if verbose () then " --verbose" else "")
- quoted_args
+ | "dnf" -> sprintf "dnf -y install %s" quoted_args
| "pisi" -> sprintf "pisi it %s" quoted_args
| "pacman" -> sprintf "pacman -S --noconfirm %s" quoted_args
| "urpmi" -> sprintf "urpmi %s" quoted_args

View File

@ -0,0 +1,128 @@
From d42726148753250e741b030a1aff09310fb9938a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 2 Dec 2024 13:25:49 +0000
Subject: [PATCH] build: Remove --with-virt-v2v-nbdkit-python-plugin=...
In theory, ./configure --with-virt-v2v-nbdkit-python-plugin=<name>
allowed you to override the default nbdkit-python-plugin name (usually
"python"). However:
(a) nbdkit no longer provides a Python version 2 plugin and hasn't
since nbdkit 1.16 (2019),
(b) we no longer support older RHEL where there were parallel Python
2 & 3 plugins and this was an issue, and
(c) the result wasn't actually used in the code (it used to be, but I
think I replaced it with "python" and forgot about this ./configure
parameter).
(cherry picked from commit 9e25b211a48804b27228e17d8e123b5f1d44df8b)
---
config.sh.in | 1 -
configure.ac | 4 ----
lib/config.ml.in | 1 -
lib/config.mli | 9 ---------
m4/guestfs-v2v.m4 | 28 ----------------------------
tests/test-o-rhv-upload.sh | 2 +-
6 files changed, 1 insertion(+), 44 deletions(-)
delete mode 100644 m4/guestfs-v2v.m4
diff --git a/config.sh.in b/config.sh.in
index be304b39..8f590853 100644
--- a/config.sh.in
+++ b/config.sh.in
@@ -19,5 +19,4 @@
# This shell script contains the results of some configure checks,
# mostly used in other shell scripts.
-export VIRT_V2V_NBDKIT_PYTHON_PLUGIN="@VIRT_V2V_NBDKIT_PYTHON_PLUGIN@"
export PYCODESTYLE="@PYCODESTYLE@"
diff --git a/configure.ac b/configure.ac
index 623c634d..a99bcb75 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,10 +97,6 @@ dnl Perl, used for running mllibvirt generator, and man pages.
HEADING([Checking for Perl])
m4_include([m4/guestfs-perl.m4])
-dnl virt-v2v.
-HEADING([Checking the virt-v2v dependencies])
-m4_include([m4/guestfs-v2v.m4])
-
dnl Bash completion.
HEADING([Checking for bash completion])
m4_include([m4/guestfs-bash-completion.m4])
diff --git a/lib/config.ml.in b/lib/config.ml.in
index 74606d1b..be3bdfa2 100644
--- a/lib/config.ml.in
+++ b/lib/config.ml.in
@@ -23,4 +23,3 @@ let package_version_full = "@PACKAGE_VERSION_FULL@"
let prefix = "@prefix@"
let datadir = prefix ^ "/share"
let host_cpu = "@host_cpu@"
-let nbdkit_python_plugin = "@VIRT_V2V_NBDKIT_PYTHON_PLUGIN@"
diff --git a/lib/config.mli b/lib/config.mli
index fe71e57c..a02864fa 100644
--- a/lib/config.mli
+++ b/lib/config.mli
@@ -33,12 +33,3 @@ val datadir : string
val host_cpu : string
(** The configure value [@host_cpu@] *)
-
-val nbdkit_python_plugin : string
-(** Return the name of the nbdkit python plugin used by
- [virt-v2v -o rhv-upload].
-
- As above this must also be the Python 3 version of the plugin,
- unless you change it. The configure command to change this is:
-
- [./configure --with-virt-v2v-nbdkit-python-plugin=...] *)
diff --git a/m4/guestfs-v2v.m4 b/m4/guestfs-v2v.m4
deleted file mode 100644
index 787864d3..00000000
--- a/m4/guestfs-v2v.m4
+++ /dev/null
@@ -1,28 +0,0 @@
-# virt-v2v
-# Copyright (C) 2009-2020 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.
-
-dnl Virt-v2v.
-
-dnl nbdkit python plugin.
-AC_MSG_CHECKING([for the nbdkit python plugin name])
-AC_ARG_WITH([virt-v2v-nbdkit-python-plugin],
- [AS_HELP_STRING([--with-virt-v2v-nbdkit-python-plugin="python|..."],
- [set nbdkit python plugin name used by virt-v2v @<:@default=python@:>@])],
- [VIRT_V2V_NBDKIT_PYTHON_PLUGIN="$withval"],
- [VIRT_V2V_NBDKIT_PYTHON_PLUGIN=python])
-AC_MSG_RESULT([$VIRT_V2V_NBDKIT_PYTHON_PLUGIN])
-AC_SUBST([VIRT_V2V_NBDKIT_PYTHON_PLUGIN])
diff --git a/tests/test-o-rhv-upload.sh b/tests/test-o-rhv-upload.sh
index 51307f80..c65fff67 100755
--- a/tests/test-o-rhv-upload.sh
+++ b/tests/test-o-rhv-upload.sh
@@ -31,7 +31,7 @@ set -x
skip_if_skipped
requires python3 --version
-requires nbdkit $VIRT_V2V_NBDKIT_PYTHON_PLUGIN --version
+requires nbdkit python --version
requires test -f ../test-data/phony-guests/windows.img
libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml"

View File

@ -0,0 +1,86 @@
From 52bbbfed912b723f5a4618571fbab57cd9d459b7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 2 Dec 2024 13:43:39 +0000
Subject: [PATCH] build: Use nbdcopy and nbdinfo from ./configure
Use the configured binaries, so that (eg) ./configure NBDCOPY=...
will do the right thing.
(cherry picked from commit 5c866e7bb2c7a08a37bb71dea094141802e849e7)
---
input/ssh.ml | 4 ++--
lib/config.ml.in | 2 ++
lib/config.mli | 6 ++++++
v2v/v2v.ml | 8 +++++---
4 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/input/ssh.ml b/input/ssh.ml
index e35a2b5a..3b17cb38 100644
--- a/input/ssh.ml
+++ b/input/ssh.ml
@@ -47,7 +47,7 @@ let start_nbdkit ~server ?port ?user ?password path =
let download_file ~server ?port ?user ?password path output =
let uri = start_nbdkit ~server ?port ?user ?password path in
- let cmd = [ "nbdcopy"; uri; output ] in
+ let cmd = [ Config.nbdcopy; uri; output ] in
if run_command cmd <> 0 then
error (f_"could not copy the VMX file from the remote server, \
see earlier error messages")
@@ -59,5 +59,5 @@ let remote_file_exists ~server ?port ?user ?password path =
(* Testing that we can connect to the nbdkit server is enough to
* prove the remote file exists.
*)
- let cmd = [ "nbdinfo"; "--can"; "connect"; uri ] in
+ let cmd = [ Config.nbdinfo; "--can"; "connect"; uri ] in
run_command cmd = 0
diff --git a/lib/config.ml.in b/lib/config.ml.in
index be3bdfa2..4f1d1e08 100644
--- a/lib/config.ml.in
+++ b/lib/config.ml.in
@@ -23,3 +23,5 @@ let package_version_full = "@PACKAGE_VERSION_FULL@"
let prefix = "@prefix@"
let datadir = prefix ^ "/share"
let host_cpu = "@host_cpu@"
+let nbdcopy = "@NBDCOPY@"
+let nbdinfo = "@NBDINFO@"
diff --git a/lib/config.mli b/lib/config.mli
index a02864fa..9cd249f1 100644
--- a/lib/config.mli
+++ b/lib/config.mli
@@ -33,3 +33,9 @@ val datadir : string
val host_cpu : string
(** The configure value [@host_cpu@] *)
+
+val nbdcopy : string
+(** The location of the nbdcopy program, from configure value [@NBDCOPY@] *)
+
+val nbdinfo : string
+(** The location of the nbdinfo program, from configure value [@NBDINFO@] *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index e56462a5..60425768 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -688,7 +688,7 @@ and nbdcopy ?request_size output_alloc input_uri output_uri =
* --target-is-zero which would be a useful optimization.
*)
let cmd = ref [] in
- List.push_back_list cmd [ "nbdcopy"; input_uri; output_uri ];
+ List.push_back_list cmd [ Config.nbdcopy; input_uri; output_uri ];
(match request_size with
| None -> ()
@@ -722,8 +722,10 @@ and nbdcopy ?request_size output_alloc input_uri output_uri =
*)
and nbdinfo ?(content = false) uri =
let cmd =
- sprintf "nbdinfo%s %s ||:"
- (if content then " --content" else " --no-content") (quote uri) in
+ sprintf "%s%s %s ||:"
+ (quote Config.nbdinfo)
+ (if content then " --content" else " --no-content")
+ (quote uri) in
external_command cmd
(* Convert a Unix domain socket path to an NBD URI. *)

View File

@ -0,0 +1,78 @@
From 7d36586c5a299ecf17ef241063988bc1b9ace2bb Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 31 Mar 2025 11:06:09 +0100
Subject: [PATCH] v2v: Use nbdcopy --blkhash in verbose mode
In verbose mode, and if nbdcopy supports it, add the nbdcopy --blkhash
option. This will compute and print a hash of the disk as we are
copying it (more precisely, a hash of the source disk after conversion
changes have been made). This will allow users to detect any
corruption during or after writing the output.
This feature requires nbdcopy >= 1.23.1
It adds some overhead to the copy, but (a) we're almost always copying
over the network which is slow anyway and (b) this is only done in
verbose mode where there's a lot of overhead from the output anyway.
However keep an eye on this overhead.
Note what is printed is a blkhash, not a regular checksum. See:
https://gitlab.com/nirs/blkhash/
Fixes: https://issues.redhat.com/browse/RHEL-85508
Fixes: https://issues.redhat.com/browse/RHEL-85512
Fixes: https://issues.redhat.com/browse/RHEL-85514
(cherry picked from commit cffd129d8fd47554255d52ad611d58a30b6b9951)
---
lib/utils.ml | 8 ++++++++
lib/utils.mli | 3 +++
v2v/v2v.ml | 3 +++
3 files changed, 14 insertions(+)
diff --git a/lib/utils.ml b/lib/utils.ml
index f2da9e80..ecdaeb80 100644
--- a/lib/utils.ml
+++ b/lib/utils.ml
@@ -181,6 +181,14 @@ let error_if_no_ssh_agent () =
is not set). This is required by qemu to do passwordless \
ssh access. See the virt-v2v(1) man page for more information.")
+let nbdcopy_supports_blkhash =
+ let check =
+ lazy (
+ let cmd = sprintf "%s --help | grep -sq -- --blkhash" Config.nbdcopy in
+ 0 = Sys.command cmd
+ ) in
+ fun () -> Lazy.force check
+
(* Create the directory containing inX and outX sockets. *)
let create_v2v_directory () =
let d = Mkdtemp.temp_dir "v2v." in
diff --git a/lib/utils.mli b/lib/utils.mli
index e7ee13d1..6b405353 100644
--- a/lib/utils.mli
+++ b/lib/utils.mli
@@ -68,6 +68,9 @@ val chown_for_libvirt_rhbz_1045069 : string -> unit
val error_if_no_ssh_agent : unit -> unit
+val nbdcopy_supports_blkhash : unit -> bool
+(** Return true if [nbdcopy] supports the [--blkhash] flag. *)
+
val create_v2v_directory : unit -> string
(** Create the directory containing inX and outX sockets. *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 60425768..3436ce14 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -704,6 +704,9 @@ and nbdcopy ?request_size output_alloc input_uri output_uri =
min 64 (target_buffer_size / request_size) in
List.push_back cmd (sprintf "--requests=%d" requests);
+ if verbose () && nbdcopy_supports_blkhash () then
+ List.push_back cmd "--blkhash";
+
List.push_back cmd "--flush";
(*List.push_back cmd "--verbose";*)

View File

@ -0,0 +1,35 @@
From 193ed2a762bf3182d760370739c7add83e89f21c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 4 Apr 2025 14:47:09 +0100
Subject: [PATCH] v2v: Print nbdcopy command in debug output
Commit fd1148f795 ("v2v: Implement --parallel=N for parallel disk
copies") changed how we run nbdcopy from using Tools_utils.run_command
to calling Unix.execvp directly. However a side effect of this is
that we no longer printed the nbdcopy command that we were about to
run in verbose mode. Fix this by printing it in debug output.
Reported-by: Ming Xie
Fixes: https://issues.redhat.com/browse/RHEL-86022
Fixes: commit fd1148f79581b148525eb12154aef7603ccf0baa
(cherry picked from commit 802172c1a868e9287416d26e77a94d01c2d7b871)
---
v2v/v2v.ml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 3436ce14..10d24364 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -713,7 +713,10 @@ 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 args = Array.of_list !cmd in
+ let args = !cmd in
+ debug "%s" (stringify_args args);
+
+ let args = Array.of_list args in
match fork () with
| 0 ->
(* Child process (nbdcopy). *)

View File

@ -0,0 +1,57 @@
From cd55bd8d160cdcdfe21aaafc15f7a1cefee98b85 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 25 Apr 2025 11:44:15 +0100
Subject: [PATCH] lib/libvirt_utils.ml: Turn live domain error into a warning
As explained in the comment, we cannot easily tell if conversion is
being attempted from a snapshot (which is safe, even if the domain is
running). Therefore turn the error into a strong warning.
Reported-by: Martin Necas
Fixes: https://issues.redhat.com/browse/RHEL-88543
(cherry picked from commit 8c27cb1e525b5e1d380ab27a141de6f026f4b2db)
---
lib/libvirt_utils.ml | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/lib/libvirt_utils.ml b/lib/libvirt_utils.ml
index 4200c7c8..41ee38d2 100644
--- a/lib/libvirt_utils.ml
+++ b/lib/libvirt_utils.ml
@@ -59,20 +59,27 @@ let get_domain conn name =
error (f_"cannot find libvirt domain %s: %s")
name (Option.value ~default:"" message)
) in
- let uri = Libvirt.Connect.get_uri conn in
- (* As a side-effect we check that the domain is shut down. Of course
- * this is only appropriate for virt-v2v. (RHBZ#1138586)
+
+ (* As a side-effect we check that the domain is shut down (RHBZ#1138586).
+ * In earlier versions of virt-v2v this was a hard error. Now it's
+ * a warning, since we can't easily tell if the user is converting
+ * from a snapshot - which is safe (RHEL-88543).
*)
+ let uri = Libvirt.Connect.get_uri conn in
if not (String.is_prefix uri "test:") then (
(match (Libvirt.Domain.get_info dom).Libvirt.Domain.state with
- | InfoRunning | InfoBlocked | InfoPaused ->
- error (f_"libvirt domain %s is running or paused. It must be \
- shut down in order to perform virt-v2v conversion")
- (Libvirt.Domain.get_name dom)
- | InfoNoState | InfoShutdown | InfoShutoff | InfoCrashed | InfoPMSuspended ->
- ()
+ | InfoRunning | InfoBlocked | InfoPaused ->
+ warning (f_"libvirt domain %s is running or paused. Converting \
+ a live guest will result in corrupted output. \
+ However this is safe if you're converting from a \
+ snapshot")
+ (Libvirt.Domain.get_name dom)
+ | InfoNoState | InfoShutdown | InfoShutoff | InfoCrashed
+ | InfoPMSuspended ->
+ ()
)
);
+
dom
let get_pool conn name =

View File

@ -0,0 +1,24 @@
From 43dc900cee261bf5b090d63745b2ddcee6590583 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 28 Apr 2025 14:53:21 +0100
Subject: [PATCH] convert: flush output after printing debug information
Make sure this information gets into the log early.
(cherry picked from commit b0494befae461f1f34f5d40a4fb901befbc8e380)
---
convert/convert.ml | 1 +
1 file changed, 1 insertion(+)
diff --git a/convert/convert.ml b/convert/convert.ml
index 604902d1..7a27467b 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -301,6 +301,7 @@ and debug_info source inspect
target_nics;
eprintf "mountpoint stats:\n";
List.iter debug_mpstat mpstats;
+ flush Stdlib.stderr
and debug_mpstat { mp_dev = dev; mp_path = path;
mp_statvfs = s; mp_vfs = vfs } =

View File

@ -0,0 +1,69 @@
From d382827a7342a9ee9835d95ed86f864c960d8c71 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 28 Apr 2025 14:53:52 +0100
Subject: [PATCH] convert: Print more readable mountpoint stats
Print mountpoint stats which are more similar to what 'virt-df -h'
prints. This makes them easier to follow.
Before this change:
mountpoint stats:
mountpoint statvfs /dev/sda1 /boot/efi (vfat):
bsize=4096 blocks=65467 bfree=63058 bavail=63058
mountpoint statvfs /dev/sda2 /boot (xfs):
bsize=4096 blocks=130219 bfree=90268 bavail=90268
mountpoint statvfs /dev/vg00/lv_root / (xfs):
bsize=4096 blocks=24956001 bfree=22727257 bavail=22727257
After this change:
mountpoint stats:
Size Used Available Use%
/dev/sda1 /boot (ext4):
510873600 81379328 391917568
487.2M 77.6M 373.8M 15.9%
/dev/sda3 / (xfs): 4820303872 898846720 3921457152
4.5G 857.2M 3.7G 18.6%
(cherry picked from commit 9b786f36ddbb76b1c7857a94c53a8b8479c57ac4)
---
convert/convert.ml | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/convert/convert.ml b/convert/convert.ml
index 7a27467b..d4d28f68 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -300,11 +300,27 @@ and debug_info source inspect
List.iter (fun nic -> eprintf "%s\n" (string_of_source_nic nic))
target_nics;
eprintf "mountpoint stats:\n";
+ eprintf "%20s %-16s %-16s %-16s %s\n" "" "Size" "Used" "Available" "Use%";
List.iter debug_mpstat mpstats;
flush Stdlib.stderr
+(* The calculations here are similar to virt-df df/output.c *)
and debug_mpstat { mp_dev = dev; mp_path = path;
- mp_statvfs = s; mp_vfs = vfs } =
- eprintf " mountpoint statvfs %s %s (%s):\n" dev path vfs;
- eprintf " bsize=%Ld blocks=%Ld bfree=%Ld bavail=%Ld\n"
- s.Guestfs.bsize s.Guestfs.blocks s.Guestfs.bfree s.Guestfs.bavail
+ mp_statvfs = { G.bsize; G.blocks; G.bfree; G.bavail };
+ mp_vfs = vfs } =
+ let label = sprintf "%s %s (%s):" dev path vfs
+ and size = blocks *^ bsize
+ and used = (blocks -^ bfree) *^ bsize
+ and avail = bavail *^ bsize
+ and percent =
+ if blocks <> 0_L then
+ 100. -. 100. *. (Int64.to_float bfree /. Int64.to_float blocks)
+ else
+ 0. in
+ if String.length label > 20 then
+ eprintf "%s\n%20s " label ""
+ else
+ eprintf "%-20s " label;
+ eprintf "%-16Ld %-16Ld %-16Ld\n" size used avail;
+ eprintf "%20s %-16s %-16s %-16s %.1f%%\n"
+ "" (human_size size) (human_size used) (human_size avail) percent

View File

@ -0,0 +1,97 @@
From 212beda84cd9366b65f73d71664f1a2aaeafc9f8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 10:29:08 +0100
Subject: [PATCH] input: Remove usage of nbdkit-cacheextents-filter
The caching in this filter
(https://libguestfs.org/nbdkit-cacheextents-filter.1.html) is very
simple. It is basically designed so that if a client asks for one
extent at a time (using the NBD flag NBD_CMD_FLAG_REQ_ONE) then we ask
for all the extents that the underlying plugin will give us, and cache
those. However only a single contiguous set of extents is cached, and
any non-contiguous read will blow away the cache.
This was designed entirely to work around the buggy behaviour of
'qemu-img convert', which makes lots of req_one requests like this.
nbdcopy works completely differently, and doesn't have this problem.
nbdcopy also reads non-contiguous stretches of the input from multiple
threads. The filter in this case isn't effective (it doesn't do
anything bad since nbdcopy doesn't use the req_one flag).
In addition, the infamously slow QueryAllocatedBlocks API is only
called from the copy stage, and never (or maybe almost never) from the
conversion stage, so nothing that qemu does could justify caching
extents.
As this filter is essentially useless with current virt-v2v / nbdcopy,
remove its use completely.
(cherry picked from commit 48c4ce8e6cf6f1c390a48245ef0f99233f80cfe8)
---
README | 1 -
input/nbdkit_curl.ml | 5 -----
input/nbdkit_ssh.ml | 5 -----
input/nbdkit_vddk.ml | 5 -----
4 files changed, 16 deletions(-)
diff --git a/README b/README
index 4354754f..e4785166 100644
--- a/README
+++ b/README
@@ -69,7 +69,6 @@ REQUIREMENTS
+ nbdkit-ssh-plugin
+ nbdkit-vddk-plugin
- + nbdkit-cacheextents-filter
+ nbdkit-cow-filter
+ nbdkit-multi-conn-filter
+ nbdkit-rate-filter
diff --git a/input/nbdkit_curl.ml b/input/nbdkit_curl.ml
index 7e13c205..695f6d7c 100644
--- a/input/nbdkit_curl.ml
+++ b/input/nbdkit_curl.ml
@@ -71,11 +71,6 @@ let create_curl ?bandwidth ?cookie_script ?cookie_script_renew ?cor
*)
Nbdkit.add_filter_if_available cmd "retry";
- (* Caching extents speeds up qemu-img, especially its consecutive
- * block_status requests with req_one=1.
- *)
- Nbdkit.add_filter_if_available cmd "cacheextents";
-
(* IMPORTANT! Add the COW filter. It must be furthest away
* except for the rate filter.
*)
diff --git a/input/nbdkit_ssh.ml b/input/nbdkit_ssh.ml
index 1a2d2b56..4aba74f3 100644
--- a/input/nbdkit_ssh.ml
+++ b/input/nbdkit_ssh.ml
@@ -69,11 +69,6 @@ let create_ssh ?bandwidth ?cor ?(retry=true)
if retry then
Nbdkit.add_filter_if_available cmd "retry";
- (* Caching extents speeds up qemu-img, especially its consecutive
- * block_status requests with req_one=1.
- *)
- Nbdkit.add_filter_if_available cmd "cacheextents";
-
(* IMPORTANT! Add the COW filter. It must be furthest away
* except for the rate filter.
*)
diff --git a/input/nbdkit_vddk.ml b/input/nbdkit_vddk.ml
index 0cb45e89..b79c28cc 100644
--- a/input/nbdkit_vddk.ml
+++ b/input/nbdkit_vddk.ml
@@ -140,11 +140,6 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
*)
Nbdkit.add_filter_if_available cmd "retry";
- (* Caching extents speeds up qemu-img, especially its consecutive
- * block_status requests with req_one=1.
- *)
- Nbdkit.add_filter_if_available cmd "cacheextents";
-
(* Split very large requests to avoid out of memory errors on the
* server. Since we're using this filter, also add minblock=512
* although it will make no difference.

View File

@ -0,0 +1,55 @@
From 65a9c8ed09f4cd04ae2176b48c4c9c1f69b08399 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 10:42:46 +0100
Subject: [PATCH] input: Document my findings with nbdkit-noextents-filter
This just adds a comment, so makes no change.
(cherry picked from commit 29fae7985eda1d1cf3e176f123a16b60cac2db53)
---
input/nbdkit_vddk.ml | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/input/nbdkit_vddk.ml b/input/nbdkit_vddk.ml
index b79c28cc..3ba00d55 100644
--- a/input/nbdkit_vddk.ml
+++ b/input/nbdkit_vddk.ml
@@ -140,6 +140,38 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
*)
Nbdkit.add_filter_if_available cmd "retry";
+ (* VDDK's QueryAllocatedBlocks API is infamously slow. It appears
+ * to block all other requests while it is running. This API is
+ * also only called during the copy phase, not during conversion
+ * (or if it is, extremely rarely).
+ *
+ * If fstrim was successful, then trimmed blocks are stored in
+ * the COW filter (see below), and so requests for extents stop
+ * at that layer. However for areas of the disk that fstrim
+ * thinks contain data, we still have to go through to VDDK to
+ * fetch extents.
+ *
+ * We could therefore add nbdkit-noextents-filter here (below COW,
+ * above VDDK plugin) which stops extents requests from going
+ * to VDDK, which would stop QueryAllocatedBlocks ever being
+ * called. In my testing this is a moderate performance win.
+ *
+ * However ... in the case where fstrim failed, or for filesystems
+ * or partitions on the disk that we don't understand, doing this
+ * would mean that those are copied completely, as there would be
+ * no extent data (nbdcopy will still sparsify them on the target,
+ * but we'd have to copy all the bits from VMware). Because
+ * here we don't know if this is the case, be conservative and
+ * actually don't use this filter.
+ *
+ * If used, this filter should be close to the plugin and MUST
+ * be below the COW filter.
+ *
+ * XXX Add some kind of debugging flag so we can test how this
+ * works in production.
+ *)
+ (*Nbdkit.add_filter_if_available cmd "noextents";*)
+
(* Split very large requests to avoid out of memory errors on the
* server. Since we're using this filter, also add minblock=512
* although it will make no difference.

View File

@ -0,0 +1,95 @@
From 7ba9e7322e5828686fee9e71d7ffa17fe406c28a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 12:47:00 +0100
Subject: [PATCH] input: Add undocumented -io vddk-noextents=true option
This turns on the noextents filter, so that the slow VDDK API
QueryAllocatedBlocks will never be called. This is just so we can
test in production if this is effective or not.
(cherry picked from commit 191b8cf418076ae3766b134ffa96eee048c7eb9d)
---
input/input_vddk.ml | 8 +++++++-
input/nbdkit_vddk.ml | 8 +++-----
input/nbdkit_vddk.mli | 1 +
3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/input/input_vddk.ml b/input/input_vddk.ml
index 6444ce18..2edd7294 100644
--- a/input/input_vddk.ml
+++ b/input/input_vddk.ml
@@ -52,6 +52,7 @@ All other settings are optional:
-io vddk-cookie=COOKIE VDDK cookie
-io vddk-libdir=LIBDIR VDDK library parent directory
-io vddk-nfchostport=PORT VDDK nfchostport
+ -io vddk-noextents=true Avoid slow VDDK QueryAllocatedBlocks API
-io vddk-port=PORT VDDK port
-io vddk-snapshot=SNAPSHOT-MOREF
VDDK snapshot moref
@@ -71,6 +72,7 @@ information on these settings.
"cookie";
"libdir";
"nfchostport";
+ "noextents";
"port";
"snapshot";
"thumbprint";
@@ -173,6 +175,9 @@ information on these settings.
try Some (List.assoc "libdir" io_options) with Not_found -> None in
let nfchostport =
try Some (List.assoc "nfchostport" io_options) with Not_found -> None in
+ let noextents =
+ try bool_of_string (List.assoc "noextents" io_options)
+ with Not_found -> false in
let port =
try Some (List.assoc "port" io_options) with Not_found -> None in
let snapshot =
@@ -204,7 +209,8 @@ information on these settings.
Nbdkit_vddk.create_vddk ?bandwidth:options.bandwidth
?config ?cookie ~cor
?libdir ~moref
- ?nfchostport ?password_file:options.input_password ?port
+ ?nfchostport ~noextents
+ ?password_file:options.input_password ?port
~server ?snapshot ~thumbprint ?transports ?user
path in
let _, pid = Nbdkit.run_unix socket nbdkit in
diff --git a/input/nbdkit_vddk.ml b/input/nbdkit_vddk.ml
index 3ba00d55..5c23efd1 100644
--- a/input/nbdkit_vddk.ml
+++ b/input/nbdkit_vddk.ml
@@ -51,7 +51,7 @@ let libNN = sprintf "lib%d" Sys.word_size
(* Create an nbdkit module specialized for reading from VDDK sources. *)
let create_vddk ?bandwidth ?config ?cookie ?cor ?libdir ~moref
- ?nfchostport ?password_file ?port
+ ?nfchostport ~noextents ?password_file ?port
~server ?snapshot ~thumbprint ?transports ?user path =
if not (Nbdkit.is_installed ()) then
error (f_"nbdkit is not installed or not working");
@@ -166,11 +166,9 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
*
* If used, this filter should be close to the plugin and MUST
* be below the COW filter.
- *
- * XXX Add some kind of debugging flag so we can test how this
- * works in production.
*)
- (*Nbdkit.add_filter_if_available cmd "noextents";*)
+ if noextents then
+ Nbdkit.add_filter_if_available cmd "noextents";
(* Split very large requests to avoid out of memory errors on the
* server. Since we're using this filter, also add minblock=512
diff --git a/input/nbdkit_vddk.mli b/input/nbdkit_vddk.mli
index 2345e6e2..ef2082db 100644
--- a/input/nbdkit_vddk.mli
+++ b/input/nbdkit_vddk.mli
@@ -25,6 +25,7 @@ val create_vddk : ?bandwidth:Types.bandwidth ->
?libdir:string ->
moref:string ->
?nfchostport:string ->
+ noextents:bool ->
?password_file:string ->
?port:string ->
server:string ->

View File

@ -0,0 +1,136 @@
From 510f8a451723303d2af527e66c73ff18a03330e8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 12:48:51 +0100
Subject: [PATCH] v2v: Remove --vddk-*, --vdsm-*, --compressed, --qemu-boot
compat options
These were deprecated in commit 0802485f2e ("v2v: Add general
mechanism for input and output options (-io/-oo).", March 2018), and
most of them haven't appeared in any documentation for a long time.
It's time to remove them now.
(cherry picked from commit 471607b01543debfb2f44d9a8aa0dc7a592f5c06)
---
docs/test-docs.sh | 14 --------------
docs/virt-v2v.pod | 4 ----
v2v/v2v.ml | 40 ++--------------------------------------
3 files changed, 2 insertions(+), 56 deletions(-)
diff --git a/docs/test-docs.sh b/docs/test-docs.sh
index 4537e774..59df4344 100755
--- a/docs/test-docs.sh
+++ b/docs/test-docs.sh
@@ -87,20 +87,6 @@ $srcdir/../podcheck.pl virt-v2v.pod virt-v2v \
--oo,\
--op,\
--os,\
---vddk-config,\
---vddk-cookie,\
---vddk-libdir,\
---vddk-nfchostport,\
---vddk-port,\
---vddk-snapshot,\
---vddk-thumbprint,\
---vddk-transports,\
---vdsm-compat,\
---vdsm-image-uuid,\
---vdsm-ovf-flavour,\
---vdsm-ovf-output,\
---vdsm-vm-uuid,\
---vdsm-vol-uuid,\
--vmtype,\
$virt_customize_options
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 216e617d..57714022 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -217,10 +217,6 @@ when the output is a tty. If the output of the program is redirected
to a file, ANSI colour sequences are disabled unless you use this
option.
-=item B<--compressed>
-
-This is the same as I<-oo compressed>.
-
=item B<--echo-keys>
When prompting for keys and passphrases, virt-v2v normally turns
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 10d24364..5f36be1c 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -55,27 +55,21 @@ let rec main () =
let input_options = ref [] in
let io_query = ref false in
- let set_input_option_compat k v =
- List.push_back input_options (k, v)
- in
let set_input_option option =
if option = "?" then io_query := true
else (
let k, v = String.split "=" option in
- set_input_option_compat k v
+ List.push_back input_options (k, v)
)
in
let output_options = ref [] in
let oo_query = ref false in
- let set_output_option_compat k v =
- List.push_back output_options (k, v)
- in
let set_output_option option =
if option = "?" then oo_query := true
else (
let k, v = String.split "=" option in
- set_output_option_compat k v
+ List.push_back output_options (k, v)
)
in
@@ -226,8 +220,6 @@ let rec main () =
s_"Set bandwidth dynamically from file";
[ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge),
s_"Map bridge in to out";
- [ 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),
s_"Set input mode (default: libvirt)";
[ M"ic" ], Getopt.String ("uri", set_string_option_once "-ic" input_conn),
@@ -270,34 +262,6 @@ let rec main () =
s_"Print source and stop";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
s_"How to choose root filesystem";
- [ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"),
- s_"Same as -io vddk-config=filename";
- [ L"vddk-cookie" ], Getopt.String ("cookie", set_input_option_compat "vddk-cookie"),
- s_"Same as -io vddk-cookie=filename";
- [ L"vddk-libdir" ], Getopt.String ("libdir", set_input_option_compat "vddk-libdir"),
- s_"Same as -io vddk-libdir=libdir";
- [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_input_option_compat "vddk-nfchostport"),
- s_"Same as -io vddk-nfchostport=nfchostport";
- [ L"vddk-port" ], Getopt.String ("port", set_input_option_compat "vddk-port"),
- s_"Same as -io vddk-port=port";
- [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_input_option_compat "vddk-snapshot"),
- s_"Same as -io vddk-snapshot=snapshot-moref";
- [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_input_option_compat "vddk-thumbprint"),
- s_"Same as -io vddk-thumbprint=thumbprint";
- [ L"vddk-transports" ], Getopt.String ("transports", set_input_option_compat "vddk-transports"),
- s_"Same as -io vddk-transports=transports";
- [ L"vdsm-compat" ], Getopt.String ("0.10|1.1", set_output_option_compat "vdsm-compat"),
- s_"Same as -oo vdsm-compat=0.10|1.1";
- [ L"vdsm-image-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-image-uuid"),
- s_"Same as -oo vdsm-image-uuid=uuid";
- [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vol-uuid"),
- s_"Same as -oo vdsm-vol-uuid=uuid";
- [ L"vdsm-vm-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vm-uuid"),
- s_"Same as -oo vdsm-vm-uuid=uuid";
- [ L"vdsm-ovf-output" ], Getopt.String ("dir", set_output_option_compat "vdsm-ovf-output"),
- s_"Same as -oo vdsm-ovf-output=dir";
- [ L"vdsm-ovf-flavour" ], Getopt.String ("ovirt|rhvexp", set_output_option_compat "vdsm-ovf-flavour"),
- s_"Same as -oo vdsm-ovf-flavour=flavour";
[ L"vmtype" ], Getopt.String ("-", vmtype_warning),
s_"Ignored for backwards compatibility";
] in

View File

@ -0,0 +1,87 @@
From 0fab89ac2c144dc521b9b2cd803801cdbb94fb5c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 12:57:29 +0100
Subject: [PATCH] v2v: Remove --no-trim and --vmtype options
These were removed and changed so the otions do nothing a long time ago:
Related: commit 740c5b10cb ("v2v: Remove --no-trim option.", Apr 2016)
Related: commit 6086c0ffcf ("v2v: Remove the --vmtype option.", Apr 2016)
(cherry picked from commit 3fe878c36f23889426ef9b032a7516a94c1f9af4)
---
bash/virt-v2v | 3 ---
docs/test-docs.sh | 2 --
v2v/v2v.ml | 12 ------------
3 files changed, 17 deletions(-)
diff --git a/bash/virt-v2v b/bash/virt-v2v
index cddd0739..1234134c 100644
--- a/bash/virt-v2v
+++ b/bash/virt-v2v
@@ -34,9 +34,6 @@ _virt_v2v ()
-oa)
COMPREPLY=( $( compgen -W "sparse preallocated" -- "$cur") )
return ;;
- --vmtype)
- COMPREPLY=( $( compgen -W "server desktop" -- "$cur") )
- return ;;
esac
case "$cur" in
diff --git a/docs/test-docs.sh b/docs/test-docs.sh
index 59df4344..1037bf7e 100755
--- a/docs/test-docs.sh
+++ b/docs/test-docs.sh
@@ -78,7 +78,6 @@ $srcdir/../podcheck.pl virt-v2v.pod virt-v2v \
--ip,\
--it,\
--in-place,\
---no-trim,\
--password-file,\
--oa,\
--oc,\
@@ -87,7 +86,6 @@ $srcdir/../podcheck.pl virt-v2v.pod virt-v2v \
--oo,\
--op,\
--os,\
---vmtype,\
$virt_customize_options
$srcdir/../podcheck.pl virt-v2v-in-place.pod virt-v2v-in-place \
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 5f36be1c..30f317ee 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -205,14 +205,6 @@ let rec main () =
error (f_"unknown -o option: %s") s
in
- (* Options that are ignored for backwards compatibility. *)
- let no_trim_warning _ =
- warning (f_"the --no-trim option has been removed and now does nothing")
- in
- let vmtype_warning _ =
- warning (f_"the --vmtype option has been removed and now does nothing")
- in
-
let argspec = [
[ L"bandwidth" ], Getopt.String ("bps", set_string_option_once "--bandwidth" bandwidth),
s_"Set bandwidth to bits per sec";
@@ -236,8 +228,6 @@ 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"no-trim" ], Getopt.String ("-", no_trim_warning),
- s_"Ignored for backwards compatibility";
[ S 'o' ], Getopt.String ("kubevirt|libvirt|local|null|openstack|qemu|rhv|rhv-upload|vdsm", set_output_mode),
s_"Set output mode (default: libvirt)";
[ M"oa" ], Getopt.String ("sparse|preallocated", set_output_alloc),
@@ -262,8 +252,6 @@ let rec main () =
s_"Print source and stop";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
s_"How to choose root filesystem";
- [ L"vmtype" ], Getopt.String ("-", vmtype_warning),
- s_"Ignored for backwards compatibility";
] in
(* Append virt-customize options. *)

View File

@ -0,0 +1,49 @@
From ce1525716b247b0c8eec8a9f0adb2c4009dcdf23 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 13:53:01 +0100
Subject: [PATCH] v2v: Remove --password-file option
This was changed to '-ip' in commit eb508ba22d ("v2v: Use -ip to pass
input password (instead of --password-file).", June 2018). It also
now can be confused with the similar --password and --password-crypto
options, used by the virt-customize code.
(cherry picked from commit 21d914d6b2443d2f41ef62c7f185e188de4a1aab)
---
docs/test-docs.sh | 2 --
v2v/v2v.ml | 2 --
2 files changed, 4 deletions(-)
diff --git a/docs/test-docs.sh b/docs/test-docs.sh
index 1037bf7e..9a4c58ab 100755
--- a/docs/test-docs.sh
+++ b/docs/test-docs.sh
@@ -78,7 +78,6 @@ $srcdir/../podcheck.pl virt-v2v.pod virt-v2v \
--ip,\
--it,\
--in-place,\
---password-file,\
--oa,\
--oc,\
--of,\
@@ -96,7 +95,6 @@ $srcdir/../podcheck.pl virt-v2v-in-place.pod virt-v2v-in-place \
--io,\
--ip,\
--it,\
---password-file,\
--oa,\
--oc,\
--of,\
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 30f317ee..7f1d4352 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -244,8 +244,6 @@ let rec main () =
s_"Use password from file to connect to output hypervisor";
[ M"os" ], Getopt.String ("storage", set_string_option_once "-os" output_storage),
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,

View File

@ -0,0 +1,59 @@
From 63c3d929e947a3c7a37dafd6ba188f38ef8a2bd0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 13:16:41 +0100
Subject: [PATCH] input/nbdkit_vddk.ml: Rename 'path' parameter to 'file'
The nbdkit parameter is called 'file'. There is no actual change here.
(cherry picked from commit 5acc67d454add0b75f6671c06979a0cc90562f7e)
---
input/input_vddk.ml | 4 ++--
input/nbdkit_vddk.ml | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/input/input_vddk.ml b/input/input_vddk.ml
index 2edd7294..659ff08f 100644
--- a/input/input_vddk.ml
+++ b/input/input_vddk.ml
@@ -198,7 +198,7 @@ information on these settings.
| BlockDev _ | NBD _ | HTTP _ -> (* These should never happen? *)
assert false
- | LocalFile path ->
+ | LocalFile file ->
(* The <source file=...> attribute returned by the libvirt
* VMX driver looks like "[datastore] path". We can use it
* directly as the nbdkit file= parameter, and it is passed
@@ -212,7 +212,7 @@ information on these settings.
?nfchostport ~noextents
?password_file:options.input_password ?port
~server ?snapshot ~thumbprint ?transports ?user
- path in
+ file in
let _, pid = Nbdkit.run_unix socket nbdkit in
On_exit.kill pid
) disks;
diff --git a/input/nbdkit_vddk.ml b/input/nbdkit_vddk.ml
index 5c23efd1..801182d1 100644
--- a/input/nbdkit_vddk.ml
+++ b/input/nbdkit_vddk.ml
@@ -51,8 +51,8 @@ let libNN = sprintf "lib%d" Sys.word_size
(* Create an nbdkit module specialized for reading from VDDK sources. *)
let create_vddk ?bandwidth ?config ?cookie ?cor ?libdir ~moref
- ?nfchostport ~noextents ?password_file ?port
- ~server ?snapshot ~thumbprint ?transports ?user path =
+ ?nfchostport ~noextents ?password_file ?port
+ ~server ?snapshot ~thumbprint ?transports ?user file =
if not (Nbdkit.is_installed ()) then
error (f_"nbdkit is not installed or not working");
@@ -114,7 +114,7 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
Nbdkit.add_arg cmd "server" server;
Nbdkit.add_arg cmd "vm" (sprintf "moref=%s" moref);
- Nbdkit.add_arg cmd "file" path;
+ Nbdkit.add_arg cmd "file" file;
(* For VDDK we require some user. If it's not supplied, assume root. *)
let user = Option.value ~default:"root" user in

View File

@ -0,0 +1,193 @@
From fb8a4d851946677d5c79afb575267f17a8b649a5 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 29 Apr 2025 13:44:07 +0100
Subject: [PATCH] input: Add -io vddk-file=... option
This option allows the file parameter of nbdkit-vddk-plugin to be
overridden. Useful for performing conversions of snapshots, since the
filename returned by libvirt may not be the correct snapshot filename.
This also updates the common submodule, pulling in:
Richard W.M. Jones (2):
mlstdutils: Implement String.implode
mlstdutils: Add List.make function
Suggested-by: Martin Necas
Fixes: https://issues.redhat.com/browse/RHEL-88543
(cherry picked from commit 5328142e6a9faae1db99c646991d27badc6efe91)
---
common | 2 +-
docs/virt-v2v-input-vmware.pod | 9 +++++----
input/input_vddk.ml | 35 ++++++++++++++++++++++++++--------
3 files changed, 33 insertions(+), 13 deletions(-)
Submodule common 57c2b3f0..3873d593:
diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
index 212a1513..6880fce5 100644
--- a/common/mlstdutils/std_utils.ml
+++ b/common/mlstdutils/std_utils.ml
@@ -409,6 +409,14 @@ module List = struct
let push_back_list xsp xs = xsp := !xsp @ xs
let push_front_list xs xsp = xsp := xs @ !xsp
+
+ let make n x =
+ let rec loop acc = function
+ | 0 -> acc
+ | i when i > 0 -> loop (x :: acc) (i-1)
+ | _ -> invalid_arg "make"
+ in
+ loop [] n
end
let (//) = Filename.concat
diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
index 72a2d44c..ae6004b2 100644
--- a/common/mlstdutils/std_utils.mli
+++ b/common/mlstdutils/std_utils.mli
@@ -291,6 +291,9 @@ module List : sig
[push_front_list] is like {!push_front} above, except it prepends
a list to the list reference. *)
+
+ val make : int -> 'a -> 'a list
+ (** [make n x] returns a list with [x] repeated [n] times. *)
end
(** Override the List module from stdlib. *)
diff --git a/common/mlstdutils/std_utils_tests.ml b/common/mlstdutils/std_utils_tests.ml
index 4e368152..5f8c1440 100644
--- a/common/mlstdutils/std_utils_tests.ml
+++ b/common/mlstdutils/std_utils_tests.ml
@@ -179,6 +179,12 @@ let test_which ctx =
end;
()
+(* Test List.make. *)
+let test_list_make ctx =
+ assert_equal_stringlist [] (List.make 0 "1");
+ assert_equal_stringlist ["1"; "1"; "1"] (List.make 3 "1");
+ assert_raises (Invalid_argument "make") (fun () -> List.make (-1) "1")
+
(* Suites declaration. *)
let suite =
"mllib Std_utils" >:::
@@ -195,6 +201,7 @@ let suite =
"strings.span" >:: test_string_span;
"strings.chomp" >:: test_string_chomp;
"which" >:: test_which;
+ "list.make" >:: test_list_make;
]
let () =
diff --git a/docs/virt-v2v-input-vmware.pod b/docs/virt-v2v-input-vmware.pod
index b28268c2..80ca560a 100644
--- a/docs/virt-v2v-input-vmware.pod
+++ b/docs/virt-v2v-input-vmware.pod
@@ -342,10 +342,11 @@ SSL thumbprint:
-o local -os /var/tmp
Other options that you might need to add in rare circumstances include
-I<-io vddk-config>, I<-io vddk-cookie>, I<-io vddk-nfchostport>,
-I<-io vddk-port>, I<-io vddk-snapshot>, and I<-io vddk-transports>,
-which are all explained in the L<nbdkit-vddk-plugin(1)> documentation.
-Do not use these options unless you know what you are doing.
+I<-io vddk-config>, I<-io vddk-cookie>, I<-io vddk-file>,
+I<-io vddk-nfchostport>, I<-io vddk-port>, I<-io vddk-snapshot>, and
+I<-io vddk-transports>, which are all explained in the
+L<nbdkit-vddk-plugin(1)> documentation. Do not use these options
+unless you know what you are doing.
=head2 VDDK: Debugging VDDK failures
diff --git a/input/input_vddk.ml b/input/input_vddk.ml
index 659ff08f..316fe5f8 100644
--- a/input/input_vddk.ml
+++ b/input/input_vddk.ml
@@ -50,6 +50,7 @@ All other settings are optional:
-io vddk-config=FILE VDDK configuration file
-io vddk-cookie=COOKIE VDDK cookie
+ -io vddk-file=FILE Override nbdkit-vddk-plugin file= parameter
-io vddk-libdir=LIBDIR VDDK library parent directory
-io vddk-nfchostport=PORT VDDK nfchostport
-io vddk-noextents=true Avoid slow VDDK QueryAllocatedBlocks API
@@ -70,6 +71,7 @@ information on these settings.
let vddk_option_keys =
[ "config";
"cookie";
+ "file";
"libdir";
"nfchostport";
"noextents";
@@ -90,11 +92,6 @@ information on these settings.
(key, value)
) options.input_options in
- (* Check no option appears more than once. *)
- let keys = List.map fst io_options in
- if List.length keys <> List.length (List.sort_uniq compare keys) then
- error (f_"-it vddk: duplicate -io options on the command line");
-
(* thumbprint is mandatory. *)
if not (List.mem_assoc "thumbprint" io_options) then
error (f_"You must pass the -io vddk-thumbprint option with the \
@@ -137,6 +134,7 @@ information on these settings.
(* Parse the libvirt XML. *)
let source, disks, xml = parse_libvirt_domain conn guest in
+ let nr_disks = List.length disks in
(* Find the <vmware:moref> element from the XML. This was added
* in libvirt >= 3.7 and is required.
@@ -188,9 +186,27 @@ information on these settings.
let transports =
try Some (List.assoc "transports" io_options) with Not_found -> None in
+ (* If -io vddk-file was given, there must be exactly one per guest
+ * disk. Get the list of file overrides.
+ *)
+ let file_overrides =
+ if List.mem_assoc "file" io_options then (
+ let fos =
+ List.filter_map (function ("file",b) -> Some (Some b) | _ -> None)
+ io_options in
+ if List.length fos <> nr_disks then
+ error (f_"-io vddk-file= must be used exactly %d times") nr_disks;
+ fos
+ )
+ else (
+ (* List of no overrides. *)
+ List.make nr_disks None
+ ) in
+
(* Create an nbdkit instance for each disk. *)
+ List.combine disks file_overrides |>
List.iteri (
- fun i { d_format = format; d_type } ->
+ fun i ({ d_format = format; d_type }, file_override) ->
let socket = sprintf "%s/in%d" dir i in
On_exit.unlink socket;
@@ -198,7 +214,10 @@ information on these settings.
| BlockDev _ | NBD _ | HTTP _ -> (* These should never happen? *)
assert false
- | LocalFile file ->
+ | LocalFile orig_file ->
+ (* If -io vddk-file, override it here. *)
+ let file = Option.value file_override ~default:orig_file in
+
(* The <source file=...> attribute returned by the libvirt
* VMX driver looks like "[datastore] path". We can use it
* directly as the nbdkit file= parameter, and it is passed
@@ -215,7 +234,7 @@ information on these settings.
file in
let _, pid = Nbdkit.run_unix socket nbdkit in
On_exit.kill pid
- ) disks;
+ );
source
end

View File

@ -0,0 +1,40 @@
From 8e3d1747271cdf112d05e099302de7520f7f8111 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 30 Apr 2025 13:26:54 +0100
Subject: [PATCH] inspector: Simplify input bandwidth code
We dropped the virt-v2v --bandwidth parameters from
virt-v2v-inspector, but left some dead code around. Simplify that
code.
(cherry picked from commit 7a96d82fb6a6330bc7e667677f62dea64a957188)
---
inspector/inspector.ml | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/inspector/inspector.ml b/inspector/inspector.ml
index ac26146f..16300d45 100644
--- a/inspector/inspector.ml
+++ b/inspector/inspector.ml
@@ -48,8 +48,6 @@ let rec main () =
else output_file := Some filename
in
- let bandwidth = ref None in
- let bandwidth_file = ref None in
let input_conn = ref None in
let input_format = ref None in
let input_password = ref None in
@@ -313,11 +311,7 @@ read the man page virt-v2v-inspector(1).
(module Input_libvirt.Libvirt_) in
let input_options = {
- Input.bandwidth =
- (match !bandwidth, !bandwidth_file with
- | None, None -> None
- | Some rate, None -> Some (StaticBandwidth rate)
- | rate, Some filename -> Some (DynamicBandwidth (rate, filename)));
+ Input.bandwidth = None;
input_conn = input_conn;
input_format = !input_format;
input_options = !input_options;

View File

@ -0,0 +1,49 @@
From e1b9a34aa4e140d3fafea4d0883d0c29fcc204bb Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 11 Apr 2025 10:01:13 +0100
Subject: [PATCH] docs: Rearrange --root titles
Makes the documentation easier to read instead of having a big block
of text.
(cherry picked from commit c1d8ed9bac616c3ba8a807da350f24c7fa54e56a)
---
docs/virt-v2v.pod | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 57714022..1746afa7 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -774,12 +774,6 @@ This disables progress bars and other unnecessary output.
=item B<--root single>
-=item B<--root first>
-
-=item B<--root> /dev/sdX
-
-=item B<--root> /dev/VG/LV
-
Choose the root filesystem to be converted.
In the case where the virtual machine is dual-boot or multi-boot, or
@@ -798,11 +792,17 @@ VM is found to be multi-boot, then virt-v2v will stop and list the
possible root filesystems and ask the user which to use. This
requires that virt-v2v is run interactively.
+=item B<--root first>
+
S<I<--root first>> means to choose the first root device in the case
of a multi-boot operating system. Since this is a heuristic, it may
sometimes choose the wrong one.
-You can also name a specific root device, eg. S<I<--root /dev/sda2>>
+=item B<--root> /dev/sdX
+
+=item B<--root> /dev/VG/LV
+
+Name a specific root device to convert, eg. S<I<--root /dev/sda2>>
would mean to use the second partition on the first hard drive. If
the named root device does not exist or was not detected as a root
device, then virt-v2v will fail.

View File

@ -0,0 +1,39 @@
From bd20b2429f04d8c7b37fbcce243687413dbe434f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 11 Apr 2025 09:49:06 +0100
Subject: [PATCH] docs: Clarify --root first documentation
Clarify that we don't necessarily choose the default bootloader option
(since we don't collect that information). It's just the first in the
list of roots returned by libguestfs.
What is intentionally not documented here is that libguestfs doesn't
necessarily return the roots in any particular order (eg. it's not
sorted alphabetically). If we fix that in future, we might break how
this option works, so don't document any expectations.
(cherry picked from commit bc936379e20e1aab5f569a577663082411f56dc2)
---
docs/virt-v2v.pod | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 1746afa7..84a7d6ac 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -794,9 +794,12 @@ requires that virt-v2v is run interactively.
=item B<--root first>
-S<I<--root first>> means to choose the first root device in the case
-of a multi-boot operating system. Since this is a heuristic, it may
-sometimes choose the wrong one.
+Choose the first root device in the case of a multi-boot operating
+system. Since this is a heuristic, it may sometimes choose the wrong
+one, and it may not choose the default option from the guest
+bootloader. For predictable results it is better to use
+L<virt-v2v-inspector(1)> to inspect the guest and then specify which
+root you want to convert.
=item B<--root> /dev/sdX

View File

@ -0,0 +1,30 @@
From 26d2ba8c21fefb14b6ad2efb380ef08bff0b3b46 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 11 Apr 2025 10:07:20 +0100
Subject: [PATCH] docs: Remove old paragraph about a bug in Grub
This paragraph dates back to 2011 and is unlikely to be relevant now:
https://github.com/rwmjones/old-virt-v2v/commit/36cc57baf395c5b05cc2174d1c04b386b94aaefd
(cherry picked from commit 3019f70565727fb7f03d475be154b1578ea2c51f)
---
docs/virt-v2v.pod | 6 ------
1 file changed, 6 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 84a7d6ac..d65e13ed 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -810,12 +810,6 @@ would mean to use the second partition on the first hard drive. If
the named root device does not exist or was not detected as a root
device, then virt-v2v will fail.
-Note that there is a bug in grub which prevents it from successfully
-booting a multiboot system if virtio is enabled. Grub is only able to
-boot an operating system from the first virtio disk. Specifically,
-F</boot> must be on the first virtio disk, and it cannot chainload an
-OS which is not in the first virtio disk.
-
=item B<-v>
=item B<--verbose>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
From ca1952901efe18f8ebdbe1aecd54cd8d86d2c890 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 15 May 2025 16:41:30 +0100
Subject: [PATCH] docs: Document -io vddk-file in the main options listing
Reported-by: Ming Xie
Fixes: commit 5328142e6a9faae1db99c646991d27badc6efe91
(cherry picked from commit 3a54eabde33fe753ebd864785de8a2fe54c2e1a2)
---
docs/virt-v2v.pod | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index b946758c..4495e53d 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -324,6 +324,8 @@ See L<virt-v2v-input-vmware(1)> for details.
=item B<-io vddk-cookie=>COOKIE
+=item B<-io vddk-file=>FILE
+
=item B<-io vddk-nfchostport=>PORT
=item B<-io vddk-port=>PORT

View File

@ -0,0 +1,125 @@
From 4df2b6c2f033b5122d0da5bbc50e10eebf038076 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 9 Jul 2025 09:38:50 +0100
Subject: [PATCH] vddk: Remove -io vddk-noextents option
Commit 191b8cf418 ("input: Add undocumented -io vddk-noextents=true
option") added an option which could be used to insert the nbdkit
noextents filter on top of the VDDK source. This was designed so we
could test in production if this improved performance (which it
didn't).
Since then we've spent more time investigating problems with
QueryAllocatedBlocks and believe we have a better solution in nbdkit.
See:
https://gitlab.com/nbdkit/nbdkit/-/commit/5a882e74cae3dbaa09bf3b942a02f9947b12f6e5
Reverts: commit 191b8cf418076ae3766b134ffa96eee048c7eb9d
(cherry picked from commit 563c581fd0d68792211edf15632bac3f419888b7)
---
input/input_vddk.ml | 7 +------
input/nbdkit_vddk.ml | 32 +-------------------------------
input/nbdkit_vddk.mli | 1 -
3 files changed, 2 insertions(+), 38 deletions(-)
diff --git a/input/input_vddk.ml b/input/input_vddk.ml
index 316fe5f8..f8b5b523 100644
--- a/input/input_vddk.ml
+++ b/input/input_vddk.ml
@@ -53,7 +53,6 @@ All other settings are optional:
-io vddk-file=FILE Override nbdkit-vddk-plugin file= parameter
-io vddk-libdir=LIBDIR VDDK library parent directory
-io vddk-nfchostport=PORT VDDK nfchostport
- -io vddk-noextents=true Avoid slow VDDK QueryAllocatedBlocks API
-io vddk-port=PORT VDDK port
-io vddk-snapshot=SNAPSHOT-MOREF
VDDK snapshot moref
@@ -74,7 +73,6 @@ information on these settings.
"file";
"libdir";
"nfchostport";
- "noextents";
"port";
"snapshot";
"thumbprint";
@@ -173,9 +171,6 @@ information on these settings.
try Some (List.assoc "libdir" io_options) with Not_found -> None in
let nfchostport =
try Some (List.assoc "nfchostport" io_options) with Not_found -> None in
- let noextents =
- try bool_of_string (List.assoc "noextents" io_options)
- with Not_found -> false in
let port =
try Some (List.assoc "port" io_options) with Not_found -> None in
let snapshot =
@@ -228,7 +223,7 @@ information on these settings.
Nbdkit_vddk.create_vddk ?bandwidth:options.bandwidth
?config ?cookie ~cor
?libdir ~moref
- ?nfchostport ~noextents
+ ?nfchostport
?password_file:options.input_password ?port
~server ?snapshot ~thumbprint ?transports ?user
file in
diff --git a/input/nbdkit_vddk.ml b/input/nbdkit_vddk.ml
index 801182d1..15460b99 100644
--- a/input/nbdkit_vddk.ml
+++ b/input/nbdkit_vddk.ml
@@ -51,7 +51,7 @@ let libNN = sprintf "lib%d" Sys.word_size
(* Create an nbdkit module specialized for reading from VDDK sources. *)
let create_vddk ?bandwidth ?config ?cookie ?cor ?libdir ~moref
- ?nfchostport ~noextents ?password_file ?port
+ ?nfchostport ?password_file ?port
~server ?snapshot ~thumbprint ?transports ?user file =
if not (Nbdkit.is_installed ()) then
error (f_"nbdkit is not installed or not working");
@@ -140,36 +140,6 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
*)
Nbdkit.add_filter_if_available cmd "retry";
- (* VDDK's QueryAllocatedBlocks API is infamously slow. It appears
- * to block all other requests while it is running. This API is
- * also only called during the copy phase, not during conversion
- * (or if it is, extremely rarely).
- *
- * If fstrim was successful, then trimmed blocks are stored in
- * the COW filter (see below), and so requests for extents stop
- * at that layer. However for areas of the disk that fstrim
- * thinks contain data, we still have to go through to VDDK to
- * fetch extents.
- *
- * We could therefore add nbdkit-noextents-filter here (below COW,
- * above VDDK plugin) which stops extents requests from going
- * to VDDK, which would stop QueryAllocatedBlocks ever being
- * called. In my testing this is a moderate performance win.
- *
- * However ... in the case where fstrim failed, or for filesystems
- * or partitions on the disk that we don't understand, doing this
- * would mean that those are copied completely, as there would be
- * no extent data (nbdcopy will still sparsify them on the target,
- * but we'd have to copy all the bits from VMware). Because
- * here we don't know if this is the case, be conservative and
- * actually don't use this filter.
- *
- * If used, this filter should be close to the plugin and MUST
- * be below the COW filter.
- *)
- if noextents then
- Nbdkit.add_filter_if_available cmd "noextents";
-
(* Split very large requests to avoid out of memory errors on the
* server. Since we're using this filter, also add minblock=512
* although it will make no difference.
diff --git a/input/nbdkit_vddk.mli b/input/nbdkit_vddk.mli
index ef2082db..2345e6e2 100644
--- a/input/nbdkit_vddk.mli
+++ b/input/nbdkit_vddk.mli
@@ -25,7 +25,6 @@ val create_vddk : ?bandwidth:Types.bandwidth ->
?libdir:string ->
moref:string ->
?nfchostport:string ->
- noextents:bool ->
?password_file:string ->
?port:string ->
server:string ->

View File

@ -1,38 +0,0 @@
From 2ab37349cf37d0ffdb9929ca24c2a024600a4848 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Thu, 21 May 2020 13:32:21 +0200
Subject: [PATCH] libvirt: make use of libvirt's default auth handler
(RHBZ#1838425)
Use the default libvirt authentication handler as base for ours,
overriding it with our callback only in case we have a password to
supply.
(cherry picked from commit ce66cac50179baf2fb8b404f7eba49048c7819b0)
---
v2v/libvirt_utils.ml | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/v2v/libvirt_utils.ml b/v2v/libvirt_utils.ml
index 7df17b29..4d0b8639 100644
--- a/v2v/libvirt_utils.ml
+++ b/v2v/libvirt_utils.ml
@@ -33,10 +33,14 @@ let auth_for_password_file ?password_file () =
) creds
in
- {
- Libvirt.Connect.credtype = [ Libvirt.Connect.CredentialPassphrase ];
- cb = auth_fn;
- }
+ let base_auth = Libvirt.Connect.get_auth_default () in
+
+ if password_file = None then
+ base_auth
+ else
+ { base_auth with
+ cb = auth_fn;
+ }
let get_domain conn name =
let dom =

View File

@ -1,211 +0,0 @@
From e04f4d6aa0e94a61b40fa6b10a5274ea89cd96a1 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Mon, 25 May 2020 16:52:07 +0200
Subject: [PATCH] -i libvirt: print URI without connecting (RHBZ#1839917)
Pass (again) around the libvirt URI string in the various input_libvirt
subclasses so that input_libvirt#as_options does not need to connect to
print the connection URI.
As related change: pass input_conn as non-optional string parameter in
classes that require one (all but input_libvirt_other, basically). This
avoids the need for extra checks.
(cherry picked from commit 86d87563ee03e86ca9abdcad4f674af66a883006)
---
v2v/input_libvirt.ml | 10 +++++-----
v2v/input_libvirt_other.ml | 12 ++++++++----
v2v/input_libvirt_other.mli | 4 ++--
v2v/input_libvirt_vcenter_https.ml | 4 ++--
v2v/input_libvirt_vcenter_https.mli | 2 +-
v2v/input_libvirt_vddk.ml | 9 ++-------
v2v/input_libvirt_vddk.mli | 4 ++--
v2v/input_libvirt_xen_ssh.ml | 4 ++--
v2v/input_libvirt_xen_ssh.mli | 2 +-
9 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml
index cd5f351c..352fae94 100644
--- a/v2v/input_libvirt.ml
+++ b/v2v/input_libvirt.ml
@@ -53,22 +53,22 @@ let input_libvirt input_conn input_password input_transport guest =
| Some _, None, _ (* No scheme? *)
| Some _, Some "", _ ->
- Input_libvirt_other.input_libvirt_other libvirt_conn guest
+ Input_libvirt_other.input_libvirt_other libvirt_conn ?input_conn guest
(* vCenter over https. *)
| Some server, Some ("esx"|"gsx"|"vpx"), None ->
Input_libvirt_vcenter_https.input_libvirt_vcenter_https
- libvirt_conn input_password parsed_uri server guest
+ libvirt_conn orig_uri input_password parsed_uri server guest
(* vCenter or ESXi using nbdkit vddk plugin *)
| Some server, Some ("esx"|"gsx"|"vpx"), Some (`VDDK vddk_options) ->
Input_libvirt_vddk.input_libvirt_vddk
- libvirt_conn input_conn input_password vddk_options parsed_uri guest
+ libvirt_conn orig_uri input_password vddk_options parsed_uri guest
(* Xen over SSH *)
| Some server, Some "xen+ssh", _ ->
Input_libvirt_xen_ssh.input_libvirt_xen_ssh
- libvirt_conn input_password parsed_uri server guest
+ libvirt_conn orig_uri input_password parsed_uri server guest
(* Old virt-v2v also supported qemu+ssh://. However I am
* deliberately not supporting this in new virt-v2v. Don't
@@ -79,6 +79,6 @@ let input_libvirt input_conn input_password input_transport guest =
| Some _, Some _, _ ->
warning (f_"no support for remote libvirt connections to '-ic %s'. The conversion may fail when it tries to read the source disks.")
orig_uri;
- Input_libvirt_other.input_libvirt_other libvirt_conn guest
+ Input_libvirt_other.input_libvirt_other libvirt_conn ?input_conn guest
let () = Modules_list.register_input_module "libvirt"
diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml
index e00944db..6a19ae52 100644
--- a/v2v/input_libvirt_other.ml
+++ b/v2v/input_libvirt_other.ml
@@ -40,12 +40,16 @@ let error_if_libvirt_does_not_support_json_backingfile () =
error (f_"because of libvirt bug https://bugzilla.redhat.com/1134878 you must EITHER upgrade to libvirt >= 2.1.0 OR set this environment variable:\n\nexport LIBGUESTFS_BACKEND=direct\n\nand then rerun the virt-v2v command.")
(* Superclass. *)
-class virtual input_libvirt libvirt_conn guest =
+class virtual input_libvirt libvirt_conn ?input_conn guest =
object (self)
inherit input
method as_options =
- sprintf "-i libvirt -ic %s %s" (Libvirt.Connect.get_uri self#conn) guest
+ sprintf "-i libvirt%s %s"
+ (match input_conn with
+ | None -> ""
+ | Some uri -> " -ic " ^ uri)
+ guest
method private conn : Libvirt.rw Libvirt.Connect.t =
Lazy.force libvirt_conn
@@ -54,9 +58,9 @@ end
(* Subclass specialized for handling anything that's *not* VMware vCenter
* or Xen.
*)
-class input_libvirt_other libvirt_conn guest =
+class input_libvirt_other libvirt_conn ?input_conn guest =
object (self)
- inherit input_libvirt libvirt_conn guest
+ inherit input_libvirt libvirt_conn ?input_conn guest
method source ?bandwidth () =
debug "input_libvirt_other: source ()";
diff --git a/v2v/input_libvirt_other.mli b/v2v/input_libvirt_other.mli
index c528c3ee..ae2c0c6d 100644
--- a/v2v/input_libvirt_other.mli
+++ b/v2v/input_libvirt_other.mli
@@ -20,11 +20,11 @@
val error_if_libvirt_does_not_support_json_backingfile : unit -> unit
-class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> object
+class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> ?input_conn:string -> string -> object
method precheck : unit -> unit
method as_options : string
method virtual source : ?bandwidth:Types.bandwidth -> unit -> Types.source * Types.source_disk list
method private conn : Libvirt.rw Libvirt.Connect.t
end
-val input_libvirt_other : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> Types.input
+val input_libvirt_other : Libvirt.rw Libvirt.Connect.t Lazy.t -> ?input_conn:string -> string -> Types.input
diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml
index 77bc315d..ed2e5eed 100644
--- a/v2v/input_libvirt_vcenter_https.ml
+++ b/v2v/input_libvirt_vcenter_https.ml
@@ -32,9 +32,9 @@ open Printf
(* Subclass specialized for handling VMware vCenter over https. *)
class input_libvirt_vcenter_https
- libvirt_conn input_password parsed_uri server guest =
+ libvirt_conn input_conn input_password parsed_uri server guest =
object (self)
- inherit input_libvirt libvirt_conn guest
+ inherit input_libvirt libvirt_conn ~input_conn guest
val mutable dcPath = ""
diff --git a/v2v/input_libvirt_vcenter_https.mli b/v2v/input_libvirt_vcenter_https.mli
index c2e0f3fe..a12a9815 100644
--- a/v2v/input_libvirt_vcenter_https.mli
+++ b/v2v/input_libvirt_vcenter_https.mli
@@ -18,4 +18,4 @@
(** [-i libvirt] when the source is VMware vCenter *)
-val input_libvirt_vcenter_https : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> Xml.uri -> string -> string -> Types.input
+val input_libvirt_vcenter_https : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> Xml.uri -> string -> string -> Types.input
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
index fbd1e0c6..75fd146e 100644
--- a/v2v/input_libvirt_vddk.ml
+++ b/v2v/input_libvirt_vddk.ml
@@ -99,7 +99,7 @@ class input_libvirt_vddk libvirt_conn input_conn input_password vddk_options
in
object (self)
- inherit input_libvirt libvirt_conn guest as super
+ inherit input_libvirt libvirt_conn ~input_conn guest as super
method precheck () =
error_unless_thumbprint ()
@@ -138,12 +138,7 @@ object (self)
match parsed_uri.Xml.uri_server with
| Some server -> server
| None ->
- match input_conn with
- | Some input_conn ->
- error (f_"-ic %s URL does not contain a host name field")
- input_conn
- | None ->
- error (f_"you must use the -ic parameter. See the virt-v2v-input-vmware(1) manual.") in
+ error (f_"-ic %s URL does not contain a host name field") input_conn in
let user = parsed_uri.Xml.uri_user in
diff --git a/v2v/input_libvirt_vddk.mli b/v2v/input_libvirt_vddk.mli
index 2fc6e9cf..f37d88e7 100644
--- a/v2v/input_libvirt_vddk.mli
+++ b/v2v/input_libvirt_vddk.mli
@@ -25,7 +25,7 @@ val print_input_options : unit -> unit
val parse_input_options : (string * string) list -> vddk_options
(** Print and parse vddk -io options. *)
-val input_libvirt_vddk : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> string option -> vddk_options -> Xml.uri -> string -> Types.input
-(** [input_libvirt_vddk libvirt_conn vddk_options parsed_uri guest]
+val input_libvirt_vddk : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> vddk_options -> Xml.uri -> string -> Types.input
+(** [input_libvirt_vddk libvirt_conn input_conn vddk_options parsed_uri guest]
creates and returns a {!Types.input} object specialized for reading
the guest disks using the nbdkit vddk plugin. *)
diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml
index bd1235a6..ec366b4a 100644
--- a/v2v/input_libvirt_xen_ssh.ml
+++ b/v2v/input_libvirt_xen_ssh.ml
@@ -30,9 +30,9 @@ open Input_libvirt_other
open Printf
(* Subclass specialized for handling Xen over SSH. *)
-class input_libvirt_xen_ssh libvirt_conn input_password parsed_uri server guest =
+class input_libvirt_xen_ssh libvirt_conn input_conn input_password parsed_uri server guest =
object (self)
- inherit input_libvirt libvirt_conn guest
+ inherit input_libvirt libvirt_conn ~input_conn guest
method precheck () =
if backend_is_libvirt () then
diff --git a/v2v/input_libvirt_xen_ssh.mli b/v2v/input_libvirt_xen_ssh.mli
index 120a52f7..3cbca9d7 100644
--- a/v2v/input_libvirt_xen_ssh.mli
+++ b/v2v/input_libvirt_xen_ssh.mli
@@ -18,4 +18,4 @@
(** [-i libvirt] when the source is Xen *)
-val input_libvirt_xen_ssh : Libvirt.rw Libvirt.Connect.t Lazy.t -> string option -> Xml.uri -> string -> string -> Types.input
+val input_libvirt_xen_ssh : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> string option -> Xml.uri -> string -> string -> Types.input

View File

@ -1,31 +0,0 @@
From bb94c68c521aa546d3f2e59aa25e388bfd9c5fc5 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Tue, 19 May 2020 12:14:18 +0200
Subject: [PATCH] vCenter: fix parsing of HTTP status string (RHBZ#1837328)
vCenter 7 answers with an HTTP/2 status string, so we cannot extract
the status code from it by using fixed positions in that string.
Hence, pick the status code by reading what's after the whitespace.
Tested with vCenter 6.5 and 7.
(cherry picked from commit d2aa82317964d62fcc8dc7b6737773003d04b998)
---
v2v/vCenter.ml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml
index c28a4ced..4c128b0c 100644
--- a/v2v/vCenter.ml
+++ b/v2v/vCenter.ml
@@ -190,7 +190,9 @@ and fetch_headers_from_url password_file uri sslverify https_url =
| [] ->
dump_response stderr;
error (f_"vcenter: no status code in output of curl command. Is curl installed?")
- | ss -> String.sub (List.hd (List.rev ss)) 9 3 in
+ | ss ->
+ let s = List.hd (List.rev ss) in
+ String.sub s (String.index s ' ' + 1) 3 in
let headers =
List.map (

View File

@ -1,94 +0,0 @@
From 939d57ef4d5bcfa31e9b98104822962b89572481 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 19 May 2020 14:40:01 +0100
Subject: [PATCH] v2v: -o libvirt: Remove cache=none (RHBZ#1837453).
Traditionally if you did live migration (KVM to KVM), you had to
ensure that cache=none was set on all disks of the guest up front.
This was because of quirks in how NFS works (I think the close-to-open
consistency and the fact that during live migration both qemus have
the file open), and we had to assume the worst case that a guest might
be backed by NFS.
Because of this when virt-v2v converts a guest to run on KVM using
libvirt it sets cache=none.
This is not necessary with modern qemu. If qemu supports the
drop-cache property of the file block driver, which libvirt will
automatically detect for us, then libvirt live migration is able to
tell qemu to drop cached data at the right time even if the backing is
NFS.
It also had a significant performance impact. In some synthetic
benchmarks it could show 2 or 3 times slower performance.
Thanks: Ming Xie, Peter Krempa.
(cherry picked from commit 9720f45e0cd9283739fd2a67c19e66912489dfc7)
---
docs/virt-v2v-output-local.pod | 2 +-
tests/test-v2v-cdrom.expected | 2 +-
tests/test-v2v-floppy.expected | 2 +-
tests/test-v2v-i-ova.xml | 2 +-
v2v/create_libvirt_xml.ml | 1 -
5 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/docs/virt-v2v-output-local.pod b/docs/virt-v2v-output-local.pod
index 38df007d..a5f155cb 100644
--- a/docs/virt-v2v-output-local.pod
+++ b/docs/virt-v2v-output-local.pod
@@ -127,7 +127,7 @@ Edit F</var/tmp/NAME.xml> to change F</var/tmp/NAME-sda> to the pool
name. In other words, locate the following bit of XML:
<disk type='file' device='disk'>
- <driver name='qemu' type='raw' cache='none' />
+ <driver name='qemu' type='raw' />
<source file='/var/tmp/NAME-sda' />
<target dev='hda' bus='ide' />
</disk>
diff --git a/tests/test-v2v-cdrom.expected b/tests/test-v2v-cdrom.expected
index e18ea6f2..34d2bf59 100644
--- a/tests/test-v2v-cdrom.expected
+++ b/tests/test-v2v-cdrom.expected
@@ -1,5 +1,5 @@
<disk type='file' device='disk'>
- <driver name='qemu' type='raw' cache='none'/>
+ <driver name='qemu' type='raw'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk device='cdrom' type='file'>
diff --git a/tests/test-v2v-floppy.expected b/tests/test-v2v-floppy.expected
index dd74ed94..a718c21f 100644
--- a/tests/test-v2v-floppy.expected
+++ b/tests/test-v2v-floppy.expected
@@ -1,5 +1,5 @@
<disk type='file' device='disk'>
- <driver name='qemu' type='raw' cache='none'/>
+ <driver name='qemu' type='raw'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk device='floppy' type='file'>
diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml
index 7c198283..e26f4f83 100644
--- a/tests/test-v2v-i-ova.xml
+++ b/tests/test-v2v-i-ova.xml
@@ -22,7 +22,7 @@
<on_crash>restart</on_crash>
<devices>
<disk type='file' device='disk'>
- <driver name='qemu' type='raw' cache='none'/>
+ <driver name='qemu' type='raw'/>
<source file='TestOva-sda'/>
<target dev='vda' bus='virtio'/>
</disk>
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 05553c4f..5a1fba0f 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -336,7 +336,6 @@ let create_libvirt_xml ?pool source targets target_buses guestcaps
e "driver" [
"name", "qemu";
"type", t.target_format;
- "cache", "none"
] [];
(match pool with
| None ->

View File

@ -1,48 +0,0 @@
From f3ea9ceb1c3c9741d4f62d0c1d23b7c94634353a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 28 May 2020 11:40:45 +0100
Subject: [PATCH] v2v: Remove extraneous '=' when setting bandwidth
(RHBZ#1841096).
Commit c3a54d6aed6dfc65f9ffa59976bb8d20044c03a8 ("v2v: Add standalone
nbdkit module.") was supposed to be a simple refactoring but it broke
the --bandwidth and --bandwidth-file options (amongst other things).
Because of an extra '=' character which was accidentally left over, it
would add an extra character in the nbdkit-rate-filter command line.
For example:
virt-v2v .. --bandwidth 200M
would invoke:
nbdkit .. --filter rate rate==200M
which causes a parse error. The --bandwidth-file option does not
invoke a parse error but does not work, for similar reasons.
Thanks: Ming Xie
(cherry picked from commit a89a084b2d0f6d40716c1d34969f6c49ea28e9b3)
---
v2v/nbdkit_sources.ml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml
index 979c3773..402dfd0e 100644
--- a/v2v/nbdkit_sources.ml
+++ b/v2v/nbdkit_sources.ml
@@ -118,11 +118,11 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args =
let args =
match bandwidth with
| StaticBandwidth rate ->
- [ "rate=", rate ]
+ [ "rate", rate ]
| DynamicBandwidth (None, filename) ->
- [ "rate-file=", filename ]
+ [ "rate-file", filename ]
| DynamicBandwidth (Some rate, filename) ->
- [ "rate=", rate; "rate-file=", filename ] in
+ [ "rate", rate; "rate-file", filename ] in
cmd, args
)
else cmd, [] in

View File

@ -1,46 +0,0 @@
From 4e0b3de57486613c8f28ef7726df728cccd7624b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 28 May 2020 10:59:57 +0100
Subject: [PATCH] v2v: -it vddk: Don't use nbdkit readahead filter with VDDK
(RHBZ#1832805).
This filter deliberately tries to coalesce reads into larger requests.
Unfortunately VMware has low limits on the size of requests it can
serve to a VDDK client and the larger requests would break with errors
like this:
nbdkit: vddk[3]: error: [NFC ERROR] NfcFssrvrProcessErrorMsg: received NFC error 5 from server: Failed to allocate the requested 33554456 bytes
We already increase the maximum request size by changing the
configuration on the VMware server, but it's not sufficient for VDDK
with the readahead filter.
As readahead is only an optimization, the simplest solution is to
disable this filter when we're using nbdkit-vddk-plugin.
Thanks: Ming Xie
(cherry picked from commit 1438174488f111fa24420758ba3bf0218dc9ee2a)
---
v2v/nbdkit_sources.ml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml
index 402dfd0e..bfda91a7 100644
--- a/v2v/nbdkit_sources.ml
+++ b/v2v/nbdkit_sources.ml
@@ -97,9 +97,13 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args =
let cmd = Nbdkit.add_filter_if_available cmd "retry" in
(* Adding the readahead filter is always a win for our access
- * patterns. However if it doesn't exist don't worry.
+ * patterns. If it doesn't exist don't worry. However it
+ * breaks VMware servers (RHBZ#1832805).
*)
- let cmd = Nbdkit.add_filter_if_available cmd "readahead" in
+ let cmd =
+ if plugin_name <> "vddk" then
+ Nbdkit.add_filter_if_available cmd "readahead"
+ else cmd in
(* Caching extents speeds up qemu-img, especially its consecutive
* block_status requests with req_one=1.

View File

@ -1,113 +0,0 @@
From bcb9f50eee4050e72a532a0b805531dc72105a4f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 1 Jun 2020 17:18:59 +0100
Subject: [PATCH] v2v: nbdkit: Handle password= parameter in common_create.
Just refactoring.
(cherry picked from commit 36c008009a601634ec1c1fbc4f619b21988f075c)
---
v2v/nbdkit_sources.ml | 42 +++++++++++++++++++-----------------------
1 file changed, 19 insertions(+), 23 deletions(-)
diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml
index bfda91a7..47832011 100644
--- a/v2v/nbdkit_sources.ml
+++ b/v2v/nbdkit_sources.ml
@@ -58,7 +58,8 @@ let error_unless_nbdkit_compiled_with_selinux config =
error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.")
)
-let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args =
+let common_create ?bandwidth ?extra_debug ?extra_env password
+ plugin_name plugin_args =
error_unless_nbdkit_working ();
let config = Nbdkit.config () in
error_unless_nbdkit_min_version config;
@@ -136,6 +137,15 @@ let common_create ?bandwidth ?extra_debug ?extra_env plugin_name plugin_args =
List.fold_left (fun cmd (k, v) -> Nbdkit.add_arg cmd k v)
cmd (plugin_args @ rate_args) in
+ (* Handle the password parameter specially. *)
+ let cmd =
+ match password with
+ | NoPassword -> cmd
+ | AskForPassword ->
+ Nbdkit.add_arg cmd "password" "-"
+ | PasswordFile password_file ->
+ Nbdkit.add_arg cmd "password" ("+" ^ password_file) in
+
cmd
(* VDDK libraries are located under lib32/ or lib64/ relative to the
@@ -223,20 +233,16 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
let get_args () = List.rev !args in
add_arg, get_args in
- let password_param =
- match password_file with
- | None ->
- (* nbdkit asks for the password interactively *)
- "password", "-"
- | Some password_file ->
- (* nbdkit reads the password from the file *)
- "password", "+" ^ password_file in
add_arg ("server", server);
add_arg ("user", user);
- add_arg password_param;
add_arg ("vm", sprintf "moref=%s" moref);
add_arg ("file", path);
+ let password =
+ match password_file with
+ | None -> AskForPassword
+ | Some password_file -> PasswordFile password_file in
+
(* The passthrough parameters. *)
Option.may (fun s -> add_arg ("config", s)) config;
Option.may (fun s -> add_arg ("cookie", s)) cookie;
@@ -251,7 +257,7 @@ See also the virt-v2v-input-vmware(1) manual.") libNN
let debug_flag =
if version >= (1, 17, 10) then Some ("vddk.datapath", "0") else None in
- common_create ?bandwidth ?extra_debug:debug_flag ?extra_env:env
+ common_create ?bandwidth ?extra_debug:debug_flag ?extra_env:env password
"vddk" (get_args ())
(* Create an nbdkit module specialized for reading from SSH sources. *)
@@ -267,14 +273,9 @@ let create_ssh ?bandwidth ~password ?port ~server ?user path =
add_arg ("host", server);
Option.may (fun s -> add_arg ("port", s)) port;
Option.may (fun s -> add_arg ("user", s)) user;
- (match password with
- | NoPassword -> ()
- | AskForPassword -> add_arg ("password", "-")
- | PasswordFile password_file -> add_arg ("password", "+" ^ password_file)
- );
add_arg ("path", path);
- common_create ?bandwidth "ssh" (get_args ())
+ common_create ?bandwidth password "ssh" (get_args ())
(* Create an nbdkit module specialized for reading from Curl sources. *)
let create_curl ?bandwidth ?cookie ~password ?(sslverify=true) ?user url =
@@ -287,18 +288,13 @@ let create_curl ?bandwidth ?cookie ~password ?(sslverify=true) ?user url =
add_arg, get_args in
Option.may (fun s -> add_arg ("user", s)) user;
- (match password with
- | NoPassword -> ()
- | AskForPassword -> add_arg ("password", "-")
- | PasswordFile password_file -> add_arg ("password", "+" ^ password_file)
- );
(* https://bugzilla.redhat.com/show_bug.cgi?id=1146007#c10 *)
add_arg ("timeout", "2000");
Option.may (fun s -> add_arg ("cookie", s)) cookie;
if not sslverify then add_arg ("sslverify", "false");
add_arg ("url", url);
- common_create ?bandwidth "curl" (get_args ())
+ common_create ?bandwidth password "curl" (get_args ())
let run cmd =
let sock, _ = Nbdkit.run_unix cmd in

View File

@ -1,54 +0,0 @@
From 89ab50eb404664ac3522294f2f46a1c904a28abd Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 1 Jun 2020 17:35:58 +0100
Subject: [PATCH] v2v: nbdkit: Don't use password=- parameter (RHBZ#1842440).
This was broken with all nbdkit plugins, some in more ways than others.
Because we start nbdkit in the background and wait 30 seconds for it
to start running, the user had only 30 seconds to type in a password
before we timed out the process. In addition with the VDDK plugin
password=- had been broken ever since we changed the plugin to use a
reexec
(https://www.redhat.com/archives/libguestfs/2020-June/msg00012.html).
The solution is to read the password ourselves and pass it to nbdkit
as a private file.
(cherry picked from commit 16b551c77c88219a2f68e2fc37daf2dc4d88e4ed)
---
v2v/nbdkit_sources.ml | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/v2v/nbdkit_sources.ml b/v2v/nbdkit_sources.ml
index 47832011..f5e91911 100644
--- a/v2v/nbdkit_sources.ml
+++ b/v2v/nbdkit_sources.ml
@@ -142,7 +142,26 @@ let common_create ?bandwidth ?extra_debug ?extra_env password
match password with
| NoPassword -> cmd
| AskForPassword ->
- Nbdkit.add_arg cmd "password" "-"
+ (* Because we will start nbdkit in the background and then wait
+ * for 30 seconds for it to start up, we cannot use the
+ * password=- feature of nbdkit to read the password
+ * interactively (since in the words of the movie the user has
+ * only "30 seconds to comply"). In any case this feature broke
+ * in the VDDK plugin in nbdkit 1.18 and 1.20. So in the
+ * AskForPassword case we read the password here.
+ *)
+ printf "password: ";
+ let open Unix in
+ let orig = tcgetattr stdin in
+ let tios = { orig with c_echo = false } in
+ tcsetattr stdin TCSAFLUSH tios; (* Disable echo. *)
+ let password = read_line () in
+ tcsetattr stdin TCSAFLUSH orig; (* Restore echo. *)
+ printf "\n";
+ let password_file = Filename.temp_file "v2vnbdkit" ".txt" in
+ unlink_on_exit password_file;
+ with_open_out password_file (fun chan -> output_string chan password);
+ Nbdkit.add_arg cmd "password" ("+" ^ password_file)
| PasswordFile password_file ->
Nbdkit.add_arg cmd "password" ("+" ^ password_file) in

View File

@ -1,41 +0,0 @@
From a8f3d2b2e87aead9f6a1db66dccebb6239ddf004 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Fri, 19 Jun 2020 17:57:36 +0200
Subject: [PATCH] libosinfo: declare autocleanup funcs with libosinfo < 1.8.0
libosinfo 1.8.0 declares them automatically for all of its classes, so
there is no need to declare ours. This requires fixing the definition of
the IS_LIBOSINFO_VERSION macro to wrap its body in brackets.
While in the process, simplify the workaround for a related bug by
removing a now-useless check.
(cherry picked from commit c1caf7132000a4560c3e20c2753978e8dd10036a)
---
v2v/libosinfo-c.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/v2v/libosinfo-c.c b/v2v/libosinfo-c.c
index 1ab6bb4d..497840c2 100644
--- a/v2v/libosinfo-c.c
+++ b/v2v/libosinfo-c.c
@@ -40,12 +40,18 @@
#define V2V_LIBOSINFO_VERSION_HEX \
MAKE_VERSION_HEX(OSINFO_MAJOR_VERSION, OSINFO_MINOR_VERSION, OSINFO_MICRO_VERSION)
#define IS_LIBOSINFO_VERSION(maj, min, mic) \
- V2V_LIBOSINFO_VERSION_HEX >= MAKE_VERSION_HEX(maj, min, mic)
+ (V2V_LIBOSINFO_VERSION_HEX >= MAKE_VERSION_HEX(maj, min, mic))
+/*
+ * libosinfo 1.8.0 provides auto-cleanup functions for all its classes,
+ * so avoid declaring our own.
+ */
+#if !IS_LIBOSINFO_VERSION(1, 8, 0)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoFilter, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoLoader, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoList, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoOsList, g_object_unref)
+#endif
typedef OsinfoDb *OsinfoDb_t;
typedef OsinfoOs *OsinfoOs_t;

View File

@ -1,57 +0,0 @@
From 6aec975c07d60a2518d3f16ee91db1d03a704882 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jul 2020 14:01:48 +0100
Subject: [PATCH] v2v: Use common documentation for --keys-from-stdin.
(cherry picked from commit 3f9b5f26398694a8a496eae85525e3be5c4b9cca)
---
common | 2 +-
docs/virt-v2v.pod | 11 ++++-------
2 files changed, 5 insertions(+), 8 deletions(-)
Submodule common be42b0b8..5ea1baec:
diff --git a/common/options/Makefile.am b/common/options/Makefile.am
index b38fedc7..f7ea7493 100644
--- a/common/options/Makefile.am
+++ b/common/options/Makefile.am
@@ -19,6 +19,7 @@ include $(top_srcdir)/subdir-rules.mk
EXTRA_DIST = \
key-option.pod \
+ keys-from-stdin-option.pod \
blocksize-option.pod
# liboptions.la contains guestfish code which is used in other
diff --git a/common/options/keys-from-stdin-option.pod b/common/options/keys-from-stdin-option.pod
new file mode 100644
index 00000000..03c5339b
--- /dev/null
+++ b/common/options/keys-from-stdin-option.pod
@@ -0,0 +1,4 @@
+=item B<--keys-from-stdin>
+
+Read key or passphrase parameters from stdin. The default is
+to try to read passphrases from the user by opening F</dev/tty>.
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index a00fa8af..74934eb4 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -382,14 +382,11 @@ through VDDK.
__INCLUDE:key-option.pod__
-=item B<--keys-from-stdin>
+__INCLUDE:keys-from-stdin-option.pod__
-Read key or passphrase parameters from stdin. The default is
-to try to read passphrases from the user by opening F</dev/tty>.
-
-Note this options only applies to keys and passphrases for encrypted
-devices and partitions, not for passwords used to connect to remote
-servers.
+Note I<--keys-from-stdin> only applies to keys and passphrases for
+encrypted devices and partitions, not for passwords used to connect to
+remote servers.
=item B<--mac> aa:bb:cc:dd:ee:ffB<:network:>out

View File

@ -1,23 +0,0 @@
From 37ae5e04bd5f95c0c8a462dc6ef3fbdcfff4af75 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jul 2020 14:10:18 +0100
Subject: [PATCH] docs: Multiple keys must be supplied one per line
(RHBZ#1858765).
(cherry picked from commit 7ba65d14c0139dcf7fec45d33cee67c0f6737dd2)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 5ea1baec..9338df5e:
diff --git a/common/options/keys-from-stdin-option.pod b/common/options/keys-from-stdin-option.pod
index 03c5339b..83790394 100644
--- a/common/options/keys-from-stdin-option.pod
+++ b/common/options/keys-from-stdin-option.pod
@@ -2,3 +2,6 @@
Read key or passphrase parameters from stdin. The default is
to try to read passphrases from the user by opening F</dev/tty>.
+
+If there are multiple encrypted devices then you may need to supply
+multiple keys on stdin, one per line.

View File

@ -1,123 +0,0 @@
From fd1cbaa0907b30f639497c38953fe605bfc68ad0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Jul 2020 13:20:10 +0100
Subject: [PATCH] v2v: Check that --mac :ip: parameters are sensible
(RHBZ#1858775).
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is not a complete check since IP addresses come in many forms,
but this at least stops nonsense being written through to the Windows
firstboot script.
$ virt-v2v --mac 11:22:33:44:55:66:ip:hello,world,999,invalid -i disk test1.img -o null
virt-v2v: error: cannot parse --mac ip ipaddr: doesnt look like
“hello” is an IP address
$ virt-v2v --mac 11:22:33:44:55:66:ip:192.168.0.10,192.168.0.1,999,192.168.2.1,192.168.2.2 -i disk test1.img -o null
virt-v2v: error: --mac ip prefix length field is out of range
Thanks: Zi Liu
(cherry picked from commit e8bcf9615490447e1b53a8b0d3e9d202ab178cf0)
---
v2v/cmdline.ml | 55 ++++++++++++++++++++++++++++++++------------------
1 file changed, 35 insertions(+), 20 deletions(-)
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 249137ab..3b74f307 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -47,6 +47,7 @@ type cmdline = {
(* Matches --mac command line parameters. *)
let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)"
+let mac_ip_re = PCRE.compile ~anchored:true "([[:xdigit:]]|:|\\.)+"
let parse_cmdline () =
let bandwidth = ref None in
@@ -102,7 +103,7 @@ let parse_cmdline () =
let network_map = Networks.create () in
let static_ips = ref [] in
- let add_network str =
+ let rec add_network str =
match String.split ":" str with
| "", "" ->
error (f_"invalid -n/--network parameter")
@@ -110,8 +111,7 @@ let parse_cmdline () =
Networks.add_default_network network_map out
| in_, out ->
Networks.add_network network_map in_ out
- in
- let add_bridge str =
+ and add_bridge str =
match String.split ":" str with
| "", "" ->
error (f_"invalid -b/--bridge parameter")
@@ -119,8 +119,7 @@ let parse_cmdline () =
Networks.add_default_bridge network_map out
| in_, out ->
Networks.add_bridge network_map in_ out
- in
- let add_mac str =
+ and add_mac str =
if not (PCRE.matches mac_re str) then
error (f_"cannot parse --mac \"%s\" parameter") str;
let mac = PCRE.sub 1 and out = PCRE.sub 3 in
@@ -130,24 +129,40 @@ let parse_cmdline () =
| "bridge" ->
Networks.add_mac network_map mac Bridge out
| "ip" ->
- let add if_mac_addr if_ip_address if_default_gateway
- if_prefix_length if_nameservers =
- List.push_back static_ips
- { if_mac_addr; if_ip_address; if_default_gateway;
- if_prefix_length; if_nameservers }
- in
(match String.nsplit "," out with
- | [] ->
- error (f_"invalid --mac ip option")
- | [ip] -> add mac ip None None []
- | [ip; gw] -> add mac ip (Some gw) None []
+ | [] -> error (f_"invalid --mac ip option")
+ | [ip] -> add_static_ip mac ip None None []
+ | [ip; gw] -> add_static_ip mac ip (Some gw) None []
| ip :: gw :: len :: nameservers ->
- let len =
- try int_of_string len with
- | Failure _ -> error (f_"cannot parse --mac ip prefix length field as an integer: %s") len in
- add mac ip (Some gw) (Some len) nameservers
- );
+ add_static_ip mac ip (Some gw) (Some len) nameservers
+ )
| _ -> assert false
+ and add_static_ip if_mac_addr if_ip_address if_default_gateway
+ if_prefix_length_str if_nameservers =
+ (* Check the IP addresses and prefix length are sensible. This
+ * is only a very simple test that they are sane, since IP addresses
+ * come in too many valid forms to check thoroughly.
+ *)
+ let rec error_unless_ip_addr what addr =
+ if not (PCRE.matches mac_ip_re addr) then
+ error (f_"cannot parse --mac ip %s: doesnt look like “%s” is an IP address") what addr
+ in
+ error_unless_ip_addr "ipaddr" if_ip_address;
+ Option.may (error_unless_ip_addr "gw") if_default_gateway;
+ List.iter (error_unless_ip_addr "nameserver") if_nameservers;
+ let if_prefix_length =
+ match if_prefix_length_str with
+ | None -> None
+ | Some len ->
+ let len =
+ try int_of_string len with
+ | Failure _ -> error (f_"cannot parse --mac ip prefix length field as an integer: %s") len in
+ if len < 0 || len > 128 then
+ error (f_"--mac ip prefix length field is out of range");
+ Some len in
+ List.push_back static_ips
+ { if_mac_addr; if_ip_address; if_default_gateway;
+ if_prefix_length; if_nameservers }
in
let no_trim_warning _ =

View File

@ -1,30 +0,0 @@
From 207552533f0b4ed2e2d570a827a85a44d4248b78 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Mon, 17 Aug 2020 09:17:51 +0200
Subject: [PATCH] libvirt: read password file outside libvirt auth callback
This way errors that occur while reading the password file are properly
propagated, instead of being reported as errors of the libvirt
authentication callback.
Reported by: Ming Xie.
(cherry picked from commit 76f9f3a0603f33c85d681fe13e24516331c6aea7)
---
v2v/libvirt_utils.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/libvirt_utils.ml b/v2v/libvirt_utils.ml
index 4d0b8639..1a24b049 100644
--- a/v2v/libvirt_utils.ml
+++ b/v2v/libvirt_utils.ml
@@ -24,8 +24,8 @@ open Common_gettext.Gettext
module. *)
let auth_for_password_file ?password_file () =
+ let password = Option.map read_first_line_from_file password_file in
let auth_fn creds =
- let password = Option.map read_first_line_from_file password_file in
List.map (
function
| { Libvirt.Connect.typ = Libvirt.Connect.CredentialPassphrase } -> password

View File

@ -1,76 +0,0 @@
From d6b625021e4bc1662b796e8c2f2a646d118f9fa1 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 8: Fix tests for libguestfs-winsupport.
It doesn't let us use guestfish for arbitrary Windows edits.
---
test-data/phony-guests/make-windows-img.sh | 1 +
tests/test-v2v-virtio-win-iso.sh | 8 +++++++-
tests/test-v2v-windows-conversion.sh | 8 +++++++-
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
index 30908a91..73cf5144 100755
--- a/test-data/phony-guests/make-windows-img.sh
+++ b/test-data/phony-guests/make-windows-img.sh
@@ -37,6 +37,7 @@ fi
# Create a disk image.
guestfish <<EOF
+set-program virt-testing
sparse windows.img-t 512M
run
diff --git a/tests/test-v2v-virtio-win-iso.sh b/tests/test-v2v-virtio-win-iso.sh
index 6e99f0f1..a8e572c5 100755
--- a/tests/test-v2v-virtio-win-iso.sh
+++ b/tests/test-v2v-virtio-win-iso.sh
@@ -79,6 +79,12 @@ mktest ()
:> "$script"
:> "$expected"
+cat >> "$script" <<EOF
+ set-program virt-testing
+ run
+ mount /dev/sda2 /
+EOF
+
firstboot_dir="/Program Files/Guestfs/Firstboot"
mktest "is-dir \"$firstboot_dir\"" true
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
@@ -91,7 +97,7 @@ for drv in netkvm vioscsi viostor; do
done
done
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
diff -u "$expected" "$response"
rm -r $d
diff --git a/tests/test-v2v-windows-conversion.sh b/tests/test-v2v-windows-conversion.sh
index f1da222a..ff94fe39 100755
--- a/tests/test-v2v-windows-conversion.sh
+++ b/tests/test-v2v-windows-conversion.sh
@@ -73,6 +73,12 @@ mktest ()
:> "$script"
:> "$expected"
+cat >> "$script" <<EOF
+ set-program virt-testing
+ run
+ mount /dev/sda2 /
+EOF
+
firstboot_dir="/Program Files/Guestfs/Firstboot"
mktest "is-dir \"$firstboot_dir\"" true
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
@@ -85,7 +91,7 @@ for drv in netkvm qxl vioscsi viostor; do
done
done
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
diff -u "$expected" "$response"
# We also update the Registry several times, for firstboot, and (ONLY

View File

@ -1,283 +0,0 @@
From d55dcb095a383ff924acbfbe1c81a3a1eb4f4495 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 14 Jan 2016 11:53:42 -0500
Subject: [PATCH] RHEL 8: v2v: Disable the virt-v2v --in-place option.
This disables the virt-v2v --in-place option which we do not
wish to support in RHEL.
(See commit d0069559a939e47e5f29973ed9a69a13f0b58301).
---
docs/test-v2v-docs.sh | 1 +
docs/virt-v2v.pod | 48 +----------------
tests/Makefile.am | 2 -
tests/test-v2v-in-place.sh | 108 -------------------------------------
v2v/cmdline.ml | 8 +--
5 files changed, 7 insertions(+), 160 deletions(-)
delete mode 100755 tests/test-v2v-in-place.sh
diff --git a/docs/test-v2v-docs.sh b/docs/test-v2v-docs.sh
index dd2b1233..8fef46cc 100755
--- a/docs/test-v2v-docs.sh
+++ b/docs/test-v2v-docs.sh
@@ -27,6 +27,7 @@ $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \
--debug-overlay,\
--ic,\
--if,\
+--in-place,\
--io,\
--ip,\
--it,\
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index a19f0a73..6f9f323e 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -8,10 +8,6 @@ virt-v2v - Convert a guest to use KVM
[-o mode] [other -o* options]
[guest|filename]
- virt-v2v --in-place
- [-i mode] [other -i* options]
- [guest|filename]
-
=head1 DESCRIPTION
Virt-v2v converts a single guest from a foreign hypervisor to run on
@@ -39,9 +35,6 @@ these sides of virt-v2v are documented separately in this manual.
Virt-v2v normally copies from the input to the output, called "copying
mode". In this case the source guest is always left unchanged.
-In-place conversion (I<--in-place>) only uses the I<-i*> options and
-modifies the source guest in-place. (See L</In-place conversion>
-below.)
=head2 Other virt-v2v topics
@@ -301,20 +294,6 @@ For I<-i disk> only, this specifies the format of the input disk
image. For other input methods you should specify the input
format in the metadata.
-=item B<--in-place>
-
-Do not create an output virtual machine in the target hypervisor.
-Instead, adjust the guest OS in the source VM to run in the input
-hypervisor.
-
-This mode is meant for integration with other toolsets, which take the
-responsibility of converting the VM configuration, providing for
-rollback in case of errors, transforming the storage, etc.
-
-See L</In-place conversion> below.
-
-Conflicts with all I<-o *> options.
-
=item B<-io> OPTION=VALUE
Set input option(s) related to the current input mode or transport.
@@ -1332,7 +1311,7 @@ have at least 100 available inodes.
=head3 Minimum free space check in the host
You must have sufficient free space in the host directory used to
-store temporary overlays (except in I<--in-place> mode). To find out
+store temporary overlays. To find out
which directory this is, use:
$ df -h "`guestfish get-cachedir`"
@@ -1435,31 +1414,6 @@ that instead.
</devices>
</domain>
-=head2 In-place conversion
-
-It is also possible to use virt-v2v in scenarios where a foreign VM
-has already been imported into a KVM-based hypervisor, but still needs
-adjustments in the guest to make it run in the new virtual hardware.
-
-In that case it is assumed that a third-party tool has created the
-target VM in the supported KVM-based hypervisor based on the source VM
-configuration and contents, but using virtual devices more appropriate
-for KVM (e.g. virtio storage and network, etc.).
-
-Then, to make the guest OS boot and run in the changed environment,
-one can use:
-
- virt-v2v -ic qemu:///system converted_vm --in-place
-
-Virt-v2v will analyze the configuration of C<converted_vm> in the
-C<qemu:///system> libvirt instance, and apply various fixups to the
-guest OS configuration to make it match the VM configuration. This
-may include installing virtio drivers, configuring the bootloader, the
-mountpoints, the network interfaces, and so on.
-
-Should an error occur during the operation, virt-v2v exits with an
-error code leaving the VM in an undefined state.
-
=head2 Machine readable output
The I<--machine-readable> option can be used to make the output more
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 871dc3c9..eee4e1af 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -76,7 +76,6 @@ TESTS = \
test-v2v-floppy.sh \
test-v2v-i-disk.sh \
test-v2v-i-ova.sh \
- test-v2v-in-place.sh \
test-v2v-mac.sh \
test-v2v-machine-readable.sh \
test-v2v-networks-and-bridges.sh \
@@ -225,7 +224,6 @@ EXTRA_DIST += \
test-v2v-i-vmx-3.vmx \
test-v2v-i-vmx-4.vmx \
test-v2v-i-vmx-5.vmx \
- test-v2v-in-place.sh \
test-v2v-it-vddk-io-query.sh \
test-v2v-machine-readable.sh \
test-v2v-mac-expected.xml \
diff --git a/tests/test-v2v-in-place.sh b/tests/test-v2v-in-place.sh
deleted file mode 100755
index 6f7d78f3..00000000
--- a/tests/test-v2v-in-place.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/bash -
-# libguestfs virt-v2v test script
-# Copyright (C) 2014 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 --in-place.
-
-unset CDPATH
-export LANG=C
-set -e
-
-$TEST_FUNCTIONS
-skip_if_skipped
-skip_if_backend uml
-skip_unless_phony_guest windows.img
-
-img_base="$abs_top_builddir/test-data/phony-guests/windows.img"
-
-export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools"
-export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win"
-
-d=$PWD/test-v2v-in-place.d
-rm -rf $d
-mkdir $d
-
-img="$d/test.qcow2"
-rm -f $img
-qemu-img create -f qcow2 -b $img_base -o compat=1.1,backing_fmt=raw $img
-md5="$(do_md5 $img_base)"
-
-libvirt_xml="$d/test.xml"
-rm -f $libvirt_xml
-n=windows-overlay
-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 --debug-gc -i libvirt -ic "test://$libvirt_xml" $n --in-place
-
-# Test that the drivers have been copied over into the guest
-script="$d/test.fish"
-expected="$d/expected"
-response="$d/response"
-
-mktest ()
-{
- local cmd="$1" exp="$2"
-
- echo "echo '$cmd'" >> "$script"
- echo "$cmd" >> "$expected"
-
- echo "$cmd" >> "$script"
- echo "$exp" >> "$expected"
-}
-
-:> "$script"
-:> "$expected"
-
-firstboot_dir="/Program Files/Guestfs/Firstboot"
-mktest "is-dir \"$firstboot_dir\"" true
-mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
-mktest "is-dir \"$firstboot_dir/scripts\"" true
-virtio_dir="/Windows/Drivers/VirtIO"
-mktest "is-dir \"$virtio_dir\"" true
-for drv in netkvm qxl vioscsi viostor; do
- for sfx in cat inf sys; do
- mktest "is-file \"$virtio_dir/$drv.$sfx\"" true
- done
-done
-
-guestfish --ro -a "$img" -i < "$script" > "$response"
-diff -u "$expected" "$response"
-
-# Test the base image remained untouched
-test "$md5" = "$(do_md5 $img_base)"
-
-# Clean up.
-rm -r $d
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index df69e2e0..7b79d462 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -252,8 +252,7 @@ let parse_cmdline () =
s_"Use password from file to connect to input hypervisor";
[ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport),
s_"Input transport";
- [ L"in-place" ], Getopt.Set in_place,
- s_"Only tune the guest in the input VM";
+ [ L"in-place" ], Getopt.Set in_place, Getopt.hidden_option_description;
[ L"mac" ], Getopt.String ("mac:network|bridge|ip:out", add_mac),
s_"Map NIC to network or bridge or assign static IP";
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),
@@ -396,7 +395,6 @@ read the man page virt-v2v(1).
pr "vddk\n";
pr "colours-option\n";
pr "vdsm-compat-option\n";
- pr "in-place\n";
pr "io/oo\n";
pr "mac-option\n";
pr "bandwidth-option\n";
@@ -572,6 +570,10 @@ read the man page virt-v2v(1).
error (f_"only -it ssh can be used here") in
Input_vmx.input_vmx input_password input_transport arg in
+ (* Prevent use of --in-place option in RHEL. *)
+ if in_place then
+ error (f_"--in-place cannot be used in RHEL");
+
(* Common error message. *)
let error_option_cannot_be_used_in_output_mode mode opt =
error (f_"-o %s: %s option cannot be used in this output mode") mode opt

View File

@ -1,23 +0,0 @@
From ca9e31a9ae2e9cf5df5c65955ad746ee9f8d560b 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 8: v2v: -i disk: force VNC as display (RHBZ#1372671)
The SDL output mode is not supported in RHEL 8's qemu-kvm.
---
v2v/input_disk.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml
index d146e84c..4e403003 100644
--- a/v2v/input_disk.ml
+++ b/v2v/input_disk.ml
@@ -89,7 +89,7 @@ class input_disk input_format disk = object
s_features = [ "acpi"; "apic"; "pae" ];
s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *)
s_display =
- Some { s_display_type = Window; s_keymap = None; s_password = None;
+ Some { s_display_type = VNC; s_keymap = None; s_password = None;
s_listen = LNoListen; s_port = None };
s_video = None;
s_sound = None;

View File

@ -1,86 +0,0 @@
From 4bd92b1fc4f830529b439c4a4e09281fcd9eab78 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 14 May 2018 10:16:58 +0100
Subject: [PATCH] RHEL 8: v2v: rhv-upload: Remove restriction on -oa sparse.
See: https://bugzilla.redhat.com/show_bug.cgi?id=1565681
and the v2v-devel private thread "Do we already support migration using FC?"
---
docs/virt-v2v-output-rhv.pod | 8 +-------
v2v/output_rhv_upload.ml | 10 +---------
v2v/rhv-upload-plugin.py | 4 +---
3 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/docs/virt-v2v-output-rhv.pod b/docs/virt-v2v-output-rhv.pod
index 7c9b478a..36c3676f 100644
--- a/docs/virt-v2v-output-rhv.pod
+++ b/docs/virt-v2v-output-rhv.pod
@@ -5,7 +5,7 @@ virt-v2v-output-rhv - Using virt-v2v to convert guests to oVirt or RHV
=head1 SYNOPSIS
virt-v2v [-i* options] -o rhv-upload [-oc ENGINE_URL] -os STORAGE
- [-op PASSWORD] [-of raw]
+ [-op PASSWORD]
[-oo rhv-cafile=FILE]
[-oo rhv-cluster=CLUSTER]
[-oo rhv-direct]
@@ -79,12 +79,6 @@ username is not specified then virt-v2v defaults to using
C<admin@internal> which is the typical superuser account for oVirt
instances.
-=item I<-of raw>
-
-Currently you must use I<-of raw> and you cannot use I<-oa preallocated>.
-
-These restrictions will be loosened in a future version.
-
=item I<-op> F<password-file>
A file containing a password to be used when connecting to the oVirt
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
index 5c6c2611..81896e53 100644
--- a/v2v/output_rhv_upload.ml
+++ b/v2v/output_rhv_upload.ml
@@ -135,17 +135,10 @@ let error_unless_nbdkit_compiled_with_selinux config =
error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.")
)
-(* Output sparse must be sparse. We may be able to
- * lift this limitation in future, but it requires changes on the
- * RHV side. See TODO file for details. XXX
- *)
+(* Output format must be raw. *)
let error_current_limitation required_param =
error (f_"rhv-upload: currently you must use %s. This restriction will be loosened in a future version.") required_param
-let error_unless_output_alloc_sparse output_alloc =
- if output_alloc <> Sparse then
- error_current_limitation "-oa sparse"
-
let json_optstring = function
| Some s -> JSON.String s
| None -> JSON.Null
@@ -247,7 +240,6 @@ object
error_unless_nbdkit_min_version config;
error_unless_nbdkit_python_plugin_working plugin_script;
error_unless_nbdkit_compiled_with_selinux config;
- error_unless_output_alloc_sparse output_alloc;
(* Python code prechecks. *)
let precheck_fn = tmpdir // "v2vprecheck.json" in
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
index d3e6260e..471102da 100644
--- a/v2v/rhv-upload-plugin.py
+++ b/v2v/rhv-upload-plugin.py
@@ -477,10 +477,8 @@ def create_disk(connection):
# size, based on qemu-img measure of the overlay.
initial_size=params['disk_size'],
provisioned_size=params['disk_size'],
- # XXX Ignores params['output_sparse'].
- # Handling this properly will be complex, see:
# https://www.redhat.com/archives/libguestfs/2018-March/msg00177.html
- sparse=True,
+ sparse=params['output_sparse'],
storage_domains=[
types.StorageDomain(
name=params['output_storage'],

View File

@ -1,24 +0,0 @@
From ca86a08fe00a56a21d239cb6d1ca6dc9f8ff28fa Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Sun, 16 Dec 2018 16:42:46 +0100
Subject: [PATCH] RHEL 8: use platform-python
Use the stable platform-python provided in BaseOS, instead of relying on
some arbitrary version installed by the user.
---
v2v/python_script.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/python_script.ml b/v2v/python_script.ml
index 33c5e9a2..b1ea8f9d 100644
--- a/v2v/python_script.ml
+++ b/v2v/python_script.ml
@@ -24,7 +24,7 @@ open Unix_utils
open Common_gettext.Gettext
-let python = "python3" (* Defined by PEP 394 *)
+let python = "/usr/libexec/platform-python"
type script = {
tmpdir : string; (* Temporary directory. *)

View File

@ -1,385 +0,0 @@
From 186c237ac1cb6f6830cfe2d08dfdcfdbdffab264 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 6 Apr 2020 10:19:12 +0100
Subject: [PATCH] v2v: Allow large temporary directory to be set on a global
basis.
Previously we placed large files in g#get_cachedir () (usually
/var/tmp). However the problem is this ties the libguestfs appliance
and the virt-v2v overlay files to the same location.
When virt-v2v is run in a container, or any other situation where
local storage is limited, it's helpful to be able to put the overlay
files on an externally mounted PVC, which might be using NFS and
shared between containers. But putting the libguestfs appliance on
NFS in a shared location is certainly not recommended.
This allows the two locations to be set separately:
VIRT_V2V_TMPDIR - location of large temporary files, can use NFS
and may be shared
LIBGUESTFS_CACHEDIR - location of libguestfs appliance
Another motivation for this patch is to allow more reliable cleanup of
large temporary files by an external process, as described in the
updated documentation.
Small temporary files are placed in $TMPDIR (usually /tmp). I cleaned
up some existing code which used /var/tmp for small temporaries.
(cherry picked from commit 717b808bc5cb632778973eb000600e87eaf5c31a)
---
docs/virt-v2v.pod | 27 +++++++++++++++++++--------
v2v/input_ova.ml | 4 ++--
v2v/input_vmx.ml | 3 +--
v2v/output_glance.ml | 3 +--
v2v/output_null.ml | 3 +--
v2v/output_rhv_upload.ml | 29 ++++++++++++++++-------------
v2v/parse_ova.ml | 6 ++----
v2v/python_script.ml | 12 +++---------
v2v/python_script.mli | 5 +----
v2v/utils.ml | 6 +++++-
v2v/utils.mli | 5 +++++
v2v/v2v.ml | 14 ++++++--------
12 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 6f9f323e..af69d633 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -1172,8 +1172,8 @@ possible.
=head3 Disk space
Virt-v2v places potentially large temporary files in
-C<$LIBGUESTFS_CACHEDIR> (which is F</var/tmp> if you don't set it).
-Using tmpfs is a bad idea.
+C<$VIRT_V2V_TMPDIR> (usually F</var/tmp>, see also
+L</ENVIRONMENT VARIBLES> below). Using tmpfs is a bad idea.
For each guest disk, an overlay is stored temporarily. This stores
the changes made during conversion, and is used as a cache. The
@@ -1186,12 +1186,12 @@ and output methods may use disk space, as outlined in the table below.
=item I<-i ova>
This temporarily places a full copy of the uncompressed source disks
-in C<$LIBGUESTFS_CACHEDIR> (or F</var/tmp>).
+in C<$VIRT_V2V_TMPDIR> (or F</var/tmp>).
=item I<-o glance>
This temporarily places a full copy of the output disks in
-C<$LIBGUESTFS_CACHEDIR> (or F</var/tmp>).
+C<$VIRT_V2V_TMPDIR> (or F</var/tmp>).
=item I<-o local>
@@ -1311,7 +1311,7 @@ have at least 100 available inodes.
=head3 Minimum free space check in the host
You must have sufficient free space in the host directory used to
-store temporary overlays. To find out
+store large temporary overlays. To find out
which directory this is, use:
$ df -h "`guestfish get-cachedir`"
@@ -1319,9 +1319,12 @@ which directory this is, use:
/dev/mapper/root 50G 40G 6.8G 86% /
and look under the C<Avail> column. Virt-v2v will refuse to do the
-conversion at all unless at least 1GB is available there.
+conversion at all unless at least 1GB is available there. You can
+change the directory that virt-v2v uses by setting
+C<$VIRT_V2V_TMPDIR>.
-See also L</Resource requirements> above.
+See also L</Resource requirements> above and L</ENVIRONMENT VARIABLES>
+below.
=head2 Running virt-v2v as root or non-root
@@ -1496,10 +1499,18 @@ conversion.
=over 4
+=item C<VIRT_V2V_TMPDIR>
+
=item C<LIBGUESTFS_CACHEDIR>
Location of the temporary directory used for the potentially large
-temporary overlay file. If not set, F</var/tmp> is used.
+temporary overlay file. If neither environment variable is set then
+F</var/tmp> is used.
+
+To reliably ensure large temporary files are cleaned up (for example
+in case virt-v2v crashes) you should create a randomly named directory
+under F</var/tmp>, set C<VIRT_V2V_TMPDIR> to point to this directory,
+then when virt-v2v exits remove the directory.
See the L</Disk space> section above.
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
index 5d3bece1..d78a5ce8 100644
--- a/v2v/input_ova.ml
+++ b/v2v/input_ova.ml
@@ -132,8 +132,8 @@ class input_ova ova = object
(* The spec allows the file to be gzip-compressed, in
* which case we must uncompress it into a temporary.
*)
- let temp_dir = (open_guestfs ())#get_cachedir () in
- let new_filename = Filename.temp_file ~temp_dir "ova" ".vmdk" in
+ let new_filename =
+ Filename.temp_file ~temp_dir:Utils.large_tmpdir "ova" ".vmdk" in
unlink_on_exit new_filename;
let cmd =
sprintf "zcat %s > %s" (quote filename) (quote new_filename) in
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
index f1d143e9..7a7647e5 100644
--- a/v2v/input_vmx.ml
+++ b/v2v/input_vmx.ml
@@ -389,8 +389,7 @@ and find_nics vmx =
class input_vmx input_password input_transport arg =
let tmpdir =
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "vmx." in
+ let t = Mkdtemp.temp_dir "vmx." in
rmdir_on_exit t;
t in
object
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
index 0a9e9181..e8facd0a 100644
--- a/v2v/output_glance.ml
+++ b/v2v/output_glance.ml
@@ -33,8 +33,7 @@ class output_glance () =
* to write to a temporary file. XXX
*)
let tmpdir =
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "glance." in
+ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "glance." in
rmdir_on_exit t;
t in
object
diff --git a/v2v/output_null.ml b/v2v/output_null.ml
index 3528da50..edb749ea 100644
--- a/v2v/output_null.ml
+++ b/v2v/output_null.ml
@@ -75,8 +75,7 @@ class output_null =
* the null-co device w/ a JSON URL.
*)
let tmpdir =
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "null." in
+ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "null." in
rmdir_on_exit t;
t in
object
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
index 81896e53..913992d9 100644
--- a/v2v/output_rhv_upload.ml
+++ b/v2v/output_rhv_upload.ml
@@ -148,25 +148,28 @@ class output_rhv_upload output_alloc output_conn
rhv_options =
(* Create a temporary directory which will be deleted on exit. *)
let tmpdir =
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "rhvupload." in
+ let t = Mkdtemp.temp_dir "rhvupload." in
rmdir_on_exit t;
t in
let diskid_file_of_id id = tmpdir // sprintf "diskid.%d" id in
(* Create Python scripts for precheck, vmcheck, plugin and create VM. *)
- let py_create = Python_script.create ~tmpdir in
- let precheck_script = py_create ~name:"rhv-upload-precheck.py"
- Output_rhv_upload_precheck_source.code in
- let vmcheck_script = py_create ~name:"rhv-upload-vmcheck.py"
- Output_rhv_upload_vmcheck_source.code in
- let plugin_script = py_create ~name:"rhv-upload-plugin.py"
- Output_rhv_upload_plugin_source.code in
- let createvm_script = py_create ~name:"rhv-upload-createvm.py"
- Output_rhv_upload_createvm_source.code in
- let deletedisks_script = py_create ~name:"rhv-upload-deletedisks.py"
- Output_rhv_upload_deletedisks_source.code in
+ let precheck_script =
+ Python_script.create ~name:"rhv-upload-precheck.py"
+ Output_rhv_upload_precheck_source.code in
+ let vmcheck_script =
+ Python_script.create ~name:"rhv-upload-vmcheck.py"
+ Output_rhv_upload_vmcheck_source.code in
+ let plugin_script =
+ Python_script.create ~name:"rhv-upload-plugin.py"
+ Output_rhv_upload_plugin_source.code in
+ let createvm_script =
+ Python_script.create ~name:"rhv-upload-createvm.py"
+ Output_rhv_upload_createvm_source.code in
+ let deletedisks_script =
+ Python_script.create ~name:"rhv-upload-deletedisks.py"
+ Output_rhv_upload_deletedisks_source.code in
(* JSON parameters which are invariant between disks. *)
let json_params = [
diff --git a/v2v/parse_ova.ml b/v2v/parse_ova.ml
index 0b939ac4..568ac5fa 100644
--- a/v2v/parse_ova.ml
+++ b/v2v/parse_ova.ml
@@ -71,8 +71,7 @@ let rec parse_ova ova =
if is_directory ova then ova, Directory
else (
let tmpdir =
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "ova." in
+ let t = Mkdtemp.temp_dir ~base_dir:large_tmpdir "ova." in
rmdir_on_exit t;
t in
@@ -221,8 +220,7 @@ and uncompress_head format file =
*)
and uncompressed_type format file =
let head, headlen = uncompress_head format file in
- let tmpfile, chan =
- Filename.open_temp_file "ova.file." "" in
+ let tmpfile, chan = Filename.open_temp_file "ova.file." "" in
output chan head 0 headlen;
close_out chan;
let ret = detect_file_type tmpfile in
diff --git a/v2v/python_script.ml b/v2v/python_script.ml
index b1ea8f9d..212c8e1b 100644
--- a/v2v/python_script.ml
+++ b/v2v/python_script.ml
@@ -31,15 +31,9 @@ type script = {
path : string; (* Path to script. *)
}
-let create ?(name = "script.py") ?tmpdir code =
- let tmpdir =
- match tmpdir with
- | None ->
- let base_dir = (open_guestfs ())#get_cachedir () in
- let t = Mkdtemp.temp_dir ~base_dir "v2v." in
- rmdir_on_exit t;
- t
- | Some dir -> dir in
+let create ?(name = "script.py") code =
+ let tmpdir = Mkdtemp.temp_dir "v2v." in
+ rmdir_on_exit tmpdir;
let path = tmpdir // name in
with_open_out path (fun chan -> output_string chan code);
{ tmpdir; path }
diff --git a/v2v/python_script.mli b/v2v/python_script.mli
index 6bf77e34..fdf73514 100644
--- a/v2v/python_script.mli
+++ b/v2v/python_script.mli
@@ -20,14 +20,11 @@
type script
-val create : ?name:string -> ?tmpdir:string -> string -> script
+val create : ?name:string -> string -> script
(** Create a Python script object.
The optional parameter [?name] is a hint for the name of the script.
- The optional parameter [?tmpdir] is the temporary directory to use
- (instead of creating a new one).
-
The parameter is the Python code. Usually this is
[Some_source.code] where [some_source.ml] is generated from
the Python file by [v2v/embed.sh] (see also [v2v/Makefile.am]). *)
diff --git a/v2v/utils.ml b/v2v/utils.ml
index c2940582..a6c359f0 100644
--- a/v2v/utils.ml
+++ b/v2v/utils.ml
@@ -24,6 +24,10 @@ open Std_utils
open Tools_utils
open Common_gettext.Gettext
+let large_tmpdir =
+ try Sys.getenv "VIRT_V2V_TMPDIR"
+ with Not_found -> (open_guestfs ())#get_cachedir ()
+
(* Is SELinux enabled and enforcing on the host? *)
let have_selinux =
0 = Sys.command "getenforce 2>/dev/null | grep -isq Enforcing"
@@ -114,6 +118,7 @@ let qemu_img_supports_offset_and_size () =
* file that has an offset and size.
*)
let tmp = Filename.temp_file "v2vqemuimgtst" ".img" in
+ unlink_on_exit tmp;
Unix.truncate tmp 1024;
let json = [
@@ -133,7 +138,6 @@ let qemu_img_supports_offset_and_size () =
(if verbose () then "" else " 2>&1") in
debug "%s" cmd;
let r = 0 = Sys.command cmd in
- Unix.unlink tmp;
debug "qemu-img supports \"offset\" and \"size\" in json URLs: %b" r;
r
diff --git a/v2v/utils.mli b/v2v/utils.mli
index 937e2b9b..d86ca507 100644
--- a/v2v/utils.mli
+++ b/v2v/utils.mli
@@ -18,6 +18,11 @@
(** Utilities used in virt-v2v only. *)
+val large_tmpdir : string
+(** [VIRT_V2V_TMPDIR] or [/var/tmp]. Create all large temporary files
+ such as overlays in this directory. Small temporary files can
+ use the default behaviour eg. of {!Filename.temp_file} *)
+
val have_selinux : bool
(** True if SELinux is enabled and enforcing on the host. *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 73edff2c..a58ff433 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -264,8 +264,6 @@ and set_source_networks_and_bridges cmdline source =
let nics = List.map (Networks.map cmdline.network_map) source.s_nics in
{ source with s_nics = nics }
-and overlay_dir = (open_guestfs ())#get_cachedir ()
-
(* Conversion can fail or hang if there is insufficient free space in
* the temporary directory used to store overlays on the host
* (RHBZ#1316479). Although only a few hundred MB is actually
@@ -273,12 +271,12 @@ and overlay_dir = (open_guestfs ())#get_cachedir ()
* guestfs appliance which is also stored here.
*)
and check_host_free_space () =
- let free_space = StatVFS.free_space (StatVFS.statvfs overlay_dir) in
- debug "check_host_free_space: overlay_dir=%s free_space=%Ld"
- overlay_dir free_space;
+ let free_space = StatVFS.free_space (StatVFS.statvfs large_tmpdir) in
+ debug "check_host_free_space: large_tmpdir=%s free_space=%Ld"
+ large_tmpdir free_space;
if free_space < 1_073_741_824L then
error (f_"insufficient free space in the conversion server temporary directory %s (%s).\n\nEither free up space in that directory, or set the LIBGUESTFS_CACHEDIR environment variable to point to another directory with more than 1GB of free space.\n\nSee also the virt-v2v(1) manual, section \"Minimum free space check in the host\".")
- overlay_dir (human_size free_space)
+ large_tmpdir (human_size free_space)
(* Create a qcow2 v3 overlay to protect the source image(s). *)
and create_overlays source_disks =
@@ -286,7 +284,7 @@ and create_overlays source_disks =
List.mapi (
fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
let overlay_file =
- Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
+ Filename.temp_file ~temp_dir:large_tmpdir "v2vovl" ".qcow2" in
unlink_on_exit overlay_file;
(* There is a specific reason to use the newer qcow2 variant:
@@ -823,7 +821,7 @@ and preserve_overlays overlays src_name =
List.iter (
fun ov ->
let saved_filename =
- sprintf "%s/%s-%s.qcow2" overlay_dir src_name ov.ov_sd in
+ sprintf "%s/%s-%s.qcow2" large_tmpdir src_name ov.ov_sd in
rename ov.ov_overlay_file saved_filename;
info (f_"Overlay saved as %s [--debug-overlays]") saved_filename
) overlays

View File

@ -1,31 +0,0 @@
From 82d56820db4f05711b125daf46a4777e99dbdf87 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 25 Aug 2020 08:23:52 +0100
Subject: [PATCH] v2v: -o openstack: Allow guests to be converted to UEFI
(RHBZ#1872094).
Since this output method was written the code has always been capable
of adding the hw_firmware_type = uefi image property, and this
property has been supported since at least OpenStack 12 which is years
old.
Interestingly now all of the output modes support both BIOS and UEFI.
(cherry picked from commit 5fa65a13fbbaab03cb558d0c776c17227433f1b3)
---
v2v/output_openstack.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/output_openstack.ml b/v2v/output_openstack.ml
index 179b0edf..fdc04b02 100644
--- a/v2v/output_openstack.ml
+++ b/v2v/output_openstack.ml
@@ -390,7 +390,7 @@ object
| None -> ""
| Some op -> " -op " ^ op)
- method supported_firmware = [ TargetBIOS ]
+ method supported_firmware = [ TargetBIOS; TargetUEFI ]
(* List of Cinder volume IDs. *)
val mutable volume_ids = []

View File

@ -1,41 +0,0 @@
From 358122c089d1e4df014a6821365341d3220ab6e6 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 19 Jan 2021 11:26:23 +0000
Subject: [PATCH] v2v: Fix spelling mistake in uninstall function name.
Fixes: commit 53847717fa1d0ffc2a174275badf486eb1ed6fae
(cherry picked from commit 3515c9f617271bec89962ba8a2b8c690e6df4c99)
---
v2v/convert_windows.ml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index ba26949f..f2f7b95c 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -135,7 +135,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
(* Locate and retrieve all the uninstallation commands for installed
* applications.
*)
- let unistallation_commands pretty_name matchfn extra_uninstall_string =
+ let uninstallation_commands pretty_name matchfn extra_uninstall_string =
let uninsts = ref [] in
Registry.with_hive_readonly g inspect.i_windows_software_hive
@@ -198,14 +198,14 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
*)
let extra_uninstall_string =
Some "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in
- unistallation_commands "Parallels Tools" matchfn extra_uninstall_string in
+ uninstallation_commands "Parallels Tools" matchfn extra_uninstall_string in
(* Locate and retrieve all uninstallation commands for VMware Tools. *)
let vmwaretools_uninst =
let matchfn s =
String.find s "VMware Tools" != -1
in
- unistallation_commands "VMware Tools" matchfn None in
+ uninstallation_commands "VMware Tools" matchfn None in
(*----------------------------------------------------------------------*)
(* Perform the conversion of the Windows guest. *)

View File

@ -1,134 +0,0 @@
From 9c81b523857e057b8361cbbcc4647ed02b572ca0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 19 Jan 2021 11:38:46 +0000
Subject: [PATCH] v2v: windows: Refactor uninstallation_commands function.
Simplify and shorten this function:
- Remove unnecessary use of Not_found exception and generally
simplify flow control.
- Use sprintf.
This shouldn't change what the function does.
(cherry picked from commit d48530209a79725f26d6e25101bed6f228f45e8d)
---
v2v/convert_windows.ml | 89 ++++++++++++++++++------------------------
1 file changed, 37 insertions(+), 52 deletions(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index f2f7b95c..84db742f 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -135,56 +135,41 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
(* Locate and retrieve all the uninstallation commands for installed
* applications.
*)
- let uninstallation_commands pretty_name matchfn extra_uninstall_string =
- let uninsts = ref [] in
+ let uninstallation_commands pretty_name matchfn extra_uninstall_params =
+ let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in
+ let uninstval = "UninstallString" in
+ let ret = ref [] in
- Registry.with_hive_readonly g inspect.i_windows_software_hive
- (fun reg ->
- try
- let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in
- let node =
- match Registry.get_node reg path with
- | None -> raise Not_found
- | Some node -> node in
- let uninstnodes = g#hivex_node_children node in
-
- Array.iter (
- fun { G.hivex_node_h = uninstnode } ->
- try
+ Registry.with_hive_readonly g inspect.i_windows_software_hive (
+ fun reg ->
+ match Registry.get_node reg path with
+ | None -> ()
+ | Some node ->
+ let uninstnodes = g#hivex_node_children node in
+ Array.iter (
+ fun { G.hivex_node_h = uninstnode } ->
let valueh = g#hivex_node_get_value uninstnode "DisplayName" in
- if valueh = 0L then
- raise Not_found;
-
- let dispname = g#hivex_value_string valueh in
- if not (matchfn dispname) then
- raise Not_found;
-
- let uninstval = "UninstallString" in
- let valueh = g#hivex_node_get_value uninstnode uninstval in
- if valueh = 0L then (
- let name = g#hivex_node_name uninstnode in
- warning (f_"cannot uninstall %s: registry key HKLM\\SOFTWARE\\%s\\%s with DisplayName %s doesn't contain value %s")
- pretty_name (String.concat "\\" path) name dispname uninstval;
- raise Not_found
- );
-
- let uninst = (g#hivex_value_string valueh) ^
- " /quiet /norestart /l*v+ \"%~dpn0.log\"" ^
- " REBOOT=ReallySuppress REMOVE=ALL" in
- let uninst =
- match extra_uninstall_string with
- | None -> uninst
- | Some s -> uninst ^ " " ^ s in
-
- List.push_front uninst uninsts
- with
- Not_found -> ()
- ) uninstnodes
- with
- Not_found -> ()
- );
-
- !uninsts
+ if valueh <> 0L then (
+ let dispname = g#hivex_value_string valueh in
+ if matchfn dispname then (
+ let valueh = g#hivex_node_get_value uninstnode uninstval in
+ if valueh <> 0L then (
+ let reg_cmd = g#hivex_value_string valueh in
+ let cmd =
+ sprintf "%s /quiet /norestart /l*v+ \"%%~dpn0.log\" REBOOT=ReallySuppress REMOVE=ALL %s"
+ reg_cmd extra_uninstall_params in
+ List.push_front cmd ret
+ )
+ else
+ let name = g#hivex_node_name uninstnode in
+ warning (f_"cannot uninstall %s: registry key HKLM\\SOFTWARE\\%s\\%s with DisplayName %s doesn't contain value %s")
+ pretty_name (String.concat "\\" path) name
+ dispname uninstval
+ )
+ )
+ ) uninstnodes
+ ) (* with_hive_readonly *);
+ !ret
in
(* Locate and retrieve all uninstallation commands for Parallels Tools. *)
@@ -196,16 +181,16 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
(* Without these custom Parallels-specific MSI properties the
* uninstaller still shows a no-way-out reboot dialog.
*)
- let extra_uninstall_string =
- Some "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in
- uninstallation_commands "Parallels Tools" matchfn extra_uninstall_string in
+ let extra_uninstall_params =
+ "PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in
+ uninstallation_commands "Parallels Tools" matchfn extra_uninstall_params in
(* Locate and retrieve all uninstallation commands for VMware Tools. *)
let vmwaretools_uninst =
let matchfn s =
String.find s "VMware Tools" != -1
in
- uninstallation_commands "VMware Tools" matchfn None in
+ uninstallation_commands "VMware Tools" matchfn "" in
(*----------------------------------------------------------------------*)
(* Perform the conversion of the Windows guest. *)

View File

@ -1,59 +0,0 @@
From 2bf5fc815d53e581398e787ae96444c438945ab3 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 19 Jan 2021 12:17:49 +0000
Subject: [PATCH] v2v: Replace broken VMware Tools uninstall command msiexec /i
with /x.
Fixes: https://bugzilla.redhat.com/1917760
Thanks: Chetan Nagarkar
(cherry picked from commit f7496b0a7e76a06bda8d7ec1aba36741f8cb295c)
---
v2v/convert_windows.ml | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index 84db742f..44cef5ed 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -135,7 +135,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
(* Locate and retrieve all the uninstallation commands for installed
* applications.
*)
- let uninstallation_commands pretty_name matchfn extra_uninstall_params =
+ let uninstallation_commands pretty_name matchfn modfn extra_uninstall_params =
let path = ["Microsoft"; "Windows"; "CurrentVersion"; "Uninstall"] in
let uninstval = "UninstallString" in
let ret = ref [] in
@@ -155,6 +155,7 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
let valueh = g#hivex_node_get_value uninstnode uninstval in
if valueh <> 0L then (
let reg_cmd = g#hivex_value_string valueh in
+ let reg_cmd = modfn reg_cmd in
let cmd =
sprintf "%s /quiet /norestart /l*v+ \"%%~dpn0.log\" REBOOT=ReallySuppress REMOVE=ALL %s"
reg_cmd extra_uninstall_params in
@@ -183,14 +184,22 @@ let convert (g : G.guestfs) inspect _ output rcaps static_ips =
*)
let extra_uninstall_params =
"PREVENT_REBOOT=Yes LAUNCHED_BY_SETUP_EXE=Yes" in
- uninstallation_commands "Parallels Tools" matchfn extra_uninstall_params in
+ uninstallation_commands "Parallels Tools" matchfn identity
+ extra_uninstall_params in
(* Locate and retrieve all uninstallation commands for VMware Tools. *)
let vmwaretools_uninst =
let matchfn s =
String.find s "VMware Tools" != -1
in
- uninstallation_commands "VMware Tools" matchfn "" in
+ (* VMware Tools writes the install command (MsiExec /I) into the
+ * UninstallString key in the registry, rather than the uninstall
+ * command. Try to spot this and rewrite. (RHBZ#1917760).
+ *)
+ let re1 = PCRE.compile ~caseless:true "msiexec" in
+ let re2 = PCRE.compile ~caseless:true "/i" in
+ let msifn s = if PCRE.matches re1 s then PCRE.replace re2 "/x" s else s in
+ uninstallation_commands "VMware Tools" matchfn msifn "" in
(*----------------------------------------------------------------------*)
(* Perform the conversion of the Windows guest. *)

View File

@ -1,447 +0,0 @@
From 9292a4637e8f4d534f4dde70e8e5451f61ad0162 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 19 Jan 2021 14:22:33 +0000
Subject: [PATCH] Update common/ submodule to latest upstream.
Only for RHEL AV 8.4.0, allowing this branch to be compiled
from git with libguestfs 1.44.
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 9338df5e...be09523d:
diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml
index 44995df6..5ecf7bd7 100644
--- a/common/mlcustomize/SELinux_relabel.ml
+++ b/common/mlcustomize/SELinux_relabel.ml
@@ -28,65 +28,80 @@ module G = Guestfs
let array_find a l =
List.mem a (Array.to_list l)
-let relabel (g : G.guestfs) =
- (* Is the guest using SELinux? *)
- if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
- g#is_file ~followsymlinks:true "/etc/selinux/config" then (
- (* Is setfiles / SELinux relabelling functionality available? *)
- if g#feature_available [| "selinuxrelabel" |] then (
- (* Use Augeas to parse /etc/selinux/config. *)
- g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
- (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
- ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
- g#aug_load ();
- debug_augeas_errors g;
-
- (* Get the SELinux policy name, eg. "targeted", "minimum".
- * Use "targeted" if not specified, just like libselinux does.
- *)
- let policy =
- let config_path = "/files/etc/selinux/config" in
- let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
- let keys = g#aug_ls config_path in
- if array_find selinuxtype_path keys then
- g#aug_get selinuxtype_path
- else
- "targeted" in
-
- g#aug_close ();
-
- (* Get the spec file name. *)
- let specfile =
- sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
-
- (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
- * invalid regular expression "/var/run/spice-vdagentd.\pid"
- * (instead of "\.p"). This stops setfiles from working on
- * the guest.
- *
- * Because an SELinux relabel writes all over the filesystem,
- * it seems reasonable to fix this problem in the specfile
- * at the same time. (RHBZ#1374232)
- *)
- if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
- debug "fixing invalid regular expression in %s" specfile;
- let old_specfile = specfile ^ "~" in
- g#mv specfile old_specfile;
- let content = g#read_file old_specfile in
- let content =
- String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
- g#write specfile content;
- g#copy_attributes ~all:true old_specfile specfile
- );
-
- (* Relabel everything. *)
- g#selinux_relabel ~force:true specfile "/";
-
- (* If that worked, we don't need to autorelabel. *)
+let rec relabel (g : G.guestfs) =
+ (* Is the guest using SELinux? (Otherwise this is a no-op). *)
+ if is_selinux_guest g then (
+ try
+ use_setfiles g;
+ (* That worked, so we don't need to autorelabel. *)
g#rm_f "/.autorelabel"
- )
- else (
- (* SELinux guest, but not SELinux host. Fallback to this. *)
+ with Failure _ ->
+ (* This is the fallback in case something in the setfiles
+ * method didn't work. That includes the case where a non-SELinux
+ * host is processing an SELinux guest, and other things.
+ *)
g#touch "/.autorelabel"
- )
)
+
+and is_selinux_guest g =
+ g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
+ g#is_file ~followsymlinks:true "/etc/selinux/config"
+
+and use_setfiles g =
+ (* Is setfiles / SELinux relabelling functionality available? *)
+ if not (g#feature_available [| "selinuxrelabel" |]) then
+ failwith "no selinux relabel feature";
+
+ (* Use Augeas to parse /etc/selinux/config. *)
+ g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
+ (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
+ ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
+ g#aug_load ();
+ debug_augeas_errors g;
+
+ (* Get the SELinux policy name, eg. "targeted", "minimum".
+ * Use "targeted" if not specified, just like libselinux does.
+ *)
+ let policy =
+ let config_path = "/files/etc/selinux/config" in
+ let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
+ let keys = g#aug_ls config_path in
+ if array_find selinuxtype_path keys then
+ g#aug_get selinuxtype_path
+ else
+ "targeted" in
+
+ g#aug_close ();
+
+ (* Get the spec file name. *)
+ let specfile =
+ sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
+
+ (* If the spec file doesn't exist then fall back to using
+ * autorelabel (RHBZ#1828952).
+ *)
+ if not (g#is_file ~followsymlinks:true specfile) then
+ failwith "no spec file";
+
+ (* RHEL 6.2 - 6.5 had a malformed specfile that contained the
+ * invalid regular expression "/var/run/spice-vdagentd.\pid"
+ * (instead of "\.p"). This stops setfiles from working on
+ * the guest.
+ *
+ * Because an SELinux relabel writes all over the filesystem,
+ * it seems reasonable to fix this problem in the specfile
+ * at the same time. (RHBZ#1374232)
+ *)
+ if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
+ debug "fixing invalid regular expression in %s" specfile;
+ let old_specfile = specfile ^ "~" in
+ g#mv specfile old_specfile;
+ let content = g#read_file old_specfile in
+ let content =
+ String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
+ g#write specfile content;
+ g#copy_attributes ~all:true old_specfile specfile
+ );
+
+ (* Relabel everything. *)
+ g#selinux_relabel ~force:true specfile "/"
diff --git a/common/mltools/Makefile.am b/common/mltools/Makefile.am
index 3b4172db..aea2dce9 100644
--- a/common/mltools/Makefile.am
+++ b/common/mltools/Makefile.am
@@ -95,6 +95,7 @@ libmltools_a_CPPFLAGS = \
-I$(shell $(OCAMLC) -where) \
-I$(top_srcdir)/common/utils \
-I$(top_srcdir)/lib \
+ $(INCLUDE_DIRECTORY) \
-I$(top_srcdir)/common/options \
-I$(top_srcdir)/common/mlgettext \
-I$(top_srcdir)/common/mlpcre \
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
index 12718022..d54ec581 100644
--- a/common/mltools/tools_utils.ml
+++ b/common/mltools/tools_utils.ml
@@ -679,3 +679,53 @@ let with_timeout op timeout ?(sleep = 2) fn =
loop ()
in
loop ()
+
+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_arch = g#inspect_get_arch root in
+ let guest_arch_compatible = guest_arch_compatible guest_arch in
+ if not guest_arch_compatible then (
+ match incompatible_fn with
+ | None -> ()
+ | Some fn -> fn ()
+ )
+ else (
+ (* Add a prologue to the scripts:
+ * - Pass environment variables through from the host.
+ * - Optionally send stdout and stderr to a log file so we capture
+ * all output in error messages.
+ * - Use setarch when running x86_64 host + i686 guest.
+ *)
+ let env_vars =
+ List.filter_map (
+ fun name ->
+ try Some (sprintf "export %s=%s" name (quote (Sys.getenv name)))
+ with Not_found -> None
+ ) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
+ let env_vars = String.concat "\n" env_vars ^ "\n" in
+
+ let cmd =
+ match Guestfs_config.host_cpu, guest_arch with
+ | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
+ sprintf "setarch i686 <<\"__EOCMD\"
+%s
+__EOCMD
+" cmd
+ | _ -> cmd in
+
+ let logfile_redirect =
+ match logfile with
+ | None -> ""
+ | Some logfile -> sprintf "exec >>%s 2>&1" (quote logfile) in
+
+ let cmd = sprintf "\
+%s
+%s
+%s
+" (logfile_redirect) env_vars cmd in
+
+ debug "running command:\n%s" cmd;
+ ignore (g#sh cmd)
+ )
diff --git a/common/mltools/tools_utils.mli b/common/mltools/tools_utils.mli
index ab70f583..1d1ac8a8 100644
--- a/common/mltools/tools_utils.mli
+++ b/common/mltools/tools_utils.mli
@@ -195,9 +195,8 @@ val is_btrfs_subvolume : Guestfs.guestfs -> string -> bool
(** Checks if a filesystem is a btrfs subvolume. *)
val inspect_decrypt : Guestfs.guestfs -> key_store -> unit
-(** Simple implementation of decryption: look for any [crypto_LUKS]
- partitions and decrypt them, then rescan for VGs. This only works
- for Fedora whole-disk encryption. *)
+(** Simple implementation of decryption: look for any encrypted
+ partitions and decrypt them, then rescan for VGs. *)
val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
(** [with_timeout op timeout ?sleep fn] implements a timeout loop.
@@ -212,3 +211,13 @@ val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
calls {!error} and the program exits. The error message will
contain the diagnostic string [op] to identify the operation
which timed out. *)
+
+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.
+
+ [?logfile] is an optional file in the guest to where redirect
+ stdout and stderr of the command. *)
diff --git a/common/mlutils/unix_utils-c.c b/common/mlutils/unix_utils-c.c
index 33099611..8acf0395 100644
--- a/common/mlutils/unix_utils-c.c
+++ b/common/mlutils/unix_utils-c.c
@@ -77,6 +77,7 @@ extern value guestfs_int_mllib_mkdtemp (value val_pattern);
extern value guestfs_int_mllib_realpath (value pathv);
extern value guestfs_int_mllib_statvfs_statvfs (value pathv);
extern value guestfs_int_mllib_statvfs_is_network_filesystem (value pathv);
+extern value guestfs_int_mllib_sysconf_nr_processors_online (value unitv);
/* NB: This is a "noalloc" call. */
value
@@ -368,3 +369,17 @@ guestfs_int_mllib_statvfs_is_network_filesystem (value pathv)
return Val_bool (0);
#endif
}
+
+/* NB: This is a "noalloc" call. */
+value
+guestfs_int_mllib_sysconf_nr_processors_online (value unitv)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ long n;
+
+ n = sysconf (_SC_NPROCESSORS_ONLN);
+ if (n > 0) return Val_int (n);
+#endif
+ /* Return a safe value so that callers don't need to deal with errors. */
+ return Val_int (1);
+}
diff --git a/common/mlutils/unix_utils.ml b/common/mlutils/unix_utils.ml
index 52eb824d..2bdda12a 100644
--- a/common/mlutils/unix_utils.ml
+++ b/common/mlutils/unix_utils.ml
@@ -84,3 +84,8 @@ module StatVFS = struct
external is_network_filesystem : string -> bool =
"guestfs_int_mllib_statvfs_is_network_filesystem" "noalloc"
end
+
+module Sysconf = struct
+ external nr_processors_online : unit -> int =
+ "guestfs_int_mllib_sysconf_nr_processors_online" "noalloc"
+end
diff --git a/common/mlutils/unix_utils.mli b/common/mlutils/unix_utils.mli
index 4fcea4a3..aead4df2 100644
--- a/common/mlutils/unix_utils.mli
+++ b/common/mlutils/unix_utils.mli
@@ -121,3 +121,12 @@ module StatVFS : sig
(** [is_network_filesystem path] returns true if [path] is located on
a network filesystem such as NFS or CIFS. *)
end
+
+module Sysconf : sig
+ val nr_processors_online : unit -> int
+ (** [nr_processors_online ()] returns the number of processors
+ currently online, from [sysconf (_SC_NPROCESSORS_ONLN)].
+
+ Note this never fails. In case we cannot get the number of
+ cores it returns 1. *)
+end
diff --git a/common/options/Makefile.am b/common/options/Makefile.am
index f7ea7493..162d143b 100644
--- a/common/options/Makefile.am
+++ b/common/options/Makefile.am
@@ -41,8 +41,9 @@ liboptions_la_SOURCES = \
liboptions_la_CPPFLAGS = \
-DGUESTFS_NO_DEPRECATED=1 \
-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
+ -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
-I$(top_srcdir)/lib -I$(top_builddir)/lib \
- -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
+ $(INCLUDE_DIRECTORY)
liboptions_la_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(LIBCONFIG_CFLAGS) \
diff --git a/common/options/decrypt.c b/common/options/decrypt.c
index 683cf5ed..434b7d58 100644
--- a/common/options/decrypt.c
+++ b/common/options/decrypt.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <libintl.h>
#include <error.h>
@@ -38,18 +39,18 @@
/**
* Make a LUKS map name from the partition name,
- * eg. C<"/dev/vda2" =E<gt> "luksvda2">
+ * eg. C<"/dev/vda2" =E<gt> "cryptvda2">
*/
static void
make_mapname (const char *device, char *mapname, size_t len)
{
size_t i = 0;
- if (len < 5)
+ if (len < 6)
abort ();
- strcpy (mapname, "luks");
- mapname += 4;
- len -= 4;
+ strcpy (mapname, "crypt");
+ mapname += 5;
+ len -= 5;
if (STRPREFIX (device, "/dev/"))
i = 5;
@@ -65,10 +66,8 @@ make_mapname (const char *device, char *mapname, size_t len)
}
/**
- * Simple implementation of decryption: look for any C<crypto_LUKS>
- * partitions and decrypt them, then rescan for VGs. This only works
- * for Fedora whole-disk encryption. WIP to make this work for other
- * encryption schemes.
+ * Simple implementation of decryption: look for any encrypted
+ * partitions and decrypt them, then rescan for VGs.
*/
void
inspect_do_decrypt (guestfs_h *g, struct key_store *ks)
@@ -82,12 +81,21 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks)
for (i = 0; partitions[i] != NULL; ++i) {
CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]);
- if (type && STREQ (type, "crypto_LUKS")) {
+ if (type &&
+ (STREQ (type, "crypto_LUKS") || STREQ (type, "BitLocker"))) {
+ bool is_bitlocker = STREQ (type, "BitLocker");
char mapname[32];
make_mapname (partitions[i], mapname, sizeof mapname);
#ifdef GUESTFS_HAVE_LUKS_UUID
- CLEANUP_FREE char *uuid = guestfs_luks_uuid (g, partitions[i]);
+ CLEANUP_FREE char *uuid = NULL;
+
+ /* This fails for Windows BitLocker disks because cryptsetup
+ * luksUUID cannot read a UUID (unclear if this is a limitation
+ * of the format or cryptsetup).
+ */
+ if (!is_bitlocker)
+ uuid = guestfs_luks_uuid (g, partitions[i]);
#else
const char *uuid = NULL;
#endif
@@ -97,11 +105,15 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks)
/* Try each key in turn. */
for (j = 0; keys[j] != NULL; ++j) {
- /* XXX Should we call guestfs_luks_open_ro if readonly flag
+ /* XXX Should we set GUESTFS_CRYPTSETUP_OPEN_READONLY if readonly
* is set? This might break 'mount_ro'.
*/
guestfs_push_error_handler (g, NULL, NULL);
+#ifdef GUESTFS_HAVE_CRYPTSETUP_OPEN
+ r = guestfs_cryptsetup_open (g, partitions[i], keys[j], mapname, -1);
+#else
r = guestfs_luks_open (g, partitions[i], keys[j], mapname);
+#endif
guestfs_pop_error_handler (g);
if (r == 0)
goto opened;
diff --git a/common/options/uri.c b/common/options/uri.c
index ac36bccb..6b696fc2 100644
--- a/common/options/uri.c
+++ b/common/options/uri.c
@@ -194,6 +194,7 @@ parse (const char *arg, char **path_ret, char **protocol_ret,
if (path && path[0] == '/' &&
(STREQ (uri->scheme, "gluster") ||
STREQ (uri->scheme, "iscsi") ||
+ STREQ (uri->scheme, "nbd") ||
STREQ (uri->scheme, "rbd") ||
STREQ (uri->scheme, "sheepdog")))
path++;
diff --git a/common/utils/guestfs-stringlists-utils.h b/common/utils/guestfs-stringlists-utils.h
index 0bac1587..ade3b6f3 100644
--- a/common/utils/guestfs-stringlists-utils.h
+++ b/common/utils/guestfs-stringlists-utils.h
@@ -21,7 +21,8 @@
/* stringlists-utils.c */
extern void guestfs_int_free_string_list (char **);
-extern size_t guestfs_int_count_strings (char *const *);
+extern size_t guestfs_int_count_strings (char *const *)
+ __attribute__((__nonnull__ (1)));
extern char *guestfs_int_concat_strings (char *const *);
extern char **guestfs_int_copy_string_list (char *const *);
extern char *guestfs_int_join_strings (const char *sep, char *const *);

View File

@ -1,80 +0,0 @@
From 987ddcd2ad7546212d3afed52b56f27a664624d6 Mon Sep 17 00:00:00 2001
From: Nir Soffer <nsoffer@redhat.com>
Date: Thu, 21 Jan 2021 03:40:00 +0200
Subject: [PATCH] v2v: rhv-upload-plugin: Defer imageio connection
When using vddk input with certain vmware version, qemu-img may spend
lot of time getting source image extents. If getting image extents takes
more than 60 seconds, imageio server closes the idle connection, and the
transfer will fail on the first write with:
nbdkit: python[1]: error: /var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py: pwrite: error:
Traceback (most recent call last):
File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 94, in wrapper
return func(h, *args)
File "/var/tmp/rhvupload.0OKqWA/rhv-upload-plugin.py", line 230, in pwrite
r = http.getresponse()
File "/usr/lib64/python3.6/http/client.py", line 1361, in getresponse
response.begin()
File "/usr/lib64/python3.6/http/client.py", line 311, in begin
version, status, reason = self._read_status()
File "/usr/lib64/python3.6/http/client.py", line 280, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response
This happens only when not using unix socket, for example when running
on non-ovirt host, or ovirt host from another data center, or when using
-oo rhv_direct=false
When using unix socket, we close the initial HTTPSConnection, and
created a new UnixHTTPConnection. This connection is not connected to
the server yet. When qemu-img tries to access the server, the connection
is connected automatically.
Fix the issue by closing the initial connection used to get server
options and initialize the handle, and storing a closed connection in
the handle.
Here is the flow with this change:
1. Create HTTPSConnection for getting server options
2. Close the connection[1]
3. If using unix socket, create UnixHTTPConnection.
4. Store the connection in the handle.
5. When qemu-img try to write/zero, the connection is reconnects
automatically to imageio server[2]
Tested by adding a 300 milliseconds delay in nbdkit file plugin. Due to
the way qemu-img works, this cause more than 2 minutes delay after
open() but before the first pwrite(). Without this change, the import
fails consistently when using rhv_direct=false.
[1] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L958
[2] https://github.com/python/cpython/blob/34df10a9a16b38d54421eeeaf73ec89828563be7/Lib/http/client.py#L972
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
(cherry picked from commit 1d5fc257765c444644e5bfc6525e86ff201755f0)
---
v2v/rhv-upload-plugin.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
index 471102da..7cd6dea6 100644
--- a/v2v/rhv-upload-plugin.py
+++ b/v2v/rhv-upload-plugin.py
@@ -117,6 +117,15 @@ def open(readonly):
destination_url = parse_transfer_url(transfer)
http = create_http(destination_url)
options = get_options(http, destination_url)
+
+ # Close the initial connection to imageio server. When qemu-img will
+ # try to access the server, HTTPConnection will reconnect
+ # automatically. If we keep this connection idle and qemu-img is too
+ # slow getting image extents, imageio server may close the connection,
+ # and the import will fail on the first write.
+ # See https://bugzilla.redhat.com/1916176.
+ http.close()
+
http = optimize_http(http, host, options)
except:
cancel_transfer(connection, transfer)

View File

@ -1,34 +0,0 @@
From 88429f56491ed0e5b3f5f91e6e352fa1251484bc Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 30 Nov 2020 08:55:34 +0000
Subject: [PATCH] v2v: windows: Fix schtasks /SD parameter.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Thanks: Dinesh Herath, Tomáš Golembiovský, Bryan Kinney, Mark Zealey
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1895323
(cherry picked from commit b65711c9293415f671d35d0e2f9b55a74343da45)
---
v2v/convert_windows.ml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index 44cef5ed..4d844e2d 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -422,11 +422,12 @@ popd
and configure_qemu_ga files =
List.iter (
fun msi_path ->
+ (* Windows is a trashfire. https://stackoverflow.com/a/18730884 *)
let fb_script = sprintf "\
echo Removing any previously scheduled qemu-ga installation
schtasks.exe /Delete /TN Firstboot-qemu-ga /F
echo Scheduling delayed installation of qemu-ga from %s
-powershell.exe -command \"$d = (get-date).AddSeconds(120); schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString('MM/dd/yyyy') /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\\\"\"
+powershell.exe -command \"$d = (get-date).AddSeconds(120); $FormatHack = ($([System.Globalization.DateTimeFormatInfo]::CurrentInfo.ShortDatePattern) -replace 'M+/', 'MM/') -replace 'd+/', 'dd/'; schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString($FormatHack) /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn