Skip to content

Commit

Permalink
MVD CP-52334 multi-version driver API/CLI - incremental update
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Christian Lindig committed Jan 10, 2025
1 parent 9bd8dc1 commit faf52c1
Showing 1 changed file with 61 additions and 3 deletions.
64 changes: 61 additions & 3 deletions ocaml/xapi/xapi_host_driver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,34 @@ module Variant = struct
debug "Destroying driver variant %s" (Ref.string_of self) ;
Db.Driver_variant.destroy ~__context ~self

(** create' is like create but updates an exisiting entry if it
exists. This avoids entries becoming stale *)
let create' ~__context ~name ~version ~driver ~hw_present ~priority
~dev_status =
let open Xapi_database.Db_filter_types in
(* driver and name identify a variant uniquely *)
let driver' = Eq (Field "driver", Literal (Ref.string_of driver)) in
let name' = Eq (Field "name", Literal name) in
let expr = And (driver', name') in
match Db.Driver_variant.get_refs_where ~__context ~expr with
| [] ->
create ~__context ~name ~version ~driver ~hw_present ~priority
~dev_status
| [self] ->
debug "%s: updating existing entry for variant %s" __FUNCTION__ name ;
Db.Driver_variant.set_version ~__context ~self ~value:version ;
Db.Driver_variant.set_priority ~__context ~self ~value:priority ;
Db.Driver_variant.set_status ~__context ~self ~value:dev_status ;
Db.Driver_variant.set_hardware_present ~__context ~self
~value:hw_present ;
self
| variants ->
warn "%s: multiple entries for %s found; recreating one" __FUNCTION__
name ;
variants |> List.iter (fun self -> destroy ~__context ~self) ;
create ~__context ~name ~version ~driver ~hw_present ~priority
~dev_status

let select ~__context ~self =
debug "%s: %s" __FUNCTION__ (Ref.string_of self) ;
let drv = Db.Driver_variant.get_driver ~__context ~self in
Expand Down Expand Up @@ -86,6 +114,37 @@ let destroy ~__context ~self =
variants |> List.iter (fun self -> Variant.destroy ~__context ~self) ;
Db.Host_driver.destroy ~__context ~self

(** create' is like create except it checks if an entry exists and
modifies it. This avoids ref/UUIDs becoming stale *)
let create' ~__context ~host ~name ~friendly_name ~_type ~description ~info:inf
~active_variant ~selected_variant =
let null = Ref.null in
let open Xapi_database.Db_filter_types in
let host' = Eq (Field "host", Literal (Ref.string_of host)) in
let name' = Eq (Field "name", Literal name) in
let expr = And (host', name') in
match Db.Host_driver.get_refs_where ~__context ~expr with
| [] ->
(* no such entry exists - create it *)
create ~__context ~host ~name ~friendly_name ~info:inf
~active_variant:null ~selected_variant:null ~description ~_type
| [self] ->
(* one existing entry - update it *)
info "%s: updating host driver %s" __FUNCTION__ name ;
Db.Host_driver.set_friendly_name ~__context ~self ~value:name ;
Db.Host_driver.set_info ~__context ~self ~value:inf ;
Db.Host_driver.set_active_variant ~__context ~self ~value:null ;
Db.Host_driver.set_selected_variant ~__context ~self ~value:null ;
Db.Host_driver.set_description ~__context ~self ~value:description ;
Db.Host_driver.set_type ~__context ~self ~value:_type ;
self
| drivers ->
warn "%s: more than one entry for driver %s; destroying them" __FUNCTION__
name ;
drivers |> List.iter (fun self -> destroy ~__context ~self) ;
create ~__context ~host ~name ~friendly_name ~info:inf
~active_variant:null ~selected_variant:null ~description ~_type

(** Runs on the host where the driver is installed *)
let select ~__context ~self ~variant =
let drv = Ref.string_of self in
Expand Down Expand Up @@ -126,19 +185,18 @@ let reset ~__context ~host =
let scan ~__context ~host =
T.Mock.install () ;
let null = Ref.null in
reset ~__context ~host ;
drivertool ["list"]
|> T.parse
|> List.iter @@ fun (_name, driver) ->
let driver_ref =
create ~__context ~host ~name:driver.T.name ~friendly_name:driver.T.name
create' ~__context ~host ~name:driver.T.name ~friendly_name:driver.T.name
~info:driver.T.info ~active_variant:null ~selected_variant:null
~description:driver.T.descr ~_type:driver.T.ty
in
driver.T.variants
|> List.iter @@ fun (name, v) ->
let var_ref =
Variant.create ~__context ~name ~version:v.T.version
Variant.create' ~__context ~name ~version:v.T.version
~driver:driver_ref ~hw_present:v.T.hw_present ~priority:v.T.priority
~dev_status:v.T.dev_status
in
Expand Down

0 comments on commit faf52c1

Please sign in to comment.