Query libosinfo to get the list of files for drivers of Windows guests,
copying them if they are local files only. In case it is not possible
(e.g. no driver files are listed, or their location is a non-local URL,
or they do not exists), the manual filtering of the virtio-win content
is done as before.
---
v2v/windows_virtio.ml | 63 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 59 insertions(+), 4 deletions(-)
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 5ec7664b..be281247 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -297,10 +297,11 @@ and ddb_regedits inspect drv_name drv_pciid =
* been copied.
*)
and copy_drivers g inspect driverdir =
- [] <> copy_from_virtio_win g inspect "/" driverdir
- virtio_iso_path_matches_guest_os
- (fun () ->
- error (f_"root directory ‘/’ is missing from the virtio-win directory or
ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in
some way. Please report this as a bug with a full debug log."))
+ [] <> copy_from_libosinfo g inspect driverdir ||
+ [] <> copy_from_virtio_win g inspect "/" driverdir
+ virtio_iso_path_matches_guest_os
+ (fun () ->
+ error (f_"root directory ‘/’ is missing from the virtio-win directory or
ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in
some way. Please report this as a bug with a full debug log."))
and copy_qemu_ga g inspect =
copy_from_virtio_win g inspect "/" "/"
@@ -460,6 +461,60 @@ and virtio_iso_path_matches_qemu_ga path inspect =
| ("x86_64", "RHEV-QGA64.msi") -> true
| _ -> false
+(* Look up in libosinfo for the OS, and copy all the locally
+ * available files specified as drivers for that OS to the [destdir].
+ *
+ * This function does nothing in case either:
+ * - the osinfo short ID is not found in the libosinfo DB
+ * - the OS does not have any driver for the same architecture
+ * - the location of the drivers is a local directory
+ *
+ * Files that do not exist are silently skipped.
+ *
+ * Returns list of copied files.
+ *)
+and copy_from_libosinfo g inspect destdir =
+ let { i_osinfo = osinfo; i_arch = arch } = inspect in
+ try
+ let os = Libosinfo_utils.get_os_by_short_id osinfo in
+ let driver =
+ List.find (
+ fun { Libosinfo.architecture; location } ->
+ (* Ignore different architectures than the guest's. *)
+ if architecture <> arch then
+ false
+ else
+ try
+ (* Ignore invalid URLs, and non-file ones. *)
+ (match Xml.parse_uri location with
+ | { Xml.uri_scheme = Some scheme;
+ Xml.uri_path = Some _ } when scheme = "file" -> true
+ | _ -> false
+ )
+ with Invalid_argument _ -> false
+ ) (os#get_device_drivers ()) in
+ let uri = Xml.parse_uri driver.Libosinfo.location in
+ let dir =
+ match uri.Xml.uri_path with
+ | Some p -> p
+ | None -> assert false in
+ List.filter_map (
+ fun f ->
+ let source = dir // f in
+ if not (Sys.file_exists source) then
+ None
+ else (
+ let target_name = String.lowercase_ascii (Filename.basename f) in
+ let target = destdir ^ "/" ^ target_name in
+ debug "windows: copying guest tools bits: 'host:%s' ->
'%s'"
+ source target;
+
+ g#copy_in source destdir;
+ Some target_name
+ )
+ ) driver.Libosinfo.files
+ with Not_found -> []
+
(* The following function is only exported for unit tests. *)
module UNIT_TESTS = struct
let virtio_iso_path_matches_guest_os = virtio_iso_path_matches_guest_os
--
2.24.1