Skip to content

Commit 5b26de4

Browse files
committed
Merge pull request #2198 from huizh/CP-10531
CP-10531: Update vm_guest_metrics to implement PV drivers update
2 parents 6d86976 + dab231c commit 5b26de4

File tree

5 files changed

+88
-10
lines changed

5 files changed

+88
-10
lines changed

ocaml/client_records/records.ml

+4
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,10 @@ let vm_record rpc session_id vm =
848848
make_field ~name:"networks"
849849
~get:(fun () -> default nid (may (fun m -> Record_util.s2sm_to_string "; " m.API.vM_guest_metrics_networks) (xgm ()) ))
850850
~get_map:(fun () -> default [] (may (fun m -> m.API.vM_guest_metrics_networks) (xgm ()))) ();
851+
make_field ~name:"network-paths-optimized"
852+
~get:(fun () -> default nid (may (fun m -> string_of_bool m.API.vM_guest_metrics_network_paths_optimized) (xgm ()) )) ();
853+
make_field ~name:"storage-paths-optimized"
854+
~get:(fun () -> default nid (may (fun m -> string_of_bool m.API.vM_guest_metrics_storage_paths_optimized) (xgm ()) )) ();
851855
make_field ~name:"other"
852856
~get:(fun () -> default nid (may (fun m -> Record_util.s2sm_to_string "; " m.API.vM_guest_metrics_other) (xgm ()) ))
853857
~get_map:(fun () -> default [] (may (fun m -> m.API.vM_guest_metrics_other) (xgm()))) ();

ocaml/idl/datamodel.ml

+16-3
Original file line numberDiff line numberDiff line change
@@ -7050,9 +7050,22 @@ let vm_guest_metrics =
70507050
field ~qualifier:DynamicRO ~ty:(Map(String, String)) "os_version" "version of the OS";
70517051
field ~qualifier:DynamicRO ~ty:(Map(String, String)) "PV_drivers_version"
70527052
"version of the PV drivers";
7053-
field ~qualifier:DynamicRO ~ty:Bool ~in_oss_since:None "PV_drivers_up_to_date"
7054-
"true if the PV drivers appear to be up to date";
7055-
7053+
field ~qualifier:DynamicRO ~ty:Bool ~in_oss_since:None
7054+
~lifecycle:[
7055+
Published, rel_rio, "true if the PV drivers appear to be up to date";
7056+
Deprecated, rel_dundee, "Deprecated in favour of network_paths_optimized and storage_paths_optimized, and redefined in terms of them"
7057+
]
7058+
"PV_drivers_up_to_date" "Logical AND of network_paths_optimized and storage_paths_optimized";
7059+
field ~qualifier:DynamicRO ~ty:Bool ~in_oss_since:None ~default_value:(Some (VBool false))
7060+
~lifecycle:[
7061+
Published, rel_dundee, "Network paths are optimized with backend";
7062+
]
7063+
"network_paths_optimized" "True if the network paths are optimized with PV driver";
7064+
field ~qualifier:DynamicRO ~ty:Bool ~in_oss_since:None ~default_value:(Some (VBool false))
7065+
~lifecycle:[
7066+
Published, rel_dundee, "Storage paths are optimized with backend";
7067+
]
7068+
"storage_paths_optimized" "True if the storage paths are optimized with PV driver";
70567069
field ~qualifier:DynamicRO ~ty:(Map(String, String))
70577070
~lifecycle:[
70587071
Published, rel_rio, "free/used/total";

ocaml/xapi/import.ml

+2
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ module GuestMetrics : HandlerTools = struct
532532
~memory:gm_record.API.vM_guest_metrics_memory
533533
~disks:gm_record.API.vM_guest_metrics_disks
534534
~networks:gm_record.API.vM_guest_metrics_networks
535+
~network_paths_optimized:gm_record.API.vM_guest_metrics_network_paths_optimized
536+
~storage_paths_optimized:gm_record.API.vM_guest_metrics_storage_paths_optimized
535537
~other:gm_record.API.vM_guest_metrics_other
536538
~last_updated:gm_record.API.vM_guest_metrics_last_updated
537539
~other_config:gm_record.API.vM_guest_metrics_other_config

ocaml/xapi/xapi_guest_agent.ml

+64-7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ let memory =
5555

5656
let device_id = [ "data/device_id", "device_id"]
5757

58+
let extend base str = Printf.sprintf "%s/%s" base str
59+
5860
(* This function is passed the 'attr' node and a function it can use to
5961
* find the directory listing of sub-nodes. It will return a map where the
6062
* keys are the xenstore paths of the VM's IP addresses, and the values are
@@ -65,7 +67,6 @@ let device_id = [ "data/device_id", "device_id"]
6567
* attr/eth0/ipv6/1/addr -> 0/ipv6/1
6668
* *)
6769
let networks path (list: string -> string list) =
68-
let extend base str = Printf.sprintf "%s/%s" base str in
6970
(* Find all ipv6 addresses under a path. *)
7071
let find_ipv6 path prefix = List.map
7172
(fun str -> (extend (extend path str) "addr", extend prefix str))
@@ -97,6 +98,33 @@ let networks path (list: string -> string list) =
9798
|> List.map (fun (path, prefix) -> find_all_ips path prefix)
9899
|> List.concat
99100

101+
(* This function is passed the "device/vif" node, a function it can use to
102+
* find the directory listing of sub-nodes and a function to retrieve the value
103+
* with the given path.
104+
* If "state" of all VIFs are "4", the return value is true
105+
* which means the network paths are optimized.
106+
* Or else the return value is false.
107+
*)
108+
let network_paths_optimized path (list: string -> string list) (lookup: string -> string option) =
109+
List.fold_left (fun result vif_id ->
110+
let vif_state = lookup (extend (extend path vif_id) "state") in
111+
result && (vif_state = Some "4")
112+
) true (list path)
113+
114+
(* This function is passed the "device/vbd" node, a function it can use to
115+
* find the directory listing of sub-nodes and a function to retrieve the value
116+
* with the given path.
117+
* If "state" of all VBDs (except cdrom) are "4", the return value is true
118+
* which means the storage paths are optimized.
119+
* Or else the return value is false.
120+
*)
121+
let storage_paths_optimized path (list: string -> string list) (lookup: string -> string option) =
122+
List.fold_left (fun result vbd_id ->
123+
let vbd_state = lookup (extend (extend path vbd_id) "state") in
124+
let vbd_type = lookup (extend (extend path vbd_id) "device-type") in
125+
result && (vbd_state = Some "4" || vbd_type = Some "cdrom")
126+
) true (list path)
127+
100128
(* One key is placed in the other map per control/* key in xenstore. This
101129
catches keys like "feature-shutdown" "feature-hibernate" "feature-reboot"
102130
"feature-sysrq" *)
@@ -110,7 +138,7 @@ let other all_control =
110138
the results of these lookups differ *)
111139

112140
type m = (string * string) list
113-
let cache : (int, (m*m*m*m*m*m*float)) Hashtbl.t = Hashtbl.create 20
141+
let cache : (int, (m*m*m*m*m*m*bool*bool*bool*float)) Hashtbl.t = Hashtbl.create 20
114142
let memory_targets : (int, int64) Hashtbl.t = Hashtbl.create 20
115143
let dead_domains : IntSet.t ref = ref IntSet.empty
116144
let mutex = Mutex.create ()
@@ -134,8 +162,12 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
134162
and networks = to_map (networks "attr" list)
135163
and other = List.append (to_map (other all_control)) ts
136164
and memory = to_map memory
165+
and network_paths_optimized = network_paths_optimized "device/vif" list lookup
166+
and storage_paths_optimized = storage_paths_optimized "device/vbd" list lookup
137167
and last_updated = Unix.gettimeofday () in
138168

169+
let pv_drivers_up_to_date = network_paths_optimized && storage_paths_optimized in
170+
139171
(* let num = Mutex.execute mutex (fun () -> Hashtbl.fold (fun _ _ c -> 1 + c) cache 0) in
140172
debug "Number of entries in hashtbl: %d" num; *)
141173

@@ -154,6 +186,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
154186
other_cached,
155187
memory_cached,
156188
device_id_cached,
189+
network_paths_optimized_cached,
190+
storage_paths_optimized_cached,
191+
pv_drivers_up_to_date_cached,
157192
last_updated_cached
158193
) = Mutex.execute mutex (fun () -> try
159194
Hashtbl.find cache domid
@@ -167,7 +202,7 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
167202
dead_domains := IntSet.remove domid !dead_domains
168203
else
169204
dead_domains := IntSet.add domid !dead_domains;
170-
([],[],[],[],[],[],0.0)) in
205+
([],[],[],[],[],[],false,false,false,0.0)) in
171206

172207
(* Consider the data valid IF the data/updated key exists AND the pv_drivers_version map
173208
contains a major and minor version-- this prevents a migration mid-way through an update
@@ -187,7 +222,7 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
187222
then begin
188223

189224
(* Only if the data is valid, cache it (CA-20353) *)
190-
Mutex.execute mutex (fun () -> Hashtbl.replace cache domid (pv_drivers_version,os_version,networks,other,memory,device_id,last_updated));
225+
Mutex.execute mutex (fun () -> Hashtbl.replace cache domid (pv_drivers_version,os_version,networks,other,memory,device_id,network_paths_optimized,storage_paths_optimized,pv_drivers_up_to_date,last_updated));
191226

192227
(* We update only if any actual data has changed *)
193228
if ( pv_drivers_version_cached <> pv_drivers_version
@@ -198,7 +233,13 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
198233
||
199234
other_cached <> other
200235
||
201-
device_id_cached <> device_id)
236+
device_id_cached <> device_id
237+
||
238+
network_paths_optimized_cached <> network_paths_optimized
239+
||
240+
storage_paths_optimized_cached <> storage_paths_optimized
241+
||
242+
pv_drivers_up_to_date_cached <> pv_drivers_up_to_date)
202243
(* Nb. we're ignoring the memory updates as far as the VM_guest_metrics API object is concerned. We are putting them into an RRD instead *)
203244
(* ||
204245
memory_cached <> memory)*)
@@ -213,7 +254,7 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
213254
let new_ref = Ref.make () and new_uuid = Uuid.to_string (Uuid.make_uuid ()) in
214255
Db.VM_guest_metrics.create ~__context ~ref:new_ref ~uuid:new_uuid
215256
~os_version:os_version ~pV_drivers_version:pv_drivers_version ~pV_drivers_up_to_date:false ~memory:[] ~disks:[] ~networks:networks ~other:other
216-
~last_updated:(Date.of_float last_updated) ~other_config:[] ~live:true;
257+
~storage_paths_optimized:false ~network_paths_optimized:false ~last_updated:(Date.of_float last_updated) ~other_config:[] ~live:true;
217258
Db.VM.set_guest_metrics ~__context ~self ~value:new_ref;
218259
(* We've just set the thing to live, let's make sure it's not in the dead list *)
219260
let sl xs = String.concat "; " (List.map (fun (k, v) -> k ^ ": " ^ v) xs) in
@@ -233,6 +274,15 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
233274
Db.VM_guest_metrics.set_other ~__context ~self:gm ~value:other;
234275
Helpers.call_api_functions ~__context (fun rpc session_id -> Client.Client.VM.update_allowed_operations rpc session_id self);
235276
end;
277+
if(network_paths_optimized_cached <> network_paths_optimized) then begin
278+
Db.VM_guest_metrics.set_network_paths_optimized ~__context ~self:gm ~value:network_paths_optimized;
279+
end;
280+
if(storage_paths_optimized_cached <> storage_paths_optimized) then begin
281+
Db.VM_guest_metrics.set_storage_paths_optimized ~__context ~self:gm ~value:storage_paths_optimized;
282+
end;
283+
if(pv_drivers_up_to_date_cached <> pv_drivers_up_to_date) then begin
284+
Db.VM_guest_metrics.set_PV_drivers_up_to_date ~__context ~self:gm ~value:pv_drivers_up_to_date;
285+
end;
236286
(* if(memory_cached <> memory) then
237287
Db.VM_guest_metrics.set_memory ~__context ~self:gm ~value:memory; *)
238288

@@ -256,7 +306,6 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
256306
(* Update the 'up to date' flag afterwards *)
257307
let gmr = Db.VM_guest_metrics.get_record_internal ~__context ~self:gm in
258308
let up_to_date = Xapi_pv_driver_version.is_up_to_date (Xapi_pv_driver_version.of_guest_metrics (Some gmr)) in
259-
Db.VM_guest_metrics.set_PV_drivers_up_to_date ~__context ~self:gm ~value:up_to_date;
260309

261310
(* CA-18034: If viridian flag isn't in there and we have current PV drivers then shove it in the metadata for next boot... *)
262311
if up_to_date then begin
@@ -288,6 +337,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
288337
other, (* not the cached version *)
289338
memory_cached,
290339
device_id_cached,
340+
network_paths_optimized_cached,
341+
storage_paths_optimized_cached,
342+
pv_drivers_up_to_date_cached,
291343
last_updated)); (* not a cached version *)
292344

293345
let gm =
@@ -305,6 +357,8 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
305357
~disks:[]
306358
~networks:networks_cached
307359
~other:other
360+
~storage_paths_optimized:false
361+
~network_paths_optimized:false
308362
~last_updated:(Date.of_float last_updated)
309363
~other_config:[]
310364
~live:false;
@@ -321,6 +375,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
321375
other, (* current version *)
322376
[], (* memory *)
323377
device_id_cached,
378+
network_paths_optimized_cached,
379+
storage_paths_optimized_cached,
380+
pv_drivers_up_to_date_cached,
324381
last_updated)); (* not a cached version *)
325382
new_ref
326383
in

ocaml/xapi/xapi_vm_helpers.ml

+2
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,8 @@ let copy_guest_metrics ~__context ~vm =
906906
~memory:all.API.vM_guest_metrics_memory
907907
~disks:all.API.vM_guest_metrics_disks
908908
~networks:all.API.vM_guest_metrics_networks
909+
~network_paths_optimized:all.API.vM_guest_metrics_network_paths_optimized
910+
~storage_paths_optimized:all.API.vM_guest_metrics_storage_paths_optimized
909911
~other:all.API.vM_guest_metrics_other
910912
~last_updated:all.API.vM_guest_metrics_last_updated
911913
~other_config:all.API.vM_guest_metrics_other_config

0 commit comments

Comments
 (0)