Update to virt-v2v-2.10.0-17

Patch series regenerated from public sources:
- https://github.com/libguestfs/virt-v2v (branch rhel-10.2)
- https://github.com/libguestfs/libguestfs-common (branch rhel-10.2-virt-v2v)
This commit is contained in:
Andrew Lukoshko 2026-06-08 12:54:36 +00:00
parent 1416614d19
commit d443c55aac
24 changed files with 1733 additions and 43 deletions

View File

@ -1,11 +1,7 @@
From 2666493010b1b82d5b8dbb517c9976727b05184f Mon Sep 17 00:00:00 2001
Message-ID: <2666493010b1b82d5b8dbb517c9976727b05184f.1770914130.git.crobinso@redhat.com>
In-Reply-To: <859c43b1eb81cfdcb5f481b571e2c387860f8a27.1770914130.git.crobinso@redhat.com>
References: <859c43b1eb81cfdcb5f481b571e2c387860f8a27.1770914130.git.crobinso@redhat.com>
From 63b2ed3a1d3381a5674ff885d28e1104814d52ef Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Wed, 11 Feb 2026 19:09:26 -0500
Subject: [PATCH] Update common submodule
Content-type: text/plain
Update to fix:
https://issues.redhat.com/browse/RHEL-148423

View File

@ -1,7 +1,4 @@
From 4e06515083d7effdee91195dbf93082e544a6283 Mon Sep 17 00:00:00 2001
Message-ID: <4e06515083d7effdee91195dbf93082e544a6283.1771345004.git.crobinso@redhat.com>
In-Reply-To: <859c43b1eb81cfdcb5f481b571e2c387860f8a27.1771345004.git.crobinso@redhat.com>
References: <859c43b1eb81cfdcb5f481b571e2c387860f8a27.1771345004.git.crobinso@redhat.com>
From 0ff94fda02a55353f6ff15ad974e12bc9e31bf3e Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Mon, 16 Feb 2026 13:58:08 -0500
Subject: [PATCH] convert: linux: properly match /etc/crypttab

View File

@ -0,0 +1,180 @@
From 0082abe25fbad04ad22f0e6a555142e93b2cdd45 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 3 Mar 2026 21:11:39 +0000
Subject: [PATCH] Update common submodule
Richard W.M. Jones (2):
mlcustomize/firstboot.ml: Be more careful about quoting
mlcustomize: Create a sentinel file when firstboot completes
Fixes: https://issues.redhat.com/browse/RHEL-152939
For RHEL 10.2:
Cherry picked from commit 45b486f5493575717bce93d00adcaefd99af0c10
For the cherry pick, we end up with this extra commit from the
submodule. This seems harmless, and better than creating a new
rhel-10.2-virt-v2v branch in the submodule.
Cole Robinson (1):
build: mark some ocaml commands with $(AM_V_GEN)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 22b583b9..cb0e19b7:
diff --git a/common/mlcustomize/Makefile.am b/common/mlcustomize/Makefile.am
index 351524c8..3bdff2a6 100644
--- a/common/mlcustomize/Makefile.am
+++ b/common/mlcustomize/Makefile.am
@@ -142,7 +142,7 @@ endif
libmlcustomize_a_DEPENDENCIES = $(OBJECTS)
$(MLCUSTOMIZE_CMA): $(OBJECTS) libmlcustomize.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmlcustomize_a_OBJECTS) -o mlcustomize
# Tests.
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index f29884c8..5e23a64b 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -271,6 +271,9 @@ module Windows = struct
(* Create a directory for firstboot scripts in the guest. *)
g#mkdir_p (firstboot_dir // "scripts");
+ (* Remove the sentinel file if it exists from a previous run. *)
+ g#rm_f (firstboot_dir // "complete");
+
(* Copy pvvxsvc or rhsrvany to the guest. *)
g#upload (virt_tools_data_dir () // srvany) (firstboot_dir // srvany);
@@ -284,11 +287,11 @@ module Windows = struct
let firstboot_script = sprintf {|@echo off
setlocal EnableDelayedExpansion
-set firstboot=%s
-set log=%%firstboot%%\log.txt
+set "firstboot=%s"
+set "log=%%firstboot%%\log.txt"
-set scripts=%%firstboot%%\scripts
-set scripts_done=%%firstboot%%\scripts-done
+set "scripts=%%firstboot%%\scripts"
+set "scripts_done=%%firstboot%%\scripts-done"
call :main >> "%%log%%" 2>&1
exit /b
@@ -327,6 +330,10 @@ for %%%%f in ("%%scripts%%"\*.bat) do (
)
:: Fallthrough here if there are no scripts.
+
+:: Touch a sentinel file to say we have finished.
+type nul > "%%firstboot%%\complete"
+
echo uninstalling firstboot service
"%%firstboot%%\%s" -s firstboot uninstall
|} firstboot_dir_win srvany in
diff --git a/common/mldrivers/Makefile.am b/common/mldrivers/Makefile.am
index 714fc9f7..aac3da4f 100644
--- a/common/mldrivers/Makefile.am
+++ b/common/mldrivers/Makefile.am
@@ -94,7 +94,7 @@ endif
libmldrivers_a_DEPENDENCIES = $(OBJECTS)
$(MLDRIVERS_CMA): $(OBJECTS) libmldrivers.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmldrivers_a_OBJECTS) -o mldrivers
# OCaml dependencies.
diff --git a/common/mlgettext/Makefile.am b/common/mlgettext/Makefile.am
index 712feb11..275b15fa 100644
--- a/common/mlgettext/Makefile.am
+++ b/common/mlgettext/Makefile.am
@@ -71,11 +71,11 @@ endif
libmlgettext_a_DEPENDENCIES = $(OBJECTS)
mlgettext.cma: $(BOBJECTS)
- $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
+ $(AM_V_GEN) $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
if HAVE_OCAMLOPT
mlgettext.cmxa: $(XOBJECTS)
- $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
+ $(AM_V_GEN) $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
endif
# Dependencies.
diff --git a/common/mlpcre/Makefile.am b/common/mlpcre/Makefile.am
index a1d8b029..30a60f64 100644
--- a/common/mlpcre/Makefile.am
+++ b/common/mlpcre/Makefile.am
@@ -83,7 +83,7 @@ endif
libmlpcre_a_DEPENDENCIES = $(OBJECTS)
$(MLPCRE_CMA): $(OBJECTS) libmlpcre.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmlpcre_a_OBJECTS) -cclib -lpcre2-8 -o mlpcre
# Tests.
diff --git a/common/mlstdutils/Makefile.am b/common/mlstdutils/Makefile.am
index b9632b07..0f881907 100644
--- a/common/mlstdutils/Makefile.am
+++ b/common/mlstdutils/Makefile.am
@@ -84,11 +84,11 @@ endif
libmlstdutils_a_DEPENDENCIES = $(OBJECTS)
mlstdutils.cma: $(BOBJECTS)
- $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
+ $(AM_V_GEN) $(OCAMLFIND) ocamlc $(OCAMLPACKAGES) -a $^ -o $@
if HAVE_OCAMLOPT
mlstdutils.cmxa: $(XOBJECTS)
- $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
+ $(AM_V_GEN) $(OCAMLFIND) ocamlopt $(OCAMLPACKAGES) -a $^ -o $@
endif
# Tests.
diff --git a/common/mltools/Makefile.am b/common/mltools/Makefile.am
index e9e0398c..44cfbb1b 100644
--- a/common/mltools/Makefile.am
+++ b/common/mltools/Makefile.am
@@ -161,7 +161,7 @@ endif
libmltools_a_DEPENDENCIES = $(OBJECTS)
$(MLTOOLS_CMA): $(OBJECTS) libmltools.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmltools_a_OBJECTS) -o mltools
# Tests.
diff --git a/common/mlutils/Makefile.am b/common/mlutils/Makefile.am
index d52cb9c8..084ce630 100644
--- a/common/mlutils/Makefile.am
+++ b/common/mlutils/Makefile.am
@@ -86,7 +86,7 @@ endif
libmlcutils_a_DEPENDENCIES = $(OBJECTS)
$(MLCUTILS_CMA): $(OBJECTS) libmlcutils.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmlcutils_a_OBJECTS) \
-cclib -lutils \
-o mlcutils
diff --git a/common/mlxml/Makefile.am b/common/mlxml/Makefile.am
index e56b6fd5..db131ab3 100644
--- a/common/mlxml/Makefile.am
+++ b/common/mlxml/Makefile.am
@@ -84,7 +84,7 @@ endif
libmlxml_a_DEPENDENCIES = $(OBJECTS)
$(MLXML_CMA): $(OBJECTS) libmlxml.a
- $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
+ $(AM_V_GEN) $(OCAMLFIND) mklib $(OCAMLPACKAGES) \
$(OBJECTS) $(libmlxml_a_OBJECTS) \
-o mlxml

View File

@ -0,0 +1,303 @@
From 78edeef5dabb46b4354d4708c4fb35901a771a23 Mon Sep 17 00:00:00 2001
From: sarika <sarika@platform9.com>
Date: Tue, 9 Dec 2025 16:12:14 +0530
Subject: [PATCH] Add --no-fstrim option to disable fstrim during conversion
In particular, fstrim on NTFS is a serialized operation which can be
very slow on large partitions.
Closes: https://github.com/libguestfs/virt-v2v/pull/121
Fixes: https://redhat.atlassian.net/browse/RHEL-164271
RWMJ: Added documentation, a test, and larger commit message.
(cherry picked from commit 251639458907f06148ecdd5acbac5c43136e7662)
(cherry picked from commit f937f290a4c032c971ad78d1b07e8aefe15eab8a)
---
convert/convert.ml | 10 ++++++--
convert/convert.mli | 1 +
docs/virt-v2v.pod | 6 +++++
in-place/in_place.ml | 5 ++++
in-place/virt-v2v-in-place.pod | 4 +++
inspector/inspector.ml | 6 +++++
inspector/virt-v2v-inspector.pod | 2 ++
tests/Makefile.am | 2 ++
tests/test-no-fstrim.sh | 44 ++++++++++++++++++++++++++++++++
v2v/v2v.ml | 6 +++++
10 files changed, 84 insertions(+), 2 deletions(-)
create mode 100755 tests/test-no-fstrim.sh
diff --git a/convert/convert.ml b/convert/convert.ml
index e3fd41b8..1c1ad2b4 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -40,6 +40,7 @@ type options = {
smp : int option;
static_ips : static_ip list;
customize_ops : Customize_cmdline.ops;
+ no_fstrim : bool;
}
(* Mountpoint stats, used for free space estimation. *)
@@ -156,8 +157,13 @@ let rec convert input_disks options source =
* because unused blocks are marked in the overlay and thus do
* not have to be copied.
*)
- message (f_"Mapping filesystem data to avoid copying unused and blank areas");
- do_fstrim g inspect;
+ if not options.no_fstrim then (
+ message
+ (f_"Mapping filesystem data to avoid copying unused and blank areas");
+ do_fstrim g inspect
+ ) else (
+ message (f_"Skipping fstrim (--no-fstrim specified)")
+ );
(* Check (fsck) the filesystems after conversion. *)
g#umount_all ();
diff --git a/convert/convert.mli b/convert/convert.mli
index f2a8d662..faf671fc 100644
--- a/convert/convert.mli
+++ b/convert/convert.mli
@@ -26,6 +26,7 @@ type options = {
smp : int option; (** [--smp] option *)
static_ips : Types.static_ip list; (** [--mac :ip:] option *)
customize_ops : Customize_cmdline.ops; (** virt-customize options *)
+ no_fstrim : bool; (** [--no-fstrim] option *)
}
(** Command line options that get passed through to the conversion code. *)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 04764832..f1bda76a 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -473,6 +473,10 @@ are mapped to C<out>.
See L</Networks and bridges> below.
+=item B<--no-fstrim>
+
+Do not trim the filesystem. See L</Trimming> below.
+
=item B<-o> B<disk>
This is the same as I<-o local>.
@@ -1039,6 +1043,8 @@ fstrim support in the Linux kernel is improving gradually, so over
time some of these restrictions will be lifted and virt-v2v will work
faster.
+Use I<--no-fstrim> to disable trimming.
+
=head2 Free space for conversion
=head3 Free space in the guest
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 7e490867..e84266ab 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -151,6 +151,7 @@ let rec main () =
let set_root_choice = Types.set_root_choice root_choice in
(* Other options that we handle here. *)
+ let no_fstrim = ref false in
let print_source = ref false in
let input_modes =
@@ -185,6 +186,8 @@ let rec main () =
s_"Map network in to out";
[ S 'O' ], Getopt.String ("output.xml", set_output_xml_option),
s_"Set the output filename";
+ [ L"no-fstrim" ], Getopt.Set no_fstrim,
+ s_"Don't trim filesystems before conversion";
[ L"print-source" ], Getopt.Set print_source,
s_"Print source and stop";
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
@@ -254,6 +257,7 @@ read the man page virt-v2v-in-place(1).
let customize_ops = get_customize_ops () in
let input_conn = !input_conn in
let input_mode = !input_mode in
+ let no_fstrim = !no_fstrim in
let memsize = !memsize in
let output_xml = !output_xml in
let print_source = !print_source in
@@ -326,6 +330,7 @@ read the man page virt-v2v-in-place(1).
smp;
static_ips;
customize_ops;
+ no_fstrim;
} in
(* Before starting the input module, check there is sufficient
diff --git a/in-place/virt-v2v-in-place.pod b/in-place/virt-v2v-in-place.pod
index 69d2092e..333a6827 100644
--- a/in-place/virt-v2v-in-place.pod
+++ b/in-place/virt-v2v-in-place.pod
@@ -235,6 +235,10 @@ are mapped to C<out>.
See L<virt-v2v(1)/Networks and bridges>.
+=item B<--no-fstrim>
+
+Do not trim the filesystem. See L<virt-v2v(1)/Trimming>.
+
=item B<-O> output.xml
=item B<-O ->
diff --git a/inspector/inspector.ml b/inspector/inspector.ml
index 752a5c1c..137d5f61 100644
--- a/inspector/inspector.ml
+++ b/inspector/inspector.ml
@@ -70,6 +70,8 @@ let rec main () =
let smp = ref None in
let set_smp arg = smp := Some arg in
+ let no_fstrim = ref false in
+
let network_map = Networks.create () in
let static_ips = ref [] in
let rec add_network str =
@@ -171,6 +173,8 @@ let rec main () =
s_"Map NIC to network or bridge or assign static IP";
[ S 'm'; L"memsize" ], Getopt.Int ("mb", set_memsize),
s_"Set memory size";
+ [ L"no-fstrim" ], Getopt.Set no_fstrim,
+ s_"Don't trim filesystems before conversion";
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),
s_"Map network in to out";
[ S 'O' ], Getopt.String ("output.xml", set_output_file_option),
@@ -233,6 +237,7 @@ read the man page virt-v2v-inspector(1).
| Some transport ->
error (f_"unknown input transport -it %s") transport in
let memsize = !memsize in
+ let no_fstrim = !no_fstrim in
let root_choice = !root_choice in
let smp = !smp in
let static_ips = !static_ips in
@@ -293,6 +298,7 @@ read the man page virt-v2v-inspector(1).
smp;
static_ips;
customize_ops;
+ no_fstrim;
} in
(* Before starting the input module, check there is sufficient
diff --git a/inspector/virt-v2v-inspector.pod b/inspector/virt-v2v-inspector.pod
index 26770459..65ce71ce 100644
--- a/inspector/virt-v2v-inspector.pod
+++ b/inspector/virt-v2v-inspector.pod
@@ -202,6 +202,8 @@ virt-v2v-inspector.
=item B<--network> ...
+=item B<--no-fstrim>
+
=item B<-q>
=item B<--quiet>
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 54cfd124..036cd3bb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -93,6 +93,7 @@ TESTS = \
test-mac.sh \
test-machine-readable.sh \
test-networks-and-bridges.sh \
+ test-no-fstrim.sh \
test-o-glance.sh \
test-o-kubevirt-fedora.sh \
test-o-kubevirt-oo-disk.sh \
@@ -292,6 +293,7 @@ EXTRA_DIST += \
test-machine-readable.sh \
test-networks-and-bridges-expected.xml \
test-networks-and-bridges.sh \
+ test-no-fstrim.sh \
test-o-glance.sh \
test-o-kubevirt-fedora.sh \
test-o-kubevirt-fedora.yaml.expected \
diff --git a/tests/test-no-fstrim.sh b/tests/test-no-fstrim.sh
new file mode 100755
index 00000000..ba84ad96
--- /dev/null
+++ b/tests/test-no-fstrim.sh
@@ -0,0 +1,44 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014-2026 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 --no-fstrim option.
+
+source ./functions.sh
+set -e
+set -x
+
+skip_if_skipped
+requires test -s ../test-data/phony-guests/windows.img
+
+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
+
+d=test-no-fstrim.d
+rm -rf $d
+cleanup_fn rm -rf $d
+mkdir $d
+
+$VG virt-v2v --debug-gc \
+ -i disk ../test-data/phony-guests/windows.img \
+ --no-fstrim \
+ -o local -os $d
+
+# Test the libvirt XML metadata and a disk was created.
+test -f $d/windows.xml
+test -f $d/windows-sda
+
+cat $d/windows.xml
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index dd224b40..480fa81a 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -80,6 +80,8 @@ let rec main () =
let smp = ref None in
let set_smp arg = smp := Some arg in
+ let no_fstrim = ref false in
+
let network_map = Networks.create () in
let static_ips = ref [] in
let rec add_network str =
@@ -242,6 +244,8 @@ 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"no-fstrim" ], Getopt.Set no_fstrim,
+ s_"Don't trim filesystems before conversion";
[ L"parallel" ], Getopt.Set_int ("N", parallel),
s_"Run up to N instances of nbdcopy in parallel";
[ L"print-source" ], Getopt.Set print_source,
@@ -324,6 +328,7 @@ read the man page virt-v2v(1).
| Some transport ->
error (f_"unknown input transport -it %s") transport in
let memsize = !memsize in
+ let no_fstrim = !no_fstrim in
let output_alloc =
match !output_alloc with
| `Not_set | `Sparse -> Types.Sparse
@@ -440,6 +445,7 @@ read the man page virt-v2v(1).
smp;
static_ips;
customize_ops;
+ no_fstrim;
} in
(* Before starting the input module, check there is sufficient

View File

@ -0,0 +1,52 @@
From bb9ddf65787ec5e04a465da8d2eee303640b5f5f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 15 Apr 2026 11:22:34 +0100
Subject: [PATCH] convert: Stop using maxmem (xfs_repair -m option)
We originally introduced this option in commit dba4f0d3ba ("convert:
Limit the amount of memory used by xfs_repair"). In the same commit
we also started to use noprefetch (xfs_repair -P). This was to avoid
xfs_repair taking too much memory, causing OOM errors.
However the -m option turns out to be deprecated. It has a number of
problems and sharp edges, including that it overestimates the amount
of memory required (often, greatly), its estimates are not very
accurate, and it prints a localized error message that libguestfs
needs to parse to obtain useful information.
xfs_repair has internal logic already to find the available physical
memory and limit memory usage. This also operates even if the -m
option is not used.
The beneficial option is noprefetch (-P) which limits the caching that
xfs_repair does. Leave that one alone.
Reported-by: Ming Xie
Thanks: Eric Sandeen, Dave Chinner
Related: https://redhat.atlassian.net/browse/RHEL-165677
(cherry picked from commit 788bd68663cfc4535753623faa25180fd35f0893)
---
convert/convert.ml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/convert/convert.ml b/convert/convert.ml
index 1c1ad2b4..1df8699a 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -333,13 +333,11 @@ and do_fsck ?(before=false) g =
*)
let nomodify = true
(* xfs_repair runs out of memory in the low memory environment
- * of the appliance unless we limit the amount of memory it will
- * use here.
+ * of the appliance unless we disable prefetch.
*)
- and noprefetch = true
- and maxmem = Int64.of_int (g#get_memsize () / 2) in
+ and noprefetch = true in
- if g#xfs_repair ~maxmem ~noprefetch ~nomodify dev <> 0 then
+ if g#xfs_repair ~noprefetch ~nomodify dev <> 0 then
error (f_"detected errors on the XFS filesystem on %s") dev
| _, _ ->

View File

@ -0,0 +1,53 @@
From 5dd78362a45ed3d64811a606b49eba5435361912 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 23 Apr 2026 15:41:31 +0100
Subject: [PATCH] Update common submodule
Richard W.M. Jones (1):
mldrivers/firmware.ml: Ignore CHS geometry error from parted
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common cb0e19b7..29176db2:
diff --git a/common/mldrivers/firmware.ml b/common/mldrivers/firmware.ml
index ee0a7caf..6698b073 100644
--- a/common/mldrivers/firmware.ml
+++ b/common/mldrivers/firmware.ml
@@ -18,6 +18,7 @@
open Printf
+open Std_utils
open Tools_utils
module G = Guestfs
@@ -28,12 +29,22 @@ type i_firmware =
let detect_firmware g =
let parttype_is_gpt dev =
- try g#part_get_parttype dev = "gpt"
- with G.Error msg as exn ->
- (* If it's _not_ "unrecognised disk label" then re-raise it. *)
- if g#last_errno () <> G.Errno.errno_EINVAL then raise exn;
- debug "%s (ignored)" msg;
- false
+ try
+ g#part_get_parttype dev = "gpt"
+ with
+ | G.Error msg when String.find msg "CHS geometry" >= 0 ->
+ (* Parted has poor handling of "sun" partition types, always
+ * issuing a warning because the CHS doesn't match the physical
+ * geometry. Ignore this as we don't care about it in this
+ * function (RHEL-165220).
+ *)
+ debug "%s (ignored)" msg;
+ false
+ | G.Error msg as exn ->
+ (* If it's _not_ "unrecognised disk label" then re-raise it. *)
+ if g#last_errno () <> G.Errno.errno_EINVAL then raise exn;
+ debug "%s (ignored)" msg;
+ false
in
let accumulate_partition (esp_parts, bboot) part =
let dev = g#part_to_dev part in

View File

@ -0,0 +1,68 @@
From d26ac59e9c5b1d8d3d4175c9ef88212c7727f0d3 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 18 Apr 2026 09:08:15 +0100
Subject: [PATCH] docs: Show input parameters for -i input methods
Show what input parameters (eg. list of disk images, XML file) should
be used for each input method. This is an attempt to make the
documentation a little clearer.
(cherry picked from commit 6cb43b899a52aa02d99b385fb270a421d58ce084)
---
docs/virt-v2v.pod | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index f1bda76a..945e8dfc 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -266,7 +266,7 @@ Note this options only applies to keys and passphrases for encrypted
devices and partitions, not for passwords used to connect to remote
servers.
-=item B<-i> B<disk>
+=item B<-i> B<disk> disk [disk ...]
Set the input method to I<disk>.
@@ -276,7 +276,7 @@ usually adequate but you can get finer control (eg. of memory and
vCPUs) by using I<-i libvirtxml> instead. Only guests that use a single
disk can be imported this way.
-=item B<-i> B<libvirt>
+=item B<-i> B<libvirt> name|UUID
Set the input method to I<libvirt>. This is the default.
@@ -286,7 +286,7 @@ I<-ic>).
See L</Starting the libvirt system instance> below.
-=item B<-i> B<libvirtxml>
+=item B<-i> B<libvirtxml> guestB<.xml>
Set the input method to I<libvirtxml>.
@@ -295,11 +295,11 @@ This file is read in order to get metadata about the source guest
(such as its name, amount of memory), and also to locate the input
disks. See L</Minimal XML for -i libvirtxml option> below.
-=item B<-i> B<local>
+=item B<-i> B<local> disk [disk ...]
This is the same as I<-i disk>.
-=item B<-i> B<ova>
+=item B<-i> B<ova> guestB<.ova>
Set the input method to I<ova>.
@@ -308,7 +308,7 @@ ova manifest file and check the vmdk volumes for validity (checksums)
as well as analyzing the ovf file, and then convert the guest. See
L<virt-v2v-input-vmware(1)>.
-=item B<-i> B<vmx>
+=item B<-i> B<vmx> guestB<.vmx>|B<ssh://>...
Set the input method to I<vmx>.

View File

@ -0,0 +1,32 @@
From 58103554de82a24b55b79e8319027b19c66f7e14 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 18 Apr 2026 09:09:04 +0100
Subject: [PATCH] docs: -i disk allows multiple disk images
Commit 255722cbf3 ("v2v: Modular virt-v2v") which modularized the
-i disk code silently added the ability to read from multiple disks.
The documentation was not updated and still stated that only a single
disk could be used.
Remove incorrect statement in the documentation.
Fixes: commit 255722cbf39afc0b012e2ac00d16fa6ba2f8c21f
(cherry picked from commit 9b758f808710490ccdb4c35d58b0861b32d295d8)
---
docs/virt-v2v.pod | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 945e8dfc..63d5814e 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -273,8 +273,7 @@ Set the input method to I<disk>.
In this mode you can read a virtual machine disk image with no
metadata. virt-v2v tries to guess the best default metadata. This is
usually adequate but you can get finer control (eg. of memory and
-vCPUs) by using I<-i libvirtxml> instead. Only guests that use a single
-disk can be imported this way.
+vCPUs) by using I<-i libvirtxml> instead.
=item B<-i> B<libvirt> name|UUID

View File

@ -0,0 +1,277 @@
From f748458503b327aedd6af47583f35533db2b472d Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 18 Apr 2026 09:54:27 +0100
Subject: [PATCH] -i disk: Allow nbd:// URIs for input disks
As well as converting from local files, you can now convert from NBD
URIs. This feature lets you do things like converting from local
xz-compressed disk images (thus saving space), or from remote NBD
servers, eg:
$ nbdkit -r --filter=xz file windows.xz
$ virt-v2v -i disk nbd://localhost -o ...
or:
$ virt-v2v -i disk nbd+ssh://server/ -o ...
This requires nbdkit-nbd-plugin to proxy to connection. (In future we
could optimize this as noted in comments.)
This is mainly useful for testing, so I didn't yet document or test it
fully. Once we have more confidence in it we can extend the
documentation.
(cherry picked from commit a153d3e66eb3ce2f08c949f6dde483991aa4bd28)
---
docs/virt-v2v.pod | 4 +
input/Makefile.am | 2 +-
input/input_disk.ml | 192 +++++++++++++++++++++++++++-----------------
3 files changed, 124 insertions(+), 74 deletions(-)
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 63d5814e..ecb29771 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -275,6 +275,10 @@ metadata. virt-v2v tries to guess the best default metadata. This is
usually adequate but you can get finer control (eg. of memory and
vCPUs) by using I<-i libvirtxml> instead.
+Each disk can be a local file or an C<nbd://> URI if you want to pull
+the guest disk from an NBD server (see L<nbd_connect_uri(3)> for the
+supported URI formats).
+
=item B<-i> B<libvirt> name|UUID
Set the input method to I<libvirt>. This is the default.
diff --git a/input/Makefile.am b/input/Makefile.am
index 0726b9a1..df116c69 100644
--- a/input/Makefile.am
+++ b/input/Makefile.am
@@ -98,7 +98,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo)
XOBJECTS = $(BOBJECTS:.cmo=.cmx)
OCAMLPACKAGES = \
- -package str,unix,guestfs,libvirt \
+ -package str,unix,guestfs,libvirt,nbd \
-I $(top_builddir)/common/utils/.libs \
-I $(top_builddir)/gnulib/lib/.libs \
-I $(top_builddir)/lib \
diff --git a/input/input_disk.ml b/input/input_disk.ml
index a5291031..20cd8214 100644
--- a/input/input_disk.ml
+++ b/input/input_disk.ml
@@ -38,23 +38,134 @@ module Disk = struct
if options.input_options <> [] then
error (f_"no -io (input options) are allowed here");
- if args = [] then
+ let nr_disks = List.length args in
+ if nr_disks = 0 then
error (f_"-i disk: expecting a disk image (filename) \
on the command line");
- (* Check the input files exist and are readable. *)
- List.iter (fun disk -> access disk [R_OK]) args;
+ (* Check nbdkit is installed. *)
+ if not (Nbdkit.is_installed ()) then
+ error (f_"nbdkit is not installed or not working. It is required to \
+ use -i disk.");
+ if not (Nbdkit.probe_plugin "file") then
+ error (f_"nbdkit-file-plugin is not installed or not working");
+ if options.read_only && not (Nbdkit.probe_filter "cow") then
+ error (f_"nbdkit-cow-filter is not installed or not working");
+
+ (* Each disk on the command line can be a local file or an NBD URI. *)
+ let is_nbd_uri =
+ let h = lazy (NBD.create ()) in
+ fun str -> NBD.is_uri (Lazy.force h) str
+ in
+
+ (* Function for detecting input format, using guestfs_disk_format. *)
+ let detect_input_format =
+ let g = lazy (open_guestfs ()) in
+ fun disk -> (Lazy.force g)#disk_format disk
+ in
+
+ (* If there are any NBD URIs on the command line, nbdkit-nbd-plugin
+ * must be available too.
+ *)
+ if List.exists is_nbd_uri args && not (Nbdkit.probe_plugin "nbd") then
+ error (f_"nbdkit-nbd-plugin is not installed or not working");
(* What name should we use for the guest? We try to derive it from
- * the first filename passed in. Users can override this using the
- * `-on name' option.
+ * the first filename passed in. If there are no filenames then
+ * we use "unknown".
+ *
+ * Users can override this using the '-on name' option.
*)
- let name = name_from_disk (List.hd args) in
+ let name =
+ let rec loop = function
+ | [] ->
+(* XXX can't print this because we don't know if the user set '-on'
+ warning (f_"-i disk: no local filenames given so we set \
+ the guest name to \"unknown\". Use -on name to \
+ override the guest name.");
+*)
+ "unknown"
+ | x :: xs when is_nbd_uri x ->
+ loop xs
+ | x :: _ ->
+ name_from_disk x
+ in
+ loop args in
+
+ (* Convert the command line disks to NBD URIs. *)
+ let uris =
+ List.mapi (
+ fun i disk ->
+ let sockname = sprintf "in%d" i in
+ let socket = sprintf "%s/%s" dir sockname in
+ On_exit.unlink socket;
+
+ if is_nbd_uri disk then (
+ (* For nbd:// on the command line, proxy through
+ * nbdkit-nbd-plugin. This is not ideal. We could
+ * catch special cases here, such as nbd+unix://
+ * and convert them directly to NBD_URI objects.
+ * That would require parsing NBD URIs ourselves
+ * but would avoid needing an extra nbdkit proxy.
+ * XXX
+ *)
+ let cmd = Nbdkit.create ~name:sockname "nbd" in
+ if options.read_only then
+ Nbdkit.add_filter cmd "cow";
+ Nbdkit.add_arg cmd "uri" disk;
+ let _, pid = Nbdkit.run_unix socket cmd in
+
+ (* --exit-with-parent should ensure nbdkit is cleaned
+ * up when we exit, but it's not supported everywhere.
+ *)
+ On_exit.kill pid
+ )
+ else (
+ (* Local filename. Use nbdkit-file-plugin for raw,
+ * or qemu-nbd for other formats.
+ *
+ * virt-v2v < 2.12 used to enforce that all disks
+ * had the same format, but that seems unnecessary.
+ *)
+
+ (* Check the input file exists and is readable. *)
+ access disk [R_OK];
+
+ let format =
+ match options.input_format with
+ | Some fmt -> fmt (* -if option overrides everything *)
+ | None -> detect_input_format disk in
+
+ match format with
+ | "raw" ->
+ let cmd = Nbdkit.create ~name:sockname "file" in
+ if options.read_only then
+ Nbdkit.add_filter cmd "cow";
+ Nbdkit.add_arg cmd "file" disk;
+ Nbdkit.reduce_memory_pressure cmd;
+ let _, pid = Nbdkit.run_unix socket cmd in
+
+ (* --exit-with-parent should ensure nbdkit is cleaned
+ * up when we exit, but it's not supported everywhere.
+ *)
+ On_exit.kill pid
+
+ | format ->
+ let cmd = QemuNBD.create disk in
+ QemuNBD.set_snapshot cmd options.read_only;
+ QemuNBD.set_format cmd (Some format);
+ let _, pid = QemuNBD.run_unix socket cmd in
+ On_exit.kill pid
+ );
+
+ NBD_URI.Unix (socket, None)
+ ) args in
let s_disks =
+ List.make nr_disks () |>
List.mapi (
- fun i _ -> { s_disk_id = i; s_controller = None }
- ) args in
+ fun i () -> { s_disk_id = i; s_controller = None }
+ ) in
(* Give the guest a simple generic network interface. *)
let s_nic = {
@@ -85,70 +196,5 @@ module Disk = struct
s_nics = [s_nic];
} in
- let input_format = detect_local_input_format options args in
-
- (* Check nbdkit is installed. *)
- if not (Nbdkit.is_installed ()) then
- error (f_"nbdkit is not installed or not working. It is required to \
- use -i disk.");
-
- if not (Nbdkit.probe_plugin "file") then
- error (f_"nbdkit-file-plugin is not installed or not working");
- if options.read_only && not (Nbdkit.probe_filter "cow") then
- error (f_"nbdkit-cow-filter is not installed or not working");
-
- let uris =
- List.mapi (
- fun i disk ->
- let sockname = sprintf "in%d" i in
- let socket = sprintf "%s/%s" dir sockname in
- On_exit.unlink socket;
-
- (match input_format with
- | "raw" ->
- let cmd = Nbdkit.create ~name:sockname "file" in
- if options.read_only then
- Nbdkit.add_filter cmd "cow";
- Nbdkit.add_arg cmd "file" disk;
- Nbdkit.reduce_memory_pressure cmd;
- let _, pid = Nbdkit.run_unix socket cmd in
-
- (* --exit-with-parent should ensure nbdkit is cleaned
- * up when we exit, but it's not supported everywhere.
- *)
- On_exit.kill pid
-
- | format ->
- let cmd = QemuNBD.create disk in
- QemuNBD.set_snapshot cmd options.read_only;
- QemuNBD.set_format cmd (Some format);
- let _, pid = QemuNBD.run_unix socket cmd in
- On_exit.kill pid
- );
-
- NBD_URI.Unix (socket, None)
- ) args in
-
source, uris
-
- (* For a list of local disks, try to detect the input format if
- * the [-if] option was not used on the command line. If the
- * formats of the disks are different, that is an error.
- *)
- and detect_local_input_format { input_format } filenames =
- match input_format with
- | Some fmt -> fmt
- | None ->
- let formats =
- let g = open_guestfs () in
- List.map g#disk_format filenames in
-
- let rec get_format = function
- | [] -> error (f_"expected >= 1 disk name on the command line")
- | [x] -> x
- | x :: y :: xs when compare x y = 0 -> get_format (y :: xs)
- | _ -> error (f_"disks on the command line have mixed formats")
- in
-
- get_format formats
end

View File

@ -0,0 +1,123 @@
From a4a65048989da029da637a1f6554c391ffe52fcf Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 18 Apr 2026 22:30:27 +0100
Subject: [PATCH] tests: Add test for -i disk nbd:// URI
Updates: commit a153d3e66eb3ce2f08c949f6dde483991aa4bd28
(cherry picked from commit 79d39ec12acfd5c90a2326ef417b948a2154adf4)
---
tests/Makefile.am | 6 ++--
tests/test-i-disk-nbd.sh | 78 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 2 deletions(-)
create mode 100755 tests/test-i-disk-nbd.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 036cd3bb..19a60f73 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -70,8 +70,9 @@ TESTS = \
test-fedora-lvm-on-luks-conversion.sh \
test-fedora-md-conversion.sh \
test-floppy.sh \
- test-i-disk-parallel.sh \
test-i-disk.sh \
+ test-i-disk-nbd.sh \
+ test-i-disk-parallel.sh \
test-i-ova-bad-sha1.sh \
test-i-ova-bad-sha256.sh \
test-i-ova-directory.sh \
@@ -233,8 +234,9 @@ EXTRA_DIST += \
test-fedora-md-conversion.sh \
test-floppy.expected \
test-floppy.sh \
- test-i-disk-parallel.sh \
test-i-disk.sh \
+ test-i-disk-nbd.sh \
+ test-i-disk-parallel.sh \
test-i-ova-as-root.ovf \
test-i-ova-as-root.sh \
test-i-ova-bad-sha1.sh \
diff --git a/tests/test-i-disk-nbd.sh b/tests/test-i-disk-nbd.sh
new file mode 100755
index 00000000..12a23d7f
--- /dev/null
+++ b/tests/test-i-disk-nbd.sh
@@ -0,0 +1,78 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014 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 -i disk with nbd URIs.
+
+source ./functions.sh
+set -e
+set -x
+
+skip_if_skipped
+
+b=fedora.img
+f=../test-data/phony-guests/$b
+requires test -f $f
+
+requires xz --version
+
+# Check we have nbdkit and the plugins and filters required.
+requires nbdkit --version
+requires nbdkit file --version
+requires nbdkit nbd --version
+requires nbdkit null --version
+requires nbdkit null --filter=cow --version
+requires nbdkit null --filter=xz --version
+
+# Check --exit-with-parent option will work.
+requires nbdkit --exit-with-parent --version
+
+d=test-i-disk-nbd.d
+rm -rf $d
+cleanup_fn rm -rf $d
+mkdir $d
+
+cp $f $d/$b
+xz $d/$b
+
+# Start nbdkit connected to the compressed file.
+nbdkit -r -f --exit-with-parent \
+ -U $d/sock -P $d/pid \
+ --filter=xz file $d/$b.xz &
+
+# Wait for the pidfile to appear.
+for i in {1..60}; do
+ if test -s "$d/pid"; then
+ break
+ fi
+ sleep 1
+done
+if ! test -s "$d/pid"; then
+ echo "$0: nbdkit: PID file $d/pid was not created"
+ exit 1
+fi
+cleanup_fn kill "$(cat $d/pid)"
+
+$VG virt-v2v --debug-gc \
+ -i disk nbd+unix:///?socket=$d/sock \
+ -o local -os $d
+
+# Test the libvirt XML metadata and a disk was created.
+test -f $d/unknown.xml
+test -f $d/unknown-sda
+
+cat $d/unknown.xml

View File

@ -0,0 +1,331 @@
From e342104e305251911ed4e769659fc708a9ab4d64 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Apr 2026 17:01:26 +0100
Subject: [PATCH] common: update submodule
Richard W.M. Jones (4):
utils: Add read_whole_file function
options/keys.c: When reading key from user, prefix with "text:"
options/keys.c: When using --key <dev>:key:<string>, prefix with "text:"
options/keys.c: When reading the key from a file, encode it with base64
Also this now requires libguestfs >= 1.59.7 because we rely on text:
and base64: prefixes in LUKS functions.
Fixes: https://redhat.atlassian.net/browse/RHEL-170864
(cherry picked from commit 020fb2cdd145ae24f9d84ea60e0e3df15afdb0ff)
---
common | 2 +-
m4/guestfs-libraries.m4 | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
Submodule common 29176db2..31d0d6d4:
diff --git a/common/options/keys.c b/common/options/keys.c
index 7027104a..432e26dc 100644
--- a/common/options/keys.c
+++ b/common/options/keys.c
@@ -37,17 +37,23 @@
* Read a passphrase ('Key') from F</dev/tty> with echo off.
*
* The caller (F<fish/cmds.c>) will call free on the string
- * afterwards. Based on the code in cryptsetup file F<lib/utils.c>.
+ * afterwards.
+ *
+ * The entered string is prefixed with "text:..." to avoid ambiguity
+ * (with libguestfs >= 1.60). Base64 encoding cannot be used here.
+ *
+ * Based on the code in cryptsetup file F<lib/utils.c>.
*/
char *
read_key (const char *param)
{
FILE *infp, *outfp;
struct termios orig, temp;
+ CLEANUP_FREE char *key = NULL;
+ size_t keysize = 0;
char *ret = NULL;
int tty;
int tcset = 0;
- size_t allocsize = 0;
ssize_t len;
/* Read and write to /dev/tty if available. */
@@ -75,16 +81,21 @@ read_key (const char *param)
}
}
- len = getline (&ret, &allocsize, infp);
+ len = getline (&key, &keysize, infp);
if (len == -1) {
perror ("getline");
- ret = NULL;
goto error;
}
/* Remove the terminating \n if there is one. */
- if (len > 0 && ret[len-1] == '\n')
- ret[len-1] = '\0';
+ if (len > 0 && key[len-1] == '\n')
+ key[len-1] = '\0';
+
+ /* Prefix with "text:". */
+ if (asprintf (&ret, "text:%s", key) == -1) {
+ perror ("asprintf");
+ goto error;
+ }
error:
/* Restore echo, close file descriptor. */
@@ -99,27 +110,60 @@ read_key (const char *param)
return ret;
}
+/* Read a key from a file and base64 encode it, returning "base64:..." */
static char *
-read_first_line_from_file (const char *filename)
+read_key_and_base64_encode (const char *filename)
{
- CLEANUP_FCLOSE FILE *fp = NULL;
- char *ret = NULL;
- size_t allocsize = 0;
- ssize_t len;
-
- fp = fopen (filename, "r");
- if (!fp)
- error (EXIT_FAILURE, errno, "fopen: %s", filename);
-
- len = getline (&ret, &allocsize, fp);
- if (len == -1)
- error (EXIT_FAILURE, errno, "getline: %s", filename);
+ CLEANUP_FREE char *inp = NULL;
+ char *out;
+ size_t inplen, outlen, i, j;
+
+ if (read_whole_file (filename, &inp, &inplen) == -1)
+ error (EXIT_FAILURE, 0, "read_key_and_base64_encode: read_whole_file: %s",
+ filename);
+
+ /* From https://stackoverflow.com/a/6782480 */
+ static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+ static int mod_table[] = {0, 2, 1};
+
+ outlen = 4 * ((inplen + 2) / 3);
+ out = malloc (outlen + 7 + 1);
+ if (!out)
+ error (EXIT_FAILURE, errno, "read_key_and_base64_encode: %s: malloc",
+ filename);
+
+ /* Add prefix and NUL-termination, then adjust 'out' to make the
+ * rest of the code simpler.
+ */
+ memcpy (out, "base64:", 7);
+ out[7 + outlen] = '\0';
+ out += 7;
+
+ for (i = 0, j = 0; i < inplen;) {
+ uint32_t octet_a = i < inplen ? (unsigned char) inp[i++] : 0;
+ uint32_t octet_b = i < inplen ? (unsigned char) inp[i++] : 0;
+ uint32_t octet_c = i < inplen ? (unsigned char) inp[i++] : 0;
+
+ uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
+
+ assert (j <= outlen-4);
+ out[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
+ out[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
+ out[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
+ out[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
+ }
- /* Remove the terminating \n if there is one. */
- if (len > 0 && ret[len-1] == '\n')
- ret[len-1] = '\0';
+ for (i = 0; i < mod_table[inplen % 3]; i++)
+ out[outlen - 1 - i] = '=';
- return ret;
+ return out - 7 /* see above */;
}
/* Return the key(s) matching this particular device from the
@@ -163,15 +207,14 @@ get_keys (struct key_store *ks, const char *device, const char *uuid,
switch (key->type) {
case key_string:
- s = strdup (key->string.s);
- if (!s)
- error (EXIT_FAILURE, errno, "strdup");
+ if (asprintf (&s, "text:%s", key->string.s) == -1)
+ error (EXIT_FAILURE, errno, "asprintf");
match->clevis = false;
match->passphrase = s;
++match;
break;
case key_file:
- s = read_first_line_from_file (key->file.name);
+ s = read_key_and_base64_encode (key->file.name);
match->clevis = false;
match->passphrase = s;
++match;
diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am
index 25c6100b..f328dcad 100644
--- a/common/utils/Makefile.am
+++ b/common/utils/Makefile.am
@@ -30,6 +30,7 @@ libutils_la_SOURCES = \
libxml2-writer-macros.h \
pcre2-cleanups.c \
stringlists-utils.c \
+ whole-file.c \
utils.c
libutils_la_CPPFLAGS = \
-DGUESTFS_NO_DEPRECATED=1 \
diff --git a/common/utils/guestfs-utils.h b/common/utils/guestfs-utils.h
index e861e7db..a8bd9ac2 100644
--- a/common/utils/guestfs-utils.h
+++ b/common/utils/guestfs-utils.h
@@ -113,4 +113,8 @@ extern const char *guestfs_int_strerror (int errnum, char *buf, size_t buflen);
/* environ.c */
extern char **guestfs_int_copy_environ (char **env, ...);
+/* whole-file.c */
+extern int read_whole_file (const char *filename,
+ char **data_r, size_t *size_r);
+
#endif /* GUESTFS_UTILS_H_ */
diff --git a/common/utils/whole-file.c b/common/utils/whole-file.c
new file mode 100644
index 00000000..a896e024
--- /dev/null
+++ b/common/utils/whole-file.c
@@ -0,0 +1,111 @@
+/* libguestfs
+ * Copyright (C) 2011-2026 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <libintl.h>
+
+#include "guestfs-utils.h"
+
+/**
+ * Read the whole file C<filename> into a memory buffer.
+ *
+ * The memory buffer is initialized and returned in C<data_r>. The
+ * size of the file in bytes is returned in C<size_r>. The return
+ * buffer must be freed by the caller.
+ *
+ * On error this prints an error on C<stderr> and returns -1. Unlike
+ * the similar C<guestfs_int_read_whole_file> this does not use the
+ * libguestfs handle or call C<error()>.
+ *
+ * For the convenience of callers, the returned buffer is
+ * NUL-terminated (the NUL is not included in the size).
+ *
+ * The file must be a B<regular>, B<local>, B<trusted> file. In
+ * particular, do not use this function to read files that might be
+ * under control of an untrusted user since that will lead to a
+ * denial-of-service attack.
+ */
+int
+read_whole_file (const char *filename, char **data_r, size_t *size_r)
+{
+ int fd;
+ char *data;
+ off_t size;
+ off_t n;
+ ssize_t r;
+ struct stat statbuf;
+
+ fd = open (filename, O_RDONLY|O_CLOEXEC);
+ if (fd == -1) {
+ perror (filename);
+ return -1;
+ }
+
+ if (fstat (fd, &statbuf) == -1) {
+ perror (filename);
+ close (fd);
+ return -1;
+ }
+
+ size = statbuf.st_size;
+ data = malloc (size + 1);
+ if (data == NULL) {
+ perror ("malloc");
+ close (fd);
+ return -1;
+ }
+
+ n = 0;
+ while (n < size) {
+ r = read (fd, &data[n], size - n);
+ if (r == -1) {
+ perror (filename);
+ free (data);
+ close (fd);
+ return -1;
+ }
+ if (r == 0) {
+ fprintf (stderr, "%s: unexpected end of input", filename);
+ free (data);
+ close (fd);
+ return -1;
+ }
+ n += r;
+ }
+
+ if (close (fd) == -1) {
+ perror (filename);
+ free (data);
+ return -1;
+ }
+
+ /* For convenience of callers, \0-terminate the data. */
+ data[size] = '\0';
+
+ *data_r = data;
+ if (size_r != NULL)
+ *size_r = size;
+
+ return 0;
+}
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
index 11c9974c..22af5db7 100644
--- a/m4/guestfs-libraries.m4
+++ b/m4/guestfs-libraries.m4
@@ -19,7 +19,8 @@ dnl Any C libraries required by virt-v2v.
dnl Of course we need libguestfs.
dnl
-dnl We need libguestfs >= 1.58.1-2.el10 for guestfs_xfs_info2.
+dnl We need libguestfs >= 1.58.1-6.el10 for guestfs_xfs_info2
+dnl and for text: and base64: prefix in LUKS funcs.
PKG_CHECK_MODULES([LIBGUESTFS], [libguestfs >= 1.58.1])
printf "libguestfs version is "; $PKG_CONFIG --modversion libguestfs

View File

@ -0,0 +1,122 @@
From bd5e315f274994bd0a537631ad80a1bcf2911647 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 5 May 2026 12:40:49 +0100
Subject: [PATCH] common: update submodule
Richard W.M. Jones (1):
mlcustomize: Update generated files
Srihari Parimi (1):
mlcustomize: firstboot.bat must not reboot VM on error code 250
(cherry picked from commit 463d0bbd471bc49df7dfb37231a468bfb0510fdc)
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 31d0d6d4..763a2102:
diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod
index c8de3953..95767cc7 100644
--- a/common/mlcustomize/customize-options.pod
+++ b/common/mlcustomize/customize-options.pod
@@ -161,10 +161,7 @@ conveniently wraps the command up in a single line script for you.
You can have multiple I<--firstboot> options. They run in the same
order that they appear on the command line.
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
-information and caveats about the first boot scripts.
-
-See also I<--run>.
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.
=item B<--firstboot-command> 'CMD+ARGS'
@@ -174,10 +171,7 @@ boots up (as root, late in the boot process).
You can have multiple I<--firstboot> options. They run in the same
order that they appear on the command line.
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
-information and caveats about the first boot scripts.
-
-See also I<--run>.
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.
=item B<--firstboot-install> PKG,PKG..
diff --git a/common/mlcustomize/customize_cmdline.ml b/common/mlcustomize/customize_cmdline.ml
index 786f4ee4..b8eda519 100644
--- a/common/mlcustomize/customize_cmdline.ml
+++ b/common/mlcustomize/customize_cmdline.ml
@@ -252,13 +252,13 @@ let rec argspec ?(v2v = false) () =
Getopt.String (s_"SCRIPT", fun s -> List.push_front (`FirstbootScript s) ops),
s_"Run script at first guest boot"
),
- Some "SCRIPT", "Install C<SCRIPT> inside the guest, so that when the guest first boots\nup, the script runs (as root, late in the boot process).\n\nThe script is automatically chmod +x after installation in the guest.\n\nThe alternative version I<--firstboot-command> is the same, but it\nconveniently wraps the command up in a single line script for you.\n\nYou can have multiple I<--firstboot> options. They run in the same\norder that they appear on the command line.\n\nPlease take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more\ninformation and caveats about the first boot scripts.\n\nSee also I<--run>.", false;
+ Some "SCRIPT", "Install C<SCRIPT> inside the guest, so that when the guest first boots\nup, the script runs (as root, late in the boot process).\n\nThe script is automatically chmod +x after installation in the guest.\n\nThe alternative version I<--firstboot-command> is the same, but it\nconveniently wraps the command up in a single line script for you.\n\nYou can have multiple I<--firstboot> options. They run in the same\norder that they appear on the command line.\n\nSee also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.", false;
(
[ L"firstboot-command" ],
Getopt.String (s_"'CMD+ARGS'", fun s -> List.push_front (`FirstbootCommand s) ops),
s_"Run command at first guest boot"
),
- Some "'CMD+ARGS'", "Run command (and arguments) inside the guest when the guest first\nboots up (as root, late in the boot process).\n\nYou can have multiple I<--firstboot> options. They run in the same\norder that they appear on the command line.\n\nPlease take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more\ninformation and caveats about the first boot scripts.\n\nSee also I<--run>.", false;
+ Some "'CMD+ARGS'", "Run command (and arguments) inside the guest when the guest first\nboots up (as root, late in the boot process).\n\nYou can have multiple I<--firstboot> options. They run in the same\norder that they appear on the command line.\n\nSee also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.", false;
(
[ L"firstboot-install" ],
Getopt.String (
diff --git a/common/mlcustomize/firstboot.ml b/common/mlcustomize/firstboot.ml
index 5e23a64b..fc3b7a69 100644
--- a/common/mlcustomize/firstboot.ml
+++ b/common/mlcustomize/firstboot.ml
@@ -320,13 +320,18 @@ for %%%%f in ("%%scripts%%"\*.bat) do (
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
+ :: Reboot the computer only if exit code indicates.
+ :: Exit code 250 means do not reboot, otherwise reboot
+ :: Reboot is necessary to free any locked files which
+ :: may prevent later scripts from running.
+ if !elvl! NEQ 250 (
+ shutdown /r /t 0 /y
- :: Exit the script (in case shutdown returns before rebooting).
- :: On next boot, the whole firstboot service will be called again.
- exit /b
+ :: Exit the script (in case shutdown returns before rebooting).
+ :: On next boot, the whole firstboot service will be called again.
+
+ exit /b
+ )
)
:: Fallthrough here if there are no scripts.
diff --git a/common/mlcustomize/v2v-customize-options.pod b/common/mlcustomize/v2v-customize-options.pod
index f02f05da..6252ffe9 100644
--- a/common/mlcustomize/v2v-customize-options.pod
+++ b/common/mlcustomize/v2v-customize-options.pod
@@ -161,10 +161,7 @@ conveniently wraps the command up in a single line script for you.
You can have multiple I<--firstboot> options. They run in the same
order that they appear on the command line.
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
-information and caveats about the first boot scripts.
-
-See also I<--run>.
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.
=item B<--firstboot-command> 'CMD+ARGS'
@@ -174,10 +171,7 @@ boots up (as root, late in the boot process).
You can have multiple I<--firstboot> options. They run in the same
order that they appear on the command line.
-Please take a look at L<virt-builder(1)/FIRST BOOT SCRIPTS> for more
-information and caveats about the first boot scripts.
-
-See also I<--run>.
+See also: L<virt-customize(1)/FIRSTBOOT>, I<--run>.
=item B<--firstboot-install> PKG,PKG..

View File

@ -1,4 +1,4 @@
From 5bb9b83c288b0c4bdac081e123f2fa54c840a6ca Mon Sep 17 00:00:00 2001
From a4c0eafbf3888e8d3d03a82ce9ba7d85ad858f03 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sun, 30 Aug 2015 03:21:57 -0400
Subject: [PATCH] RHEL: Fixes for libguestfs-winsupport.
@ -19,10 +19,10 @@ https://bugzilla.redhat.com/show_bug.cgi?id=2187961#c1
7 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/convert/convert.ml b/convert/convert.ml
index e3fd41b8..eb51e9b9 100644
index 1df8699a..5aca94f1 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -55,6 +55,7 @@ let rec convert input_disks options source =
@@ -56,6 +56,7 @@ let rec convert input_disks options source =
message (f_"Opening the source");
let g = open_guestfs ~identifier:"v2v" () in

View File

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

View File

@ -1,4 +1,4 @@
From b00922090f704e97388dbc96f6f710fd5e22af92 Mon Sep 17 00:00:00 2001
From af3ceff3108a8470b35e3bc78b9d31ff4bd05e91 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 30 Sep 2014 10:50:27 +0100
Subject: [PATCH] RHEL: v2v: Disable the --qemu-boot / -oo qemu-boot option
@ -43,7 +43,7 @@ index 49f00754..bdf12c5d 100644
=item B<-o null>
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
index 04764832..eb550da0 100644
index ecb29771..41bb58ce 100644
--- a/docs/virt-v2v.pod
+++ b/docs/virt-v2v.pod
@@ -169,11 +169,6 @@ Since F<guest-domain.xml> contains the path(s) to the guest disk
@ -58,7 +58,7 @@ index 04764832..eb550da0 100644
=head1 OPTIONS
=over 4
@@ -578,9 +573,6 @@ This is similar to I<-o local>, except that a shell script is written
@@ -585,9 +580,6 @@ This is similar to I<-o local>, except that a shell script is written
which you can use to boot the guest in qemu. The converted disks and
shell script are written to the directory specified by I<-os>.
@ -68,7 +68,7 @@ index 04764832..eb550da0 100644
ifelse(ENABLE_OVIRT, yes, `
=item B<-o> B<vdsm>
@@ -653,11 +645,6 @@ For I<-o openstack> (L<virt-v2v-output-openstack(1)>) only, set a guest ID
@@ -660,11 +652,6 @@ For I<-o openstack> (L<virt-v2v-output-openstack(1)>) only, set a guest ID
which is saved on each Cinder volume in the C<virt_v2v_guest_id>
volume property.

View File

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

View File

@ -1,4 +1,4 @@
From 2e69a53b203968d77eb0a0447bdb347bd34481c6 Mon Sep 17 00:00:00 2001
From 2f4eb183837ee7a13fb10f64f6a0d34075acc871 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 2 Mar 2017 14:21:37 +0100
Subject: [PATCH] RHEL: v2v: -i disk: force VNC as display (RHBZ#1372671)
@ -9,10 +9,10 @@ The SDL output mode is not supported in RHEL's qemu-kvm.
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/input/input_disk.ml b/input/input_disk.ml
index a5291031..599436f9 100644
index 20cd8214..b998a89d 100644
--- a/input/input_disk.ml
+++ b/input/input_disk.ml
@@ -77,7 +77,7 @@ module Disk = struct
@@ -188,7 +188,7 @@ module Disk = struct
s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *)
s_uefi_secureboot = false;
s_display =

View File

@ -1,4 +1,4 @@
From 19cd953d2b43f1d385845ed86c1802d4343093e7 Mon Sep 17 00:00:00 2001
From 57cd1fb96593e9bb7e4d09f316ade8b57a00bed6 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptoscano@redhat.com>
Date: Tue, 26 Mar 2019 09:42:25 +0100
Subject: [PATCH] RHEL: point to KB for supported v2v hypervisors/guests

View File

@ -1,4 +1,4 @@
From 57a29e5f33a5035917ef0bfffaa61326148c7afa Mon Sep 17 00:00:00 2001
From fe21f14e35d6b5606b1f5f84cca6fd4bea41d915 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 5 Jul 2022 11:58:09 +0100
Subject: [PATCH] RHEL: tests: Remove btrfs test
@ -9,7 +9,7 @@ RHEL does not have btrfs so this test always fails.
1 file changed, 1 deletion(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 54cfd124..8e142b09 100644
index 19a60f73..9a0726d2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -64,7 +64,6 @@ TESTS = \

View File

@ -1,4 +1,4 @@
From 61eac56a5cb787d591b9338324513b94f0f51b74 Mon Sep 17 00:00:00 2001
From 93ef7cb7183afaa4a5a6800ff0ecca0913010e79 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 9 Jul 2024 11:30:09 +0100
Subject: [PATCH] RHEL: Add warning about virt-v2v-in-place not being supported
@ -10,10 +10,10 @@ Fixes: https://issues.redhat.com/browse/RHEL-40903
2 files changed, 7 insertions(+)
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 7e490867..6c2790af 100644
index e84266ab..a96d55d9 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -229,6 +229,9 @@ read the man page virt-v2v-in-place(1).
@@ -232,6 +232,9 @@ read the man page virt-v2v-in-place(1).
let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true ~machine_readable:true usage_msg in
Getopt.parse opthandle.getopt;
@ -24,7 +24,7 @@ index 7e490867..6c2790af 100644
debug "info: %s: %s %s (%s)"
prog Config.package_name Config.package_version_full
diff --git a/in-place/virt-v2v-in-place.pod b/in-place/virt-v2v-in-place.pod
index 69d2092e..7c0a4d90 100644
index 333a6827..ac4142ae 100644
--- a/in-place/virt-v2v-in-place.pod
+++ b/in-place/virt-v2v-in-place.pod
@@ -16,6 +16,10 @@ virt-v2v-in-place - Convert a guest to use KVM in-place

View File

@ -1,4 +1,4 @@
From 9e9546aa983337e197407ce25ef3d3cd0a3cf173 Mon Sep 17 00:00:00 2001
From 7deb382a96bc6bfbff34b6880106d4875d8baeb8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 12 Dec 2025 16:18:15 +0000
Subject: [PATCH] RHEL: output/output.ml: Remove reduce-memory-pressure=on

View File

@ -0,0 +1,96 @@
From 02752f0c9ec3825cec6e96b78ef833a8ffac381f Mon Sep 17 00:00:00 2001
From: Susant Sahani <ssahani@redhat.com>
Date: Fri, 27 Mar 2026 06:54:25 +0530
Subject: [PATCH] smp: use cgroup CPU limits for appliance SMP
Use Cgroup.nr_cpus_available instead of nr_processors_online
to respect container cgroup CPU limits when setting SMP.
(cherry picked from commit db696f4cff486373a87c71d1de2d4dda4b047c8f)
[For RHEL 10.2 I also updated the common submodule to include:
commit bff133edf "smp: respect cgroup v2 CPU limits for appliance SMP"]
---
common | 2 +-
convert/convert.ml | 8 +-------
2 files changed, 2 insertions(+), 8 deletions(-)
Submodule common 763a2102..5971cbb3:
diff --git a/common/mlutils/unix_utils.ml b/common/mlutils/unix_utils.ml
index b79144a9..b21b9227 100644
--- a/common/mlutils/unix_utils.ml
+++ b/common/mlutils/unix_utils.ml
@@ -89,3 +89,28 @@ module Sysconf = struct
external nr_processors_online : unit -> int =
"guestfs_int_mllib_sysconf_nr_processors_online" [@@noalloc]
end
+
+module Cgroup = struct
+ let v2_cpus () =
+ let file = "/sys/fs/cgroup/cpu.max" in
+ if Sys.file_exists file then
+ try
+ let line = read_first_line_from_file file in
+ if String.starts_with ~prefix:"max" line then
+ None
+ else
+ let quota, period =
+ Scanf.sscanf line "%Ld %Ld" (fun q p -> (q, p)) in
+ if period > 0L then
+ Some (max 1 (Int64.to_int (Int64.div quota period)))
+ else None
+ with
+ | Scanf.Scan_failure _ | Failure _ | End_of_file -> None
+ else
+ None
+
+ let nr_cpus_available () =
+ match v2_cpus () with
+ | Some cpus -> cpus
+ | None -> Sysconf.nr_processors_online ()
+end
diff --git a/common/mlutils/unix_utils.mli b/common/mlutils/unix_utils.mli
index aead4df2..cb4f0426 100644
--- a/common/mlutils/unix_utils.mli
+++ b/common/mlutils/unix_utils.mli
@@ -130,3 +130,21 @@ module Sysconf : sig
Note this never fails. In case we cannot get the number of
cores it returns 1. *)
end
+
+module Cgroup : sig
+ (** Functions to read CPU limits from cgroup filesystems. *)
+
+ val v2_cpus : unit -> int option
+ (** [v2_cpus ()] reads the cgroup v2 CPU quota from
+ [/sys/fs/cgroup/cpu.max] and returns the number of CPUs
+ allocated (quota / period), or [None] if the file does not
+ exist, the quota is "max" (unlimited), or the file cannot
+ be parsed. The kernel stores quota and period as [long]
+ values in microseconds, so we parse them as [Int64]. *)
+
+ val nr_cpus_available : unit -> int
+ (** [nr_cpus_available ()] returns the number of CPUs available,
+ taking into account cgroup v2 CPU limits.
+ Falls back to {!Sysconf.nr_processors_online} if no cgroup
+ limits are set. *)
+end
diff --git a/convert/convert.ml b/convert/convert.ml
index 5aca94f1..bd1dfe65 100644
--- a/convert/convert.ml
+++ b/convert/convert.ml
@@ -69,13 +69,7 @@ let rec convert input_disks options source =
let smp =
match options.smp with
| None ->
- (* Default (if [--smp] option is not used) is to set the number
- * according to the number of physical CPUs on the host, but
- * limit it because each vCPU consumes guest RAM. This is
- * necessary to allow parallel mkinitrd which greatly improves
- * performance.
- *)
- min 8 (Sysconf.nr_processors_online ())
+ min 8 (Cgroup.nr_cpus_available ())
| Some smp -> smp in
g#set_smp smp;

View File

@ -0,0 +1,31 @@
From f3c6cbcfa3704800668e663c7767664f8be07737 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 12 May 2026 14:58:06 +0100
Subject: [PATCH] Update common submodule
Richard W.M. Jones (2):
mlcustomize: Remove fictitious "vista" virtio-win directory
mlcustomize: Use 2k8 drivers for Windows Vista and 2008 Server R1
Fixes: https://redhat.atlassian.net/browse/RHEL-174513
---
common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Submodule common 5971cbb3..3fdd2edc:
diff --git a/common/mlcustomize/inject_virtio_win.ml b/common/mlcustomize/inject_virtio_win.ml
index a2938080..ce24332f 100644
--- a/common/mlcustomize/inject_virtio_win.ml
+++ b/common/mlcustomize/inject_virtio_win.ml
@@ -468,10 +468,8 @@ and virtio_iso_path_matches_guest_os t path =
((=) "winxp")
else if pathelem "2k3" then
(function "win2k3" | "win2k3r2" -> true | _ -> false)
- else if pathelem "vista" then
- ((=) "winvista")
else if pathelem "2k8" then
- ((=) "win2k8")
+ (function "win2k8" | "winvista" -> true | _ -> false)
else if pathelem "w7" then
((=) "win7")
else if pathelem "2k8r2" then

View File

@ -45,7 +45,7 @@ ExclusiveArch: x86_64
Name: virt-v2v
Epoch: 1
Version: 2.10.0
Release: 7%{?dist}
Release: 17%{?dist}
Summary: Convert a virtual machine to run on KVM
License: GPL-2.0-or-later AND LGPL-2.0-or-later
@ -84,17 +84,29 @@ Patch0016: 0016-output-introduce-disk_name-helper.patch
Patch0017: 0017-output-Replace-in-VM-names-with-_.patch
Patch0018: 0018-output-sanitize-guest-names-in-metadata-file-paths.patch
Patch0019: 0019-output-sanitize-VM-names-in-libvirt-XML.patch
Patch0020: 0020-RHEL-Fixes-for-libguestfs-winsupport.patch
Patch0021: 0021-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch
Patch0022: 0022-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch
Patch0023: 0023-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch
Patch0024: 0024-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch
Patch0025: 0025-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch
Patch0026: 0026-RHEL-tests-Remove-btrfs-test.patch
Patch0027: 0027-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0028: 0028-RHEL-output-output.ml-Remove-reduce-memory-pressure-.patch
Patch0029: 0029-Update-common-submodule.patch
Patch0030: 0030-convert-linux-properly-match-etc-crypttab.patch
Patch0020: 0020-Update-common-submodule.patch
Patch0021: 0021-convert-linux-properly-match-etc-crypttab.patch
Patch0022: 0022-Update-common-submodule.patch
Patch0023: 0023-Add-no-fstrim-option-to-disable-fstrim-during-conver.patch
Patch0024: 0024-convert-Stop-using-maxmem-xfs_repair-m-option.patch
Patch0025: 0025-Update-common-submodule.patch
Patch0026: 0026-docs-Show-input-parameters-for-i-input-methods.patch
Patch0027: 0027-docs-i-disk-allows-multiple-disk-images.patch
Patch0028: 0028-i-disk-Allow-nbd-URIs-for-input-disks.patch
Patch0029: 0029-tests-Add-test-for-i-disk-nbd-URI.patch
Patch0030: 0030-common-update-submodule.patch
Patch0031: 0031-common-update-submodule.patch
Patch0032: 0032-RHEL-Fixes-for-libguestfs-winsupport.patch
Patch0033: 0033-RHEL-v2v-Select-correct-qemu-binary-for-o-qemu-mode-.patch
Patch0034: 0034-RHEL-v2v-Disable-the-qemu-boot-oo-qemu-boot-option-R.patch
Patch0035: 0035-RHEL-Fix-list-of-supported-sound-cards-to-match-RHEL.patch
Patch0036: 0036-RHEL-v2v-i-disk-force-VNC-as-display-RHBZ-1372671.patch
Patch0037: 0037-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch
Patch0038: 0038-RHEL-tests-Remove-btrfs-test.patch
Patch0039: 0039-RHEL-Add-warning-about-virt-v2v-in-place-not-being-s.patch
Patch0040: 0040-RHEL-output-output.ml-Remove-reduce-memory-pressure-.patch
Patch0041: 0041-smp-use-cgroup-CPU-limits-for-appliance-SMP.patch
Patch0042: 0042-Update-common-submodule.patch
BuildRequires: autoconf, automake, libtool
BuildRequires: make
@ -105,7 +117,7 @@ BuildRequires: perl(IPC::Run3)
BuildRequires: gcc
BuildRequires: ocaml >= 4.08
BuildRequires: libguestfs-devel >= 1:1.58.1-2
BuildRequires: libguestfs-devel >= 1:1.58.1-6
BuildRequires: augeas-devel
BuildRequires: bash-completion
%if 0%{?fedora} || 0%{?rhel} >= 11
@ -151,7 +163,7 @@ BuildRequires: glibc-static
BuildRequires: gnupg2
%endif
Requires: libguestfs%{?_isa} >= 1:1.58.1-2
Requires: libguestfs%{?_isa} >= 1:1.58.1-6
Requires: guestfs-tools >= 1.54
# XFS is the default filesystem in Fedora and RHEL.
@ -399,6 +411,23 @@ done
%changelog
* Mon Jun 08 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 2.10.0-17
- Update to virt-v2v-2.10.0-17
- mlcustomize firstboot: be more careful about quoting and create a
sentinel file when firstboot completes
- Add --no-fstrim option to disable fstrim during conversion
- convert: stop using maxmem (xfs_repair -m option)
- mldrivers/firmware.ml: ignore CHS geometry error from parted
(Veritas/Sun partitions)
- docs: show input parameters for -i input methods
- docs: -i disk allows multiple disk images
- -i disk: allow nbd:// URIs for input disks
- Fix binary LUKS keys (read_whole_file, text: and base64: key prefixes)
- Windows firstboot: add exit code 250 to skip reboots
- smp: use cgroup CPU limits for appliance SMP
- Fix location of Windows Vista and Windows 2008 Server R1 drivers
- Require libguestfs >= 1:1.58.1-6 (text:/base64 LUKS prefixes)
* Tue Feb 17 2026 Cole Robinson <crobinso@redhat.com> - 2.10.0-7
- Attempt 2 to fix sles12sp5 crypttab
resolves: RHEL-93583