[Pkg-libvirt-commits] [libguestfs] 29/266: v2v: Add support for converting Windows guests.
Hilko Bengen
bengen at moszumanska.debian.org
Fri Oct 3 14:41:35 UTC 2014
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag debian/1%1.27.35-1
in repository libguestfs.
commit bcdbe6405c10ecb7374ae47eee6385be17dbd49e
Author: Richard W.M. Jones <rjones at redhat.com>
Date: Tue Jul 8 16:33:45 2014 +0100
v2v: Add support for converting Windows guests.
This completes commit f296d34f3b30c82309b22b54bf5a2c133992bd93.
---
run.in | 6 -
v2v/Makefile.am | 16 ++-
v2v/convert_windows.ml | 289 +++++++++++++++++++++++++++++++++++--------------
v2v/link.sh.in | 2 +-
4 files changed, 220 insertions(+), 93 deletions(-)
diff --git a/run.in b/run.in
index 1fcd795..f09b8fd 100755
--- a/run.in
+++ b/run.in
@@ -92,12 +92,6 @@ if [ -z "$XDG_CONFIG_DIRS" ]; then
export XDG_CONFIG_DIRS
fi
-# Data directory used by virt-v2v.
-if [ -z "$VIRT_TOOLS_DATA_DIR" ]; then
- VIRT_TOOLS_DATA_DIR="$s/v2v"
- export VIRT_TOOLS_DATA_DIR
-fi
-
# For Perl.
if [ -z "$PERL5LIB" ]; then
PERL5LIB="$b/perl/blib/lib:$b/perl/blib/arch"
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index a62e191..69875fd 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -68,9 +68,20 @@ virt_v2v_CFLAGS = \
BOBJECTS = \
$(top_builddir)/mllib/common_gettext.cmo \
$(top_builddir)/mllib/common_utils.cmo \
+ $(top_builddir)/mllib/regedit.cmo \
$(top_builddir)/mllib/tTY.cmo \
$(top_builddir)/mllib/progress.cmo \
$(top_builddir)/mllib/config.cmo \
+ $(top_builddir)/customize/urandom.cmx \
+ $(top_builddir)/customize/random_seed.cmx \
+ $(top_builddir)/customize/hostname.cmx \
+ $(top_builddir)/customize/timezone.cmx \
+ $(top_builddir)/customize/firstboot.cmx \
+ $(top_builddir)/customize/perl_edit.cmx \
+ $(top_builddir)/customize/crypt-c.o \
+ $(top_builddir)/customize/crypt.cmx \
+ $(top_builddir)/customize/password.cmx \
+ $(top_builddir)/customize/customize_run.cmo \
$(SOURCES_ML:.ml=.cmo)
XOBJECTS = $(BOBJECTS:.cmo=.cmx)
@@ -82,7 +93,8 @@ OCAMLPACKAGES = \
-I $(top_builddir)/src/.libs \
-I ../gnulib/lib/.libs \
-I $(top_builddir)/ocaml \
- -I $(top_builddir)/mllib
+ -I $(top_builddir)/mllib \
+ -I $(top_builddir)/customize
if HAVE_OCAML_PKG_GETTEXT
OCAMLPACKAGES += -package gettext-stub
endif
@@ -150,7 +162,7 @@ depend: .depend
.depend: $(wildcard $(abs_srcdir)/*.mli) $(wildcard $(abs_srcdir)/*.ml)
rm -f $@ $@-t
- $(OCAMLFIND) ocamldep -I ../ocaml -I $(abs_srcdir) -I $(abs_top_builddir)/mllib $^ | \
+ $(OCAMLFIND) ocamldep -I ../ocaml -I $(abs_srcdir) -I $(abs_top_builddir)/mllib -I $(abs_top_builddir)/customize $^ | \
$(SED) 's/ *$$//' | \
$(SED) -e :a -e '/ *\\$$/N; s/ *\\\n */ /; ta' | \
$(SED) -e 's,$(abs_srcdir)/,$(builddir)/,g' | \
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
index d8df3c8..3b0f673 100644
--- a/v2v/convert_windows.ml
+++ b/v2v/convert_windows.ml
@@ -21,6 +21,8 @@ open Printf
open Common_gettext.Gettext
open Common_utils
+open Regedit
+
open Utils
open Types
@@ -44,22 +46,26 @@ let convert verbose (g : G.guestfs) inspect source =
let virt_tools_data_dir =
try Sys.getenv "VIRT_TOOLS_DATA_DIR"
with Not_found -> Config.datadir // "virt-tools" in
+
let virtio_win_dir = "/usr/share/virtio-win" in
- (* Since this is a Windows guest, RHSrvAny must exist. (Check also
- * that it's not a dangling symlink but a real file).
- *)
- let rhsrvany_exe = virt_tools_data_dir // "rhsrvany.exe" in
- (try
- let chan = open_in rhsrvany_exe in
- close_in chan
- with
- Sys_error msg ->
- error (f_"'%s' is missing. This file is required in order to do Windows conversions. You can get it by building rhsrvany (https://github.com/rwmjones/rhsrvany). Original error: %s")
- rhsrvany_exe msg
- );
-
- let systemroot = g#inspect_get_windows_systemroot inspect.i_root 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 =
+ try
+ let chan = open_in rhev_apt_exe in
+ close_in chan;
+ Some rhev_apt_exe
+ with
+ Sys_error msg ->
+ warning ~prog (f_"'%s' is missing. Unable to install RHEV-APT (RHEV guest agent). Original error: %s")
+ rhev_apt_exe msg;
+ None in
+
+ let systemroot = g#inspect_get_windows_systemroot inspect.i_root
+ and major_version = g#inspect_get_major_version inspect.i_root
+ and minor_version = g#inspect_get_minor_version inspect.i_root
+ and arch = g#inspect_get_arch inspect.i_root in
(* This is a wrapper that handles opening and closing the hive
* properly around a function [f]. If [~write] is [true] then the
@@ -90,32 +96,6 @@ let convert verbose (g : G.guestfs) inspect source =
let node = g#hivex_node_get_child node x in
if node = 0L then raise Not_found;
get_node node xs
-
- (* Take a 7 bit ASCII string and encode it as UTF16LE. *)
- and encode_utf16le str =
- let len = String.length str in
- let copy = String.make (len*2) '\000' in
- for i = 0 to len-1 do
- String.unsafe_set copy (i*2) (String.unsafe_get str i)
- done;
- copy
-
- (* Take a UTF16LE string and decode it to UTF-8. Actually this
- * fails if the string is not 7 bit ASCII. XXX Use iconv here.
- *)
- and decode_utf16le str =
- let len = String.length str in
- if len mod 2 <> 0 then
- error (f_"decode_utf16le: Windows string does not appear to be in UTF16-LE encoding. This could be a bug in virt-v2v.");
- let copy = String.create (len/2) in
- for i = 0 to (len/2)-1 do
- let cl = String.unsafe_get str (i*2) in
- let ch = String.unsafe_get str ((i*2)+1) in
- if ch != '\000' || Char.code cl >= 127 then
- error (f_"decode_utf16le: Windows UTF16-LE string contains non-7-bit characters. This is a bug in virt-v2v, please report it.");
- String.unsafe_set copy i cl
- done;
- copy
in
(*----------------------------------------------------------------------*)
@@ -135,7 +115,7 @@ let convert verbose (g : G.guestfs) inspect source =
raise Not_found
);
let data = g#hivex_value_value valueh in
- let data = decode_utf16le data in
+ let data = decode_utf16le ~prog data in
(* The uninstall program will be uninst.exe. This is a wrapper
* around _uninst.exe which prompts the user. As we don't want
@@ -162,6 +142,44 @@ let convert verbose (g : G.guestfs) inspect source =
(*----------------------------------------------------------------------*)
(* Perform the conversion of the Windows guest. *)
+ let rec configure_firstboot () =
+ let fb = Buffer.create 1024 in
+ bprintf fb "@echo off\n";
+
+ configure_rhev_apt fb;
+ unconfigure_xenpv fb;
+
+ (* Write the completed script to the guest. *)
+ let firstboot_script = Buffer.contents fb in
+ Firstboot.add_firstboot_script ~prog g inspect.i_root 1 firstboot_script
+
+ and configure_rhev_apt fb =
+ (* 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 *)
+
+ bprintf fb "\
+echo installing rhev-apt
+\"\\rhev-apt.exe\" /S /v /qn
+
+echo starting rhev-apt
+net start rhev-apt
+"
+
+ and unconfigure_xenpv fb =
+ match xenpv_uninst with
+ | None -> () (* nothing to be uninstalled *)
+ | Some uninst ->
+ bprintf fb "\
+echo uninstalling Xen PV driver
+\"%s\"
+" uninst
+ in
+
let rec update_system_hive root =
(* Update the SYSTEM hive. When this function is called the hive has
* already been opened as a hivex handle inside guestfs.
@@ -175,58 +193,158 @@ let convert verbose (g : G.guestfs) inspect source =
if verbose then printf "current ControlSet is %s\n%!" current_cs;
- let firstboot = configure_firstboot root current_cs in
- configure_rhev_apt root firstboot;
- (match xenpv_uninst with
- | None -> () (* nothing to be uninstalled *)
- | Some uninst -> unconfigure_xenpv root firstboot uninst
- );
- close_firstboot root firstboot;
disable_services root current_cs;
- let block_net_drivers = install_virtio_drivers root current_cs in
-
- block_net_drivers
-
- and configure_firstboot root current_cs =
- ignore virt_tools_data_dir;
- ()
-
-
-
-
- and configure_rhev_apt root firstboot =
- ()
-
-
-
- and unconfigure_xenpv root firstboot uninst_exe =
- ()
-
-
-
-
-
- and close_firstboot root firstboot =
- ()
-
-
-
-
+ install_virtio_drivers root current_cs
and disable_services root current_cs =
- ()
-
-
-
+ (* Disable miscellaneous services. *)
+ let services = get_node root [current_cs; "Services"] in
+ (* Disable the Processor and Intelppm services
+ * http://blogs.msdn.com/b/virtual_pc_guy/archive/2005/10/24/484461.aspx
+ *
+ * Disable the rhelscsi service (RHBZ#809273).
+ *)
+ let disable = [ "Processor"; "Intelppm"; "rhelscsi" ] in
+ List.iter (
+ fun name ->
+ let node = g#hivex_node_get_child services name in
+ if node <> 0L then (
+ (* Delete the node instead of trying to disable it. RHBZ#737600. *)
+ g#hivex_node_delete_child node
+ )
+ ) disable
and install_virtio_drivers root current_cs =
- ignore virtio_win_dir;
- ("XXX", "XXX")
-
+ (* Copy the virtio drivers to the guest. *)
+ let driverdir = sprintf "%s/Drivers/VirtIO" systemroot in
+ let driverdir = g#case_sensitive_path driverdir in
+ g#mkdir_p driverdir;
+
+ (* See if the drivers for this guest are available in virtio_win_dir. *)
+ let path =
+ match major_version, minor_version, arch with
+ | 5, 1, "i386" ->
+ Some (virtio_win_dir // "drivers/i386/WinXP")
+ | 5, 2, "i386" ->
+ Some (virtio_win_dir // "drivers/i386/Win2003")
+ | 5, 2, "x86_64" ->
+ Some (virtio_win_dir // "drivers/amd64/Win2003")
+ | 6, 0, "i386" ->
+ Some (virtio_win_dir // "drivers/i386/Win2008")
+ | 6, 0, "x86_64" ->
+ Some (virtio_win_dir // "drivers/amd64/Win2008")
+ | 6, 1, "i386" ->
+ Some (virtio_win_dir // "drivers/i386/Win2008R2")
+ | 6, 1, "x86_64" ->
+ Some (virtio_win_dir // "drivers/amd64/Win2008R2")
+ | 6, 3, "i386" ->
+ Some (virtio_win_dir // "drivers/i386/Win2012R2")
+ | 6, 3, "x86_64" ->
+ Some (virtio_win_dir // "drivers/amd64/Win2012R2")
+ | _, _, _ ->
+ None in
+
+ let path =
+ match path with
+ | None -> None
+ | Some path ->
+ if is_directory path then Some path else None in
+
+ match path with
+ | None ->
+ warning ~prog (f_"there are no virtio drivers available for this version of Windows (%d.%d %s). virt-v2v looks for drivers in %s\n\nThe guest will be configured to use slower emulated devices.")
+ major_version minor_version arch virtio_win_dir;
+ ( "ide", "rtl8139" )
+
+ | Some path ->
+ (* Can we install the block driver? *)
+ let block =
+ let block_path = path // "viostor.sys" in
+ if not (Sys.file_exists block_path) then (
+ warning ~prog (f_"there is no viostor (virtio block device) driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver here: %s\n\nThe guest will be configured to use a slower emulated device.")
+ major_version minor_version arch block_path;
+ "ide"
+ )
+ else (
+ let target = sprintf "%s/system32/drivers/viostor.sys" systemroot in
+ let target = g#case_sensitive_path target in
+ g#cp block_path target;
+ add_viostor_to_critical_device_database root current_cs;
+ "virtio"
+ ) in
+
+ (* Can we install the virtio-net driver? *)
+ let net =
+ let net_path = path // "netkvm.inf" in
+ if not (Sys.file_exists net_path) then (
+ warning ~prog (f_"there is no virtio network driver for this version of Windows (%d.%d %s). virt-v2v looks for this driver here: %s\n\nThe guest will be configured to use a slower emulated device.")
+ major_version minor_version arch net_path;
+ "rtl8139"
+ )
+ else
+ (* It will be installed at firstboot. *)
+ "virtio" in
+ (* Copy the drivers to the driverdir. They will be installed at
+ * firstboot.
+ *)
+ let files = Sys.readdir path in
+ let files = Array.to_list files in
+ let files = List.map ((//) path) files in
+ List.iter (fun file -> g#upload file driverdir) files;
+ (block, net)
+ and add_viostor_to_critical_device_database root current_cs =
+ (* 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 regedits = [
+ [ current_cs; "Control"; "CriticalDeviceDatabase"; "pci#ven_1af4&dev_1001&subsys_00000000" ],
+ [ "Service", REG_SZ "viostor";
+ "ClassGUID", REG_SZ "{4D36E97B-E325-11CE-BFC1-08002BE10318}" ];
+
+ [ current_cs; "Control"; "CriticalDeviceDatabase"; "pci#ven_1af4&dev_1001&subsys_00020000" ],
+ [ "Service", REG_SZ "viostor";
+ "ClassGUID", REG_SZ "{4D36E97B-E325-11CE-BFC1-08002BE10318}" ];
+
+ [ current_cs; "Control"; "CriticalDeviceDatabase"; "pci#ven_1af4&dev_1001&subsys_00021af4" ],
+ [ "Service", REG_SZ "viostor";
+ "ClassGUID", REG_SZ "{4D36E97B-E325-11CE-BFC1-08002BE10318}" ];
+
+ [ current_cs; "Services"; "viostor" ],
+ [ "Type", REG_DWORD 0x1_l;
+ "Start", REG_DWORD 0x0_l;
+ "Group", REG_SZ "SCSI miniport";
+ "ErrorControl", REG_DWORD 0x1_l;
+ "ImagePath", REG_SZ "system32\\\\drivers\\\\viostor.sys";
+ "Tag", REG_DWORD 0x21_l ];
+
+ [ current_cs; "Services"; "viostor"; "Parameters" ],
+ [ "BusType", REG_DWORD 0x1_l ];
+
+ [ current_cs; "Services"; "viostor"; "Parameters"; "MaxTransferSize" ],
+ [ "ParamDesc", REG_SZ "Maximum Transfer Size";
+ "type", REG_SZ "enum";
+ "default", REG_SZ "0" ];
+
+ [ current_cs; "Services"; "viostor"; "Parameters"; "MaxTransferSize"; "enum" ],
+ [ "0", REG_SZ "64 KB";
+ "1", REG_SZ "128 KB";
+ "2", REG_SZ "256 KB" ];
+
+ [ current_cs; "Services"; "viostor"; "Parameters"; "PnpInterface" ],
+ [ "5", REG_DWORD 0x1_l ];
+
+ [ current_cs; "Services"; "viostor"; "Enum" ],
+ [ "0", REG_SZ "PCI\\VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00\\3&13c0b0c5&0&20";
+ "Count", REG_DWORD 0x1_l;
+ "NextInstance", REG_DWORD 0x1_l ];
+ ] in
+
+ reg_import g root regedits
and update_software_hive root =
(* Update the SOFTWARE hive. When this function is called the
@@ -336,6 +454,9 @@ let convert verbose (g : G.guestfs) inspect source =
)
in
+ (* Firstboot configuration. *)
+ configure_firstboot ();
+
(* Open the system hive and update it. *)
let block_driver, net_driver =
with_hive "system" ~write:true update_system_hive in
diff --git a/v2v/link.sh.in b/v2v/link.sh.in
index 9e5684b..f909015 100644
--- a/v2v/link.sh.in
+++ b/v2v/link.sh.in
@@ -19,4 +19,4 @@
# Hack automake to link binary properly. There is no other way to add
# the -cclib parameter to the end of the command line.
-exec "$@" -linkpkg -cclib '-lutils -lncurses @LIBXML2_LIBS@ -lgnu'
+exec "$@" -linkpkg -cclib '-lutils -lncurses -lcrypt @LIBXML2_LIBS@ -lgnu'
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git
More information about the Pkg-libvirt-commits
mailing list