[Libguestfs] [PATCH v3 2/3] v2v: add support for SUSE VMDP drivers

Cédric Bosdonnat cbosdonnat at suse.com
Mon May 23 13:31:45 UTC 2016


To add this support, two things are needed:
 * make the existing code searches for either the viostor
   or the SUSE VMDP (Virtual Machine Driver Pack) files.

 * add a firstboot script setting up VMDP.

Note that 2 firstboot scripts are intentionally added for the VMDP
setup. This is due to windows potentially rebooting after loading the
virtio block driver. It may happen that this reboot interrupts the VMDP
setup in the firstboot script, we thus make sure the setup is run a
second time in case it needs to finish the previous run.
---
 v2v/convert_windows.ml | 77 +++++++++++++++++++++++++++++++++++++-------------
 v2v/windows_virtio.ml  | 35 +++++++++++++++--------
 2 files changed, 81 insertions(+), 31 deletions(-)

diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index aa5cb3b..62bb536 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 = [`RhevApt, "rhev-apt.exe"; `VmdpExe, "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 t, tool = List.find (
+        fun (_, tool) ->
+          try (
+            let exe_path = virt_tools_data_dir // tool in
+            let chan = open_in exe_path in
+            close_in chan;
+            true
+          ) with _ ->
+            false
+      ) tools in
+      Some (t, 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,20 +218,20 @@ 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 -> ()
+    | Some (`RhevApt, tool_path) -> configure_rhev_apt tool_path
+    | Some (`VmdpExe, tool_path) -> configure_vmdp tool_path;
     unconfigure_xenpv ();
     unconfigure_prltools ()
 
-  and configure_rhev_apt () =
+  and configure_rhev_apt tool_path =
     (* Configure RHEV-APT (the RHEV guest agent).  However if it doesn't
      * exist just warn about it and continue.
      *)
-    match rhev_apt_exe with
-    | None -> ()
-    | Some rhev_apt_exe ->
-      g#upload rhev_apt_exe "/rhev-apt.exe"; (* XXX *)
+    g#upload tool_path "/rhev-apt.exe"; (* XXX *)
 
-      let fb_script = "\
+    let fb_script = "\
 @echo off
 
 echo installing rhev-apt
@@ -233,8 +240,38 @@ echo installing rhev-apt
 echo starting rhev-apt
 net start rhev-apt
 " in
-      Firstboot.add_firstboot_script g inspect.i_root
-        "configure rhev-apt" fb_script
+    Firstboot.add_firstboot_script g inspect.i_root
+      "configure rhev-apt" fb_script
+
+  and configure_vmdp tool_path =
+    (* Configure VMDP if possible *)
+    g#upload tool_path "/vmdp.exe";
+
+    let fb_script = "\
+echo V2V first boot script started
+echo Decompressing VMDP installer
+\"\\vmdp.exe\"
+pushd \"VMDP-*\"
+echo Installing VMDP
+setup.exe /eula_accepted /no_reboot
+popd
+" in
+
+    let fb_recover_script = "\
+echo Finishing VMDP installation
+if not exist VMDP-* (
+  \"\\vmdp.exe\"
+)
+pushd \"VMDP-*\"
+setup.exe /eula_accepted /no_reboot
+popd
+" in
+
+    Firstboot.add_firstboot_script g inspect.i_root
+      "configure vmdp" fb_script;
+
+    Firstboot.add_firstboot_script g inspect.i_root
+      "finish vmdp setup" fb_recover_script
 
   and unconfigure_xenpv () =
     match xenpv_uninst with
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
index 07b4d4b..6c8396c 100644
--- a/v2v/windows_virtio.ml
+++ b/v2v/windows_virtio.ml
@@ -66,11 +66,20 @@ 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 = ["virtio_blk"; "vrtioblk"; "viostor"] in
+      let viostor_driver = try (
+        Some (
+          List.find (
+            fun driver_file ->
+              let source = driverdir // driver_file ^ ".sys" in
+              g#exists source
+          ) filenames
+        )
+      ) with Not_found -> None in
       let has_vioscsi = g#exists (driverdir // "vioscsi.inf") in
-      match rcaps.rcaps_block_bus, has_viostor, has_vioscsi 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.")
+      match rcaps.rcaps_block_bus, viostor_driver, has_vioscsi with
+      | Some Virtio_blk, None, _ ->
+        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
 
@@ -79,20 +88,20 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
               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.")
+      | None, None, _ ->
+        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
 
-      | (Some Virtio_blk | None), true, _ ->
+      | (Some Virtio_blk | None), Some driver_name, _ ->
         (* 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 ^ ".sys") in
+        let target = sprintf "%s/system32/drivers/%s.sys" systemroot driver_name in
         let target = g#case_sensitive_path target in
         g#cp source target;
-        add_guestor_to_registry g root current_cs "viostor"
+        add_guestor_to_registry g root current_cs driver_name
                                 viostor_pciid;
         Virtio_blk
 
@@ -112,7 +121,11 @@ 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 = ["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")
-- 
2.6.6




More information about the Libguestfs mailing list