Skip to content

Commit 8da184b

Browse files
committed
Change how receive_start2 is called
Previously `MIRROR.receive_start2` is called as a remote function, i.e. `Remote.DATA.MIRROR.receive_start2` and it will be forwarded to the destination host and multiplexes based on the destination SR type. This is inconvenient as what `receive_start2` should do is more dependent on what the source SR type is. For example, if the source SR is using SMAPIv1, then `receive_start2` needs to tell the destination host to create snapshots VDIs, while this is not necessary if the source SR type is of SMAPIv3. Hence instead of calling `Remote.receive_start2`, call each individual functions inside `receive_start2` remotely, such as `Remote.VDI.create`, and these SMAPIv2 functions will still be multiplexed on the destiantion side, based on the destination SR type. And this is indeed what we want, imagine a case where we are migrating v1 -> v3, what we want is still create a snapshot VDI, but on the v3 SR. This does mean that the state tracking, such as `State.add`, which was previously tracked by the destination host, now needs to be tracked by the source host. And this will affect a number of other `receive_` functions such as `receive_finalize2` and `receive_cancel2`, which are updated accordingly. For backwards compatability reasons, we still need to preserve `receive_start` which might still be called from an older host trying to do a v1 -> v1 migration. And this is done by making sure that the SMAPIv2 done inside `receive_start` are all local, while the `receive_start` call itself is remote. Signed-off-by: Vincent Liu <[email protected]>
1 parent 59236c6 commit 8da184b

File tree

9 files changed

+160
-103
lines changed

9 files changed

+160
-103
lines changed

ocaml/xapi-idl/storage/storage_interface.ml

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,8 @@ module StorageAPI (R : RPC) = struct
11361136
@-> id_p
11371137
@-> similar_p
11381138
@-> vm_p
1139+
@-> url_p
1140+
@-> verify_dest_p
11391141
@-> returning result err
11401142
)
11411143

@@ -1154,13 +1156,29 @@ module StorageAPI (R : RPC) = struct
11541156
should be used in conjunction with [receive_start2] *)
11551157
let receive_finalize2 =
11561158
declare "DATA.MIRROR.receive_finalize2" []
1157-
(dbg_p @-> id_p @-> returning unit_p err)
1159+
(dbg_p
1160+
@-> id_p
1161+
@-> sr_p
1162+
@-> url_p
1163+
@-> verify_dest_p
1164+
@-> returning unit_p err
1165+
)
11581166

11591167
(** [receive_cancel dbg id] is called in the case of migration failure to
1160-
do the clean up.*)
1168+
do the clean up.
1169+
@deprecated This function is deprecated, and is only here to keep backward
1170+
compatibility with old xapis that call Remote.DATA.MIRROR.receive_cancel
1171+
during SXM. Use the receive_cancel2 function instead.
1172+
*)
11611173
let receive_cancel =
11621174
declare "DATA.MIRROR.receive_cancel" []
11631175
(dbg_p @-> id_p @-> returning unit_p err)
1176+
1177+
(** [receive_cancel2 dbg mirror_id url verify_dest] cleans up the side effects
1178+
done by [receive_start2] on the destination host when the migration fails. *)
1179+
let receive_cancel2 =
1180+
declare "DATA.MIRROR.receive_cancel2" []
1181+
(dbg_p @-> id_p @-> url_p @-> verify_dest_p @-> returning unit_p err)
11641182
end
11651183
end
11661184

@@ -1240,16 +1258,33 @@ module type MIRROR = sig
12401258
-> dbg:debug_info
12411259
-> sr:sr
12421260
-> vdi_info:vdi_info
1243-
-> id:Mirror.id
1261+
-> mirror_id:Mirror.id
12441262
-> similar:Mirror.similars
12451263
-> vm:vm
1264+
-> url:string
1265+
-> verify_dest:bool
12461266
-> Mirror.mirror_receive_result
12471267

12481268
val receive_finalize : context -> dbg:debug_info -> id:Mirror.id -> unit
12491269

1250-
val receive_finalize2 : context -> dbg:debug_info -> id:Mirror.id -> unit
1270+
val receive_finalize2 :
1271+
context
1272+
-> dbg:debug_info
1273+
-> mirror_id:Mirror.id
1274+
-> sr:sr
1275+
-> url:string
1276+
-> verify_dest:bool
1277+
-> unit
12511278

12521279
val receive_cancel : context -> dbg:debug_info -> id:Mirror.id -> unit
1280+
1281+
val receive_cancel2 :
1282+
context
1283+
-> dbg:debug_info
1284+
-> mirror_id:Mirror.id
1285+
-> url:string
1286+
-> verify_dest:bool
1287+
-> unit
12531288
end
12541289

12551290
module type Server_impl = sig
@@ -1706,17 +1741,23 @@ module Server (Impl : Server_impl) () = struct
17061741
S.DATA.MIRROR.receive_start (fun dbg sr vdi_info id similar ->
17071742
Impl.DATA.MIRROR.receive_start () ~dbg ~sr ~vdi_info ~id ~similar
17081743
) ;
1709-
S.DATA.MIRROR.receive_start2 (fun dbg sr vdi_info id similar vm ->
1710-
Impl.DATA.MIRROR.receive_start2 () ~dbg ~sr ~vdi_info ~id ~similar ~vm
1744+
S.DATA.MIRROR.receive_start2
1745+
(fun dbg sr vdi_info mirror_id similar vm url verify_dest ->
1746+
Impl.DATA.MIRROR.receive_start2 () ~dbg ~sr ~vdi_info ~mirror_id
1747+
~similar ~vm ~url ~verify_dest
17111748
) ;
17121749
S.DATA.MIRROR.receive_cancel (fun dbg id ->
17131750
Impl.DATA.MIRROR.receive_cancel () ~dbg ~id
17141751
) ;
1752+
S.DATA.MIRROR.receive_cancel2 (fun dbg mirror_id url verify_dest ->
1753+
Impl.DATA.MIRROR.receive_cancel2 () ~dbg ~mirror_id ~url ~verify_dest
1754+
) ;
17151755
S.DATA.MIRROR.receive_finalize (fun dbg id ->
17161756
Impl.DATA.MIRROR.receive_finalize () ~dbg ~id
17171757
) ;
1718-
S.DATA.MIRROR.receive_finalize2 (fun dbg id ->
1719-
Impl.DATA.MIRROR.receive_finalize2 () ~dbg ~id
1758+
S.DATA.MIRROR.receive_finalize2 (fun dbg mirror_id sr url verify_dest ->
1759+
Impl.DATA.MIRROR.receive_finalize2 () ~dbg ~mirror_id ~sr ~url
1760+
~verify_dest
17201761
) ;
17211762
S.DATA.import_activate (fun dbg dp sr vdi vm ->
17221763
Impl.DATA.import_activate () ~dbg ~dp ~sr ~vdi ~vm

ocaml/xapi-idl/storage/storage_skeleton.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,19 @@ module DATA = struct
169169
let receive_start ctx ~dbg ~sr ~vdi_info ~id ~similar =
170170
u "DATA.MIRROR.receive_start"
171171

172-
let receive_start2 ctx ~dbg ~sr ~vdi_info ~id ~similar ~vm =
172+
let receive_start2 ctx ~dbg ~sr ~vdi_info ~mirror_id ~similar ~vm ~url
173+
~verify_dest =
173174
u "DATA.MIRROR.receive_start2"
174175

175176
let receive_finalize ctx ~dbg ~id = u "DATA.MIRROR.receive_finalize"
176177

177-
let receive_finalize2 ctx ~dbg ~id = u "DATA.MIRROR.receive_finalize2"
178+
let receive_finalize2 ctx ~dbg ~mirror_id ~sr ~url ~verify_dest =
179+
u "DATA.MIRROR.receive_finalize2"
178180

179181
let receive_cancel ctx ~dbg ~id = u "DATA.MIRROR.receive_cancel"
182+
183+
let receive_cancel2 ctx ~dbg ~mirror_id ~url ~verify_dest =
184+
u "DATA.MIRROR.receive_cancel2"
180185
end
181186
end
182187

ocaml/xapi-storage-script/main.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,7 @@ let bind ~volume_script_dir =
19261926
S.DATA.MIRROR.receive_finalize (u "DATA.MIRROR.receive_finalize") ;
19271927
S.DATA.MIRROR.receive_finalize2 (u "DATA.MIRROR.receive_finalize2") ;
19281928
S.DATA.MIRROR.receive_cancel (u "DATA.MIRROR.receive_cancel") ;
1929+
S.DATA.MIRROR.receive_cancel2 (u "DATA.MIRROR.receive_cancel2") ;
19291930
S.DP.create (u "DP.create") ;
19301931
S.TASK.cancel (u "TASK.cancel") ;
19311932
S.TASK.list (u "TASK.list") ;

ocaml/xapi/storage_migrate.ml

Lines changed: 31 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,29 @@ let choose_backend dbg sr =
4040
(** module [MigrateRemote] is similar to [MigrateLocal], but most of these functions
4141
tend to be executed on the receiver side. *)
4242
module MigrateRemote = struct
43-
let receive_finalize ~dbg ~id =
44-
let recv_state = State.find_active_receive_mirror id in
45-
let open State.Receive_state in
46-
Option.iter (fun r -> Local.DP.destroy dbg r.leaf_dp false) recv_state ;
47-
State.remove_receive_mirror id
48-
49-
let receive_finalize2 ~dbg ~id =
50-
let recv_state = State.find_active_receive_mirror id in
51-
let open State.Receive_state in
52-
Option.iter
53-
(fun r ->
54-
SXM.info
55-
"%s Mirror done. Compose on the dest sr %s parent %s and leaf %s"
56-
__FUNCTION__ (Sr.string_of r.sr)
57-
(Vdi.string_of r.parent_vdi)
58-
(Vdi.string_of r.leaf_vdi) ;
59-
Local.DP.destroy2 dbg r.leaf_dp r.sr r.leaf_vdi r.mirror_vm false ;
60-
Local.VDI.compose dbg r.sr r.parent_vdi r.leaf_vdi ;
61-
(* On SMAPIv3, compose would have removed the now invalid dummy vdi, so
62-
there is no need to destroy it anymore, while this is necessary on SMAPIv1 SRs. *)
63-
log_and_ignore_exn (fun () -> Local.VDI.destroy dbg r.sr r.dummy_vdi) ;
64-
Local.VDI.remove_from_sm_config dbg r.sr r.leaf_vdi "base_mirror"
65-
)
66-
recv_state ;
67-
State.remove_receive_mirror id
43+
(** [receive_finalize2 dbg mirror_id sr url verify_dest] takes an [sr] parameter
44+
which is the source sr and multiplexes based on the type of that *)
45+
let receive_finalize2 ~dbg ~mirror_id ~sr ~url ~verify_dest =
46+
let (module Migrate_Backend) = choose_backend dbg sr in
47+
Migrate_Backend.receive_finalize2 () ~dbg ~mirror_id ~sr ~url ~verify_dest
6848

69-
let receive_cancel ~dbg ~id =
70-
let receive_state = State.find_active_receive_mirror id in
49+
let receive_cancel2 ~dbg ~mirror_id ~url ~verify_dest =
50+
let (module Remote) =
51+
Storage_migrate_helper.get_remote_backend url verify_dest
52+
in
53+
let receive_state = State.find_active_receive_mirror mirror_id in
7154
let open State.Receive_state in
7255
Option.iter
7356
(fun r ->
74-
log_and_ignore_exn (fun () -> Local.DP.destroy dbg r.leaf_dp false) ;
57+
D.log_and_ignore_exn (fun () -> Remote.DP.destroy dbg r.leaf_dp false) ;
7558
List.iter
76-
(fun v -> log_and_ignore_exn (fun () -> Local.VDI.destroy dbg r.sr v))
59+
(fun v ->
60+
D.log_and_ignore_exn (fun () -> Remote.VDI.destroy dbg r.sr v)
61+
)
7762
[r.dummy_vdi; r.leaf_vdi; r.parent_vdi]
7863
)
7964
receive_state ;
80-
State.remove_receive_mirror id
65+
State.remove_receive_mirror mirror_id
8166
end
8267

8368
(** This module [MigrateLocal] consists of the concrete implementations of the
@@ -121,11 +106,10 @@ module MigrateLocal = struct
121106
| None ->
122107
debug "Snapshot VDI already cleaned up"
123108
) ;
124-
125-
let (module Remote) =
126-
get_remote_backend remote_info.url remote_info.verify_dest
127-
in
128-
try Remote.DATA.MIRROR.receive_cancel dbg id with _ -> ()
109+
try
110+
MigrateRemote.receive_cancel2 ~dbg ~mirror_id:id
111+
~url:remote_info.url ~verify_dest:remote_info.verify_dest
112+
with _ -> ()
129113
)
130114
| None ->
131115
()
@@ -145,11 +129,10 @@ module MigrateLocal = struct
145129
let prepare ~dbg ~sr ~vdi ~dest ~local_vdi ~mirror_id ~mirror_vm ~url
146130
~verify_dest =
147131
try
148-
let (module Remote) = get_remote_backend url verify_dest in
132+
let (module Migrate_Backend) = choose_backend dbg sr in
149133
let similars = similar_vdis ~dbg ~sr ~vdi in
150-
151-
Remote.DATA.MIRROR.receive_start2 dbg dest local_vdi mirror_id similars
152-
mirror_vm
134+
Migrate_Backend.receive_start2 () ~dbg ~sr:dest ~vdi_info:local_vdi
135+
~mirror_id ~similar:similars ~vm:mirror_vm ~url ~verify_dest
153136
with e ->
154137
error "%s Caught error %s while preparing for SXM" __FUNCTION__
155138
(Printexc.to_string e) ;
@@ -215,7 +198,7 @@ module MigrateLocal = struct
215198
| Storage_error (Migration_mirror_snapshot_failure reason) ) as e ->
216199
error "%s: Caught %s: during storage migration preparation" __FUNCTION__
217200
reason ;
218-
MigrateRemote.receive_cancel ~dbg ~id:mirror_id ;
201+
MigrateRemote.receive_cancel2 ~dbg ~mirror_id ~url ~verify_dest ;
219202
raise e
220203
| Storage_error (Migration_mirror_copy_failure reason) as e ->
221204
error "%s: Caught %s: during storage migration copy" __FUNCTION__ reason ;
@@ -331,9 +314,12 @@ module MigrateLocal = struct
331314
)
332315
copy_ops ;
333316
List.iter
334-
(fun (id, _recv_state) ->
335-
debug "Receive in progress: %s" id ;
336-
log_and_ignore_exn (fun () -> Local.DATA.MIRROR.receive_cancel dbg id)
317+
(fun (mirror_id, (recv_state : State.Receive_state.t)) ->
318+
debug "Receive in progress: %s" mirror_id ;
319+
log_and_ignore_exn (fun () ->
320+
MigrateRemote.receive_cancel2 ~dbg ~mirror_id ~url:recv_state.url
321+
~verify_dest:recv_state.verify_dest
322+
)
337323
)
338324
recv_ops ;
339325
State.clear ()
@@ -405,7 +391,8 @@ let post_deactivate_hook ~sr ~vdi ~dp:_ =
405391
let (module Remote) = get_remote_backend r.url verify_dest in
406392
debug "Calling receive_finalize2" ;
407393
log_and_ignore_exn (fun () ->
408-
Remote.DATA.MIRROR.receive_finalize2 "Mirror-cleanup" id
394+
MigrateRemote.receive_finalize2 ~dbg:"Mirror-cleanup" ~mirror_id:id
395+
~sr ~url:r.url ~verify_dest
409396
) ;
410397
debug "Finished calling receive_finalize2" ;
411398
State.remove_local_mirror id ;
@@ -525,12 +512,6 @@ let killall = MigrateLocal.killall
525512

526513
let stat = MigrateLocal.stat
527514

528-
let receive_finalize = MigrateRemote.receive_finalize
529-
530-
let receive_finalize2 = MigrateRemote.receive_finalize2
531-
532-
let receive_cancel = MigrateRemote.receive_cancel
533-
534515
(* The remote end of this call, SR.update_snapshot_info_dest, is implemented in
535516
* the SMAPIv1 section of storage_migrate.ml. It needs to access the setters
536517
* for snapshot_of, snapshot_time and is_a_snapshot, which we don't want to add

ocaml/xapi/storage_mux.ml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -838,23 +838,25 @@ module Mux = struct
838838
~similar
839839

840840
(** see storage_smapiv{1,3}_migrate.receive_start2 *)
841-
let receive_start2 () ~dbg:_ ~sr:_ ~vdi_info:_ ~id:_ ~similar:_ ~vm:_ =
841+
let receive_start2 () ~dbg:_ ~sr:_ ~vdi_info:_ ~mirror_id:_ ~similar:_
842+
~vm:_ =
842843
u __FUNCTION__
843844

844845
let receive_finalize () ~dbg ~id =
845846
with_dbg ~name:"DATA.MIRROR.receive_finalize" ~dbg @@ fun di ->
846847
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
847-
Storage_migrate.receive_finalize ~dbg:di.log ~id
848+
Storage_smapiv1_migrate.MIRROR.receive_finalize () ~dbg:di.log ~id
848849

849-
let receive_finalize2 () ~dbg ~id =
850-
with_dbg ~name:"DATA.MIRROR.receive_finalize2" ~dbg @@ fun di ->
851-
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
852-
Storage_migrate.receive_finalize2 ~dbg:di.log ~id
850+
let receive_finalize2 () ~dbg:_ ~mirror_id:_ ~sr:_ ~url:_ ~verify_dest:_ =
851+
u __FUNCTION__
853852

854853
let receive_cancel () ~dbg ~id =
855854
with_dbg ~name:"DATA.MIRROR.receive_cancel" ~dbg @@ fun di ->
856855
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
857-
Storage_migrate.receive_cancel ~dbg:di.log ~id
856+
Storage_smapiv1_migrate.MIRROR.receive_cancel () ~dbg:di.log ~id
857+
858+
let receive_cancel2 () ~dbg:_ ~mirror_id:_ ~url:_ ~verify_dest:_ =
859+
u __FUNCTION__
858860
end
859861
end
860862

ocaml/xapi/storage_smapiv1.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,15 +1143,20 @@ module SMAPIv1 : Server_impl = struct
11431143
let receive_start _context ~dbg:_ ~sr:_ ~vdi_info:_ ~id:_ ~similar:_ =
11441144
assert false
11451145

1146-
let receive_start2 _context ~dbg:_ ~sr:_ ~vdi_info:_ ~id:_ ~similar:_
1147-
~vm:_ =
1146+
let receive_start2 _context ~dbg:_ ~sr:_ ~vdi_info:_ ~mirror_id:_
1147+
~similar:_ ~vm:_ ~url:_ ~verify_dest:_ =
11481148
assert false
11491149

11501150
let receive_finalize _context ~dbg:_ ~id:_ = assert false
11511151

1152-
let receive_finalize2 _context ~dbg:_ ~id:_ = assert false
1152+
let receive_finalize2 _context ~dbg:_ ~mirror_id:_ ~sr:_ ~url:_
1153+
~verify_dest:_ =
1154+
assert false
11531155

11541156
let receive_cancel _context ~dbg:_ ~id:_ = assert false
1157+
1158+
let receive_cancel2 _context ~dbg:_ ~mirror_id:_ ~url:_ ~verify_dest:_ =
1159+
assert false
11551160
end
11561161
end
11571162

0 commit comments

Comments
 (0)