Skip to content

Commit c76b956

Browse files
authored
Merge pull request #2675 from kc284/cp-17481
CP-17481: Allow other VMs to use is_control_domain
2 parents f85079c + 30a56a4 commit c76b956

23 files changed

+91
-78
lines changed

ocaml/client_records/records.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,7 @@ let host_record rpc session_id host =
10961096
make_field ~name:"virtual-hardware-platform-versions"
10971097
~get:(fun () -> String.concat "; " (List.map Int64.to_string (x ()).API.host_virtual_hardware_platform_versions))
10981098
~get_set:(fun () -> List.map Int64.to_string (x ()).API.host_virtual_hardware_platform_versions) ();
1099+
make_field ~name:"control-domain-uuid" ~get:(fun () -> get_uuid_from_ref (x ()).API.host_control_domain) ();
10991100
]}
11001101

11011102
let vdi_record rpc session_id vdi =

ocaml/idl/datamodel.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4683,6 +4683,7 @@ let host =
46834683
field ~qualifier:RW ~in_product_since:rel_tampa ~default_value:(Some (VMap [])) ~ty:(Map (String, String)) "guest_VCPUs_params" "VCPUs params to apply to all resident guests";
46844684
field ~qualifier:RW ~in_product_since:rel_cream ~default_value:(Some (VEnum "enabled")) ~ty:host_display "display" "indicates whether the host is configured to output its console to a physical display device";
46854685
field ~qualifier:DynamicRO ~in_product_since:rel_cream ~default_value:(Some (VSet [VInt 0L])) ~ty:(Set (Int)) "virtual_hardware_platform_versions" "The set of versions of the virtual hardware platform that the host can offer to its guests";
4686+
field ~qualifier:DynamicRO ~default_value:(Some (VRef (Ref.string_of Ref.null))) ~in_product_since:rel_dundee_plus ~ty:(Ref _vm) "control_domain" "The control domain (domain 0)";
46864687
])
46874688
()
46884689

ocaml/test/test_common.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ let make_localhost ~__context =
6060
simple thing first and just set localhost_ref instead. *)
6161
(* Dbsync_slave.refresh_localhost_info ~__context host_info; *)
6262
Xapi_globs.localhost_ref := Helpers.get_localhost ~__context;
63-
Create_misc.ensure_domain_zero_records ~__context host_info;
63+
Create_misc.ensure_domain_zero_records ~__context ~host:!Xapi_globs.localhost_ref host_info;
6464
Dbsync_master.create_pool_record ~__context
6565

6666
(** Make a simple in-memory database containing a single host and dom0 VM record. *)

ocaml/test/test_vdi_allowed_operations.ml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ let test_ca101669 () =
108108
`copy (Some (Api_errors.vdi_in_use, []))
109109

110110
let test_ca125187 () =
111-
let __context = Mock.make_context_with_new_db "Mock context" in
111+
let __context = Test_common.make_test_database () in
112112

113113
(* A VDI being copied can be copied again concurrently. *)
114114
run_assert_equal_with_vdi ~__context
@@ -123,9 +123,8 @@ let test_ca125187 () =
123123
* the VBD is plugged after the VDI is marked with the copy operation. *)
124124
let _, _ = setup_test ~__context
125125
~vdi_fun:(fun vdi_ref ->
126-
let vm_ref = make_vm ~__context () in
127-
Db.VM.set_is_control_domain ~__context ~self:vm_ref ~value:true;
128-
Db.VM.set_power_state ~__context ~self:vm_ref ~value:`Running;
126+
let host_ref = Helpers.get_localhost ~__context in
127+
let vm_ref = Db.Host.get_control_domain ~__context ~self:host_ref in
129128
let vbd_ref = Ref.make () in
130129
let (_: API.ref_VBD) = make_vbd ~__context
131130
~ref:vbd_ref

ocaml/xapi/create_misc.ml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,23 @@ let (+++) = Int64.add
133133
(** This function makes sure there is exactly one record of each type. *)
134134
(** It updates existing records if they are found, or else creates new *)
135135
(** records for any records that are missing. *)
136-
let rec ensure_domain_zero_records ~__context (host_info: host_info) : unit =
136+
let rec ensure_domain_zero_records ~__context ~host (host_info: host_info) : unit =
137+
maybe_upgrade_domain_zero_record ~__context ~host host_info;
137138
let domain_zero_ref = ensure_domain_zero_record ~__context host_info in
138139
ensure_domain_zero_console_record ~__context ~domain_zero_ref;
139140
ensure_domain_zero_guest_metrics_record ~__context ~domain_zero_ref host_info;
140141
ensure_domain_zero_shadow_record ~__context ~domain_zero_ref
141142

143+
and maybe_upgrade_domain_zero_record ~__context ~host (host_info: host_info) =
144+
try
145+
let control_domain = Db.VM.get_by_uuid ~__context ~uuid:host_info.dom0_uuid in
146+
if Db.Host.get_control_domain ~__context ~self:host = Ref.null then begin
147+
debug "Setting control domain for host %s to %s"
148+
(Ref.string_of host) (Ref.string_of control_domain);
149+
Db.Host.set_control_domain ~__context ~self:host ~value:control_domain;
150+
end
151+
with Db_exn.Read_missing_uuid(_) -> ()
152+
142153
and ensure_domain_zero_record ~__context (host_info: host_info): [`VM] Ref.t =
143154
let ref_lookup () = Helpers.get_domain_zero ~__context in
144155
let ref_create () = Ref.make () in
@@ -225,6 +236,7 @@ and create_domain_zero_record ~__context ~domain_zero_ref (host_info: host_info)
225236
~hardware_platform_version:0L
226237
~has_vendor_device:false
227238
;
239+
Db.Host.set_control_domain ~__context ~self:localhost ~value:domain_zero_ref;
228240
Xapi_vm_helpers.update_memory_overhead ~__context ~vm:domain_zero_ref
229241

230242
and create_domain_zero_console_record_with_protocol ~__context ~domain_zero_ref ~dom0_console_protocol =

ocaml/xapi/create_misc.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type host_info = {
3232
val read_dom0_memory_usage : unit -> int64 option
3333
val read_localhost_info : unit -> host_info
3434

35-
val ensure_domain_zero_records : __context:Context.t -> host_info -> unit
35+
val ensure_domain_zero_records : __context:Context.t -> host:[`host] Ref.t -> host_info -> unit
3636

3737
val create_root_user : __context:Context.t -> unit
3838

ocaml/xapi/dbsync_slave.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,13 @@ let update_env __context sync_keys =
280280
Create_misc.create_host_cpu ~__context;
281281
);
282282

283+
let localhost = Helpers.get_localhost ~__context in
284+
283285
switched_sync Xapi_globs.sync_create_domain_zero (fun () ->
284286
debug "creating domain 0";
285-
Create_misc.ensure_domain_zero_records ~__context info;
287+
Create_misc.ensure_domain_zero_records ~__context ~host:localhost info;
286288
);
287289

288-
let localhost = Helpers.get_localhost ~__context in
289-
290290
switched_sync Xapi_globs.sync_crashdump_resynchronise (fun () ->
291291
debug "resynchronising host crashdumps";
292292
Xapi_host_crashdump.resynchronise ~__context ~host:localhost;

ocaml/xapi/helpers.ml

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,11 @@ let get_user ~__context username =
310310
failwith "Failed to find any users";
311311
List.hd uuids (* FIXME! it assumes that there is only one element in the list (root), username is not used*)
312312

313-
(* Expects only 1 control domain per host; just return first in list for now if multiple.. *)
313+
let is_domain_zero ~__context vm_ref =
314+
let host_ref = Db.VM.get_resident_on ~__context ~self:vm_ref in
315+
Db.VM.get_is_control_domain ~__context ~self:vm_ref
316+
&& Db.Host.get_control_domain ~__context ~self:host_ref = vm_ref
317+
314318
exception No_domain_zero of string
315319
let domain_zero_ref_cache = ref None
316320
let domain_zero_ref_cache_mutex = Mutex.create ()
@@ -324,14 +328,14 @@ let get_domain_zero ~__context : API.ref_VM =
324328
let uuid = Xapi_inventory.lookup Xapi_inventory._control_domain_uuid in
325329
try
326330
let vm = Db.VM.get_by_uuid ~__context ~uuid in
327-
if not (Db.VM.get_is_control_domain ~__context ~self:vm) then begin
328-
error "VM uuid %s is not a control domain but the uuid is in my inventory file" uuid;
331+
if not (is_domain_zero ~__context vm) then begin
332+
error "VM uuid %s is not domain zero but the uuid is in my inventory file" uuid;
329333
raise (No_domain_zero uuid);
330334
end;
331335
domain_zero_ref_cache := Some vm;
332336
vm
333337
with _ ->
334-
error "Failed to find control domain (uuid = %s)" uuid;
338+
error "Failed to find domain zero (uuid = %s)" uuid;
335339
raise (No_domain_zero uuid)
336340
)
337341

@@ -509,21 +513,23 @@ let boot_method_of_vm ~__context ~vm =
509513
(** Returns true if the supplied VM configuration is HVM.
510514
NB that just because a VM's current configuration looks like HVM doesn't imply it
511515
actually booted that way; you must check the boot_record to be sure *)
512-
let is_hvm (x: API.vM_t) = not(x.API.vM_is_control_domain) && x.API.vM_HVM_boot_policy <> ""
516+
let is_hvm ~__context (x: API.vM_t) =
517+
let vm_ref = Db.VM.get_by_uuid ~__context ~uuid:x.API.vM_uuid in
518+
(not (is_domain_zero ~__context vm_ref)) && x.API.vM_HVM_boot_policy <> ""
513519

514520
let will_boot_hvm ~__context ~self = Db.VM.get_HVM_boot_policy ~__context ~self <> ""
515521

516522
let has_booted_hvm ~__context ~self =
517-
(not (Db.VM.get_is_control_domain ~__context ~self))
518-
&&
519-
let boot_record = get_boot_record ~__context ~self in
520-
boot_record.API.vM_HVM_boot_policy <> ""
523+
let boot_record = get_boot_record ~__context ~self in
524+
(not (is_domain_zero ~__context self)) && boot_record.API.vM_HVM_boot_policy <> ""
521525

522526
let has_booted_hvm_of_record ~__context r =
523-
(not (r.Db_actions.vM_is_control_domain))
524-
&&
525-
let boot_record = get_boot_record_of_record ~__context ~string:r.Db_actions.vM_last_booted_record ~uuid:r.Db_actions.vM_uuid in
526-
boot_record.API.vM_HVM_boot_policy <> ""
527+
let vm_uuid = r.Db_actions.vM_uuid in
528+
let vm_ref = Db.VM.get_by_uuid ~__context ~uuid:vm_uuid in
529+
let boot_record =
530+
get_boot_record_of_record ~__context
531+
~string:r.Db_actions.vM_last_booted_record ~uuid:vm_uuid in
532+
(not (is_domain_zero ~__context vm_ref)) && boot_record.API.vM_HVM_boot_policy <> ""
527533

528534
let is_running ~__context ~self = Db.VM.get_domid ~__context ~self <> -1L
529535

ocaml/xapi/import.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ module VM : HandlerTools = struct
410410
{vm_record with API.vM_has_vendor_device = false;}
411411
) in
412412
let vm_record = {vm_record with API.
413-
vM_memory_overhead = Memory_check.vm_compute_memory_overhead vm_record
413+
vM_memory_overhead = Memory_check.vm_compute_memory_overhead ~__context vm_record
414414
} in
415415
let vm_record = {vm_record with API.vM_protection_policy = Ref.null} in
416416
(* Full restore preserves UUIDs, so if we are replacing an existing VM the version number should be incremented *)

ocaml/xapi/memory_check.ml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ let ( /// ) = Int64.div
2121

2222
(** Calculates the amounts of 'normal' and 'shadow' host memory needed *)
2323
(** to run the given guest with the given amount of guest memory. *)
24-
let vm_compute_required_memory vm_record guest_memory_kib =
24+
let vm_compute_required_memory ~__context vm_record guest_memory_kib =
2525
let vcpu_count = Int64.to_int vm_record.API.vM_VCPUs_max in
2626
let multiplier =
27-
if Helpers.is_hvm vm_record
27+
if Helpers.is_hvm ~__context vm_record
2828
then vm_record.API.vM_HVM_shadow_multiplier
2929
else XenopsMemory.Linux.shadow_multiplier_default in
3030
let target_mib = XenopsMemory.mib_of_kib_used guest_memory_kib in
3131
let max_mib = XenopsMemory.mib_of_bytes_used vm_record.API.vM_memory_static_max in
3232
let footprint_mib = (
33-
if Helpers.is_hvm vm_record
33+
if Helpers.is_hvm ~__context vm_record
3434
then XenopsMemory.HVM.footprint_mib
3535
else XenopsMemory.Linux.footprint_mib)
3636
target_mib max_mib vcpu_count multiplier in
3737
let shadow_mib = (
38-
if Helpers.is_hvm vm_record
38+
if Helpers.is_hvm ~__context vm_record
3939
then XenopsMemory.HVM.shadow_mib
4040
else XenopsMemory.Linux.shadow_mib)
4141
max_mib vcpu_count multiplier in
@@ -78,7 +78,7 @@ let vm_compute_start_memory ~__context ?(policy=Dynamic_min) vm_record =
7878
~memory_dynamic_min: vm_record.API.vM_memory_dynamic_min
7979
~memory_dynamic_max: vm_record.API.vM_memory_dynamic_max
8080
~memory_static_max: vm_record.API.vM_memory_static_max in
81-
vm_compute_required_memory vm_record
81+
vm_compute_required_memory ~__context vm_record
8282
(XenopsMemory.kib_of_bytes_used memory_required)
8383

8484
(** Calculates the amount of memory required in both 'normal' and 'shadow'
@@ -101,7 +101,7 @@ let vm_compute_used_memory ~__context policy vm_ref =
101101
let vm_compute_resume_memory ~__context vm_ref =
102102
if Xapi_fist.disable_memory_checks () then 0L else
103103
let vm_boot_record = Helpers.get_boot_record ~__context ~self:vm_ref in
104-
let (_, shadow_bytes) = vm_compute_required_memory
104+
let (_, shadow_bytes) = vm_compute_required_memory ~__context
105105
vm_boot_record vm_boot_record.API.vM_memory_static_max in
106106
(* CA-31759: use the live target field for this *)
107107
(* rather than the LBR to make upgrade easy. *)
@@ -112,7 +112,7 @@ let vm_compute_resume_memory ~__context vm_ref =
112112
let vm_compute_migrate_memory ~__context vm_ref =
113113
if Xapi_fist.disable_memory_checks () then 0L else
114114
let vm_record = Db.VM.get_record ~__context ~self:vm_ref in
115-
let (_, shadow_bytes) = vm_compute_required_memory
115+
let (_, shadow_bytes) = vm_compute_required_memory ~__context
116116
vm_record vm_record.API.vM_memory_static_max in
117117
(* Only used when in rolling upgrade mode (from a pre-ballooning product) *)
118118
let current_memory_usage_bytes = vm_record.API.vM_memory_static_max in
@@ -243,13 +243,13 @@ let host_compute_memory_overhead ~__context ~host =
243243
(* to time and simply fetch the existing cached value from the database. *)
244244
Db.Host.get_memory_overhead ~__context ~self:host
245245

246-
let vm_compute_memory_overhead snapshot =
246+
let vm_compute_memory_overhead ~__context snapshot =
247247
let static_max_bytes = snapshot.API.vM_memory_static_max in
248248
let static_max_mib = XenopsMemory.mib_of_bytes_used static_max_bytes in
249249
let multiplier = snapshot.API.vM_HVM_shadow_multiplier in
250250
let vcpu_count = Int64.to_int (snapshot.API.vM_VCPUs_max) in
251251
let memory_overhead_mib = (
252-
if Helpers.is_hvm snapshot
252+
if Helpers.is_hvm ~__context snapshot
253253
then XenopsMemory.HVM.overhead_mib
254254
else XenopsMemory.Linux.overhead_mib)
255255
static_max_mib vcpu_count multiplier in

0 commit comments

Comments
 (0)