let my_installation_uuid = Xapi_inventory.lookup Xapi_inventory._installation_uuid in
let my_control_uuid = Xapi_inventory.lookup Xapi_inventory._control_domain_uuid in
- let uuid_of_master_in_db = manifest.Db_cache_types.installation_uuid in
- let uuid_of_master_dom0_in_db = manifest.Db_cache_types.control_domain_uuid in
-
- let find_row_by_uuid uuid tbl =
- let rs = get_rowlist tbl in
- try Some (List.find (fun r->(lookup_field_in_row r uuid_fname)=uuid) rs)
- with e -> (debug "find_row_by_uuid 'uuid=%s' failed: %s"
- uuid (Printexc.to_string e);
- None) in
-
- let master_host_record = find_row_by_uuid uuid_of_master_in_db (lookup_table_in_cache cache "host") in
- let master_dom0_record = find_row_by_uuid uuid_of_master_dom0_in_db (lookup_table_in_cache cache "VM") in
-
- (* update master host record in db, so it has my installation uuid from my inventory file *)
- begin
- match master_host_record with
- None -> debug "Not updating host record"
- | Some mhr ->
- (set_field_in_row mhr uuid_fname my_installation_uuid;
- let _ref = lookup_field_in_row mhr reference_fname in
- Ref_index.update_uuid _ref my_installation_uuid)
+ let not_found = "" in
+ (* Look up the pool master: *)
+ let pools = lookup_table_in_cache cache Db_names.pool in
+ let master = fold_over_rows (fun _ref r acc -> lookup_field_in_row r Db_names.master) pools not_found in
+ if master = not_found
+ then debug "No master record to update"
+ else begin
+
+ let mhr = find_row cache Db_names.host master in
+ set_field_in_row mhr uuid_fname my_installation_uuid;
+ let _ref = lookup_field_in_row mhr reference_fname in
+ Ref_index.update_uuid _ref my_installation_uuid
end;
- (* update master dom0 record in db, so it has my control domain uuid from my inventory file in dom0 *)
- begin
- match master_dom0_record with
- None -> debug "Not updating dom0 record"
- | Some mhr ->
- (set_field_in_row mhr uuid_fname my_control_uuid;
- let _ref = lookup_field_in_row mhr reference_fname in
- Ref_index.update_uuid _ref my_control_uuid)
+
+ (* Look up the pool master's control domain: *)
+ let vms = lookup_table_in_cache cache Db_names.vm in
+ let master_dom0 = fold_over_rows (fun _ref r acc -> if lookup_field_in_row r Db_names.resident_on = master && (lookup_field_in_row r Db_names.is_control_domain = "true") then _ref else acc) vms not_found in
+ if master_dom0 = not_found
+ then debug "No master control domain record to update"
+ else begin
+
+ let mdr = find_row cache Db_names.vm master_dom0 in
+ set_field_in_row mdr uuid_fname my_control_uuid;
+ let _ref = lookup_field_in_row mdr reference_fname in
+ Ref_index.update_uuid _ref my_control_uuid
end;
debug "post_restore_hook executed"
type db_dump_manifest =
{
- installation_uuid : string;
control_domain_uuid : string;
pool_conf : string;
pool_token : string;
let gen_manifest gen_count =
{
- installation_uuid = Xapi_inventory.lookup Xapi_inventory._installation_uuid;
control_domain_uuid = Xapi_inventory.lookup Xapi_inventory._control_domain_uuid;
pool_conf = Unixext.string_of_file Xapi_globs.pool_config_file;
pool_token = Unixext.string_of_file Xapi_globs.pool_secret_path;
}
type structured_op_t = AddSet | RemoveSet | AddMap | RemoveMap
type db_dump_manifest = {
- installation_uuid : string;
control_domain_uuid : string;
pool_conf : string;
pool_token : string;
let domid = "domid"
let ha_always_run = "ha_always_run"
let host = "host"
+let pool = "pool"
+let master = "master"
let bios_strings = "bios_strings"
let protection_policy = "protection_policy"
let name x = ("", x) (* no namespace *)
let make_tag n attrs : Xmlm.tag = (name n), List.map (fun (k, v) -> name k, v) attrs
-let _installation_uuid = "installation_uuid"
let _control_domain_uuid = "control_domain_uuid"
let _pool_conf = "pool_conf"
let _pool_token = "pool_token"
(* Write out a manifest *)
let manifest (output: Xmlm.output) (manifest: db_dump_manifest) : unit =
Xmlm.output output (`El_start (make_tag "manifest" []));
- string output _installation_uuid manifest.installation_uuid;
string output _control_domain_uuid manifest.control_domain_uuid;
string output _pool_conf manifest.pool_conf;
string output _pool_token manifest.pool_token;
let (cache, _, manifest) = f (create_empty_cache (), create_empty_table (), []) in
(* Manifest is actually a record *)
let manifest = {
- installation_uuid = List.assoc _installation_uuid manifest;
control_domain_uuid = List.assoc _control_domain_uuid manifest;
pool_conf = List.assoc _pool_conf manifest;
pool_token = List.assoc _pool_token manifest;
(* CA-18377: The smallest database that is compatible with the Miami database schema. *)
let minimally_compliant_miami_database =
- "<database><manifest><pair key=\"installation_uuid\" value=\"d16fa814-95ac-48d5-bfc9-83c3dbcdea53\"/><pair key=\"control_domain_uuid\" value=\"422f53c6-be3b-439c-b8ea-d47c659752d2\"/><pair key=\"pool_conf\" value=\"master\"/><pair key=\"pool_token\" value=\"0495123c-aea2-be65-5885-c82ef39c630e/b56675f7-9f11-6b89-aebe-a82396a3bf0f/0141aea4-2858-4414-fbb7-a25dc95daa58\"/><pair key=\"schema_major_vsn\" value=\"5\"/><pair key=\"schema_minor_vsn\" value=\"35\"/><pair key=\"product_version\" value=\"4.1.0\"/><pair key=\"product_brand\" value=\"XenServer\"/><pair key=\"build_number\" value=\"7843c\"/><pair key=\"xapi_major_vsn\" value=\"1\"/><pair key=\"xapi_minor_vsn\" value=\"1\"/><pair key=\"generation_count\" value=\"103\"/></manifest><table name=\"SR\" /><table name=\"pool\" /><table name=\"VBD_metrics\"/><table name=\"console\" /><table name=\"host\" /><table name=\"VIF_metrics\"/><table name=\"user\" /><table name=\"PBD\" /><table name=\"pool_patch\" /><table name=\"host_metrics\" /><table name=\"VLAN\" /><table name=\"Bond\" /><table name=\"VTPM\" /><table name=\"event\"/><table name=\"VBD\" /><table name=\"VM_guest_metrics\" /><table name=\"VDI\" /><table name=\"VM_metrics\"/><table name=\"task\"/><table name=\"VM\" /><table name=\"crashdump\"/><table name=\"network\" /><table name=\"PIF\" /><table name=\"host_patch\"/><table name=\"host_crashdump\"/><table name=\"SM\" /><table name=\"host_cpu\" /><table name=\"VIF\" /><table name=\"session\" /><table name=\"PIF_metrics\" /></database>"
+ "<database><manifest><pair key=\"control_domain_uuid\" value=\"422f53c6-be3b-439c-b8ea-d47c659752d2\"/><pair key=\"pool_conf\" value=\"master\"/><pair key=\"pool_token\" value=\"0495123c-aea2-be65-5885-c82ef39c630e/b56675f7-9f11-6b89-aebe-a82396a3bf0f/0141aea4-2858-4414-fbb7-a25dc95daa58\"/><pair key=\"schema_major_vsn\" value=\"5\"/><pair key=\"schema_minor_vsn\" value=\"35\"/><pair key=\"product_version\" value=\"4.1.0\"/><pair key=\"product_brand\" value=\"XenServer\"/><pair key=\"build_number\" value=\"7843c\"/><pair key=\"xapi_major_vsn\" value=\"1\"/><pair key=\"xapi_minor_vsn\" value=\"1\"/><pair key=\"generation_count\" value=\"103\"/></manifest><table name=\"SR\" /><table name=\"pool\" /><table name=\"VBD_metrics\"/><table name=\"console\" /><table name=\"host\" /><table name=\"VIF_metrics\"/><table name=\"user\" /><table name=\"PBD\" /><table name=\"pool_patch\" /><table name=\"host_metrics\" /><table name=\"VLAN\" /><table name=\"Bond\" /><table name=\"VTPM\" /><table name=\"event\"/><table name=\"VBD\" /><table name=\"VM_guest_metrics\" /><table name=\"VDI\" /><table name=\"VM_metrics\"/><table name=\"task\"/><table name=\"VM\" /><table name=\"crashdump\"/><table name=\"network\" /><table name=\"PIF\" /><table name=\"host_patch\"/><table name=\"host_crashdump\"/><table name=\"SM\" /><table name=\"host_cpu\" /><table name=\"VIF\" /><table name=\"session\" /><table name=\"PIF_metrics\" /></database>"
(** Write the database dump out to a file/socket *)
let write_database (s: Unix.file_descr) ~__context =
let hosts = lookup_table_in_cache unmarshalled_db "host" in
let uuid_to_ref = fold_over_rows
(fun _ref r acc -> (lookup_field_in_row r "uuid", _ref)::acc) hosts [] in
- (* This should never happen by construction: *)
- if not(List.mem_assoc manifest.Db_cache_types.installation_uuid uuid_to_ref)
- then failwith "Master host's UUID not present in the backup file";
- let master = List.assoc manifest.Db_cache_types.installation_uuid uuid_to_ref in
+
+ (* Look up the pool master: *)
+ let pools = lookup_table_in_cache unmarshalled_db Datamodel._pool in
+ let master = fold_over_rows (fun _ref r acc -> lookup_field_in_row r "master") pools "" in
+
(* Remove all slaves from the database *)
let hosts' = create_empty_table () in
iter_over_rows (fun _ref r -> if _ref = master then set_row_in_table hosts' master r) hosts;
set_table_in_cache unmarshalled_db "host" hosts';
debug "All hosts: [ %s ]" (String.concat "; " (List.map fst uuid_to_ref));
- debug "Previous master: %s" manifest.Db_cache_types.installation_uuid;
+ debug "Previous master: %s" master;
(* Rewrite this host's PIFs' MAC addresses based on device name. *)
raise NoGeneration
| Some generation ->
(* Write the in-memory cache to the file *)
- let db_cache_manifest = Db_cache_types.gen_manifest generation in
- Db_xml.To.file staging_path (db_cache_manifest, Db_backend.cache);
+ let manifest = Db_cache_types.gen_manifest generation in
+ Db_xml.To.file staging_path (manifest, Db_backend.cache);
Unixext.write_string_to_file (staging_path ^ ".generation") (Generation.to_string generation)
end
with _ -> () (* it's just a best effort. if we can't read from the log, then don't worry. *)