@@ -55,6 +55,8 @@ let memory =
55
55
56
56
let device_id = [ " data/device_id" , " device_id" ]
57
57
58
+ let extend base str = Printf. sprintf " %s/%s" base str
59
+
58
60
(* This function is passed the 'attr' node and a function it can use to
59
61
* find the directory listing of sub-nodes. It will return a map where the
60
62
* 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"]
65
67
* attr/eth0/ipv6/1/addr -> 0/ipv6/1
66
68
* *)
67
69
let networks path (list: string -> string list ) =
68
- let extend base str = Printf. sprintf " %s/%s" base str in
69
70
(* Find all ipv6 addresses under a path. *)
70
71
let find_ipv6 path prefix = List. map
71
72
(fun str -> (extend (extend path str) " addr" , extend prefix str))
@@ -97,6 +98,33 @@ let networks path (list: string -> string list) =
97
98
|> List. map (fun (path , prefix ) -> find_all_ips path prefix)
98
99
|> List. concat
99
100
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
+
100
128
(* One key is placed in the other map per control/* key in xenstore. This
101
129
catches keys like "feature-shutdown" "feature-hibernate" "feature-reboot"
102
130
"feature-sysrq" *)
@@ -110,7 +138,7 @@ let other all_control =
110
138
the results of these lookups differ *)
111
139
112
140
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
114
142
let memory_targets : (int, int64) Hashtbl.t = Hashtbl. create 20
115
143
let dead_domains : IntSet.t ref = ref IntSet. empty
116
144
let mutex = Mutex. create ()
@@ -134,8 +162,12 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
134
162
and networks = to_map (networks " attr" list )
135
163
and other = List. append (to_map (other all_control)) ts
136
164
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
137
167
and last_updated = Unix. gettimeofday () in
138
168
169
+ let pv_drivers_up_to_date = network_paths_optimized && storage_paths_optimized in
170
+
139
171
(* let num = Mutex.execute mutex (fun () -> Hashtbl.fold (fun _ _ c -> 1 + c) cache 0) in
140
172
debug "Number of entries in hashtbl: %d" num; *)
141
173
@@ -154,6 +186,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
154
186
other_cached,
155
187
memory_cached,
156
188
device_id_cached,
189
+ network_paths_optimized_cached,
190
+ storage_paths_optimized_cached,
191
+ pv_drivers_up_to_date_cached,
157
192
last_updated_cached
158
193
) = Mutex. execute mutex (fun () -> try
159
194
Hashtbl. find cache domid
@@ -167,7 +202,7 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
167
202
dead_domains := IntSet. remove domid ! dead_domains
168
203
else
169
204
dead_domains := IntSet. add domid ! dead_domains;
170
- ([] ,[] ,[] ,[] ,[] ,[] ,0.0 )) in
205
+ ([] ,[] ,[] ,[] ,[] ,[] ,false , false , false , 0.0 )) in
171
206
172
207
(* Consider the data valid IF the data/updated key exists AND the pv_drivers_version map
173
208
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
187
222
then begin
188
223
189
224
(* 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));
191
226
192
227
(* We update only if any actual data has changed *)
193
228
if ( pv_drivers_version_cached <> pv_drivers_version
@@ -198,7 +233,13 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
198
233
||
199
234
other_cached <> other
200
235
||
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)
202
243
(* 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 *)
203
244
(* ||
204
245
memory_cached <> memory)*)
@@ -213,7 +254,7 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
213
254
let new_ref = Ref. make () and new_uuid = Uuid. to_string (Uuid. make_uuid () ) in
214
255
Db.VM_guest_metrics. create ~__context ~ref: new_ref ~uuid: new_uuid
215
256
~os_version: os_version ~p V_drivers_version:pv_drivers_version ~p V_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 ;
217
258
Db.VM. set_guest_metrics ~__context ~self ~value: new_ref;
218
259
(* We've just set the thing to live, let's make sure it's not in the dead list *)
219
260
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
233
274
Db.VM_guest_metrics. set_other ~__context ~self: gm ~value: other;
234
275
Helpers. call_api_functions ~__context (fun rpc session_id -> Client.Client.VM. update_allowed_operations rpc session_id self);
235
276
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 ;
236
286
(* if(memory_cached <> memory) then
237
287
Db.VM_guest_metrics.set_memory ~__context ~self:gm ~value:memory; *)
238
288
@@ -256,7 +306,6 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
256
306
(* Update the 'up to date' flag afterwards *)
257
307
let gmr = Db.VM_guest_metrics. get_record_internal ~__context ~self: gm in
258
308
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;
260
309
261
310
(* CA-18034: If viridian flag isn't in there and we have current PV drivers then shove it in the metadata for next boot... *)
262
311
if up_to_date then begin
@@ -288,6 +337,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
288
337
other, (* not the cached version *)
289
338
memory_cached,
290
339
device_id_cached,
340
+ network_paths_optimized_cached,
341
+ storage_paths_optimized_cached,
342
+ pv_drivers_up_to_date_cached,
291
343
last_updated)); (* not a cached version *)
292
344
293
345
let gm =
@@ -305,6 +357,8 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
305
357
~disks: []
306
358
~networks: networks_cached
307
359
~other: other
360
+ ~storage_paths_optimized: false
361
+ ~network_paths_optimized: false
308
362
~last_updated: (Date. of_float last_updated)
309
363
~other_config: []
310
364
~live: false ;
@@ -321,6 +375,9 @@ let all (lookup: string -> string option) (list: string -> string list) ~__conte
321
375
other, (* current version *)
322
376
[] , (* memory *)
323
377
device_id_cached,
378
+ network_paths_optimized_cached,
379
+ storage_paths_optimized_cached,
380
+ pv_drivers_up_to_date_cached,
324
381
last_updated)); (* not a cached version *)
325
382
new_ref
326
383
in
0 commit comments