@@ -93,31 +93,38 @@ open Storage_interface
9393open Listext
9494open Fun
9595
96- let assert_sr_support_migration ~__context ~vdi_map ~remote =
96+ let assert_sr_support_operations ~__context ~vdi_map ~remote ~ops =
97+ let op_supported_on_source_sr vdi ops =
98+ (* Check VDIs must not be present on SR which doesn't have required capability *)
99+ let source_sr = Db.VDI. get_SR ~__context ~self: vdi in
100+ let sr_record = Db.SR. get_record_internal ~__context ~self: source_sr in
101+ let sr_features = Xapi_sr_operations. features_of_sr ~__context sr_record in
102+ if not (List. for_all (fun op -> Smint. (has_capability op sr_features)) ops) then
103+ raise (Api_errors. Server_error (Api_errors. sr_does_not_support_migration, [Ref. string_of source_sr]));
104+ in
105+ let op_supported_on_dest_sr sr ops sm_record remote =
106+ (* Check VDIs must not be mirrored to SR which doesn't have required capability *)
107+ let sr_type = XenAPI.SR. get_type remote.rpc remote.session sr in
108+ let sm_capabilities =
109+ match List. filter (fun (_ , r ) -> r.API. sM_type = sr_type) sm_record with
110+ | [ _, plugin ] -> plugin.API. sM_capabilities
111+ | _ -> []
112+ in
113+ if not (List. for_all (fun op -> List. mem Smint. (string_of_capability op) sm_capabilities) ops) then
114+ raise (Api_errors. Server_error (Api_errors. sr_does_not_support_migration, [Ref. string_of sr]))
115+ in
97116 (* Get destination host SM record *)
98117 let sm_record = XenAPI.SM. get_all_records remote.rpc remote.session in
99- List. iter (fun (vdi , sr ) ->
100- (* Check VDIs must not be present on SR which doesn't have snapshot capability *)
101- let source_sr = Db.VDI. get_SR ~__context ~self: vdi in
102- let sr_record = Db.SR. get_record_internal ~__context ~self: source_sr in
103- let sr_features = Xapi_sr_operations. features_of_sr ~__context sr_record in
104- if not Smint. (has_capability Vdi_snapshot sr_features) then
105- raise (Api_errors. Server_error (Api_errors. sr_does_not_support_migration, [Ref. string_of source_sr]));
106- (* Check VDIs must not be mirrored to SR which doesn't have snapshot capability *)
107- let sr_type = XenAPI.SR. get_type remote.rpc remote.session sr in
108- let sm_capabilities =
109- match List. filter (fun (_ , r ) -> r.API. sM_type = sr_type) sm_record with
110- | [ _, plugin ] -> plugin.API. sM_capabilities
111- | _ -> []
112- in
113- if not (List. exists (fun cp -> cp = Smint. (string_of_capability Vdi_snapshot )) sm_capabilities) then
114- raise (Api_errors. Server_error (Api_errors. sr_does_not_support_migration, [Ref. string_of sr]))
115- ) vdi_map
118+ (* Don't fail if source and destination SR for all VDIs are same *)
119+ List. filter (fun (vdi ,sr ) -> Db.VDI. get_SR ~__context ~self: vdi <> sr) vdi_map
120+ |> List. iter (fun (vdi , sr ) ->
121+ op_supported_on_source_sr vdi ops;
122+ op_supported_on_dest_sr sr ops sm_record remote;
123+ )
116124
117125let assert_licensed_storage_motion ~__context =
118126 Pool_features. assert_enabled ~__context ~f: Features. Storage_motion
119127
120-
121128let rec migrate_with_retries ~__context queue_name max try_no dbg vm_uuid xenops_vdi_map xenops_vif_map xenops =
122129 let open Xapi_xenops_queue in
123130 let module Client = (val make_client queue_name: XENOPS ) in
@@ -975,6 +982,11 @@ let assert_can_migrate ~__context ~vm ~dest ~live ~vdi_map ~vif_map ~options =
975982 debug " This is a cross-pool migration" ;
976983 `cross_pool
977984 in
985+
986+ (* Check VDIs are not migrating to or from an SR which doesn't have required_sr_operations *)
987+ let required_sr_operations = [Smint. Vdi_mirror ; Smint. Vdi_snapshot ] in
988+ assert_sr_support_operations ~__context ~vdi_map ~remote ~ops: required_sr_operations;
989+
978990 match migration_type with
979991 | `intra_pool ->
980992 (* Prevent VMs from being migrated onto a host with a lower platform version *)
@@ -998,9 +1010,6 @@ let assert_can_migrate ~__context ~vm ~dest ~live ~vdi_map ~vif_map ~options =
9981010 if (not force) && copy && power_state <> `Halted then raise (Api_errors. Server_error (Api_errors. vm_bad_power_state, [Ref. string_of vm; Record_util. power_to_string `Halted ; Record_util. power_to_string power_state]));
9991011 (* Check the host can support the VM's required version of virtual hardware platform *)
10001012 Xapi_vm_helpers. assert_hardware_platform_support ~__context ~vm ~host: host_to;
1001- (* Check VDIs are not on SR which doesn't have snapshot capability *)
1002- assert_sr_support_migration ~__context ~vdi_map ~remote ;
1003-
10041013 (* Check that the remote host is enabled and not in maintenance mode*)
10051014 let check_host_enabled = XenAPI.Host. get_enabled remote.rpc remote.session (remote.dest_host) in
10061015 if not check_host_enabled then raise (Api_errors. Server_error (Api_errors. host_disabled,[Ref. string_of remote.dest_host]));
0 commit comments