|
|
ffd6ed |
From f8a041846bd596276dc37cabd217d5f37312256c Mon Sep 17 00:00:00 2001
|
|
|
ffd6ed |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
ffd6ed |
Date: Mon, 7 Sep 2015 17:18:41 +0100
|
|
|
ffd6ed |
Subject: [PATCH] v2v: windows: Warn if Group Policy or AV software may result
|
|
|
ffd6ed |
in 7B boot failure (RHBZ#1260689).
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Check if the Windows guest has Group Policy Objects installed, or one
|
|
|
ffd6ed |
of several popular pieces of anti-virus software. If we are
|
|
|
ffd6ed |
installing a virtio block driver, then experience has shown this may
|
|
|
ffd6ed |
cause a 7B boot failure.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Print a warning when this combination happens.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
The warnings look like this:
|
|
|
ffd6ed |
|
|
|
ffd6ed |
[ 19.9] Converting Windows Server 2008 R2 Enterprise to run on KVM
|
|
|
ffd6ed |
virt-v2v: warning: this guest has Windows Group Policy Objects (GPO) and a
|
|
|
ffd6ed |
new virtio block device driver was installed. In some circumstances, Group
|
|
|
ffd6ed |
Policy may prevent new drivers from working (resulting in a 7B boot error).
|
|
|
ffd6ed |
If this happens, try disabling Group Policy before doing the conversion.
|
|
|
ffd6ed |
virt-v2v: warning: this guest has Anti-Virus (AV) software and a new virtio
|
|
|
ffd6ed |
block device driver was installed. In some circumstances, AV may prevent
|
|
|
ffd6ed |
new drivers from working (resulting in a 7B boot error). If this happens,
|
|
|
ffd6ed |
try disabling AV before doing the conversion.
|
|
|
ffd6ed |
virt-v2v: This guest has virtio drivers installed.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(cherry picked from commit 8e28d6b18860f8ff4e02489317749a723fa145ab)
|
|
|
ffd6ed |
---
|
|
|
ffd6ed |
mllib/common_utils.ml | 6 +++++
|
|
|
ffd6ed |
mllib/common_utils.mli | 2 ++
|
|
|
ffd6ed |
v2v/convert_windows.ml | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
ffd6ed |
3 files changed, 68 insertions(+)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
|
|
|
ffd6ed |
index 8f0f065..198a5fb 100644
|
|
|
ffd6ed |
--- a/mllib/common_utils.ml
|
|
|
ffd6ed |
+++ b/mllib/common_utils.ml
|
|
|
ffd6ed |
@@ -58,6 +58,12 @@ let le32_of_int i =
|
|
|
ffd6ed |
String.unsafe_set s 3 (Char.unsafe_chr (Int64.to_int c3));
|
|
|
ffd6ed |
s
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+let isxdigit = function
|
|
|
ffd6ed |
+ | '0'..'9' -> true
|
|
|
ffd6ed |
+ | 'a'..'f' -> true
|
|
|
ffd6ed |
+ | 'A'..'F' -> true
|
|
|
ffd6ed |
+ | _ -> false
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
type wrap_break_t = WrapEOS | WrapSpace | WrapNL
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let rec wrap ?(chan = stdout) ?(indent = 0) str =
|
|
|
ffd6ed |
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
|
|
|
ffd6ed |
index ad2b4c7..ed7de7f 100644
|
|
|
ffd6ed |
--- a/mllib/common_utils.mli
|
|
|
ffd6ed |
+++ b/mllib/common_utils.mli
|
|
|
ffd6ed |
@@ -32,6 +32,8 @@ val div_roundup64 : int64 -> int64 -> int64
|
|
|
ffd6ed |
val int_of_le32 : string -> int64
|
|
|
ffd6ed |
val le32_of_int : int64 -> string
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+val isxdigit : char -> bool
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
val wrap : ?chan:out_channel -> ?indent:int -> string -> unit
|
|
|
ffd6ed |
(** Wrap text. *)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
|
|
ffd6ed |
index e3d3a39..36cf8c1 100644
|
|
|
ffd6ed |
--- a/v2v/convert_windows.ml
|
|
|
ffd6ed |
+++ b/v2v/convert_windows.ml
|
|
|
ffd6ed |
@@ -41,6 +41,14 @@ module G = Guestfs
|
|
|
ffd6ed |
|
|
|
ffd6ed |
type ('a, 'b) maybe = Either of 'a | Or of 'b
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+(* Antivirus regexps that match on inspect.i_apps.app2_name fields. *)
|
|
|
ffd6ed |
+let av_rex =
|
|
|
ffd6ed |
+ let alternatives = [
|
|
|
ffd6ed |
+ "virus"; (* generic *)
|
|
|
ffd6ed |
+ "Kaspersky"; "McAfee"; "Norton"; "Sophos";
|
|
|
ffd6ed |
+ ] in
|
|
|
ffd6ed |
+ Str.regexp_case_fold (String.concat "\\|" alternatives)
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
let convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
|
|
|
ffd6ed |
(* Get the data directory. *)
|
|
|
ffd6ed |
let virt_tools_data_dir =
|
|
|
ffd6ed |
@@ -103,6 +111,47 @@ let convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
|
|
|
ffd6ed |
(*----------------------------------------------------------------------*)
|
|
|
ffd6ed |
(* Inspect the Windows guest. *)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+ (* Warn if Windows guest appears to be using group policy. *)
|
|
|
ffd6ed |
+ let has_group_policy =
|
|
|
ffd6ed |
+ let check_group_policy root =
|
|
|
ffd6ed |
+ try
|
|
|
ffd6ed |
+ let node =
|
|
|
ffd6ed |
+ get_node root
|
|
|
ffd6ed |
+ ["Microsoft"; "Windows"; "CurrentVersion"; "Group Policy";
|
|
|
ffd6ed |
+ "History"] in
|
|
|
ffd6ed |
+ let children = g#hivex_node_children node in
|
|
|
ffd6ed |
+ let children = Array.to_list children in
|
|
|
ffd6ed |
+ let children =
|
|
|
ffd6ed |
+ List.map (fun { G.hivex_node_h = h } -> g#hivex_node_name h)
|
|
|
ffd6ed |
+ children in
|
|
|
ffd6ed |
+ (* Just assume any children looking like "{<GUID>}" mean that
|
|
|
ffd6ed |
+ * some GPOs were installed.
|
|
|
ffd6ed |
+ *
|
|
|
ffd6ed |
+ * In future we might want to look for nodes which match:
|
|
|
ffd6ed |
+ * History\{<GUID>}\<N> where <N> is a small integer (the order
|
|
|
ffd6ed |
+ * in which policy objects were applied.
|
|
|
ffd6ed |
+ *
|
|
|
ffd6ed |
+ * For an example registry containing GPOs, see RHBZ#1219651.
|
|
|
ffd6ed |
+ * See also: https://support.microsoft.com/en-us/kb/201453
|
|
|
ffd6ed |
+ *)
|
|
|
ffd6ed |
+ let is_gpo_guid name =
|
|
|
ffd6ed |
+ let len = String.length name in
|
|
|
ffd6ed |
+ len > 3 && name.[0] = '{' && isxdigit name.[1] && name.[len-1] = '}'
|
|
|
ffd6ed |
+ in
|
|
|
ffd6ed |
+ List.exists is_gpo_guid children
|
|
|
ffd6ed |
+ with
|
|
|
ffd6ed |
+ Not_found -> false
|
|
|
ffd6ed |
+ in
|
|
|
ffd6ed |
+ with_hive "software" ~write:false check_group_policy in
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
+ (* Warn if Windows guest has AV installed. *)
|
|
|
ffd6ed |
+ let has_antivirus =
|
|
|
ffd6ed |
+ let check_app { G.app2_name = name } =
|
|
|
ffd6ed |
+ try ignore (Str.search_forward av_rex name 0); true
|
|
|
ffd6ed |
+ with Not_found -> false
|
|
|
ffd6ed |
+ in
|
|
|
ffd6ed |
+ List.exists check_app inspect.i_apps in
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
(* Open the software hive (readonly) and find the Xen PV uninstaller,
|
|
|
ffd6ed |
* if it exists.
|
|
|
ffd6ed |
*)
|
|
|
ffd6ed |
@@ -488,6 +537,17 @@ echo uninstalling Xen PV driver
|
|
|
ffd6ed |
|
|
|
ffd6ed |
fix_ntfs_heads ();
|
|
|
ffd6ed |
|
|
|
ffd6ed |
+ (* Warn if installation of virtio block drivers might conflict with
|
|
|
ffd6ed |
+ * group policy or AV software causing a boot 0x7B error (RHBZ#1260689).
|
|
|
ffd6ed |
+ *)
|
|
|
ffd6ed |
+ let () =
|
|
|
ffd6ed |
+ if block_driver = Virtio_blk then (
|
|
|
ffd6ed |
+ if has_group_policy then
|
|
|
ffd6ed |
+ warning ~prog (f_"this guest has Windows Group Policy Objects (GPO) and a new virtio block device driver was installed. In some circumstances, Group Policy may prevent new drivers from working (resulting in a 7B boot error). If this happens, try disabling Group Policy before doing the conversion.");
|
|
|
ffd6ed |
+ if has_antivirus then
|
|
|
ffd6ed |
+ warning ~prog (f_"this guest has Anti-Virus (AV) software and a new virtio block device driver was installed. In some circumstances, AV may prevent new drivers from working (resulting in a 7B boot error). If this happens, try disabling AV before doing the conversion.");
|
|
|
ffd6ed |
+ ) in
|
|
|
ffd6ed |
+
|
|
|
ffd6ed |
(* Return guest capabilities. *)
|
|
|
ffd6ed |
let guestcaps = {
|
|
|
ffd6ed |
gcaps_block_bus = block_driver;
|
|
|
ffd6ed |
--
|
|
|
ffd6ed |
1.8.3.1
|
|
|
ffd6ed |
|