mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
customize, v2v: Use %systemroot% and CurrentControlSet from inspection.
For reasons unknown virt-v2v recomputed the CurrentControlSet from first principles, and passed %systemroot% around to all functions. However that data is available from the libguestfs inspection APIs.
This commit is contained in:
@@ -318,12 +318,7 @@ echo uninstalling firstboot service
|
||||
let filename = g#case_sensitive_path filename in
|
||||
Registry.with_hive_write g filename
|
||||
(fun root_node ->
|
||||
(* Find the 'Current' ControlSet. *)
|
||||
let current_cs =
|
||||
let select = g#hivex_node_get_child root_node "Select" in
|
||||
let valueh = g#hivex_node_get_value select "Current" in
|
||||
let value = int_of_le32 (g#hivex_value_value valueh) in
|
||||
sprintf "ControlSet%03Ld" value in
|
||||
let current_cs = g#inspect_get_windows_current_control_set root in
|
||||
|
||||
(* Add a new rhsrvany service to the system registry to execute
|
||||
* firstboot. NB: All these edits are in the HKLM\SYSTEM hive.
|
||||
|
||||
@@ -68,17 +68,16 @@ let convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
|
||||
None
|
||||
) in
|
||||
|
||||
(* Get the Windows %systemroot%. *)
|
||||
let systemroot = g#inspect_get_windows_systemroot inspect.i_root in
|
||||
|
||||
(* Get the software and system hive files. *)
|
||||
let software_hive_filename =
|
||||
let filename = sprintf "%s/system32/config/software" systemroot in
|
||||
let filename = sprintf "%s/system32/config/software"
|
||||
inspect.i_windows_systemroot in
|
||||
let filename = g#case_sensitive_path filename in
|
||||
filename in
|
||||
|
||||
let system_hive_filename =
|
||||
let filename = sprintf "%s/system32/config/system" systemroot in
|
||||
let filename = sprintf "%s/system32/config/system"
|
||||
inspect.i_windows_systemroot in
|
||||
let filename = g#case_sensitive_path filename in
|
||||
filename in
|
||||
|
||||
@@ -223,13 +222,6 @@ let convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
|
||||
(*----------------------------------------------------------------------*)
|
||||
(* Perform the conversion of the Windows guest. *)
|
||||
|
||||
(* Find the 'Current' ControlSet. *)
|
||||
let get_current_cs root =
|
||||
let select = g#hivex_node_get_child root "Select" in
|
||||
let valueh = g#hivex_node_get_value select "Current" in
|
||||
let value = int_of_le32 (g#hivex_value_value valueh) in
|
||||
sprintf "ControlSet%03Ld" value in
|
||||
|
||||
let rec configure_firstboot () =
|
||||
wait_pnp ();
|
||||
(match installer with
|
||||
@@ -298,8 +290,8 @@ reg delete \"%s\" /v %s /f" strkey name
|
||||
let name = "SuppressUI" in
|
||||
let value = Registry.with_hive_write g system_hive_filename (
|
||||
fun root ->
|
||||
let current_cs = get_current_cs root in
|
||||
set_reg_val_dword_1 root (current_cs :: key_path) name
|
||||
set_reg_val_dword_1 root (inspect.i_windows_current_control_set
|
||||
:: key_path) name
|
||||
) in
|
||||
reg_restore ("HKLM\\SYSTEM\\CurrentControlSet" :: key_path) name
|
||||
value
|
||||
@@ -402,18 +394,16 @@ if errorlevel 3010 exit /b 0
|
||||
(* Update the SYSTEM hive. When this function is called the hive has
|
||||
* already been opened as a hivex handle inside guestfs.
|
||||
*)
|
||||
let current_cs = get_current_cs root in
|
||||
debug "current ControlSet is %s" current_cs;
|
||||
disable_xenpv_win_drivers root;
|
||||
disable_prl_drivers root;
|
||||
disable_autoreboot root;
|
||||
Windows_virtio.install_drivers g inspect root rcaps
|
||||
|
||||
disable_xenpv_win_drivers root current_cs;
|
||||
disable_prl_drivers root current_cs;
|
||||
disable_autoreboot root current_cs;
|
||||
Windows_virtio.install_drivers g inspect systemroot
|
||||
root current_cs rcaps
|
||||
|
||||
and disable_xenpv_win_drivers root current_cs =
|
||||
and disable_xenpv_win_drivers root =
|
||||
(* Disable xenpv-win service (RHBZ#809273). *)
|
||||
let services = Registry.get_node g root [current_cs; "Services"] in
|
||||
let services =
|
||||
Registry.get_node g root
|
||||
[inspect.i_windows_current_control_set; "Services"] in
|
||||
|
||||
match services with
|
||||
| None -> ()
|
||||
@@ -422,9 +412,11 @@ if errorlevel 3010 exit /b 0
|
||||
if node <> 0L then
|
||||
g#hivex_node_set_value node "Start" 4_L (le32_of_int 4_L)
|
||||
|
||||
and disable_prl_drivers root current_cs =
|
||||
and disable_prl_drivers root =
|
||||
(* Prevent Parallels drivers from loading at boot. *)
|
||||
let services = Registry.get_node g root [current_cs; "Services"] in
|
||||
let services =
|
||||
Registry.get_node g root
|
||||
[inspect.i_windows_current_control_set; "Services"] in
|
||||
let prl_svcs = [ "prl_boot"; "prl_dd"; "prl_eth5"; "prl_fs"; "prl_memdev";
|
||||
"prl_mouf"; "prl_pv32"; "prl_pv64"; "prl_scsi";
|
||||
"prl_sound"; "prl_strg"; "prl_tg"; "prl_time";
|
||||
@@ -447,7 +439,8 @@ if errorlevel 3010 exit /b 0
|
||||
* HKLM, System\CurrentControlSet\Control\Class\{4d36e967-e325-11ce-bfc1-08002be10318}, LowerFilters, 0x00018002, prl_strg
|
||||
*)
|
||||
let strg_cls = Registry.get_node g root
|
||||
[current_cs; "Control"; "Class";
|
||||
[inspect.i_windows_current_control_set;
|
||||
"Control"; "Class";
|
||||
"{4d36e967-e325-11ce-bfc1-08002be10318}"] in
|
||||
match strg_cls with
|
||||
| None -> ()
|
||||
@@ -467,12 +460,13 @@ if errorlevel 3010 exit /b 0
|
||||
g#hivex_node_set_value strg_cls lfkey 7_L data
|
||||
)
|
||||
|
||||
and disable_autoreboot root current_cs =
|
||||
and disable_autoreboot root =
|
||||
(* If the guest reboots after a crash, it's hard to see the original
|
||||
* error (eg. the infamous 0x0000007B). Turn off autoreboot.
|
||||
*)
|
||||
let crash_control =
|
||||
Registry.get_node g root [current_cs; "Control"; "CrashControl"] in
|
||||
Registry.get_node g root [inspect.i_windows_current_control_set;
|
||||
"Control"; "CrashControl"] in
|
||||
match crash_control with
|
||||
| None -> ()
|
||||
| Some crash_control ->
|
||||
|
||||
@@ -32,6 +32,8 @@ let rec inspect_source root_choice g =
|
||||
|
||||
reject_if_not_installed_image g root;
|
||||
|
||||
let typ = g#inspect_get_type root in
|
||||
|
||||
(* Mount up the filesystems. *)
|
||||
let mps = g#inspect_get_mountpoints root in
|
||||
let cmp (a,_) (b,_) = compare (String.length a) (String.length b) in
|
||||
@@ -65,9 +67,20 @@ let rec inspect_source root_choice g =
|
||||
StringMap.add name (app :: vs) map
|
||||
) StringMap.empty apps in
|
||||
|
||||
(* If the guest is Windows, get some Windows-specific inspection
|
||||
* data, else (for simplicity when accessing) use empty strings.
|
||||
*)
|
||||
let systemroot, current_cs =
|
||||
match typ with
|
||||
| "windows" ->
|
||||
g#inspect_get_windows_systemroot root,
|
||||
g#inspect_get_windows_current_control_set root
|
||||
| _ ->
|
||||
"", "" in
|
||||
|
||||
let inspect = {
|
||||
i_root = root;
|
||||
i_type = g#inspect_get_type root;
|
||||
i_type = typ;
|
||||
i_distro = g#inspect_get_distro root;
|
||||
i_arch = g#inspect_get_arch root;
|
||||
i_major_version = g#inspect_get_major_version root;
|
||||
@@ -80,6 +93,8 @@ let rec inspect_source root_choice g =
|
||||
i_apps = apps;
|
||||
i_apps_map = apps_map;
|
||||
i_firmware = get_firmware_bootable_device g;
|
||||
i_windows_systemroot = systemroot;
|
||||
i_windows_current_control_set = current_cs;
|
||||
} in
|
||||
debug "%s" (string_of_inspect inspect);
|
||||
|
||||
|
||||
@@ -324,6 +324,8 @@ type inspect = {
|
||||
i_apps : Guestfs.application2 list;
|
||||
i_apps_map : Guestfs.application2 list StringMap.t;
|
||||
i_firmware : i_firmware;
|
||||
i_windows_systemroot : string;
|
||||
i_windows_current_control_set : string;
|
||||
}
|
||||
|
||||
let string_of_inspect inspect =
|
||||
@@ -339,6 +341,8 @@ i_package_management = %s
|
||||
i_product_name = %s
|
||||
i_product_variant = %s
|
||||
i_firmware = %s
|
||||
i_windows_systemroot = %s
|
||||
i_windows_current_control_set = %s
|
||||
" inspect.i_root
|
||||
inspect.i_type
|
||||
inspect.i_distro
|
||||
@@ -352,6 +356,8 @@ i_firmware = %s
|
||||
(match inspect.i_firmware with
|
||||
| I_BIOS -> "BIOS"
|
||||
| I_UEFI devices -> sprintf "UEFI [%s]" (String.concat ", " devices))
|
||||
inspect.i_windows_systemroot
|
||||
inspect.i_windows_current_control_set
|
||||
|
||||
type mpstat = {
|
||||
mp_dev : string;
|
||||
|
||||
@@ -230,6 +230,8 @@ type inspect = {
|
||||
i_firmware : i_firmware;
|
||||
(** The list of EFI system partitions for the guest with UEFI,
|
||||
otherwise the BIOS identifier. *)
|
||||
i_windows_systemroot : string;
|
||||
i_windows_current_control_set : string;
|
||||
}
|
||||
(** Inspection information. *)
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ let inspect_defaults = {
|
||||
i_major_version = 0; i_minor_version = 0;
|
||||
i_root = ""; i_package_format = ""; i_package_management = "";
|
||||
i_product_name = ""; i_product_variant = ""; i_mountpoints = [];
|
||||
i_apps = []; i_apps_map = StringMap.empty; i_firmware = I_BIOS
|
||||
i_apps = []; i_apps_map = StringMap.empty; i_firmware = I_BIOS;
|
||||
i_windows_systemroot = ""; i_windows_current_control_set = "";
|
||||
}
|
||||
|
||||
let test_get_ostype ctx =
|
||||
|
||||
@@ -37,9 +37,9 @@ let scsi_class_guid = "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
|
||||
let viostor_pciid = "VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00"
|
||||
let vioscsi_pciid = "VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00"
|
||||
|
||||
let rec install_drivers g inspect systemroot root current_cs rcaps =
|
||||
let rec install_drivers g inspect root rcaps =
|
||||
(* Copy the virtio drivers to the guest. *)
|
||||
let driverdir = sprintf "%s/Drivers/VirtIO" systemroot in
|
||||
let driverdir = sprintf "%s/Drivers/VirtIO" inspect.i_windows_systemroot in
|
||||
g#mkdir_p driverdir;
|
||||
|
||||
if not (copy_drivers g inspect driverdir) then (
|
||||
@@ -98,22 +98,22 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
|
||||
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
|
||||
* manager *)
|
||||
let source = driverdir // (driver_name ^ ".sys") in
|
||||
let target = sprintf "%s/system32/drivers/%s.sys" systemroot driver_name in
|
||||
let target = sprintf "%s/system32/drivers/%s.sys"
|
||||
inspect.i_windows_systemroot driver_name in
|
||||
let target = g#case_sensitive_path target in
|
||||
g#cp source target;
|
||||
add_guestor_to_registry g root current_cs driver_name
|
||||
viostor_pciid;
|
||||
add_guestor_to_registry g inspect root driver_name viostor_pciid;
|
||||
Virtio_blk
|
||||
|
||||
| Some Virtio_SCSI, _, true ->
|
||||
(* Block driver needs tweaks to allow booting; the rest is set up by PnP
|
||||
* manager *)
|
||||
let source = driverdir // "vioscsi.sys" in
|
||||
let target = sprintf "%s/system32/drivers/vioscsi.sys" systemroot in
|
||||
let target = sprintf "%s/system32/drivers/vioscsi.sys"
|
||||
inspect.i_windows_systemroot in
|
||||
let target = g#case_sensitive_path target in
|
||||
g#cp source target;
|
||||
add_guestor_to_registry g root current_cs "vioscsi"
|
||||
vioscsi_pciid;
|
||||
add_guestor_to_registry g inspect root "vioscsi" vioscsi_pciid;
|
||||
Virtio_SCSI
|
||||
|
||||
| Some IDE, _, _ ->
|
||||
@@ -168,18 +168,18 @@ let rec install_drivers g inspect systemroot root current_cs rcaps =
|
||||
(block, net, video)
|
||||
)
|
||||
|
||||
and add_guestor_to_registry g root current_cs drv_name drv_pciid =
|
||||
and add_guestor_to_registry g inspect root drv_name drv_pciid =
|
||||
let ddb_node = g#hivex_node_get_child root "DriverDatabase" in
|
||||
|
||||
let regedits =
|
||||
if ddb_node = 0L then
|
||||
cdb_regedits current_cs drv_name drv_pciid
|
||||
cdb_regedits inspect drv_name drv_pciid
|
||||
else
|
||||
ddb_regedits current_cs drv_name drv_pciid in
|
||||
ddb_regedits inspect drv_name drv_pciid in
|
||||
|
||||
let drv_sys_path = sprintf "system32\\drivers\\%s.sys" drv_name in
|
||||
let common_regedits = [
|
||||
[ current_cs; "Services"; drv_name ],
|
||||
[ inspect.i_windows_current_control_set; "Services"; drv_name ],
|
||||
[ "Type", REG_DWORD 0x1_l;
|
||||
"Start", REG_DWORD 0x0_l;
|
||||
"Group", REG_SZ "SCSI miniport";
|
||||
@@ -189,19 +189,20 @@ and add_guestor_to_registry g root current_cs drv_name drv_pciid =
|
||||
|
||||
reg_import g root (regedits @ common_regedits)
|
||||
|
||||
and cdb_regedits current_cs drv_name drv_pciid =
|
||||
and cdb_regedits inspect drv_name drv_pciid =
|
||||
(* 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.
|
||||
*)
|
||||
[
|
||||
[ current_cs; "Control"; "CriticalDeviceDatabase";
|
||||
[ inspect.i_windows_current_control_set;
|
||||
"Control"; "CriticalDeviceDatabase";
|
||||
"PCI#" ^ drv_pciid ],
|
||||
[ "Service", REG_SZ drv_name;
|
||||
"ClassGUID", REG_SZ scsi_class_guid ];
|
||||
]
|
||||
|
||||
and ddb_regedits current_cs drv_name drv_pciid =
|
||||
and ddb_regedits inspect drv_name drv_pciid =
|
||||
(* Windows >= 8 doesn't use the CriticalDeviceDatabase. Instead
|
||||
* one must add keys into the DriverDatabase.
|
||||
*)
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
(** Functions for installing Windows virtio drivers. *)
|
||||
|
||||
val install_drivers
|
||||
: Guestfs.guestfs -> Types.inspect -> string -> Registry.node -> string ->
|
||||
: Guestfs.guestfs -> Types.inspect -> Registry.node ->
|
||||
Types.requested_guestcaps ->
|
||||
Types.guestcaps_block_type * Types.guestcaps_net_type * Types.guestcaps_video_type
|
||||
(** [install_drivers g inspect systemroot root current_cs rcaps]
|
||||
(** [install_drivers g inspect root rcaps]
|
||||
installs virtio drivers from the driver directory or driver
|
||||
ISO into the guest driver directory and updates the registry
|
||||
so that the [viostor.sys] driver gets loaded by Windows at boot.
|
||||
|
||||
[root] is the root node of the system hive (which is open for writes
|
||||
when this function is called). [current_cs] is the name of the
|
||||
[CurrentControlSet] (eg. ["ControlSet001"]).
|
||||
when this function is called).
|
||||
|
||||
[rcaps] is the set of guest "capabilities" requested by the caller. This
|
||||
may include the type of the block driver, network driver, and video driver.
|
||||
|
||||
Reference in New Issue
Block a user