From: Jon Ludlam Date: Wed, 26 Jan 2011 17:39:04 +0000 (+0000) Subject: CP-1981: Resynchronise the locks in the sm_config maps of VDIs in dbsync_slave X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=934cfa278750ecaa03612e91d3d231e9264c583d;p=xcp%2Fxen-api.git CP-1981: Resynchronise the locks in the sm_config maps of VDIs in dbsync_slave The 'locks' for the VDIs, which are maintained by the SM backends now, are stored in xapi's database. In the event of a master failover, the pool database may revert to a previous backup, which is then resynced with reality. Unfortunately there's no logic to resync the SM backends' data, nor any hook point to do this. Ideally, the SM backends would store their critical data internally somehow, but until this happens xapi will have to contain the important logic to resynchronise these locks. This patch implements the logic to resynchronise the sm_config keys based on the information stored in the local database Signed-off-by: Jon Ludlam --- diff --git a/ocaml/xapi/dbsync_slave.ml b/ocaml/xapi/dbsync_slave.ml index ed0fa727..81e45584 100644 --- a/ocaml/xapi/dbsync_slave.ml +++ b/ocaml/xapi/dbsync_slave.ml @@ -31,6 +31,35 @@ let ( -- ) = Int64.sub let ( ** ) = Int64.mul let ( // ) = Int64.div + + +let refresh_local_vdi_activations ~__context = + let all_vdi_recs = Db.VDI.get_all_records ~__context in + + (* First remove any existing records relating to this host *) + let host_key = Printf.sprintf "host_%s" (Ref.string_of (Helpers.get_localhost ~__context)) in + let vdis = List.filter (fun (_,r) -> List.mem_assoc host_key r.API.vDI_sm_config) all_vdi_recs in + List.iter (fun (vdi,_) -> + debug "Removing key '%s' from sm_config on VDI: %s" host_key (Ref.string_of vdi); + Db.VDI.remove_from_sm_config ~__context ~self:vdi ~key:host_key) vdis; + + (* Make a lookup hashtbl *) + let hashtbl = Hashtbl.create (List.length all_vdi_recs) in + List.iter (fun (vref,vrec) -> Hashtbl.add hashtbl vrec.API.vDI_location vref) all_vdi_recs; + + (* Now fix it back up *) + Xapi_local_vdi_state.iter (fun rw loc -> + let vref_opt = try Some (Hashtbl.find hashtbl loc) with Not_found -> None in + match vref_opt with + | Some vref -> + debug "Found VDI to add host key to: %s" (Ref.string_of vref); + Db.VDI.add_to_sm_config ~__context ~self:vref ~key:host_key ~value:(if rw then "RW" else "RO") + | None -> + warn "Warning: Local db think's we've activated a VDI that's not in the database. Restarting xapi after a scan might fix this..."; + ()) + + + (* create localhost record *) let get_my_ip_addr() = @@ -584,3 +613,6 @@ let update_env __context sync_keys = refresh_localhost_info ~__context; ); + switched_sync Xapi_globs.sync_local_vdi_activations (fun () -> + refresh_local_vdi_activations ~__context; + ) diff --git a/ocaml/xapi/xapi_globs.ml b/ocaml/xapi/xapi_globs.ml index b715fbdf..b4b3a159 100644 --- a/ocaml/xapi/xapi_globs.ml +++ b/ocaml/xapi/xapi_globs.ml @@ -334,6 +334,7 @@ let _start_time_key = "start_time" let sync_switch_off = "nosync" (* Set the following keys to this value to disable the dbsync operation *) (* dbsync_slave *) +let sync_local_vdi_activations = "sync_local_vdi_activations" let sync_create_localhost = "sync_create_localhost" let sync_enable_localhost = "sync_enable_localhost" let sync_refresh_localhost_info = "sync_refresh_localhost_info"