@@ -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 *)
90149let select ~__context ~self ~variant =
91150 let drv = Ref. string_of self in
@@ -126,19 +185,18 @@ let reset ~__context ~host =
126185let 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