From 8e28d6b18860f8ff4e02489317749a723fa145ab 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. --- mllib/common_utils.ml | 6 +++++ mllib/common_utils.mli | 1 + v2v/convert_windows.ml | 58 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml index edbd82ca8..f8fa8fd0d 100644 --- a/mllib/common_utils.ml +++ b/mllib/common_utils.ml @@ -62,6 +62,12 @@ let isdigit = function | '0'..'9' -> true | _ -> false +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 5562e4a25..7d886cf51 100644 --- a/mllib/common_utils.mli +++ b/mllib/common_utils.mli @@ -33,6 +33,7 @@ val int_of_le32 : string -> int64 val le32_of_int : int64 -> string val isdigit : char -> bool +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 bde75d054..8abb1a21b 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 ~keep_serial_console (g : G.guestfs) inspect source = (* Get the data directory. *) let virt_tools_data_dir = @@ -104,7 +112,46 @@ let convert ~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. @@ -705,6 +752,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 (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 (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;