Skip to content

Commit 5759634

Browse files
author
Christian Lindig
committed
MVD CP-52334 multi-version driver API/CLI - incremental update
When scanning a host for drivers, don't remove and re-create them but instead update an entry if it already exists. Signed-off-by: Christian Lindig <[email protected]>
1 parent f801eef commit 5759634

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

ocaml/xapi/xapi_host_driver.ml

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,34 @@ module Variant = struct
5858
debug "Destroying driver variant %s" (Ref.string_of self) ;
5959
Db.Driver_variant.destroy ~__context ~self
6060

61+
(** create' is like create but updates an exisiting entry if it
62+
exists. This avoids entries becoming stale *)
63+
let create' ~__context ~name ~version ~driver ~hw_present ~priority
64+
~dev_status =
65+
let open Xapi_database.Db_filter_types in
66+
(* driver and name identify a variant uniquely *)
67+
let driver' = Eq (Field "driver", Literal (Ref.string_of driver)) in
68+
let name' = Eq (Field "name", Literal name) in
69+
let expr = And (driver', name') in
70+
match Db.Driver_variant.get_refs_where ~__context ~expr with
71+
| [] ->
72+
create ~__context ~name ~version ~driver ~hw_present ~priority
73+
~dev_status
74+
| [self] ->
75+
debug "%s: updating existing entry for variant %s" __FUNCTION__ name ;
76+
Db.Driver_variant.set_version ~__context ~self ~value:version ;
77+
Db.Driver_variant.set_priority ~__context ~self ~value:priority ;
78+
Db.Driver_variant.set_status ~__context ~self ~value:dev_status ;
79+
Db.Driver_variant.set_hardware_present ~__context ~self
80+
~value:hw_present ;
81+
self
82+
| variants ->
83+
warn "%s: multiple entries for %s found; recreating one" __FUNCTION__
84+
name ;
85+
variants |> List.iter (fun self -> destroy ~__context ~self) ;
86+
create ~__context ~name ~version ~driver ~hw_present ~priority
87+
~dev_status
88+
6189
let select ~__context ~self =
6290
debug "%s: %s" __FUNCTION__ (Ref.string_of self) ;
6391
let drv = Db.Driver_variant.get_driver ~__context ~self in
@@ -86,6 +114,37 @@ let destroy ~__context ~self =
86114
variants |> List.iter (fun self -> Variant.destroy ~__context ~self) ;
87115
Db.Host_driver.destroy ~__context ~self
88116

117+
(** create' is like create except it checks if an entry exists and
118+
modifies it. This avoids ref/UUIDs becoming stale *)
119+
let create' ~__context ~host ~name ~friendly_name ~_type ~description ~info:inf
120+
~active_variant ~selected_variant =
121+
let null = Ref.null in
122+
let open Xapi_database.Db_filter_types in
123+
let host' = Eq (Field "host", Literal (Ref.string_of host)) in
124+
let name' = Eq (Field "name", Literal name) in
125+
let expr = And (host', name') in
126+
match Db.Host_driver.get_refs_where ~__context ~expr with
127+
| [] ->
128+
(* no such entry exists - create it *)
129+
create ~__context ~host ~name ~friendly_name ~info:inf
130+
~active_variant:null ~selected_variant:null ~description ~_type
131+
| [self] ->
132+
(* one existing entry - update it *)
133+
info "%s: updating host driver %s" __FUNCTION__ name ;
134+
Db.Host_driver.set_friendly_name ~__context ~self ~value:name ;
135+
Db.Host_driver.set_info ~__context ~self ~value:inf ;
136+
Db.Host_driver.set_active_variant ~__context ~self ~value:null ;
137+
Db.Host_driver.set_selected_variant ~__context ~self ~value:null ;
138+
Db.Host_driver.set_description ~__context ~self ~value:description ;
139+
Db.Host_driver.set_type ~__context ~self ~value:_type ;
140+
self
141+
| drivers ->
142+
warn "%s: more than one entry for driver %s; destroying them" __FUNCTION__
143+
name ;
144+
drivers |> List.iter (fun self -> destroy ~__context ~self) ;
145+
create ~__context ~host ~name ~friendly_name ~info:inf
146+
~active_variant:null ~selected_variant:null ~description ~_type
147+
89148
(** Runs on the host where the driver is installed *)
90149
let select ~__context ~self ~variant =
91150
let drv = Ref.string_of self in
@@ -126,19 +185,18 @@ let reset ~__context ~host =
126185
let scan ~__context ~host =
127186
T.Mock.install () ;
128187
let null = Ref.null in
129-
reset ~__context ~host ;
130188
drivertool ["list"]
131189
|> T.parse
132190
|> List.iter @@ fun (_name, driver) ->
133191
let driver_ref =
134-
create ~__context ~host ~name:driver.T.name ~friendly_name:driver.T.name
192+
create' ~__context ~host ~name:driver.T.name ~friendly_name:driver.T.name
135193
~info:driver.T.info ~active_variant:null ~selected_variant:null
136194
~description:driver.T.descr ~_type:driver.T.ty
137195
in
138196
driver.T.variants
139197
|> List.iter @@ fun (name, v) ->
140198
let var_ref =
141-
Variant.create ~__context ~name ~version:v.T.version
199+
Variant.create' ~__context ~name ~version:v.T.version
142200
~driver:driver_ref ~hw_present:v.T.hw_present ~priority:v.T.priority
143201
~dev_status:v.T.dev_status
144202
in

0 commit comments

Comments
 (0)