Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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]>
  • Loading branch information
Christian Lindig committed Jan 21, 2025
commit 57596343ecadc843724c901acbe33dbc35b550b8
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