Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [[PATCH v2v v2 0/6] convert: Find out if Windows guest is expecting RTC set to UTC
The main changes are: - BIOS -> RTC passim - Split out the minor refactoring patch - Enhanced commit messages - Add Laszlo's R-b tag Rich.
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 1/6] types: Add gcaps_rtc_utc to record if the RTC is set to UTC or localtime
Almost every Linux guest expects the motherboard Real Time Clock (RTC) to be set to UTC and they adjust the time displayed based on their timezone (which may be different for each user). Most Windows guests expect the RTC to be set to the local time. Windows can be configured to use a UTC clock. We can detect this by looking at the Windows registry. To cope with this difference we need to add a guestcaps flag based on what we think the guest is expecting. (We might also use the source hypervisor RTC setting, but it is not thought to be as reliable as inspecting the guest.) This change simply adds the flag to guestcaps, and sets it to always true, so there is no change to the output. Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- lib/types.mli | 5 +++++ convert/convert_linux.ml | 1 + convert/convert_windows.ml | 1 + lib/types.ml | 3 +++ 4 files changed, 10 insertions(+) diff --git a/lib/types.mli b/lib/types.mli index 65ef2e35cf..3446bb64bd 100644 --- a/lib/types.mli +++ b/lib/types.mli @@ -277,6 +277,11 @@ type guestcaps = { gcaps_virtio_1_0 : bool; (** The guest supports the virtio devices that it does at the virtio-1.0 protocol level. *) + + gcaps_rtc_utc : bool; + (** Is the RTC set to UTC ([true]) or localtime ([false])? For + Linux guests this is always true. For Windows we find out + what the guest is expecting by looking at the registry. *) } (** Guest capabilities after conversion. eg. Was virtio found or installed? *) diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml index 8d7020848f..bd54568b10 100644 --- a/convert/convert_linux.ml +++ b/convert/convert_linux.ml @@ -220,6 +220,7 @@ let convert (g : G.guestfs) source inspect i_firmware _ keep_serial_console _ gcaps_arch = Utils.kvm_arch inspect.i_arch; gcaps_arch_min_version = arch_min_version; gcaps_virtio_1_0 = virtio_1_0; + gcaps_rtc_utc = true; (* almost all Linux expect RTC to be UTC *) } in guestcaps diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml index 122d95469d..7e3aa8d789 100644 --- a/convert/convert_windows.ml +++ b/convert/convert_windows.ml @@ -275,6 +275,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips gcaps_arch = Utils.kvm_arch inspect.i_arch; gcaps_arch_min_version = 0; gcaps_virtio_1_0 = virtio_win_installed.Inject_virtio_win.virtio_1_0; + gcaps_rtc_utc = true; } in guestcaps diff --git a/lib/types.ml b/lib/types.ml index 75c14fd4f6..d6f9a266c5 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -399,6 +399,7 @@ type guestcaps = { gcaps_arch : string; gcaps_arch_min_version : int; gcaps_virtio_1_0 : bool; + gcaps_rtc_utc : bool; } and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE and guestcaps_net_type = Virtio_net | E1000 | RTL8139 @@ -429,6 +430,7 @@ let string_of_guestcaps gcaps gcaps_arch = %s\n\ gcaps_arch_min_version = %d\n\ gcaps_virtio_1_0 = %b\n\ + gcaps_rtc_utc = %b\n\ " (string_of_block_type gcaps.gcaps_block_bus) (string_of_net_type gcaps.gcaps_net_bus) @@ -440,6 +442,7 @@ let string_of_guestcaps gcaps gcaps.gcaps_arch gcaps.gcaps_arch_min_version gcaps.gcaps_virtio_1_0 + gcaps.gcaps_rtc_utc type target_buses = { target_virtio_blk_bus : target_bus_slot array; -- 2.41.0
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 2/6] -o kubevirt: Add comment about future support for clock = localtime
Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- output/create_kubevirt_yaml.ml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/output/create_kubevirt_yaml.ml b/output/create_kubevirt_yaml.ml index 689555e4dc..e3a3f422df 100644 --- a/output/create_kubevirt_yaml.ml +++ b/output/create_kubevirt_yaml.ml @@ -54,6 +54,11 @@ let create_kubevirt_yaml source inspect "pit", Assoc [ "tickPolicy", String "delay" ]; "rtc", Assoc [ "tickPolicy", String "catchup" ]; ]; + (* XXX Note that we may need to set "localtime" here + * depending on guestcaps.gcaps_rtc_utc. However that + * requires the following PR to be merged in Kubevirt: + * https://github.com/kubevirt/kubevirt/pull/9587 + *) "utc", List [] ] ) -- 2.41.0
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 3/6] output/create_libvirt_xml.ml: Refactor os_section
Minor refactoring of how <os> section is generated in XML output. There is no change in the output. Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- output/create_libvirt_xml.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/output/create_libvirt_xml.ml b/output/create_libvirt_xml.ml index 964acd25fd..12586fde17 100644 --- a/output/create_libvirt_xml.ml +++ b/output/create_libvirt_xml.ml @@ -292,10 +292,10 @@ let create_libvirt_xml ?pool source inspect e "nvram" ["template", vars_template] [] ] in List.push_back_list os loader; - !os in + e "os" [] !os in List.push_back_list body [ - e "os" [] os_section; + os_section; e "on_poweroff" [] [PCData "destroy"]; e "on_reboot" [] [PCData "restart"]; -- 2.41.0
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 4/6] -o libvirt: Add <clock offset="utc|localtime"/> to libvirt XML
Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- output/create_libvirt_xml.ml | 6 ++++++ tests/test-v2v-i-ova.xml | 1 + 2 files changed, 7 insertions(+) diff --git a/output/create_libvirt_xml.ml b/output/create_libvirt_xml.ml index 12586fde17..30119d1357 100644 --- a/output/create_libvirt_xml.ml +++ b/output/create_libvirt_xml.ml @@ -294,8 +294,14 @@ let create_libvirt_xml ?pool source inspect List.push_back_list os loader; e "os" [] !os in + (* The <clock> section. *) + let clock_section + let offset = if guestcaps.gcaps_rtc_utc then "utc" else "localtime" in + e "clock" [ "offset", offset ] [] in + List.push_back_list body [ os_section; + clock_section; e "on_poweroff" [] [PCData "destroy"]; e "on_reboot" [] [PCData "restart"]; diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml index e5907ea1cc..a41827bfd5 100644 --- a/tests/test-v2v-i-ova.xml +++ b/tests/test-v2v-i-ova.xml @@ -18,6 +18,7 @@ <os> <type arch='x86_64' machine='q35'>hvm</type> </os> + <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> -- 2.41.0
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 5/6] -o qemu: Set -rtc base=localtime when guest expects RTC set to localtime
I didn't set the -rtc flag in the normal (UTC) case as that is the default. Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- output/output_qemu.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/output/output_qemu.ml b/output/output_qemu.ml index 57b1e58da2..1a5f7f7147 100644 --- a/output/output_qemu.ml +++ b/output/output_qemu.ml @@ -158,6 +158,8 @@ module QEMU = struct arg_list "-device" ["vmgenid"; sprintf "guid=%s" genid; "id=vmgenid0"] ); + if not guestcaps.gcaps_rtc_utc then arg "-rtc" "base=localtime"; + arg_list "-machine" (machine_str :: (if smm then ["smm=on"] else []) @ ["accel=kvm:tcg"]); -- 2.41.0
Richard W.M. Jones
2023-Sep-25 16:21 UTC
[Libguestfs] [PATCH v2v v2 6/6] convert: Find out if Windows guest is expecting RTC set to UTC
Read HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation key "RealTimeIsUniversal" to see if the Windows guest is expecting RTC set to localtime (not present) or UTC (present and set to 1). See: https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows See: https://listman.redhat.com/archives/libguestfs/2023-September/thread.html#32556 Reported-by: Lee Garrett Reviewed-by: Laszlo Ersek <lersek at redhat.com> --- convert/convert_windows.ml | 38 +++++++++++++++++++++++++++++++++++++- tests/test-v2v-i-ova.xml | 2 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml index 7e3aa8d789..34cf341b8e 100644 --- a/convert/convert_windows.ml +++ b/convert/convert_windows.ml @@ -103,6 +103,42 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips (* If the Windows guest has AV installed. *) let has_antivirus = Windows.detect_antivirus inspect in + (* Does the guest expect the RTC to be set to UTC or localtime? + * See https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows + * Note this might be a QWORD on 64 bit Windows instances. + *) + let rtc_utc + Registry.with_hive_readonly g inspect.i_windows_system_hive + (fun reg -> + try + let key_path = [ "Control"; "TimeZoneInformation" ] in + let path = inspect.i_windows_current_control_set :: key_path in + let node + match Registry.get_node reg path with + | None -> raise Not_found + | Some node -> node in + let valueh = g#hivex_node_get_value node "RealTimeIsUniversal" in + if valueh = 0L then raise Not_found; + let t = g#hivex_value_type valueh in + let data = g#hivex_value_value valueh in + let is_utc + match t with + | 0_L (* REG_NONE *) -> false (* localtime *) + | 4_L (* REG_DWORD *) -> data = "\001\000\000\000" + | 11_L (* REG_QWORD *) -> data = "\001\000\000\000\000\000\000\000" + | _ (* who knows ... *) -> + warning (f_"unknown CurrentControlSet\\Control\\\ + TimeZoneInformation key RealTimeIsUniversal \ + type 0x%Lx, assuming RTC set to UTC") t; + true in + is_utc + with Not_found -> + (* If the key is not found then by default we assume + * that Windows is expecting the RTC to be set to localtime. + *) + false + ) in + (* Open the software hive (readonly) and find the Xen PV uninstaller, * if it exists. *) @@ -275,7 +311,7 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _ static_ips gcaps_arch = Utils.kvm_arch inspect.i_arch; gcaps_arch_min_version = 0; gcaps_virtio_1_0 = virtio_win_installed.Inject_virtio_win.virtio_1_0; - gcaps_rtc_utc = true; + gcaps_rtc_utc = rtc_utc; } in guestcaps diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml index a41827bfd5..fa7b4dbfc5 100644 --- a/tests/test-v2v-i-ova.xml +++ b/tests/test-v2v-i-ova.xml @@ -18,7 +18,7 @@ <os> <type arch='x86_64' machine='q35'>hvm</type> </os> - <clock offset='utc'/> + <clock offset='localtime'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> -- 2.41.0