@@ -36,6 +36,13 @@ exception InvalidOperation of string
3636
3737let assert_operation_valid = Xapi_vm_lifecycle. assert_operation_valid
3838
39+ (* Convenience function currently not exposed in .mli but could be. *)
40+ (* Not thread-safe. *)
41+ let db_set_in_other_config ~__context ~self ~key ~value =
42+ if List. mem_assoc key (Db.VM. get_other_config ~__context ~self ) then
43+ Db.VM. remove_from_other_config ~__context ~self ~key ;
44+ Db.VM. add_to_other_config ~__context ~self ~key ~value
45+
3946let update_allowed_operations ~__context ~self =
4047 Helpers. log_exn_continue " updating allowed operations of VBDs/VIFs/VDIs in VM.update_allowed_operations"
4148 (fun () ->
@@ -1019,6 +1026,55 @@ let set_auto_update_drivers ~__context ~self ~value=
10191026 assert_can_set_auto_update_drivers ~__context ~self ~value ;
10201027 Db.VM. set_auto_update_drivers ~__context ~self ~value
10211028
1029+ let xenprep_mutex = Mutex. create ()
1030+
10221031let xenprep_start ~__context ~self =
1023- info " Xapi_vm.xenprep_start: VM=%s" (Db.VM. get_uuid ~__context ~self );
1024- Db.VM. add_to_other_config ~__context ~self ~key: " xenprep_progress" ~value: " dummyvalue_should_be_cd_inserted"
1032+ let key = " xenprep_progress" in
1033+ let vm_uuid = Db.VM. get_uuid ~__context ~self in (* Just for log-msgs *)
1034+ info " Xapi_vm.xenprep_start: VM=%s" vm_uuid;
1035+ let started_already = Mutex. execute xenprep_mutex (fun () ->
1036+ if List. mem_assoc key (Db.VM. get_other_config ~__context ~self ) then true
1037+ else (Db.VM. add_to_other_config ~__context ~self ~key ~value: " about_to_insert_iso" ;
1038+ false )
1039+ ) in
1040+ if started_already then (
1041+ info " Xapi_vm.xenprep_start: VM is in xenprep already: VM=%s" vm_uuid
1042+ ) else (
1043+ ( try
1044+ let cd_name = Xapi_globs. xenprep_iso_name_label in
1045+ let sr = Helpers. get_tools_sr ~__context in
1046+ let vdis =
1047+ let open Db_filter_types in
1048+ Db.VDI. get_refs_where ~__context ~expr: (
1049+ And (
1050+ Eq (Field " SR" , Literal (Ref. string_of sr)),
1051+ Eq (Field " name__label" , Literal cd_name)
1052+ )
1053+ ) in
1054+ if List. length vdis <> 1 then failwith
1055+ (" xenprep_start failed: found " ^ (string_of_int (List. length vdis))^ " ISOs with name_label=" ^ cd_name^ " in tools SR" );
1056+ let vdi = List. hd vdis in
1057+ (* Find any empty CD-drive VBD for the VM. *)
1058+ (* We don't care if currently_attached is false: VBD.insert will take care of things. *)
1059+ let vbds = Db.VM. get_VBDs ~__context ~self in
1060+ let empty_cd_vbds = List. filter (fun vbd -> (Db.VBD. get_type ~__context ~self: vbd = `CD ) && (Db.VBD. get_empty ~__context ~self: vbd)) vbds in
1061+ if [] = empty_cd_vbds then raise (Api_errors. Server_error (Api_errors. vm_no_empty_cd_vbd, [ Ref. string_of self ]));
1062+ let cd_vbd = List. hd empty_cd_vbds in
1063+ (* We found a suitable drive, so insert the CD. *)
1064+ (* We use the API to be on the safe side, because calling
1065+ * Xapi_vbd.insert directly would bypass the "operations"
1066+ * handling in Message_forwarding *)
1067+ Helpers. call_api_functions ~__context
1068+ (fun rpc session_id ->
1069+ Client.VBD. insert ~rpc ~session_id ~vbd: cd_vbd ~vdi
1070+ )
1071+ with e ->
1072+ Mutex. execute xenprep_mutex (fun () ->
1073+ Db.VM. remove_from_other_config ~__context ~self ~key
1074+ );
1075+ raise e
1076+ );
1077+ Mutex. execute xenprep_mutex (fun () ->
1078+ db_set_in_other_config ~__context ~self ~key ~value: " ISO_inserted"
1079+ )
1080+ )
0 commit comments