[Libguestfs] [PATCH 7/7] v2v: add support for SUSE VMDP drivers
Richard W.M. Jones
rjones at redhat.com
Tue Apr 5 12:21:19 UTC 2016
On Tue, Apr 05, 2016 at 01:47:33PM +0200, Cédric Bosdonnat wrote:
> To add this support, the existing code searches for either the viostor
> or the VMDP (Virtual Machine Driver Pack) files and updates the registry
> accordingly.
>
> Note that VMDP's block driver pvvxblk depends on the ballooning driver
> pvvxbn.
I didn't check this in detail, but it seems reasonable.
Rich.
> v2v/convert_windows.ml | 59 ++++++++++++++++++++------
> v2v/windows_virtio.ml | 113 +++++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 141 insertions(+), 31 deletions(-)
>
> diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
> index 5daae6c..cb936ec 100644
> --- a/v2v/convert_windows.ml
> +++ b/v2v/convert_windows.ml
> @@ -43,18 +43,25 @@ let convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
> try Sys.getenv "VIRT_TOOLS_DATA_DIR"
> with Not_found -> Guestfs_config.datadir // "virt-tools" in
>
> - (* Check if RHEV-APT exists. This is optional. *)
> - let rhev_apt_exe = virt_tools_data_dir // "rhev-apt.exe" in
> - let rhev_apt_exe =
> + (* Check if either RHEV-APT or VMDP exists. This is optional. *)
> + let tools = ["rhev-apt.exe"; "vmdp.exe"] in
> + let installer =
> try
> - let chan = open_in rhev_apt_exe in
> - close_in chan;
> - Some rhev_apt_exe
> - with
> - Sys_error msg ->
> - warning (f_"'%s' is missing. Unable to install RHEV-APT (RHEV guest agent). Original error: %s")
> - rhev_apt_exe msg;
> - None in
> + let tool = List.find (
> + fun item ->
> + try (
> + let exe_path = virt_tools_data_dir // item in
> + let chan = open_in exe_path in
> + close_in chan;
> + true
> + ) with _ ->
> + false
> + ) tools in
> + Some (virt_tools_data_dir // tool)
> + with Not_found -> (
> + warning (f_"Neither rhev-apt.exe nor vmdp.exe can be found. Unable to install one of them.");
> + None
> + ) in
>
> (* Get the Windows %systemroot%. *)
> let systemroot = g#inspect_get_windows_systemroot inspect.i_root in
> @@ -211,7 +218,14 @@ let convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
> (* Perform the conversion of the Windows guest. *)
>
> let rec configure_firstboot () =
> - configure_rhev_apt ();
> + match installer with
> + | None -> info (f_"No firstboot installer to configure")
> + | Some installer_path ->
> + let installer_name = Filename.basename installer_path in
> + match installer_name with
> + | "rhev-apt.exe" -> configure_rhev_apt ()
> + | "vmdp.exe" -> configure_vmdp ()
> + | _ -> info (f_"No setup function for installer '%s'") installer_path;
> unconfigure_xenpv ();
> unconfigure_prltools ()
>
> @@ -219,7 +233,7 @@ let convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
> (* Configure RHEV-APT (the RHEV guest agent). However if it doesn't
> * exist just warn about it and continue.
> *)
> - match rhev_apt_exe with
> + match installer with
> | None -> ()
> | Some rhev_apt_exe ->
> g#upload rhev_apt_exe "/rhev-apt.exe"; (* XXX *)
> @@ -236,6 +250,25 @@ net start rhev-apt
> Firstboot.add_firstboot_script g inspect.i_root
> "configure rhev-apt" fb_script
>
> + and configure_vmdp () =
> + (* Configure VMDP if possible *)
> + match installer with
> + | None -> ()
> + | Some vmdp_exe ->
> + g#upload vmdp_exe "/vmdp.exe";
> +
> + let fb_script = "\
> +echo V2V first boot script started
> +echo Decompressing VMDP installer
> +\"\\vmdp.exe\"
> +cd \"VMDP-WIN*\"
> +echo Installing VMDP
> +setup.exe /eula_accepted /auto_reboot
> +cd ..
> +" in
> + Firstboot.add_firstboot_script g inspect.i_root
> + "configure vmdp" fb_script
> +
> and unconfigure_xenpv () =
> match xenpv_uninst with
> | None -> () (* nothing to be uninstalled *)
> diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
> index 22e3e31..87e39e6 100644
> --- a/v2v/windows_virtio.ml
> +++ b/v2v/windows_virtio.ml
> @@ -62,15 +62,23 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
> else (
> (* Can we install the block driver? *)
> let block : guestcaps_block_type =
> - let has_viostor = g#exists (driverdir // "viostor.inf") in
> + let filenames = ["pvvxblk.sys"; "virtio_blk.sys"; "vrtioblk.sys"; "viostor.sys"] in
> + let driver_name = try (
> + List.find (
> + fun driver_file ->
> + let source = driverdir // driver_file in
> + g#exists source
> + ) filenames
> + ) with Not_found -> "" in
> + let has_viostor = not (driver_name = "") in
> match rcaps.rcaps_block_bus, has_viostor with
> | Some Virtio_blk, false ->
> - error (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
> + error (f_"there is no virtio block device driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
> inspect.i_major_version inspect.i_minor_version
> inspect.i_arch virtio_win
>
> | None, false ->
> - warning (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
> + warning (f_"there is no virtio block device driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s\n\nThe guest will be configured to use a slower emulated device.")
> inspect.i_major_version inspect.i_minor_version
> inspect.i_arch virtio_win;
> IDE
> @@ -78,11 +86,17 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
> | (Some Virtio_blk | None), true ->
> (* Block driver needs tweaks to allow booting; the rest is set up by PnP
> * manager *)
> - let source = driverdir // "viostor.sys" in
> - let target = sprintf "%s/system32/drivers/viostor.sys" systemroot in
> + let source = driverdir // driver_name in
> + let targetdir = systemroot ^ "/system32/drivers/" in
> + let target = targetdir // driver_name in
> let target = g#case_sensitive_path target in
> g#cp source target;
> - add_viostor_to_registry g inspect root current_cs driverdir;
> + if (driver_name = "pvvxblk.sys") then (
> + let target = targetdir // "pvvxbn.sys" in
> + let target = g#case_sensitive_path target in
> + g#cp (driverdir // "pvvxbn.sys") target
> + );
> + add_viostor_to_registry g inspect root current_cs driverdir driver_name;
> Virtio_blk
>
> | Some IDE, _ ->
> @@ -90,7 +104,8 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
>
> (* Can we install the virtio-net driver? *)
> let net : guestcaps_net_type =
> - let has_netkvm = g#exists (driverdir // "netkvm.inf") in
> + let filenames = ["pvvxnet.inf"; "virtio_net.inf"; "netkvm.inf"] in
> + let has_netkvm = List.exists (fun driver_file -> g#exists (driverdir // driver_file)) filenames in
> match rcaps.rcaps_net_bus, has_netkvm with
> | Some Virtio_net, false ->
> error (f_"there is no virtio network driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver in %s")
> @@ -133,20 +148,19 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
> (block, net, video)
> )
>
> -and add_viostor_to_registry g inspect root current_cs driverdir =
> +and add_viostor_to_registry g inspect root current_cs driverdir driver_name =
> let { i_major_version = major; i_minor_version = minor;
> i_arch = arch } = inspect in
> if (major == 6 && minor >= 2) || major >= 7 then (* Windows >= 8 *)
> - add_viostor_to_driver_database g root arch current_cs driverdir
> + add_viostor_to_driver_database g root arch current_cs driverdir driver_name
> else (* Windows <= 7 *)
> - add_viostor_to_critical_device_database g root current_cs major
> + add_viostor_to_critical_device_database g root current_cs major driver_name
>
> -and add_viostor_to_critical_device_database g root current_cs major =
> +and add_viostor_to_critical_device_database g root current_cs major driver =
> (* See http://rwmj.wordpress.com/2010/04/30/tip-install-a-device-driver-in-a-windows-vm/
> * NB: All these edits are in the HKLM\SYSTEM hive. No other
> * hive may be modified here.
> *)
> - let driver = "viostor.sys" in
> let driver_name = Filename.chop_extension driver in
> (* Windows 2k3 uses '&0&', windows 2k8 '&2&' *)
> let subkey =
> @@ -208,11 +222,10 @@ and add_viostor_to_critical_device_database g root current_cs major =
>
> reg_import g root regedits
>
> -and add_viostor_to_driver_database g root arch current_cs driverdir =
> +and add_viostor_to_driver_database g root arch current_cs driverdir driver =
> (* Windows >= 8 doesn't use the CriticalDeviceDatabase. Instead
> * one must add keys into the DriverDatabase.
> *)
> - let driver = "viostor.sys" in
> let driver_name = Filename.chop_extension driver in
>
> let inf_full =
> @@ -229,8 +242,12 @@ and add_viostor_to_driver_database g root arch current_cs driverdir =
>
> let scsi_adapter_guid = "{4d36e97b-e325-11ce-bfc1-08002be10318}" in
>
> - let driverdesc = "Red Hat VirtIO SCSI controller" in
> - let provider = "Red Hat, Inc." in
> + let driverdesc = if (driver_name = "pvvxblk")
> + then "SUSE Block Driver for Windows"
> + else "Red Hat VirtIO SCSI controller" in
> +
> + let provider = if (driver_name = "pvvxblk") then "SUSE" else "Red Hat, Inc." in
> + let msi_supported = if (driver_name = "pvvxblk") then 0x0_l else 0x1_l in
>
> let driver_inst = (sprintf "%s_inst" driver_name) in
>
> @@ -256,11 +273,14 @@ and add_viostor_to_driver_database g root arch current_cs driverdir =
> [ "DevicePolicy", REG_DWORD 0x00000005_l ];
>
> [ "DriverDatabase"; "DriverPackages"; inf_full; "Configurations"; driver_inst; "Device"; "Interrupt Management"; "MessageSignaledInterruptProperties" ],
> - [ "MSISupported", REG_DWORD 0x00000001_l;
> + [ "MSISupported", REG_DWORD msi_supported;
> "MessageNumberLimit", REG_DWORD 0x00000002_l ];
> ] in
>
> - reg_import g root regedits;
> + (reg_import g root regedits;
> + if (driver_name = "pvvxblk") then
> + add_pvvxbn_to_driver_database g root arch current_cs driverdir
> + );
>
> (*
> A few more keys which we don't add above. Note that "oem1.inf" ==
> @@ -454,6 +474,63 @@ and get_common_regedits g root current_cs adapter_guid driverdir driver driverde
> driverdesc_key, REG_SZ driverdesc ];
> ]
>
> +and add_pvvxbn_to_driver_database g root arch current_cs driverdir =
> +
> + let driver_name = "pvvxbn" in
> +
> + let inf_full =
> + let arch =
> + match arch with
> + | "x86_64" -> "amd64"
> + | "i386" | "i486" | "i585" | "i686" -> "x86"
> + | _ ->
> + error (f_"when adding pvvxbn to the DriverDatabase, unknown architecture: %s") arch in
> + sprintf "%s.inf_%s_%s" driver_name arch "9b414b949945d17b" in
> +
> + let driverdesc = "SUSE Bus/Balloon Driver for Windows" in
> + let driver_inst = "pvvxbn_inst" in
> + let provider = "SUSE" in
> +
> + let device_id = "VEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00" in
> + let device_subkey = "3&13c0b0c5&0&20" in
> + let device_alt = "CC_00FF00" in
> +
> + let balloon_bus_guid = "{4d36e97d-e325-11ce-bfc1-08002be10318}" in
> +
> + let class_guid = "{9fae43c0-44bf-465e-90c9-3da1c30ed68b}" in
> +
> + let service_group = "Boot Bus Extender" in
> + (* NB: balloon_bus_guid appears inside this string. *)
> + let driver_version = "\x00\xff\x09\x00\x00\x00\x00\x00\x7d\xe9\x36\x4d\x25\xe3\xce\x11\xbf\xc1\x08\x00\x2b\xe1\x03\x18\x00\x40\x7f\x1d\xdc\xfb\xd0\x01\x13\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" in
> + let device_addr = "(0,4,0)" in
> +
> + let common_regedits = get_common_regedits g root current_cs balloon_bus_guid driverdir "pvvxbn.sys" driverdesc driver_version service_group inf_full device_id device_subkey device_alt device_addr provider in
> +
> + let regedits = common_regedits @ [
> + [ current_cs; "Control"; "DeviceClasses"; class_guid ],
> + [];
> +
> + [ current_cs; "Control"; "DeviceClasses"; class_guid;
> + sprintf "##?#PCI#%s#%s#%s" device_id device_subkey class_guid ],
> + [ "DeviceInstance", REG_SZ (sprintf "PCI\\%s\\%s" device_id device_subkey) ];
> +
> + [ current_cs; "Control"; "DeviceClasses"; class_guid;
> + sprintf "##?#PCI#%s#%s#%s" device_id device_subkey class_guid; "#" ],
> + [];
> +
> + [ current_cs; "Services"; driver_name; "Parameters"; "Device" ],
> + [ "grant_frames", REG_DWORD 0xA_l;
> + "pvctrl_flags", REG_DWORD 0x5_l;
> + "shutdown_notification", REG_DWORD 0x1_l;
> + "use_pv_drivers", REG_DWORD 0x1c0003_l ];
> +
> + [ "DriverDatabase"; "DriverPackages"; inf_full; "Configurations"; driver_inst; "Services"; driver_name; "Parameters"; "Device" ],
> + [ "dbg_print_mask", REG_DWORD 0x7_l ];
> +
> + ] in
> +
> + reg_import g root regedits;
> +
> (* Copy the matching drivers to the driverdir; return true if any have
> * been copied.
> *)
> --
> 2.6.2
>
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
More information about the Libguestfs
mailing list