diff --git a/SOURCES/0034-Update-common-submodule.patch b/SOURCES/0034-Update-common-submodule.patch new file mode 100644 index 0000000..f36532d --- /dev/null +++ b/SOURCES/0034-Update-common-submodule.patch @@ -0,0 +1,31 @@ +From b9259a577edf5532d936af491afd8789e5f7d874 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 diff --git a/SOURCES/0035-build-Remove-with-virt-v2v-nbdkit-python-plugin.patch b/SOURCES/0035-build-Remove-with-virt-v2v-nbdkit-python-plugin.patch new file mode 100644 index 0000000..6818a56 --- /dev/null +++ b/SOURCES/0035-build-Remove-with-virt-v2v-nbdkit-python-plugin.patch @@ -0,0 +1,128 @@ +From d42726148753250e741b030a1aff09310fb9938a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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= +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" diff --git a/SOURCES/0036-build-Use-nbdcopy-and-nbdinfo-from-.-configure.patch b/SOURCES/0036-build-Use-nbdcopy-and-nbdinfo-from-.-configure.patch new file mode 100644 index 0000000..b08b629 --- /dev/null +++ b/SOURCES/0036-build-Use-nbdcopy-and-nbdinfo-from-.-configure.patch @@ -0,0 +1,86 @@ +From 52bbbfed912b723f5a4618571fbab57cd9d459b7 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. *) diff --git a/SOURCES/0037-v2v-Use-nbdcopy-blkhash-in-verbose-mode.patch b/SOURCES/0037-v2v-Use-nbdcopy-blkhash-in-verbose-mode.patch new file mode 100644 index 0000000..7381bdc --- /dev/null +++ b/SOURCES/0037-v2v-Use-nbdcopy-blkhash-in-verbose-mode.patch @@ -0,0 +1,78 @@ +From 7d36586c5a299ecf17ef241063988bc1b9ace2bb Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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";*) + diff --git a/SOURCES/0038-v2v-Print-nbdcopy-command-in-debug-output.patch b/SOURCES/0038-v2v-Print-nbdcopy-command-in-debug-output.patch new file mode 100644 index 0000000..445d174 --- /dev/null +++ b/SOURCES/0038-v2v-Print-nbdcopy-command-in-debug-output.patch @@ -0,0 +1,35 @@ +From 193ed2a762bf3182d760370739c7add83e89f21c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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). *) diff --git a/SOURCES/0039-lib-libvirt_utils.ml-Turn-live-domain-error-into-a-w.patch b/SOURCES/0039-lib-libvirt_utils.ml-Turn-live-domain-error-into-a-w.patch new file mode 100644 index 0000000..c89741a --- /dev/null +++ b/SOURCES/0039-lib-libvirt_utils.ml-Turn-live-domain-error-into-a-w.patch @@ -0,0 +1,57 @@ +From cd55bd8d160cdcdfe21aaafc15f7a1cefee98b85 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 = diff --git a/SOURCES/0040-convert-flush-output-after-printing-debug-informatio.patch b/SOURCES/0040-convert-flush-output-after-printing-debug-informatio.patch new file mode 100644 index 0000000..5245a3a --- /dev/null +++ b/SOURCES/0040-convert-flush-output-after-printing-debug-informatio.patch @@ -0,0 +1,24 @@ +From 43dc900cee261bf5b090d63745b2ddcee6590583 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 } = diff --git a/SOURCES/0041-convert-Print-more-readable-mountpoint-stats.patch b/SOURCES/0041-convert-Print-more-readable-mountpoint-stats.patch new file mode 100644 index 0000000..3f8a1ef --- /dev/null +++ b/SOURCES/0041-convert-Print-more-readable-mountpoint-stats.patch @@ -0,0 +1,69 @@ +From d382827a7342a9ee9835d95ed86f864c960d8c71 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 diff --git a/SOURCES/0042-input-Remove-usage-of-nbdkit-cacheextents-filter.patch b/SOURCES/0042-input-Remove-usage-of-nbdkit-cacheextents-filter.patch new file mode 100644 index 0000000..9dfbf06 --- /dev/null +++ b/SOURCES/0042-input-Remove-usage-of-nbdkit-cacheextents-filter.patch @@ -0,0 +1,97 @@ +From 212beda84cd9366b65f73d71664f1a2aaeafc9f8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. diff --git a/SOURCES/0043-input-Document-my-findings-with-nbdkit-noextents-fil.patch b/SOURCES/0043-input-Document-my-findings-with-nbdkit-noextents-fil.patch new file mode 100644 index 0000000..4c1fb1a --- /dev/null +++ b/SOURCES/0043-input-Document-my-findings-with-nbdkit-noextents-fil.patch @@ -0,0 +1,55 @@ +From 65a9c8ed09f4cd04ae2176b48c4c9c1f69b08399 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. diff --git a/SOURCES/0044-input-Add-undocumented-io-vddk-noextents-true-option.patch b/SOURCES/0044-input-Add-undocumented-io-vddk-noextents-true-option.patch new file mode 100644 index 0000000..2ce4bd3 --- /dev/null +++ b/SOURCES/0044-input-Add-undocumented-io-vddk-noextents-true-option.patch @@ -0,0 +1,95 @@ +From 7ba9e7322e5828686fee9e71d7ffa17fe406c28a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 -> diff --git a/SOURCES/0045-v2v-Remove-vddk-vdsm-compressed-qemu-boot-compat-opt.patch b/SOURCES/0045-v2v-Remove-vddk-vdsm-compressed-qemu-boot-compat-opt.patch new file mode 100644 index 0000000..65c654a --- /dev/null +++ b/SOURCES/0045-v2v-Remove-vddk-vdsm-compressed-qemu-boot-compat-opt.patch @@ -0,0 +1,136 @@ +From 510f8a451723303d2af527e66c73ff18a03330e8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 diff --git a/SOURCES/0046-v2v-Remove-no-trim-and-vmtype-options.patch b/SOURCES/0046-v2v-Remove-no-trim-and-vmtype-options.patch new file mode 100644 index 0000000..9dfdb65 --- /dev/null +++ b/SOURCES/0046-v2v-Remove-no-trim-and-vmtype-options.patch @@ -0,0 +1,87 @@ +From 0fab89ac2c144dc521b9b2cd803801cdbb94fb5c Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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. *) diff --git a/SOURCES/0047-v2v-Remove-password-file-option.patch b/SOURCES/0047-v2v-Remove-password-file-option.patch new file mode 100644 index 0000000..0d0b422 --- /dev/null +++ b/SOURCES/0047-v2v-Remove-password-file-option.patch @@ -0,0 +1,49 @@ +From ce1525716b247b0c8eec8a9f0adb2c4009dcdf23 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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, diff --git a/SOURCES/0048-input-nbdkit_vddk.ml-Rename-path-parameter-to-file.patch b/SOURCES/0048-input-nbdkit_vddk.ml-Rename-path-parameter-to-file.patch new file mode 100644 index 0000000..0c3d60c --- /dev/null +++ b/SOURCES/0048-input-nbdkit_vddk.ml-Rename-path-parameter-to-file.patch @@ -0,0 +1,59 @@ +From 63c3d929e947a3c7a37dafd6ba188f38ef8a2bd0 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 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 diff --git a/SOURCES/0049-input-Add-io-vddk-file-.-option.patch b/SOURCES/0049-input-Add-io-vddk-file-.-option.patch new file mode 100644 index 0000000..88bdca2 --- /dev/null +++ b/SOURCES/0049-input-Add-io-vddk-file-.-option.patch @@ -0,0 +1,193 @@ +From fb8a4d851946677d5c79afb575267f17a8b649a5 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 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 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 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 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 diff --git a/SOURCES/0050-inspector-Simplify-input-bandwidth-code.patch b/SOURCES/0050-inspector-Simplify-input-bandwidth-code.patch new file mode 100644 index 0000000..efb8d3a --- /dev/null +++ b/SOURCES/0050-inspector-Simplify-input-bandwidth-code.patch @@ -0,0 +1,40 @@ +From 8e3d1747271cdf112d05e099302de7520f7f8111 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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; diff --git a/SOURCES/0051-docs-Rearrange-root-titles.patch b/SOURCES/0051-docs-Rearrange-root-titles.patch new file mode 100644 index 0000000..bdc223b --- /dev/null +++ b/SOURCES/0051-docs-Rearrange-root-titles.patch @@ -0,0 +1,49 @@ +From e1b9a34aa4e140d3fafea4d0883d0c29fcc204bb Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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> 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> ++=item B<--root> /dev/sdX ++ ++=item B<--root> /dev/VG/LV ++ ++Name a specific root device to convert, eg. S> + 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. diff --git a/SOURCES/0052-docs-Clarify-root-first-documentation.patch b/SOURCES/0052-docs-Clarify-root-first-documentation.patch new file mode 100644 index 0000000..c774bac --- /dev/null +++ b/SOURCES/0052-docs-Clarify-root-first-documentation.patch @@ -0,0 +1,39 @@ +From bd20b2429f04d8c7b37fbcce243687413dbe434f Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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> 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 to inspect the guest and then specify which ++root you want to convert. + + =item B<--root> /dev/sdX + diff --git a/SOURCES/0053-docs-Remove-old-paragraph-about-a-bug-in-Grub.patch b/SOURCES/0053-docs-Remove-old-paragraph-about-a-bug-in-Grub.patch new file mode 100644 index 0000000..8a1a7ff --- /dev/null +++ b/SOURCES/0053-docs-Remove-old-paragraph-about-a-bug-in-Grub.patch @@ -0,0 +1,30 @@ +From 26d2ba8c21fefb14b6ad2efb380ef08bff0b3b46 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 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> diff --git a/SOURCES/0054-Add-new-virt-v2v-open-tool.patch b/SOURCES/0054-Add-new-virt-v2v-open-tool.patch new file mode 100644 index 0000000..cbda6ff --- /dev/null +++ b/SOURCES/0054-Add-new-virt-v2v-open-tool.patch @@ -0,0 +1,1016 @@ +From 99e27f9670f7e0e6416bf76074ebd84bd3315c6b Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 30 Apr 2025 12:47:30 +0100 +Subject: [PATCH] Add new virt-v2v-open tool + +This can be used to open the virt-v2v input method and run an almost +arbitrary program on it. For example you can run virt-inspector to +inspect the input (eg. to find root devices and other information for +the virt-v2v --root option), or guestfish. + +Currently this only opens the input read-only, although read-write +access might be added in future. + +Suggested-by: Martin Necas +Fixes: https://issues.redhat.com/browse/RHEL-88985 +(cherry picked from commit cb7d1cd1cf1e6e29e9945227aff3162e3cc9fb6a) +--- + .gitignore | 3 + + Makefile.am | 4 +- + configure.ac | 1 + + docs/Makefile.am | 15 ++ + docs/virt-v2v-open.pod | 183 +++++++++++++++++++++ + docs/virt-v2v.pod | 9 +- + open/Makefile.am | 126 +++++++++++++++ + open/dummy.c | 2 + + open/open.ml | 298 +++++++++++++++++++++++++++++++++++ + open/open.mli | 19 +++ + run.in | 1 + + tests/Makefile.am | 4 + + tests/test-open-encrypted.sh | 56 +++++++ + tests/test-open.sh | 77 +++++++++ + 14 files changed, 795 insertions(+), 3 deletions(-) + create mode 100644 docs/virt-v2v-open.pod + create mode 100644 open/Makefile.am + create mode 100644 open/dummy.c + create mode 100644 open/open.ml + create mode 100644 open/open.mli + create mode 100755 tests/test-open-encrypted.sh + create mode 100755 tests/test-open.sh + +diff --git a/.gitignore b/.gitignore +index 9dcd4611..f86caaee 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -52,6 +52,7 @@ Makefile.in + /docs/virt-v2v-input-vmware.1 + /docs/virt-v2v-input-xen.1 + /docs/virt-v2v-inspector.1 ++/docs/virt-v2v-open.1 + /docs/virt-v2v-output-local.1 + /docs/virt-v2v-output-openstack.1 + /docs/virt-v2v-output-rhv.1 +@@ -84,6 +85,8 @@ Makefile.in + /missing + /ocaml-dep.sh + /ocaml-link.sh ++/open/.depend ++/open/virt-v2v-open + /output/.depend + /output/oUnit-anon.cache + /output/output_rhv_upload_*_source.ml +diff --git a/Makefile.am b/Makefile.am +index 4cc87324..dcbde1b5 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -44,6 +44,7 @@ SUBDIRS += convert + SUBDIRS += v2v + SUBDIRS += inspector + SUBDIRS += in-place ++SUBDIRS += open + + SUBDIRS += tests + +@@ -112,7 +113,8 @@ po/POTFILES: configure.ac + po/POTFILES-ml: configure.ac + rm -f $@ $@-t + cd $(srcdir); \ +- find common/ml* lib in-place input inspector output v2v -name '*.ml' | \ ++ find common/ml* lib in-place input inspector open output v2v \ ++ -name '*.ml' | \ + grep -v '^common/mlprogress/' | \ + grep -v '^common/mlvisit/' | \ + grep -v '^lib/config.ml$$' | \ +diff --git a/configure.ac b/configure.ac +index a99bcb75..e1e01742 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -145,6 +145,7 @@ AC_CONFIG_FILES([Makefile + inspector/Makefile + lib/Makefile + lib/config.ml ++ open/Makefile + output/Makefile + po-docs/Makefile + po-docs/ja/Makefile +diff --git a/docs/Makefile.am b/docs/Makefile.am +index d86349f4..d3547b4d 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -25,6 +25,7 @@ EXTRA_DIST = \ + virt-v2v-input-vmware.pod \ + virt-v2v-input-xen.pod \ + virt-v2v-inspector.pod \ ++ virt-v2v-open.pod \ + virt-v2v-output-local.pod \ + virt-v2v-output-openstack.pod \ + virt-v2v-output-rhv.pod \ +@@ -45,6 +46,7 @@ man_MANS = \ + virt-v2v-input-vmware.1 \ + virt-v2v-input-xen.1 \ + virt-v2v-inspector.1 \ ++ virt-v2v-open.1 \ + virt-v2v-output-local.1 \ + virt-v2v-output-openstack.1 \ + virt-v2v-output-rhv.1 \ +@@ -62,6 +64,7 @@ noinst_DATA = \ + $(top_builddir)/website/virt-v2v-input-vmware.1.html \ + $(top_builddir)/website/virt-v2v-input-xen.1.html \ + $(top_builddir)/website/virt-v2v-inspector.1.html \ ++ $(top_builddir)/website/virt-v2v-open.1.html \ + $(top_builddir)/website/virt-v2v-output-local.1.html \ + $(top_builddir)/website/virt-v2v-output-openstack.1.html \ + $(top_builddir)/website/virt-v2v-output-rhv.1.html \ +@@ -142,6 +145,18 @@ stamp-virt-v2v-inspector.pod: virt-v2v-inspector.pod + $< + touch $@ + ++virt-v2v-open.1 $(top_builddir)/website/virt-v2v-open.1.html: stamp-virt-v2v-open.pod ++ ++stamp-virt-v2v-open.pod: virt-v2v-open.pod ++ $(PODWRAPPER) \ ++ --man virt-v2v-open.1 \ ++ --html $(top_builddir)/website/virt-v2v-open.1.html \ ++ --path $(top_srcdir)/common/options \ ++ --license GPLv2+ \ ++ --warning safe \ ++ $< ++ touch $@ ++ + virt-v2v-output-local.1 $(top_builddir)/website/virt-v2v-output-local.1.html: stamp-virt-v2v-output-local.pod + + stamp-virt-v2v-output-local.pod: virt-v2v-output-local.pod +diff --git a/docs/virt-v2v-open.pod b/docs/virt-v2v-open.pod +new file mode 100644 +index 00000000..660ac83e +--- /dev/null ++++ b/docs/virt-v2v-open.pod +@@ -0,0 +1,183 @@ ++=head1 NAME ++ ++virt-v2v-open - Open the virt-v2v input and run a program on it ++ ++=head1 SYNOPSIS ++ ++ virt-v2v-open [-i* options] guest --run 'program [--options] @@' ++ ++ virt-v2v-open -i disk guest.img --run 'virt-inspector --format=raw @@' ++ ++ virt-v2v-open -i disk guest.img --run 'guestfish --ro --format=raw @@ -i' ++ ++=head1 DESCRIPTION ++ ++Virt-v2v-open is a companion tool for L and ++L which can be used before conversion to open ++the input side of virt-v2v and run a program. ++ ++Some uses for this include running L directly on ++the source guest to find source operating systems (to use with the ++virt-v2v I<--root> option). Or running guestfish to take a look ++inside the source guest before conversion. You can follow that by ++running L to estimate how much space would be ++needed to convert that guest, and if conversion of the guest is ++possible. ++ ++This manual page only documents the program options, not all of the ++I<-i*> options which are the same as virt-v2v. You should read ++L first. ++ ++Notes: ++ ++=over 4 ++ ++=item * ++ ++The source guest is always opened read-only. You will not be able to ++make persistent changes. ++ ++=item * ++ ++L can be used directly on local disk images. ++ ++=back ++ ++=head2 Selecting the input guest ++ ++You can run virt-v2v-open with the same I<-i*> options as virt-v2v. ++(Don't use any I<-o*> options). This will select the guest that you ++want to open. ++ ++=head2 Running the program ++ ++On the command line, put the program that you want to run on the ++source guest and any other parameters that program needs into the ++I<--run> parameter. C<@@> in the parameter is substituted with ++I<-a DISK ...> for each source disk, in a way which is compatible with ++L and L. ++ ++ virt-v2v-open [-i ...] guest \ ++ --run 'virt-inspector --format=raw @@ > output.xml' ++ ++ virt-v2v-open [-i ...] guest \ ++ --run 'guestfish --ro --format=raw @@ -i' ++ ++ virt-v2v-open [-i ...] guest \ ++ --run 'guestfish --ro --format=raw @@ run : list-filesystems' ++ ++=head1 OPTIONS ++ ++=over 4 ++ ++=item B<--help> ++ ++Display help. ++ ++=item B<-v> ++ ++=item B<--verbose> ++ ++Enable verbose messages for debugging. ++ ++=item B<-V> ++ ++=item B<--version> ++ ++Display version number and exit. ++ ++=item B<-x> ++ ++Enable tracing of libguestfs API calls. ++ ++=item B<-i> ... ++ ++=item B<-ic> ... ++ ++=item B<-if> ... ++ ++=item B<-io> ... ++ ++=item B<-ip> ... ++ ++=item B<-it> ... ++ ++All of the I<-i*> options supported by virt-v2v are also supported by ++virt-v2v-open. ++ ++=item B<--colors> ++ ++=item B<--colours> ++ ++=item B<--machine-readable> ++ ++=item B<--machine-readable>=format ++ ++=item B<-q> ++ ++=item B<--quiet> ++ ++=item B<--wrap> ++ ++These options work in the same way as the equivalent virt-v2v options. ++ ++=item B<--run> COMMAND ++ ++The command that you want to run on the source guest. C<@@> in the ++command is substituted with a list of I<-a DISK> options that is ++compatible with virt-inspector and guestfish. ++ ++=back ++ ++=head1 FILES ++ ++Files used are the same as for virt-v2v. See L. ++ ++=head1 ENVIRONMENT VARIABLES ++ ++Environment variables used are the same as for virt-v2v. See ++L. ++ ++=head1 SEE ALSO ++ ++L, ++L, ++L, ++L, ++L, ++L, ++L, ++L, ++L. ++ ++=head1 AUTHORS ++ ++Matthew Booth ++ ++Cédric Bosdonnat ++ ++Laszlo Ersek ++ ++Tomáš Golembiovský ++ ++Shahar Havivi ++ ++Richard W.M. Jones ++ ++Roman Kagan ++ ++Mike Latimer ++ ++Nir Soffer ++ ++Pino Toscano ++ ++Xiaodai Wang ++ ++Ming Xie ++ ++Tingting Zheng ++ ++=head1 COPYRIGHT ++ ++Copyright (C) 2009-2025 Red Hat Inc. +diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod +index d65e13ed..b946758c 100644 +--- a/docs/virt-v2v.pod ++++ b/docs/virt-v2v.pod +@@ -784,6 +784,9 @@ Windows Recovery Console, certain attached DVD drives, and bugs in + libguestfs inspection heuristics, can make a guest look like a + multi-boot operating system. + ++Either L or L can be used to list ++the roots for a dual-boot or multi-boot VM. ++ + The default in virt-v2v E 0.7.1 was S>, which + causes virt-v2v to die if a multi-boot operating system is found. + +@@ -798,8 +801,8 @@ 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 to inspect the guest and then specify which +-root you want to convert. ++L and L to inspect the guest and ++then specify which root you want to convert. + + =item B<--root> /dev/sdX + +@@ -1670,9 +1673,11 @@ L, + L, ++L, + L, + L, + L, ++L, + L, + L, + L, +diff --git a/open/Makefile.am b/open/Makefile.am +new file mode 100644 +index 00000000..e904eec9 +--- /dev/null ++++ b/open/Makefile.am +@@ -0,0 +1,126 @@ ++# libguestfs virt-v2v-open tool ++# Copyright (C) 2009-2025 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 = \ ++ $(SOURCES_MLI) \ ++ $(SOURCES_ML) \ ++ $(SOURCES_C) ++ ++SOURCES_MLI = \ ++ open.mli ++ ++SOURCES_ML = \ ++ open.ml ++ ++SOURCES_C = \ ++ dummy.c ++ ++bin_PROGRAMS = virt-v2v-open ++ ++virt_v2v_open_SOURCES = $(SOURCES_C) ++virt_v2v_open_CPPFLAGS = \ ++ -DCAML_NAME_SPACE \ ++ -I. \ ++ -I$(top_builddir) \ ++ -I$(shell $(OCAMLC) -where) \ ++ -I$(top_srcdir)/lib ++virt_v2v_open_CFLAGS = \ ++ -pthread \ ++ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ ++ $(LIBGUESTFS_CFLAGS) \ ++ $(LIBVIRT_CFLAGS) ++ ++BOBJECTS = $(SOURCES_ML:.ml=.cmo) ++XOBJECTS = $(BOBJECTS:.cmo=.cmx) ++ ++OCAMLPACKAGES = \ ++ -package str,unix,guestfs,libvirt,nbd \ ++ -I $(top_builddir)/common/utils/.libs \ ++ -I $(top_builddir)/common/qemuopts/.libs \ ++ -I $(top_builddir)/gnulib/lib/.libs \ ++ -I $(top_builddir)/lib \ ++ -I $(top_builddir)/input \ ++ -I $(top_builddir)/common/mlstdutils \ ++ -I $(top_builddir)/common/mlutils \ ++ -I $(top_builddir)/common/mlgettext \ ++ -I $(top_builddir)/common/mlpcre \ ++ -I $(top_builddir)/common/mlxml \ ++ -I $(top_builddir)/common/mltools \ ++ -I $(top_builddir)/common/mlcustomize \ ++ -I $(top_builddir)/common/mldrivers ++if HAVE_OCAML_PKG_GETTEXT ++OCAMLPACKAGES += -package gettext-stub ++endif ++ ++OCAMLCLIBS = \ ++ -pthread \ ++ -lqemuopts \ ++ $(LIBGUESTFS_LIBS) \ ++ $(LIBVIRT_LIBS) \ ++ $(LIBCRYPT_LIBS) \ ++ $(LIBXML2_LIBS) \ ++ $(JSON_C_LIBS) \ ++ $(LIBOSINFO_LIBS) \ ++ $(LIBINTL) \ ++ $(LIBNBD_LIBS) \ ++ -lgnu ++ ++OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)' ++ ++if !HAVE_OCAMLOPT ++OBJECTS = $(BOBJECTS) ++else ++OBJECTS = $(XOBJECTS) ++endif ++ ++OCAMLLINKFLAGS = \ ++ mlstdutils.$(MLARCHIVE) \ ++ mlgettext.$(MLARCHIVE) \ ++ mlpcre.$(MLARCHIVE) \ ++ mlxml.$(MLARCHIVE) \ ++ mlcutils.$(MLARCHIVE) \ ++ mltools.$(MLARCHIVE) \ ++ mllibvirt.$(MLARCHIVE) \ ++ mlcustomize.$(MLARCHIVE) \ ++ mldrivers.$(MLARCHIVE) \ ++ mlv2vlib.$(MLARCHIVE) \ ++ mlinput.$(MLARCHIVE) \ ++ $(LINK_CUSTOM_OCAMLC_ONLY) ++ ++virt_v2v_open_DEPENDENCIES = \ ++ $(OBJECTS) \ ++ $(top_builddir)/input/mlinput.$(MLARCHIVE) \ ++ $(top_builddir)/lib/mlv2vlib.$(MLARCHIVE) \ ++ $(top_srcdir)/ocaml-link.sh ++virt_v2v_open_LINK = \ ++ $(top_srcdir)/ocaml-link.sh -cclib '$(OCAMLCLIBS)' -- \ ++ $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLPACKAGES) $(OCAMLLINKFLAGS) \ ++ $(OBJECTS) -o $@ ++ ++# Data directory. ++ ++virttoolsdatadir = $(datadir)/virt-tools ++ ++# Dependencies. ++.depend: \ ++ $(srcdir)/*.mli \ ++ $(srcdir)/*.ml \ ++ $(filter %.ml,$(BUILT_SOURCES)) ++ $(top_builddir)/ocaml-dep.sh $^ ++-include .depend +diff --git a/open/dummy.c b/open/dummy.c +new file mode 100644 +index 00000000..ebab6198 +--- /dev/null ++++ b/open/dummy.c +@@ -0,0 +1,2 @@ ++/* Dummy source, to be used for OCaml-based tools with no C sources. */ ++enum { foo = 1 }; +diff --git a/open/open.ml b/open/open.ml +new file mode 100644 +index 00000000..8a82b13e +--- /dev/null ++++ b/open/open.ml +@@ -0,0 +1,298 @@ ++(* virt-v2v-open ++ * Copyright (C) 2009-2025 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 Unix ++ ++open Std_utils ++open Tools_utils ++open Unix_utils ++open Common_gettext.Gettext ++open Getopt.OptionName ++ ++open Types ++open Utils ++ ++let template_rex = PCRE.compile "@@" ++ ++module G = Guestfs ++ ++let rec main () = ++ let set_string_option_once optname optref arg = ++ match !optref with ++ | Some _ -> ++ error (f_"%s option used more than once on the command line") optname ++ | None -> ++ optref := Some arg ++ in ++ ++ let input_conn = ref None in ++ let input_format = ref None in ++ let input_password = ref None in ++ let input_transport = ref None in ++ 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 ++ ) ++ in ++ ++ let input_mode = ref `Not_set in ++ let set_input_mode mode = ++ if !input_mode <> `Not_set then ++ error (f_"%s option used more than once on the command line") "-i"; ++ match mode with ++ | "disk" | "local" -> input_mode := `Disk ++ | "libvirt" -> input_mode := `Libvirt ++ | "libvirtxml" -> input_mode := `LibvirtXML ++ | "ova" -> input_mode := `OVA ++ | "vmx" -> input_mode := `VMX ++ | s -> ++ error (f_"unknown -i option: %s") s ++ in ++ ++ let command_template = ref None in ++ ++ let argspec = [ ++ [ 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), ++ s_"Libvirt URI"; ++ [ M"if" ], Getopt.String ("format", set_string_option_once "-if" input_format), ++ s_"Input format"; ++ [ M"io" ], Getopt.String ("option[=value]", set_input_option), ++ s_"Set option for input mode"; ++ [ M"ip" ], Getopt.String ("filename", set_string_option_once "-ip" input_password), ++ 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"run" ], Getopt.String ("COMMAND", set_string_option_once "--run" command_template), ++ s_"External command to run"; ++ ] in ++ ++ let args = ref [] in ++ let anon_fun s = List.push_front s args in ++ let usage_msg = ++ sprintf (f_"\ ++%s: open the virt-v2v input and run a program on it ++ ++virt-v2v-open -i disk disk.img --run 'virt-inspector --format=raw @@' ++ ++A short summary of the options is given below. For detailed help please ++read the man page virt-v2v-open(1). ++") ++ prog in ++ ++ let opthandle = create_standard_options argspec ~anon_fun ~key_opts:false ++ ~machine_readable:true usage_msg in ++ Getopt.parse opthandle.getopt; ++ ++ (* Print the version, easier than asking users to tell us. *) ++ debug "info: %s: %s %s (%s)" ++ prog Config.package_name Config.package_version_full ++ Config.host_cpu; ++ ++ (* Print the libvirt version if debugging. *) ++ if verbose () then ( ++ let major, minor, release = Libvirt_utils.libvirt_get_version () in ++ debug "info: libvirt version: %d.%d.%d" major minor release ++ ); ++ ++ (* Create the v2v directory to control conversion. *) ++ let v2vdir = create_v2v_directory () in ++ ++ (* Dereference the arguments. *) ++ let args = List.rev !args in ++ let input_conn = !input_conn in ++ let input_mode = !input_mode in ++ let input_transport = ++ match !input_transport with ++ | None -> None ++ | Some "ssh" -> Some `SSH ++ | Some "vddk" -> Some `VDDK ++ | Some transport -> ++ error (f_"unknown input transport ‘-it %s’") transport in ++ ++ let command_template = ++ match !command_template with ++ | None -> error (f_"you must supply the --run parameter") ++ | Some c -> c in ++ ++ (* No arguments and machine-readable mode? Print out some facts ++ * about what this binary supports. ++ *) ++ (match args, machine_readable () with ++ | [], Some { pr } -> ++ pr "virt-v2v-open\n"; ++ pr "libguestfs-rewrite\n"; ++ pr "colours-option\n"; ++ pr "io\n"; ++ pr "input:disk\n"; ++ pr "input:libvirt\n"; ++ pr "input:libvirtxml\n"; ++ pr "input:ova\n"; ++ pr "input:vmx\n"; ++ exit 0 ++ | _, _ -> () ++ ); ++ ++ (* Get the input module. *) ++ let (module Input_module) = ++ match input_mode with ++ | `Disk -> (module Input_disk.Disk : Input.INPUT) ++ | `LibvirtXML -> (module Input_libvirt.LibvirtXML) ++ | `OVA -> (module Input_ova.OVA) ++ | `VMX -> (module Input_vmx.VMX) ++ | `Not_set | `Libvirt -> ++ match input_conn with ++ | None -> (module Input_libvirt.Libvirt_) ++ | Some orig_uri -> ++ let { Xml.uri_server = server; uri_scheme = scheme } = ++ try Xml.parse_uri orig_uri ++ with Invalid_argument msg -> ++ error (f_"could not parse '-ic %s'. \ ++ Original error message was: %s") ++ orig_uri msg in ++ ++ match server, scheme, input_transport with ++ | None, _, _ ++ | Some "", _, _ (* Not a remote URI. *) ++ ++ | Some _, None, _ (* No scheme? *) ++ | Some _, Some "", _ -> ++ (module Input_libvirt.Libvirt_) ++ ++ (* vCenter over https. *) ++ | Some server, Some ("esx"|"gsx"|"vpx"), None -> ++ (module Input_vcenter_https.VCenterHTTPS) ++ ++ (* vCenter or ESXi using nbdkit vddk plugin *) ++ | Some server, Some ("esx"|"gsx"|"vpx"), Some `VDDK -> ++ (module Input_vddk.VDDK) ++ ++ (* Xen over SSH *) ++ | Some server, Some "xen+ssh", _ -> ++ (module Input_xen_ssh.XenSSH) ++ ++ (* Old virt-v2v also supported qemu+ssh://. However I am ++ * deliberately not supporting this in new virt-v2v. Don't ++ * use virt-v2v if a guest already runs on KVM. ++ *) ++ ++ (* Unknown remote scheme. *) ++ | 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; ++ (module Input_libvirt.Libvirt_) in ++ ++ let input_options = { ++ Input.bandwidth = None; ++ input_conn = input_conn; ++ input_format = !input_format; ++ input_options = !input_options; ++ input_password = !input_password; ++ input_transport = input_transport; ++ (* This must always be true so that we do not modify the ++ * source. This is set to [false] by in-place mode. ++ *) ++ read_only = true; ++ } in ++ ++ (* If -io ? then we want to query input options supported in this mode. *) ++ if !io_query then ( ++ Input_module.query_input_options (); ++ exit 0 ++ ); ++ ++ (* Before starting the input module, check there is sufficient ++ * free space in the temporary directory on the host. ++ *) ++ check_host_free_space (); ++ ++ (* Start the input module (runs an NBD server in the background). *) ++ message (f_"Setting up the source: %s") ++ (Input_module.to_string input_options args); ++ let source = Input_module.setup v2vdir input_options args in ++ ++ message (f_"Running external command"); ++ ++ (* We're not really doing a conversion here, but write the 'convert' ++ * file around this to tune the input module correctly. ++ *) ++ with_open_out (v2vdir // "convert") (fun _ -> ()); ++ ++ (* Get the list of input sockets (NBD endpoints), formatted as ++ * a shell-quoted list of [-a] options. ++ *) ++ let add_params = ++ List.map ( ++ fun { s_disk_id = i } -> ++ let socket = sprintf "nbd+unix://?socket=%s/in%d" v2vdir i in ++ sprintf "-a %s" (quote socket) ++ ) source.s_disks ++ |> String.concat " " in ++ ++ (* Run external program. *) ++ debug "command template: %S" command_template; ++ let cmd = PCRE.replace template_rex add_params command_template in ++ let r = shell_command cmd in ++ if r <> 0 then exit r; ++ ++ unlink (v2vdir // "convert"); ++ ++ (* Debug the v2vdir. *) ++ if verbose () then ( ++ let cmd = sprintf "ls -alZ %s 1>&2" (quote v2vdir) in ++ ignore (Sys.command cmd) ++ ); ++ ++ message (f_"Finishing off"); ++ (* As the last thing, write a file indicating success before ++ * we exit (so before we kill the helpers). The helpers may ++ * use the presence or absence of the file to determine if ++ * on-success or on-fail cleanup is required. ++ *) ++ with_open_out (v2vdir // "done") (fun _ -> ()) ++ ++(* Some input modules use large_tmpdir to unpack OVAs or store qcow2 ++ * overlays and some output modules use it to store temporary files. ++ * In addition the 500 MB guestfs appliance may be created there. ++ * (RHBZ#1316479, RHBZ#2051394) ++ *) ++and check_host_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\".") ++ large_tmpdir (human_size free_space) ++ ++let () = run_main_and_handle_errors main +diff --git a/open/open.mli b/open/open.mli +new file mode 100644 +index 00000000..9fd556f6 +--- /dev/null ++++ b/open/open.mli +@@ -0,0 +1,19 @@ ++(* virt-v2v-open ++ * Copyright (C) 2009-2025 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. ++ *) ++ ++(* Nothing is exported. *) +diff --git a/run.in b/run.in +index c75e4e0f..93a0f20f 100755 +--- a/run.in ++++ b/run.in +@@ -71,6 +71,7 @@ chcon --reference=/tmp "$b/tmp" 2>/dev/null ||: + prepend PATH "$b/v2v" + prepend PATH "$b/in-place" + prepend PATH "$b/inspector" ++prepend PATH "$b/open" + export PATH + + # This is a cheap way to find some use-after-free and uninitialized +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 4d46daf9..97393d02 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -105,6 +105,8 @@ TESTS = \ + test-oa-option-raw.sh \ + test-of-option.sh \ + test-on-option.sh \ ++ test-open.sh \ ++ test-open-encrypted.sh \ + test-print-source.sh \ + test-rhbz1232192.sh \ + test-sound.sh \ +@@ -278,6 +280,8 @@ EXTRA_DIST += \ + test-oa-option-raw.sh \ + test-of-option.sh \ + test-on-option.sh \ ++ test-open.sh \ ++ test-open-encrypted.sh \ + test-print-source.expected \ + test-print-source.sh \ + test-rhbz1232192.sh \ +diff --git a/tests/test-open-encrypted.sh b/tests/test-open-encrypted.sh +new file mode 100755 +index 00000000..1ff14c31 +--- /dev/null ++++ b/tests/test-open-encrypted.sh +@@ -0,0 +1,56 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# Copyright (C) 2014-2025 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 virt-v2v-show-roots with an encrypted guest. ++ ++unset CDPATH ++export LANG=C ++set -e ++ ++source ./functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++f=../test-data/phony-guests/fedora-luks-on-lvm.img ++requires test -f $f ++ ++requires virt-inspector --version ++ ++d=$PWD/test-open-encrypted.d ++rm -rf $d ++cleanup_fn rm -r $d ++mkdir $d ++ ++out="$d/out" ++ ++keys="--key /dev/Volume-Group/Root:key:FEDORA-Root \ ++ --key /dev/Volume-Group/Logical-Volume-1:key:FEDORA-LV1 \ ++ --key /dev/Volume-Group/Logical-Volume-2:key:FEDORA-LV2 \ ++ --key /dev/Volume-Group/Logical-Volume-3:key:FEDORA-LV3" ++ ++$VG virt-v2v-open --debug-gc -i disk $f \ ++ --run "virt-inspector --format=raw @@ $keys > $out" ++cat $out ++ ++# Expect certain elements to be present. ++grep '^' $out ++grep '' $out ++grep '/dev/mapper/luks-' $out ++grep 'fedora' $out ++grep 'fedora14' $out +diff --git a/tests/test-open.sh b/tests/test-open.sh +new file mode 100755 +index 00000000..9eddfbc7 +--- /dev/null ++++ b/tests/test-open.sh +@@ -0,0 +1,77 @@ ++#!/bin/bash - ++# libguestfs virt-v2v test script ++# Copyright (C) 2014-2025 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 virt-v2v-open + virt-inspector. ++ ++unset CDPATH ++export LANG=C ++set -e ++ ++source ./functions.sh ++set -e ++set -x ++ ++skip_if_skipped ++img="$abs_top_builddir/test-data/phony-guests/windows.img" ++requires test -s $img ++ ++requires virt-inspector --version ++ ++export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools" ++export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers" ++ ++d=$PWD/test-open.d ++rm -rf $d ++cleanup_fn rm -r $d ++mkdir $d ++ ++out="$d/out" ++ ++libvirt_xml="$d/test.xml" ++rm -f $libvirt_xml ++n=windows ++cat > $libvirt_xml < ++ ++ $n ++ 1048576 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++EOF ++ ++$VG virt-v2v-open --debug-gc -i libvirt -ic "test://$libvirt_xml" $n \ ++ --run "virt-inspector --format=raw @@ > $out" ++cat $out ++ ++# Expect certain elements to be present. ++grep '^' $out ++grep '' $out ++grep '/dev/sda2' $out ++grep 'windows' $out ++grep 'win2k22' $out diff --git a/SOURCES/0055-docs-Document-io-vddk-file-in-the-main-options-listi.patch b/SOURCES/0055-docs-Document-io-vddk-file-in-the-main-options-listi.patch new file mode 100644 index 0000000..9cc0b83 --- /dev/null +++ b/SOURCES/0055-docs-Document-io-vddk-file-in-the-main-options-listi.patch @@ -0,0 +1,25 @@ +From ca1952901efe18f8ebdbe1aecd54cd8d86d2c890 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 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 diff --git a/SOURCES/0056-vddk-Remove-io-vddk-noextents-option.patch b/SOURCES/0056-vddk-Remove-io-vddk-noextents-option.patch new file mode 100644 index 0000000..23bacc6 --- /dev/null +++ b/SOURCES/0056-vddk-Remove-io-vddk-noextents-option.patch @@ -0,0 +1,125 @@ +From 4df2b6c2f033b5122d0da5bbc50e10eebf038076 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +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 -> diff --git a/SOURCES/0057-Modify-configure_pnputil_install-script-to-check.patch b/SOURCES/0057-Modify-configure_pnputil_install-script-to-check.patch new file mode 100644 index 0000000..0529b53 --- /dev/null +++ b/SOURCES/0057-Modify-configure_pnputil_install-script-to-check.patch @@ -0,0 +1,108 @@ +From f93106129586d21c5326445b730113744d140ebd Mon Sep 17 00:00:00 2001 +From: Vadim Rozenfeld +Date: Thu, 10 Jul 2025 10:12:56 +1000 +Subject: [PATCH] Modify configure_pnputil_install script to check pending + reboot status and report PnPUtil execution status + +This change adds checks for system reboot status and reports +the result of PnPUtil driver installation attempt. + +Related: https://issues.redhat.com/browse/RHEL-100682 + +Signed-off-by: Vadim Rozenfeld + +RWMJ: +Cherry picked from commit 594b05d6940c8719167d10c0cdfaa253349060ab. +I also updated the common submodule to cherry pick +libguestfs-common commit b40e534fefb74af32bd496904e44ce9bca1a7b34 +--- + common | 2 +- + convert/convert_windows.ml | 48 +++++++++++++++++++++++++++++++++++--- + 2 files changed, 46 insertions(+), 4 deletions(-) + +Submodule common 3873d593..b48c7d00: +diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml +index 6aca4c34..5f2642b0 100644 +--- a/common/mlcustomize/firstboot.ml ++++ b/common/mlcustomize/firstboot.ml +@@ -305,13 +305,19 @@ if not exist \"%%scripts_done%%\" ( + :: Pick the next script to run. + for %%%%f in (\"%%scripts%%\"\\*.bat) do ( + echo running \"%%%%f\" +- move \"%%%%f\" \"%%scripts_done%%\" +- pushd \"%%scripts_done%%\" ++ pushd \"%%scripts%%\" + call \"%%%%~nf\" + set elvl=!errorlevel! + echo .... exit code !elvl! + popd + ++ if !elvl! NEQ 249 ( ++ echo Script succeeded, moving to scripts-done ++ move \"%%%%f\" \"%%scripts_done%%\" ++ ) else ( ++ echo Script failed, will retry on next boot ++ ) ++ + :: Reboot the computer. This is necessary to free any locked + :: files which may prevent later scripts from running. + shutdown /r /t 0 /y +diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml +index 7434ac69..a9ec276a 100644 +--- a/convert/convert_windows.ml ++++ b/convert/convert_windows.ml +@@ -396,9 +396,51 @@ let convert (g : G.guestfs) source inspect i_firmware + and configure_pnputil_install () = + let fb_script = "@echo off\n\ + \n\ +- echo Wait for VirtIO drivers to be installed\n\ +- %systemroot%\\Sysnative\\PnPutil -i -a \ +- %systemroot%\\Drivers\\Virtio\\*.inf" in ++ setlocal EnableDelayedExpansion\n\ ++ set inf_dir=%systemroot%\\Drivers\\Virtio\\\n\ ++ echo Installing drivers from %inf_dir%\n\ ++ set REBOOT_PENDING=0\n\ ++ \n\ ++ timeout /t 10 /nobreak\n\ ++ \n\ ++ reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired\"\n\ ++ if %errorlevel%==0 (\n\ ++ echo Windows Update: Reboot required.\n\ ++ set REBOOT_PENDING=1\n\ ++ )\n\ ++ \n\ ++ reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending\"\n\ ++ if %errorlevel%==0 (\n\ ++ echo CBS: Reboot required.\n\ ++ set REBOOT_PENDING=1\n\ ++ )\n\ ++ \n\ ++ reg query \"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\" /v PendingFileRenameOperations\n\ ++ if %errorlevel%==0 (\n\ ++ echo Session Manager: Reboot required.\n\ ++ set REBOOT_PENDING=1\n\ ++ )\n\ ++ \n\ ++ if \"%REBOOT_PENDING%\"==\"1\" (\n\ ++ echo A reboot is pending.\n\ ++ exit /b 249\n\ ++ ) else (\n\ ++ echo No pending reboot detected.\n\ ++ )\n\ ++ \n\ ++ for %%f in (\"%inf_dir%*.inf\") do (\n\ ++ echo Installing: %%~nxf.\n\ ++ %systemroot%\\Sysnative\\PnPutil -i -a \"%%f\"\n\ ++ if !errorlevel! NEQ 0 (\n\ ++ echo Failed to install %%~nxf.\n\ ++ exit /b 249\n\ ++ ) else (\n\ ++ echo Successfully installed %%~nxf.\n\ ++ )\n\ ++ )\n\ ++ echo All drivers installed successfully.\n\ ++ exit /b 0\n\ ++ )" in + + (* Set priority higher than that of "network-configure" firstboot script. *) + Firstboot.add_firstboot_script g inspect.i_root ~prio:2000 diff --git a/SOURCES/0058-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch b/SOURCES/0058-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch new file mode 100644 index 0000000..53a5e65 --- /dev/null +++ b/SOURCES/0058-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch @@ -0,0 +1,27 @@ +From c744f4b588ae2db333c7975d20d9ccb281d07f65 Mon Sep 17 00:00:00 2001 +From: Vadim Rozenfeld +Date: Tue, 15 Jul 2025 18:35:16 +1000 +Subject: [PATCH] Ignore ERROR_NO_MORE_ITEMS status from PnPUtil. + +This status indicates the target device already has a +better or newer driver installed. + +Signed-off-by: Vadim Rozenfeld +(cherry picked from commit e445c45d9c2b0e5411730b3e737e067e03d6316d) +--- + convert/convert_windows.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml +index a9ec276a..9b86b9a1 100644 +--- a/convert/convert_windows.ml ++++ b/convert/convert_windows.ml +@@ -431,7 +431,7 @@ let convert (g : G.guestfs) source inspect i_firmware + for %%f in (\"%inf_dir%*.inf\") do (\n\ + echo Installing: %%~nxf.\n\ + %systemroot%\\Sysnative\\PnPutil -i -a \"%%f\"\n\ +- if !errorlevel! NEQ 0 (\n\ ++ if !errorlevel! neq 0 if !errorlevel! neq 259 (\n\ + echo Failed to install %%~nxf.\n\ + exit /b 249\n\ + ) else (\n\ diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh index bca1935..8b76a26 100755 --- a/SOURCES/copy-patches.sh +++ b/SOURCES/copy-patches.sh @@ -7,7 +7,7 @@ set -e # ./copy-patches.sh project=virt-v2v -rhel_version=9.6 +rhel_version=9.7 # Check we're in the right directory. if [ ! -f $project.spec ]; then diff --git a/SPECS/virt-v2v.spec b/SPECS/virt-v2v.spec index 6b5223e..6ec8e11 100644 --- a/SPECS/virt-v2v.spec +++ b/SPECS/virt-v2v.spec @@ -8,7 +8,7 @@ Name: virt-v2v Epoch: 1 Version: 2.7.1 -Release: 5%{?dist} +Release: 15%{?dist} Summary: Convert a virtual machine to run on KVM License: GPL-2.0-or-later AND LGPL-2.0-or-later @@ -61,6 +61,31 @@ Patch0030: 0030-Update-common-submodule.patch Patch0031: 0031-convert-Use-yum-apt-.-for-package-removals-not-rpm-d.patch Patch0032: 0032-test-data-phony-fedora-Add-simple-static-bin-sh.patch Patch0033: 0033-convert-Handle-large-output-from-rpm-ql-command.patch +Patch0034: 0034-Update-common-submodule.patch +Patch0035: 0035-build-Remove-with-virt-v2v-nbdkit-python-plugin.patch +Patch0036: 0036-build-Use-nbdcopy-and-nbdinfo-from-.-configure.patch +Patch0037: 0037-v2v-Use-nbdcopy-blkhash-in-verbose-mode.patch +Patch0038: 0038-v2v-Print-nbdcopy-command-in-debug-output.patch +Patch0039: 0039-lib-libvirt_utils.ml-Turn-live-domain-error-into-a-w.patch +Patch0040: 0040-convert-flush-output-after-printing-debug-informatio.patch +Patch0041: 0041-convert-Print-more-readable-mountpoint-stats.patch +Patch0042: 0042-input-Remove-usage-of-nbdkit-cacheextents-filter.patch +Patch0043: 0043-input-Document-my-findings-with-nbdkit-noextents-fil.patch +Patch0044: 0044-input-Add-undocumented-io-vddk-noextents-true-option.patch +Patch0045: 0045-v2v-Remove-vddk-vdsm-compressed-qemu-boot-compat-opt.patch +Patch0046: 0046-v2v-Remove-no-trim-and-vmtype-options.patch +Patch0047: 0047-v2v-Remove-password-file-option.patch +Patch0048: 0048-input-nbdkit_vddk.ml-Rename-path-parameter-to-file.patch +Patch0049: 0049-input-Add-io-vddk-file-.-option.patch +Patch0050: 0050-inspector-Simplify-input-bandwidth-code.patch +Patch0051: 0051-docs-Rearrange-root-titles.patch +Patch0052: 0052-docs-Clarify-root-first-documentation.patch +Patch0053: 0053-docs-Remove-old-paragraph-about-a-bug-in-Grub.patch +Patch0054: 0054-Add-new-virt-v2v-open-tool.patch +Patch0055: 0055-docs-Document-io-vddk-file-in-the-main-options-listi.patch +Patch0056: 0056-vddk-Remove-io-vddk-noextents-option.patch +Patch0057: 0057-Modify-configure_pnputil_install-script-to-check.patch +Patch0058: 0058-Ignore-ERROR_NO_MORE_ITEMS-status-from-PnPUtil.patch %if !0%{?rhel} # libguestfs hasn't been built on i686 for a while since there is no @@ -329,6 +354,7 @@ make -C tests TESTS=test-fedora-luks-on-lvm-conversion.sh check %{_libexecdir}/virt-v2v-in-place %endif %{_bindir}/virt-v2v-inspector +%{_bindir}/virt-v2v-open %{_mandir}/man1/virt-v2v.1* %{_mandir}/man1/virt-v2v-hacking.1* %{_mandir}/man1/virt-v2v-input-vmware.1* @@ -337,6 +363,7 @@ make -C tests TESTS=test-fedora-luks-on-lvm-conversion.sh check %{_mandir}/man1/virt-v2v-in-place.1* %endif %{_mandir}/man1/virt-v2v-inspector.1* +%{_mandir}/man1/virt-v2v-open.1* %{_mandir}/man1/virt-v2v-output-local.1* %{_mandir}/man1/virt-v2v-output-openstack.1* %{_mandir}/man1/virt-v2v-output-rhv.1* @@ -362,6 +389,28 @@ make -C tests TESTS=test-fedora-luks-on-lvm-conversion.sh check %changelog +* Tue Jul 15 2025 Richard W.M. Jones - 1:2.7.1-15 +- mlcustomize: Remove dnf --verbose option + resolves: RHEL-83289 +- Print blkhash of converted image in virt-v2v debugging output + resolves: RHEL-85512 +- Print nbdcopy command in debug output + resolves: RHEL-86022 +- Turn live domain error into a warning + resolves: RHEL-88543 +- Remove usage of nbdkit-cacheextents-filter + resolves: RHEL-88857 +- Print better mountpoint stats in debug output + resolves: RHEL-88861 +- Remove several ancient, deprecated options + resolves: RHEL-88866 +- New tool: virt-v2v-open + resolves: RHEL-88985 +- Remove virt-v2v -io vddk-noextents=true option + resolves: RHEL-102618 +- Fix installation of drivers on firstboot with pending reboots + resolves: RHEL-100682 + * Tue Feb 25 2025 Richard W.M. Jones - 1:2.7.1-5 - Rebase to upstream development version 2.7.1 resolves: RHEL-56813