Skip to content

Commit 790aa22

Browse files
authored
Merge feature/guest-vm-service-aware into master (#6407)
commit 2653f74 is new to update datamodel lifecycle
2 parents e21647c + 2653f74 commit 790aa22

10 files changed

Lines changed: 147 additions & 11 deletions

File tree

ocaml/idl/datamodel.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7621,6 +7621,10 @@ module VM_guest_metrics = struct
76217621
~ty:Bool ~default_value:(Some (VBool false)) "PV_drivers_detected"
76227622
"At least one of the guest's devices has successfully connected to \
76237623
the backend."
7624+
; field ~qualifier:DynamicRO ~lifecycle:[]
7625+
~ty:(Map (String, String))
7626+
~default_value:(Some (VMap [])) "services"
7627+
"The guest's services data."
76247628
]
76257629
()
76267630
end

ocaml/idl/datamodel_common.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ open Datamodel_roles
1010
to leave a gap for potential hotfixes needing to increment the schema version.*)
1111
let schema_major_vsn = 5
1212

13-
let schema_minor_vsn = 786
13+
let schema_minor_vsn = 787
1414

1515
(* Historical schema versions just in case this is useful later *)
1616
let rio_schema_major_vsn = 5

ocaml/idl/datamodel_lifecycle.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ let prototyped_of_field = function
109109
Some "22.27.0"
110110
| "host", "last_software_update" ->
111111
Some "22.20.0"
112+
| "VM_guest_metrics", "services" ->
113+
Some "25.14.0-next"
112114
| "VM_guest_metrics", "netbios_name" ->
113115
Some "24.28.0"
114116
| "VM", "groups" ->

ocaml/idl/schematest.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ let hash x = Digest.string x |> Digest.to_hex
33
(* BEWARE: if this changes, check that schema has been bumped accordingly in
44
ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *)
55

6-
let last_known_schema_hash = "ad67a64cd47cdea32085518c1fb38d27"
6+
let last_known_schema_hash = "7756b4bea0be3985c1c8f6708f04d442"
77

88
let current_schema_hash : string =
99
let open Datamodel_types in

ocaml/tests/test_guest_agent.ml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,93 @@ module Initial_guest_metrics = Generic.MakeStateless (struct
468468
]
469469
end)
470470

471+
module Services = Generic.MakeStateless (struct
472+
module Io = struct
473+
type input_t = (string * string) list
474+
475+
type output_t = (string * string) list
476+
477+
let string_of_input_t = Test_printers.(assoc_list string string)
478+
479+
let string_of_output_t = Test_printers.(assoc_list string string)
480+
end
481+
482+
(* prototype funtions lookup and list are in Xapi_xenops.ml::update_vm *)
483+
let lookup state key = List.assoc_opt key state
484+
485+
let list_subkeys state dir =
486+
if dir = "" then
487+
[]
488+
else
489+
let dir =
490+
if dir.[0] = '/' then
491+
String.sub dir 1 (String.length dir - 1)
492+
else
493+
dir
494+
in
495+
let results =
496+
List.filter_map
497+
(fun (path, _) ->
498+
if String.starts_with ~prefix:dir path then
499+
let rest =
500+
String.sub path (String.length dir)
501+
(String.length path - String.length dir)
502+
in
503+
let is_sep = function '/' -> true | _ -> false in
504+
match Astring.String.fields ~empty:false ~is_sep rest with
505+
| x :: _ ->
506+
Some x
507+
| _ ->
508+
None
509+
else
510+
None
511+
)
512+
state
513+
|> Xapi_stdext_std.Listext.List.setify
514+
in
515+
results
516+
517+
let transform input =
518+
Xapi_guest_agent.get_guest_services (lookup input) (list_subkeys input)
519+
520+
let tests =
521+
`QuickAndAutoDocumented
522+
[
523+
(* no data/service *)
524+
([("data/key1", "v1"); ("data/key2", "v2")], [])
525+
; (* less than two depth in data/service *)
526+
([("data/service/key1", "v1"); ("data/service/key2", "v2")], [])
527+
; (* beyond two depth in data/service *)
528+
( [
529+
("data/service/service-a/sub/key1", "sab-v1")
530+
; ("data/service/service-a/sub/key2", "sab-v2")
531+
]
532+
, [("service-a/sub", "")]
533+
)
534+
; (* normal case *)
535+
( [
536+
("data/service", "")
537+
; ("data/service/service-a", "")
538+
; ("data/service/service-b", "")
539+
; ("data/service/service-a/key1", "sa-v1")
540+
; ("data/service/service-a/key2", "sa-v2")
541+
; ("data/service/service-b/key1", "sb-v1")
542+
; ("data/service/service-b/key2", "sb-v2")
543+
]
544+
, [
545+
("service-a/key1", "sa-v1")
546+
; ("service-a/key2", "sa-v2")
547+
; ("service-b/key1", "sb-v1")
548+
; ("service-b/key2", "sb-v2")
549+
]
550+
)
551+
]
552+
end)
553+
471554
let tests =
472555
make_suite "guest_agent_"
473556
[
474557
("networks", Networks.tests)
475558
; ("get_initial_guest_metrics", Initial_guest_metrics.tests)
559+
; ("get_guest_services", Services.tests)
476560
]

ocaml/xapi-cli-server/records.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,18 @@ let vm_record rpc session_id vm =
24162416
(xgm ())
24172417
)
24182418
()
2419+
; make_field ~name:"services"
2420+
~get:(fun () ->
2421+
Option.fold ~none:nid
2422+
~some:(fun m -> get_from_map m.API.vM_guest_metrics_services)
2423+
(xgm ())
2424+
)
2425+
~get_map:(fun () ->
2426+
Option.fold ~none:[]
2427+
~some:(fun m -> m.API.vM_guest_metrics_services)
2428+
(xgm ())
2429+
)
2430+
()
24192431
; make_field ~name:"PV-drivers-detected"
24202432
~get:(fun () ->
24212433
Option.fold ~none:nid

ocaml/xapi/import.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ module GuestMetrics : HandlerTools = struct
836836
~memory:gm_record.API.vM_guest_metrics_memory
837837
~disks:gm_record.API.vM_guest_metrics_disks
838838
~networks:gm_record.API.vM_guest_metrics_networks
839+
~services:gm_record.API.vM_guest_metrics_services
839840
~pV_drivers_detected:gm_record.API.vM_guest_metrics_PV_drivers_detected
840841
~other:gm_record.API.vM_guest_metrics_other
841842
~last_updated:gm_record.API.vM_guest_metrics_last_updated

ocaml/xapi/xapi_guest_agent.ml

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ type guest_metrics_t = {
224224
; other: m
225225
; memory: m
226226
; device_id: m
227+
; services: m
227228
; last_updated: float
228229
; can_use_hotplug_vbd: API.tristate_type
229230
; can_use_hotplug_vif: API.tristate_type
@@ -235,6 +236,29 @@ let dead_domains : IntSet.t ref = ref IntSet.empty
235236

236237
let mutex = Mutex.create ()
237238

239+
(* Parse data/service which has the following structure:
240+
data/service/<service_name>/<key> = <value>
241+
data/service/<service_name>/<key> = <value>
242+
...
243+
data/service/<service_name>/<key> = <value>
244+
Read and convert to [(<service_name>/<key>, <value>)] pair list.
245+
The list is intended to store in VM_guest_metrics.services at last *)
246+
let get_guest_services (lookup : string -> string option)
247+
(list : string -> string list) =
248+
let base_path = "data/service" in
249+
let services = list base_path in
250+
services
251+
|> List.concat_map (fun service ->
252+
let sub_path = base_path // service in
253+
list sub_path
254+
|> List.map (fun key ->
255+
let full_path_key = sub_path // key in
256+
let db_key = service // key in
257+
let value = lookup full_path_key in
258+
(db_key, Option.value ~default:"" value)
259+
)
260+
)
261+
238262
(* In the following functions, 'lookup' reads a key from xenstore and 'list' reads
239263
a directory from xenstore. Both are relative to the guest's domainpath. *)
240264
let get_initial_guest_metrics (lookup : string -> string option)
@@ -289,6 +313,7 @@ let get_initial_guest_metrics (lookup : string -> string option)
289313
; networks "xenserver/attr" "net-sriov-vf" list
290314
]
291315
)
316+
and services = get_guest_services lookup list
292317
and other = List.append (to_map (other all_control)) ts
293318
and memory = to_map memory
294319
and last_updated = Unix.gettimeofday () in
@@ -310,6 +335,7 @@ let get_initial_guest_metrics (lookup : string -> string option)
310335
; other
311336
; memory
312337
; device_id
338+
; services
313339
; last_updated
314340
; can_use_hotplug_vbd
315341
; can_use_hotplug_vif
@@ -326,7 +352,8 @@ let create_and_set_guest_metrics (lookup : string -> string option)
326352
~os_version:initial_gm.os_version ~netbios_name:initial_gm.netbios_name
327353
~pV_drivers_version:initial_gm.pv_drivers_version
328354
~pV_drivers_up_to_date:pV_drivers_detected ~memory:[] ~disks:[]
329-
~networks:initial_gm.networks ~pV_drivers_detected ~other:initial_gm.other
355+
~networks:initial_gm.networks ~services:initial_gm.services
356+
~pV_drivers_detected ~other:initial_gm.other
330357
~last_updated:(Date.of_unix_time initial_gm.last_updated)
331358
~other_config:[] ~live:true
332359
~can_use_hotplug_vbd:initial_gm.can_use_hotplug_vbd
@@ -356,6 +383,7 @@ let all (lookup : string -> string option) (list : string -> string list)
356383
; other
357384
; memory
358385
; device_id
386+
; services
359387
; last_updated
360388
; can_use_hotplug_vbd
361389
; can_use_hotplug_vif
@@ -390,6 +418,7 @@ let all (lookup : string -> string option) (list : string -> string list)
390418
; other= []
391419
; memory= []
392420
; device_id= []
421+
; services= []
393422
; last_updated= 0.0
394423
; can_use_hotplug_vbd= `unspecified
395424
; can_use_hotplug_vif= `unspecified
@@ -407,6 +436,7 @@ let all (lookup : string -> string option) (list : string -> string list)
407436
; other
408437
; memory
409438
; device_id
439+
; services
410440
; last_updated
411441
; can_use_hotplug_vbd
412442
; can_use_hotplug_vif
@@ -420,6 +450,7 @@ let all (lookup : string -> string option) (list : string -> string list)
420450
|| guest_metrics_cached.networks <> networks
421451
|| guest_metrics_cached.other <> other
422452
|| guest_metrics_cached.device_id <> device_id
453+
|| guest_metrics_cached.services <> services
423454
)
424455
|| guest_metrics_cached.can_use_hotplug_vbd <> can_use_hotplug_vbd
425456
|| guest_metrics_cached.can_use_hotplug_vif <> can_use_hotplug_vif
@@ -452,6 +483,8 @@ let all (lookup : string -> string option) (list : string -> string list)
452483
~value:netbios_name ;
453484
if guest_metrics_cached.networks <> networks then
454485
Db.VM_guest_metrics.set_networks ~__context ~self:gm ~value:networks ;
486+
if guest_metrics_cached.services <> services then
487+
Db.VM_guest_metrics.set_services ~__context ~self:gm ~value:services ;
455488
if guest_metrics_cached.other <> other then (
456489
Db.VM_guest_metrics.set_other ~__context ~self:gm ~value:other ;
457490
Helpers.call_api_functions ~__context (fun rpc session_id ->

ocaml/xapi/xapi_vm_helpers.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,7 @@ let copy_guest_metrics ~__context ~vm =
14651465
~memory:all.API.vM_guest_metrics_memory
14661466
~disks:all.API.vM_guest_metrics_disks
14671467
~networks:all.API.vM_guest_metrics_networks
1468+
~services:all.API.vM_guest_metrics_services
14681469
~pV_drivers_detected:all.API.vM_guest_metrics_PV_drivers_detected
14691470
~other:all.API.vM_guest_metrics_other
14701471
~last_updated:all.API.vM_guest_metrics_last_updated

ocaml/xenopsd/xc/xenops_server_xen.ml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,9 +2748,10 @@ module VM = struct
27482748
(fun port -> {Vm.protocol= Vm.Vt100; port; path= ""})
27492749
(Device.get_tc_port ~xs di.Xenctrl.domid)
27502750
in
2751-
let local x =
2752-
Printf.sprintf "/local/domain/%d/%s" di.Xenctrl.domid x
2751+
let root_path =
2752+
Printf.sprintf "/local/domain/%d" di.Xenctrl.domid
27532753
in
2754+
let local x = Printf.sprintf "%s/%s" root_path x in
27542755
let uncooperative =
27552756
try
27562757
ignore_string (xs.Xs.read (local "memory/uncooperative")) ;
@@ -2853,22 +2854,19 @@ module VM = struct
28532854
; ("drivers", None, 0)
28542855
; ("data", None, 0)
28552856
(* in particular avoid data/volumes which contains many entries for each disk *)
2857+
; ("data/service", None, 1) (* data/service/<service-name>/<key>*)
28562858
]
28572859
|> List.fold_left
28582860
(fun acc (dir, excludes, depth) ->
2859-
ls_lR ?excludes ~depth
2860-
(Printf.sprintf "/local/domain/%d" di.Xenctrl.domid)
2861-
acc dir
2861+
ls_lR ?excludes ~depth root_path acc dir
28622862
)
28632863
(quota, [])
28642864
|> fun (quota, acc) ->
28652865
(quota, map_tr (fun (k, v) -> (k, Xenops_utils.utf8_recode v)) acc)
28662866
in
28672867
let quota, xsdata_state =
28682868
Domain.allowed_xsdata_prefixes
2869-
|> List.fold_left
2870-
(ls_lR (Printf.sprintf "/local/domain/%d" di.Xenctrl.domid))
2871-
(quota, [])
2869+
|> List.fold_left (ls_lR root_path) (quota, [])
28722870
in
28732871
let path =
28742872
Device_common.xenops_path_of_domain di.Xenctrl.domid
@@ -4829,6 +4827,7 @@ module Actions = struct
48294827
sprintf "/local/domain/%d/attr" domid
48304828
; sprintf "/local/domain/%d/data/updated" domid
48314829
; sprintf "/local/domain/%d/data/ts" domid
4830+
; sprintf "/local/domain/%d/data/service" domid
48324831
; sprintf "/local/domain/%d/memory/target" domid
48334832
; sprintf "/local/domain/%d/memory/uncooperative" domid
48344833
; sprintf "/local/domain/%d/console/vnc-port" domid

0 commit comments

Comments
 (0)