diff --git a/ocaml/idl/api_errors.ml b/ocaml/idl/api_errors.ml index 9f330ea987..39e88f2789 100644 --- a/ocaml/idl/api_errors.ml +++ b/ocaml/idl/api_errors.ml @@ -51,7 +51,6 @@ let vm_hvm_required = "VM_HVM_REQUIRED" let vm_no_vcpus = "VM_NO_VCPUS" let vm_toomany_vcpus = "VM_TOO_MANY_VCPUS" let vm_is_protected = "VM_IS_PROTECTED" -let vm_is_immobile= "VM_IS_IMMOBILE" let host_in_use = "HOST_IN_USE" let host_in_emergency_mode = "HOST_IN_EMERGENCY_MODE" diff --git a/ocaml/idl/datamodel.ml b/ocaml/idl/datamodel.ml index 398ce25a81..6ad7e11960 100644 --- a/ocaml/idl/datamodel.ml +++ b/ocaml/idl/datamodel.ml @@ -1337,10 +1337,8 @@ let _ = ~doc:"The VM cannot be imported unforced because it is either the same version or an older version of an existing VM." (); error Api_errors.vm_call_plugin_rate_limit ["VM"; "interval"; "wait"] - ~doc:"There is a minimal interval required between consecutive plugin calls made on the same VM, please wait before retry." (); + ~doc:"There is a minimal interval required between consecutive plugin calls made on the same VM, please wait before retry." () - error Api_errors.vm_is_immobile ["VM"] - ~doc:"The VM is configured in a way that prevents it from being mobile." () let _ = message (fst Api_messages.ha_pool_overcommitted) ~doc:"Pool has become overcommitted: it can no longer guarantee to restart protected VMs if the configured number of hosts fail." (); diff --git a/ocaml/test/OMakefile b/ocaml/test/OMakefile index 777c996755..02f580dfda 100644 --- a/ocaml/test/OMakefile +++ b/ocaml/test/OMakefile @@ -63,7 +63,6 @@ OCAML_OBJS = \ test_daily_license_check \ test_dbsync_master \ test_xapi_xenops \ - test_no_migrate \ OCamlProgram(suite, suite $(OCAML_OBJS) ) diff --git a/ocaml/test/suite.ml b/ocaml/test/suite.ml index 8b1fcb6aa1..bd3006a00e 100644 --- a/ocaml/test/suite.ml +++ b/ocaml/test/suite.ml @@ -53,7 +53,6 @@ let base_suite = Test_daily_license_check.test; Test_dbsync_master.test; Test_xapi_xenops.test; - Test_no_migrate.test; ] let handlers = [ diff --git a/ocaml/test/test_no_migrate.ml b/ocaml/test/test_no_migrate.ml deleted file mode 100644 index 94ca090e37..0000000000 --- a/ocaml/test/test_no_migrate.ml +++ /dev/null @@ -1,112 +0,0 @@ -(* - * Copyright (C) 2016 Citrix Systems Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; version 2.1 only. with the special - * exception on linking described in file LICENSE. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *) - -open OUnit -open Test_common - -module LC = Xapi_vm_lifecycle - -let critical = - [ `suspend - ; `checkpoint - ; `pool_migrate - ; `migrate_send - ] - - -type mobility = Mobile | Static - -let platforms = - [ Static, ["nested-virt","true"] - ; Mobile, ["nested-virt","false"] - ; Static, ["nomigrate","true"] - ; Mobile, ["nomigrate","false"] - ; Static, ["nomigrate","true"; "nested-virt", "true"] - ; Static, ["nomigrate","true"; "nested-virt", "false"] - ; Mobile, ["nomigrate","false"; "nested-virt", "false"] - ; Static, ["nomigrate","false"; "nested-virt", "true"] - ; Static, ["nomigrate","TRUE"] - ; Static, ["nomigrate","1"] - ; Static, ["nested-virt","1"] - ; Mobile, ["nested-virt","0"] - ] - -let simple () = - let __context = make_test_database () in - let vm = make_vm ~__context ~hVM_boot_policy:"" () in - ( Db.VM.set_power_state ~__context ~self:vm ~value:`Running - ; LC.get_operation_error ~__context ~self:vm ~op:`suspend ~strict:true - |> function - | None -> assert_bool "success" true - | Some (x,xs) -> assert_failure (String.concat "|" (x::xs)) - ) - -let base () = - let __context = make_test_database () in - let vm = make_vm ~__context ~hVM_boot_policy:"" () in - ( Db.VM.set_power_state ~__context ~self:vm ~value:`Running - ; assert_equal ~msg:"suspend" None - (LC.get_operation_error ~__context ~self:vm ~op:`suspend ~strict:true) - ; assert_equal ~msg:"checkpoint" None - (LC.get_operation_error ~__context ~self:vm ~op:`checkpoint ~strict:true) - ; assert_equal ~msg:"pool_migrate" None - (LC.get_operation_error ~__context ~self:vm ~op:`pool_migrate ~strict:true) - ; assert_equal ~msg:"migrate_send" None - (LC.get_operation_error ~__context ~self:vm ~op:`migrate_send ~strict:true) - ) - -(** [with_platform] checks that mobility is signaled according to the - * values found in the platform flags of the last_booted_record *) -let with_platform () = - let __context = make_test_database () in - let self = make_vm ~__context ~hVM_boot_policy:"" () in - let test platform predicate = - ( Db.VM.set_power_state ~__context ~self ~value:`Running - ; Db.VM.set_platform ~__context ~self ~value:platform - ; Helpers.set_boot_record ~__context ~self - (Db.VM.get_record ~__context ~self) - ; critical (* check all critical operations *) - |> List.map (fun op -> LC.get_operation_error ~__context ~self ~op ~strict:true) - |> List.for_all predicate - |> assert_bool "with_platform" - ) in - let predicate = function - | Mobile -> (=) None (* mobile, no error expected *) - | Static -> (<>) None in (* not mobile, expect an error message *) - List.iter (fun (mobile, platform) -> test platform (predicate mobile)) platforms - -(** [override] checks that migration is always possible when --force is - * used *) -let override () = - let __context = make_test_database () in - let self = make_vm ~__context ~hVM_boot_policy:"" () in - let test platform = - ( Db.VM.set_power_state ~__context ~self ~value:`Running - ; Db.VM.set_platform ~__context ~self ~value:platform - ; Helpers.set_boot_record ~__context ~self - (Db.VM.get_record ~__context ~self) - ; critical (* check all critical operations *) - |> List.map (fun op -> LC.get_operation_error ~__context ~self ~op ~strict:false) - |> List.for_all ((=) None) (* should not see any error *) - |> assert_bool "override" - ) in - List.iter (fun (_, platform) -> test platform) platforms - -let test = "test_no_migrate" >::: - [ "test_no_migrate_00" >:: simple - ; "test_no_migrate_01" >:: base - ; "test_no_migrate_02" >:: with_platform - ; "test_no_migrate_03" >:: override - ] - diff --git a/ocaml/test/test_platformdata.ml b/ocaml/test/test_platformdata.ml index 02a3622fb7..85ba6cbdc8 100644 --- a/ocaml/test/test_platformdata.ml +++ b/ocaml/test/test_platformdata.ml @@ -31,7 +31,7 @@ module SanityCheck = Generic.Make(struct end let transform (platformdata, filter_out_unknowns, vcpu_max, vcpu_at_startup, hvm) = - try Either.Right (Vm_platform.sanity_check ~platformdata ~vcpu_max ~vcpu_at_startup ~hvm ~filter_out_unknowns) + try Either.Right (Xapi_xenops.Platform.sanity_check ~platformdata ~vcpu_max ~vcpu_at_startup ~hvm ~filter_out_unknowns) with e -> Either.Left e let tests = diff --git a/ocaml/test/test_xapi_xenops.ml b/ocaml/test/test_xapi_xenops.ml index ef91d2ecb3..acabdb553f 100644 --- a/ocaml/test/test_xapi_xenops.ml +++ b/ocaml/test/test_xapi_xenops.ml @@ -13,8 +13,8 @@ let test_enabled_in_xenguest () = let k = "test_key" in let p v = [k,v] in - let val_fn p = Vm_platform.is_true ~key:k ~platformdata:p ~default:false in - let valid_fn p = Vm_platform.is_valid ~key:k ~platformdata:p in + let val_fn p = Xapi_xenops.Platform.is_true ~key:k ~platformdata:p ~default:false in + let valid_fn p = Xapi_xenops.Platform.is_valid ~key:k ~platformdata:p in (* Empty list should be valid *) if not (valid_fn []) then err "[]"; @@ -61,7 +61,7 @@ let test_nested_virt_licensing () = begin try Db.Pool.set_restrictions ~__context ~self:pool ~value:["restrict_nested_virt","true"]; - Vm_platform.check_restricted_flags ~__context platform; + Xapi_xenops.Platform.check_restricted_flags ~__context platform; if should_raise then failwith @@ -77,7 +77,7 @@ let test_nested_virt_licensing () = (* If the feature is unrestricted, nothing should raise an exception *) Db.Pool.set_restrictions ~__context ~self:pool ~value:["restrict_nested_virt","false"]; - Vm_platform.check_restricted_flags ~__context platform + Xapi_xenops.Platform.check_restricted_flags ~__context platform in List.iter check_one nested_virt_checks diff --git a/ocaml/xapi/OMakefile b/ocaml/xapi/OMakefile index 9e4101b0c2..26b0f412ca 100644 --- a/ocaml/xapi/OMakefile +++ b/ocaml/xapi/OMakefile @@ -277,7 +277,6 @@ XAPI_MODULES = $(COMMON) \ ../util/rpc_retry \ xapi \ cluster_stack_constraints \ - vm_platform \ OCamlProgram(xapi, xapi_main $(XAPI_MODULES)) diff --git a/ocaml/xapi/vm_platform.ml b/ocaml/xapi/vm_platform.ml deleted file mode 100644 index 0d3dabe05a..0000000000 --- a/ocaml/xapi/vm_platform.ml +++ /dev/null @@ -1,167 +0,0 @@ -(* - * Copyright (C) 2016 Citrix Systems Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; version 2.1 only. with the special - * exception on linking described in file LICENSE. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - *) - -open Stdext -open Xstringext -open Listext - -(* Keys we push through to xenstore. *) -let acpi = "acpi" -let apic = "apic" -let nx = "nx" -let pae = "pae" -let viridian = "viridian" -let acpi_s3 = "acpi_s3" -let acpi_s4 = "acpi_s4" -let mmio_size_mib = "mmio_size_mib" -let revision = "revision" -let device_id = "device_id" -let tsc_mode = "tsc_mode" -let device_model = "device-model" -let xenguest = "xenguest" -let pv_kernel_max_size = "pv-kernel-max-size" -let pv_ramdisk_max_size = "pv-ramdisk-max-size" -let pv_postinstall_kernel_max_size = "pv-postinstall-kernel-max-size" -let pv_postinstall_ramdisk_max_size = "pv-postinstall-ramdisk-max-size" -let usb = "usb" -let usb_tablet = "usb_tablet" -let parallel = "parallel" -let vga = "vga" -let vgpu_pci_id = Xapi_globs.vgpu_pci_key -let vgpu_config = Xapi_globs.vgpu_config_key -let igd_passthru_key = Xapi_globs.igd_passthru_key -let featureset = "featureset" -let nested_virt = "nested-virt" - -(* This is only used to block the 'present multiple physical cores as one big hyperthreaded core' feature *) -let filtered_flags = [ - acpi; - apic; - nx; - pae; - viridian; - acpi_s3; - acpi_s4; - mmio_size_mib; - revision; - device_id; - tsc_mode; - device_model; - xenguest; - pv_kernel_max_size; - pv_ramdisk_max_size; - pv_postinstall_kernel_max_size; - pv_postinstall_ramdisk_max_size; - usb; - usb_tablet; - parallel; - vga; - vgpu_pci_id; - vgpu_config; - featureset; - nested_virt; -] - -(* Other keys we might want to write to the platform map. *) -let timeoffset = "timeoffset" -let generation_id = "generation-id" - -(* Helper functions. *) -(* [is_valid key platformdata] returns true if: - 1. The key is _not_ in platformdata (absence of key is valid) or - 2. The key is in platformdata, associated with a booleanish value *) -let is_valid ~key ~platformdata = - (not (List.mem_assoc key platformdata)) || - (match List.assoc key platformdata |> String.lowercase with - | "true" | "1" | "false" | "0" -> true - | v -> false) - -let is_true ~key ~platformdata ~default = - try - match List.assoc key platformdata |> String.lowercase with - | "true" | "1" -> true - | "false" | "0" -> false - | _ -> default (* Check for validity using is_valid if required *) - with Not_found -> - default - -let sanity_check ~platformdata ~vcpu_max ~vcpu_at_startup ~hvm ~filter_out_unknowns = - (* Filter out unknown flags, if applicable *) - let platformdata = - if filter_out_unknowns - then List.filter (fun (k, v) -> List.mem k filtered_flags) platformdata - else platformdata - in - (* Filter out invalid TSC modes. *) - let platformdata = - List.filter - (fun (k, v) -> k <> tsc_mode || List.mem v ["0"; "1"; "2"; "3"]) - platformdata - in - (* Sanity check for HVM domains with invalid VCPU configuration*) - if hvm && (List.mem_assoc "cores-per-socket" platformdata) then - begin - try - let cores_per_socket = int_of_string(List.assoc "cores-per-socket" platformdata) in - (* cores per socket has to be in multiples of VCPUs_max and VCPUs_at_startup *) - if (((Int64.to_int(vcpu_max) mod cores_per_socket) <> 0) - || ((Int64.to_int(vcpu_at_startup) mod cores_per_socket) <> 0)) then - raise (Api_errors.Server_error(Api_errors.invalid_value, - ["platform:cores-per-socket"; - "VCPUs_max/VCPUs_at_startup must be a multiple of this field"])) - with Failure msg -> - raise (Api_errors.Server_error(Api_errors.invalid_value, ["platform:cores-per-socket"; - Printf.sprintf "value = %s is not a valid int" (List.assoc "cores-per-socket" platformdata)])) - end; - (* Add usb emulation flags. - Make sure we don't send usb=false and usb_tablet=true, - as that wouldn't make sense. *) - let usb_enabled = - is_true ~key:usb ~platformdata ~default:true in - let usb_tablet_enabled = - if usb_enabled - then is_true ~key:usb_tablet ~platformdata ~default:true - else false - in - let platformdata = - List.update_assoc - [(usb, string_of_bool usb_enabled); - (usb_tablet, string_of_bool usb_tablet_enabled)] - platformdata - in - (* Filter out invalid values for the "parallel" key. We don't want to give - * guests access to anything other than a real parallel port. *) - let platformdata = - let is_valid_parallel_flag = function - | "none" -> true - | dev -> String.startswith "/dev/parport" dev - in - List.filter - (fun (k, v) -> k <> parallel || is_valid_parallel_flag v) - platformdata - in - platformdata - - -let check_restricted_flags ~__context platform = - if not (is_valid nested_virt platform) then - raise (Api_errors.Server_error - (Api_errors.invalid_value, - [Printf.sprintf "platform:%s" nested_virt; - List.assoc nested_virt platform])); - - if is_true nested_virt platform false - then Pool_features.assert_enabled ~__context ~f:Features.Nested_virt - - diff --git a/ocaml/xapi/xapi_vm.ml b/ocaml/xapi/xapi_vm.ml index af9f1b8d9e..4f39f074ed 100644 --- a/ocaml/xapi/xapi_vm.ml +++ b/ocaml/xapi/xapi_vm.ml @@ -197,7 +197,7 @@ let start ~__context ~vm ~start_paused ~force = (* Check to see if we're using any restricted platform kvs. This raises an exception if so *) - Vm_platform.check_restricted_flags ~__context vmr.API.vM_platform; + Xapi_xenops.Platform.check_restricted_flags ~__context vmr.API.vM_platform; (* Clear out any VM guest metrics record. Guest metrics will be updated by * the running VM and for now they might be wrong, especially network diff --git a/ocaml/xapi/xapi_vm_lifecycle.ml b/ocaml/xapi/xapi_vm_lifecycle.ml index b777400f28..81acd3c333 100644 --- a/ocaml/xapi/xapi_vm_lifecycle.ml +++ b/ocaml/xapi/xapi_vm_lifecycle.ml @@ -261,26 +261,6 @@ let check_protection_policy ~vmr ~op ~ref_str = [ref_str; Ref.string_of vmr.Db_actions.vM_protection_policy]) | _ -> None -(** Some VMs can't migrate. The predicate [is_mobile] is true, if and - * only if a VM is mobile. - * - * A VM is not mobile if in its [last_booted_record] any of the - * following values are true: [platform:nomigrate] or - * [platform:nested-virt]. If we cannot find a boot record the VM can - * migrate. A VM can always migrate if strict=false. - * - **) -let is_mobile strict vm = - let not_true platformdata key = - not @@ Vm_platform.is_true ~key ~platformdata ~default:false in - match strict, vm.Db_actions.vM_last_booted_record with - | false, _ -> true (* --force overrides actual checks *) - | true , "" -> true (* no LBR exists, VM is not yet started *) - | true, xml -> (* check platform of last boot record *) - Helpers.parse_boot_record ~string:xml - |> fun lbr -> lbr.API.vM_platform - |> fun plf -> not_true plf "nomigrate" && not_true plf "nested-virt" - (** Take an internal VM record and a proposed operation. Return None iff the operation would be acceptable; otherwise Some (Api_errors., [list of strings]) corresponding to the first error found. Checking stops at the first error. @@ -337,17 +317,6 @@ let check_operation_error ~__context ~vmr ~vmgmr ~ref ~clone_suspended_vm_enable then Some (Api_errors.only_revert_snapshot, []) else None) in - (* Migration must be blocked if VM is not mobile *) - let current_error = check current_error (fun () -> - match op with - | `suspend - | `checkpoint - | `pool_migrate - | `migrate_send - when not (is_mobile strict vmr) -> Some (Api_errors.vm_is_immobile, [ref_str]) - | _ -> None - ) in - (* Check if the VM is a control domain (eg domain 0). *) (* FIXME: Instead of special-casing for the control domain here, *) (* make use of the Helpers.ballooning_enabled_for_vm function. *) diff --git a/ocaml/xapi/xapi_xenops.ml b/ocaml/xapi/xapi_xenops.ml index e94ee58c22..e684bcd931 100644 --- a/ocaml/xapi/xapi_xenops.ml +++ b/ocaml/xapi/xapi_xenops.ml @@ -82,6 +82,156 @@ let xenops_of_xenapi_power_state = function | `Suspended -> Suspended | `Paused -> Paused +module Platform = struct + (* Keys we push through to xenstore. *) + let acpi = "acpi" + let apic = "apic" + let nx = "nx" + let pae = "pae" + let viridian = "viridian" + let acpi_s3 = "acpi_s3" + let acpi_s4 = "acpi_s4" + let mmio_size_mib = "mmio_size_mib" + let revision = "revision" + let device_id = "device_id" + let tsc_mode = "tsc_mode" + let device_model = "device-model" + let xenguest = "xenguest" + let pv_kernel_max_size = "pv-kernel-max-size" + let pv_ramdisk_max_size = "pv-ramdisk-max-size" + let pv_postinstall_kernel_max_size = "pv-postinstall-kernel-max-size" + let pv_postinstall_ramdisk_max_size = "pv-postinstall-ramdisk-max-size" + let usb = "usb" + let usb_tablet = "usb_tablet" + let parallel = "parallel" + let vga = "vga" + let vgpu_pci_id = Xapi_globs.vgpu_pci_key + let vgpu_config = Xapi_globs.vgpu_config_key + let igd_passthru_key = Xapi_globs.igd_passthru_key + let featureset = "featureset" + let nested_virt = "nested-virt" + + (* This is only used to block the 'present multiple physical cores as one big hyperthreaded core' feature *) + let filtered_flags = [ + acpi; + apic; + nx; + pae; + viridian; + acpi_s3; + acpi_s4; + mmio_size_mib; + revision; + device_id; + tsc_mode; + device_model; + xenguest; + pv_kernel_max_size; + pv_ramdisk_max_size; + pv_postinstall_kernel_max_size; + pv_postinstall_ramdisk_max_size; + usb; + usb_tablet; + parallel; + vga; + vgpu_pci_id; + vgpu_config; + featureset; + nested_virt; + ] + + (* Other keys we might want to write to the platform map. *) + let timeoffset = "timeoffset" + let generation_id = "generation-id" + + (* Helper functions. *) + (* [is_valid key platformdata] returns true if: + 1. The key is _not_ in platformdata (absence of key is valid) or + 2. The key is in platformdata, associated with a booleanish value *) + let is_valid ~key ~platformdata = + (not (List.mem_assoc key platformdata)) || + (match List.assoc key platformdata |> String.lowercase with + | "true" | "1" | "false" | "0" -> true + | v -> false) + + let is_true ~key ~platformdata ~default = + try + match List.assoc key platformdata |> String.lowercase with + | "true" | "1" -> true + | "false" | "0" -> false + | _ -> default (* Check for validity using is_valid if required *) + with Not_found -> + default + + let sanity_check ~platformdata ~vcpu_max ~vcpu_at_startup ~hvm ~filter_out_unknowns = + (* Filter out unknown flags, if applicable *) + let platformdata = + if filter_out_unknowns + then List.filter (fun (k, v) -> List.mem k filtered_flags) platformdata + else platformdata + in + (* Filter out invalid TSC modes. *) + let platformdata = + List.filter + (fun (k, v) -> k <> tsc_mode || List.mem v ["0"; "1"; "2"; "3"]) + platformdata + in + (* Sanity check for HVM domains with invalid VCPU configuration*) + if hvm && (List.mem_assoc "cores-per-socket" platformdata) then + begin + try + let cores_per_socket = int_of_string(List.assoc "cores-per-socket" platformdata) in + (* cores per socket has to be in multiples of VCPUs_max and VCPUs_at_startup *) + if (((Int64.to_int(vcpu_max) mod cores_per_socket) <> 0) + || ((Int64.to_int(vcpu_at_startup) mod cores_per_socket) <> 0)) then + raise (Api_errors.Server_error(Api_errors.invalid_value, + ["platform:cores-per-socket"; + "VCPUs_max/VCPUs_at_startup must be a multiple of this field"])) + with Failure msg -> + raise (Api_errors.Server_error(Api_errors.invalid_value, ["platform:cores-per-socket"; + Printf.sprintf "value = %s is not a valid int" (List.assoc "cores-per-socket" platformdata)])) + end; + (* Add usb emulation flags. + Make sure we don't send usb=false and usb_tablet=true, + as that wouldn't make sense. *) + let usb_enabled = + is_true ~key:usb ~platformdata ~default:true in + let usb_tablet_enabled = + if usb_enabled + then is_true ~key:usb_tablet ~platformdata ~default:true + else false + in + let platformdata = + List.update_assoc + [(usb, string_of_bool usb_enabled); + (usb_tablet, string_of_bool usb_tablet_enabled)] + platformdata + in + (* Filter out invalid values for the "parallel" key. We don't want to give + * guests access to anything other than a real parallel port. *) + let platformdata = + let is_valid_parallel_flag = function + | "none" -> true + | dev -> String.startswith "/dev/parport" dev + in + List.filter + (fun (k, v) -> k <> parallel || is_valid_parallel_flag v) + platformdata + in + platformdata + + + let check_restricted_flags ~__context platform = + if not (is_valid nested_virt platform) then + raise (Api_errors.Server_error + (Api_errors.invalid_value, + [Printf.sprintf "platform:%s" nested_virt; + List.assoc nested_virt platform])); + + if is_true nested_virt platform false + then Pool_features.assert_enabled ~__context ~f:Features.Nested_virt +end + let xenops_vdi_locator_of_strings sr_uuid vdi_location = Printf.sprintf "%s/%s" sr_uuid vdi_location @@ -130,7 +280,7 @@ let int = find int_of_string let bool = find (function "1" -> true | "0" -> false | x -> bool_of_string x) let rtc_timeoffset_of_vm ~__context (vm, vm_t) vbds = - let timeoffset = string vm_t.API.vM_platform "0" Vm_platform.timeoffset in + let timeoffset = string vm_t.API.vM_platform "0" Platform.timeoffset in (* If any VDI has on_boot = reset AND has a VDI.other_config:timeoffset then we override the platform/timeoffset. This is needed because windows stores the local time in timeoffset (the BIOS clock) but records whether @@ -146,7 +296,7 @@ let rtc_timeoffset_of_vm ~__context (vm, vm_t) vbds = |> List.filter_map (fun (reference, record) -> Opt.of_exception (fun () -> reference, - List.assoc Vm_platform.timeoffset + List.assoc Platform.timeoffset record.API.vDI_other_config)) in match vdis_with_timeoffset_to_be_reset_on_boot with | [] -> @@ -176,13 +326,13 @@ let builder_of_vm ~__context (vmref, vm) timeoffset pci_passthrough vgpu = let video_mode = if vgpu then Vgpu - else if (Vm_platform.is_true - ~key:Vm_platform.igd_passthru_key + else if (Platform.is_true + ~key:Platform.igd_passthru_key ~platformdata:vm.API.vM_platform ~default:false) then (IGD_passthrough GVT_d) else - match string vm.API.vM_platform "cirrus" Vm_platform.vga with + match string vm.API.vM_platform "cirrus" Platform.vga with | "std" -> Standard_VGA | "cirrus" -> Cirrus | x -> @@ -570,8 +720,8 @@ module MD = struct let vgpus_of_vm ~__context (vmref, vm) = let open Vgpu in if Vgpuops.vgpu_manual_setup_of_vm vm - && (List.mem_assoc Vm_platform.vgpu_pci_id vm.API.vM_platform) - && (List.mem_assoc Vm_platform.vgpu_config vm.API.vM_platform) + && (List.mem_assoc Platform.vgpu_pci_id vm.API.vM_platform) + && (List.mem_assoc Platform.vgpu_config vm.API.vM_platform) then begin (* We're using the vGPU manual setup mode, so get the vGPU configuration * from the VM platform keys. *) @@ -579,8 +729,8 @@ module MD = struct Nvidia { physical_pci_address = Xenops_interface.Pci.address_of_string - (List.assoc Vm_platform.vgpu_pci_id vm.API.vM_platform); - config_file = List.assoc Vm_platform.vgpu_config vm.API.vM_platform; + (List.assoc Platform.vgpu_pci_id vm.API.vM_platform); + config_file = List.assoc Platform.vgpu_config vm.API.vM_platform; } in [{ id = (vm.API.vM_uuid, "0"); @@ -666,7 +816,7 @@ module MD = struct { priority = priority; affinity = affinity } in let platformdata = - Vm_platform.sanity_check + Platform.sanity_check ~platformdata:vm.API.vM_platform ~vcpu_max:vm.API.vM_VCPUs_max ~vcpu_at_startup:vm.API.vM_VCPUs_at_startup @@ -677,24 +827,24 @@ module MD = struct (* Replace the timeoffset in the platform data too, to avoid confusion *) let timeoffset = rtc_timeoffset_of_vm ~__context (vmref, vm) vbds in let platformdata = - (Vm_platform.timeoffset, timeoffset) :: - (List.filter (fun (key, _) -> key <> Vm_platform.timeoffset) platformdata) in + (Platform.timeoffset, timeoffset) :: + (List.filter (fun (key, _) -> key <> Platform.timeoffset) platformdata) in let platformdata = let genid = match vm.API.vM_generation_id with | "0:0" -> Xapi_vm_helpers.vm_fresh_genid ~__context ~self:vmref | _ -> vm.API.vM_generation_id in - (Vm_platform.generation_id, genid) :: platformdata + (Platform.generation_id, genid) :: platformdata in (* Add the CPUID feature set for the VM to the platform data. *) let platformdata = - if not (List.mem_assoc Vm_platform.featureset platformdata) then + if not (List.mem_assoc Platform.featureset platformdata) then let featureset = if List.mem_assoc Xapi_globs.cpu_info_features_key vm.API.vM_last_boot_CPU_flags then List.assoc Xapi_globs.cpu_info_features_key vm.API.vM_last_boot_CPU_flags else failwith "VM's CPU featureset not initialised" in - (Vm_platform.featureset, featureset) :: platformdata + (Platform.featureset, featureset) :: platformdata else platformdata in @@ -1343,8 +1493,8 @@ let update_vm ~__context id = (fun (_, state) -> if state.rtc_timeoffset <> "" then begin debug "xenopsd event: Updating VM %s platform:timeoffset <- %s" id state.rtc_timeoffset; - (try Db.VM.remove_from_platform ~__context ~self ~key:Vm_platform.timeoffset with _ -> ()); - Db.VM.add_to_platform ~__context ~self ~key:Vm_platform.timeoffset ~value:state.rtc_timeoffset; + (try Db.VM.remove_from_platform ~__context ~self ~key:Platform.timeoffset with _ -> ()); + Db.VM.add_to_platform ~__context ~self ~key:Platform.timeoffset ~value:state.rtc_timeoffset; end ) info with e ->