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