Skip to content

Commit c696d49

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 d4c1b0d commit c696d49

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
@@ -1133,6 +1133,8 @@ module StorageAPI (R : RPC) = struct
11331133
@-> id_p
11341134
@-> similar_p
11351135
@-> vm_p
1136+
@-> url_p
1137+
@-> verify_dest_p
11361138
@-> returning result err
11371139
)
11381140

@@ -1151,13 +1153,29 @@ module StorageAPI (R : RPC) = struct
11511153
should be used in conjunction with [receive_start2] *)
11521154
let receive_finalize2 =
11531155
declare "DATA.MIRROR.receive_finalize2" []
1154-
(dbg_p @-> id_p @-> returning unit_p err)
1156+
(dbg_p
1157+
@-> id_p
1158+
@-> sr_p
1159+
@-> url_p
1160+
@-> verify_dest_p
1161+
@-> returning unit_p err
1162+
)
11551163

11561164
(** [receive_cancel dbg id] is called in the case of migration failure to
1157-
do the clean up.*)
1165+
do the clean up.
1166+
@deprecated This function is deprecated, and is only here to keep backward
1167+
compatibility with old xapis that call Remote.DATA.MIRROR.receive_cancel
1168+
during SXM. Use the receive_cancel2 function instead.
1169+
*)
11581170
let receive_cancel =
11591171
declare "DATA.MIRROR.receive_cancel" []
11601172
(dbg_p @-> id_p @-> returning unit_p err)
1173+
1174+
(** [receive_cancel2 dbg mirror_id url verify_dest] cleans up the side effects
1175+
done by [receive_start2] on the destination host when the migration fails. *)
1176+
let receive_cancel2 =
1177+
declare "DATA.MIRROR.receive_cancel2" []
1178+
(dbg_p @-> id_p @-> url_p @-> verify_dest_p @-> returning unit_p err)
11611179
end
11621180
end
11631181

@@ -1237,16 +1255,33 @@ module type MIRROR = sig
12371255
-> dbg:debug_info
12381256
-> sr:sr
12391257
-> vdi_info:vdi_info
1240-
-> id:Mirror.id
1258+
-> mirror_id:Mirror.id
12411259
-> similar:Mirror.similars
12421260
-> vm:vm
1261+
-> url:string
1262+
-> verify_dest:bool
12431263
-> Mirror.mirror_receive_result
12441264

12451265
val receive_finalize : context -> dbg:debug_info -> id:Mirror.id -> unit
12461266

1247-
val receive_finalize2 : context -> dbg:debug_info -> id:Mirror.id -> unit
1267+
val receive_finalize2 :
1268+
context
1269+
-> dbg:debug_info
1270+
-> mirror_id:Mirror.id
1271+
-> sr:sr
1272+
-> url:string
1273+
-> verify_dest:bool
1274+
-> unit
12481275

12491276
val receive_cancel : context -> dbg:debug_info -> id:Mirror.id -> unit
1277+
1278+
val receive_cancel2 :
1279+
context
1280+
-> dbg:debug_info
1281+
-> mirror_id:Mirror.id
1282+
-> url:string
1283+
-> verify_dest:bool
1284+
-> unit
12501285
end
12511286

12521287
module type Server_impl = sig
@@ -1703,17 +1738,23 @@ module Server (Impl : Server_impl) () = struct
17031738
S.DATA.MIRROR.receive_start (fun dbg sr vdi_info id similar ->
17041739
Impl.DATA.MIRROR.receive_start () ~dbg ~sr ~vdi_info ~id ~similar
17051740
) ;
1706-
S.DATA.MIRROR.receive_start2 (fun dbg sr vdi_info id similar vm ->
1707-
Impl.DATA.MIRROR.receive_start2 () ~dbg ~sr ~vdi_info ~id ~similar ~vm
1741+
S.DATA.MIRROR.receive_start2
1742+
(fun dbg sr vdi_info mirror_id similar vm url verify_dest ->
1743+
Impl.DATA.MIRROR.receive_start2 () ~dbg ~sr ~vdi_info ~mirror_id
1744+
~similar ~vm ~url ~verify_dest
17081745
) ;
17091746
S.DATA.MIRROR.receive_cancel (fun dbg id ->
17101747
Impl.DATA.MIRROR.receive_cancel () ~dbg ~id
17111748
) ;
1749+
S.DATA.MIRROR.receive_cancel2 (fun dbg mirror_id url verify_dest ->
1750+
Impl.DATA.MIRROR.receive_cancel2 () ~dbg ~mirror_id ~url ~verify_dest
1751+
) ;
17121752
S.DATA.MIRROR.receive_finalize (fun dbg id ->
17131753
Impl.DATA.MIRROR.receive_finalize () ~dbg ~id
17141754
) ;
1715-
S.DATA.MIRROR.receive_finalize2 (fun dbg id ->
1716-
Impl.DATA.MIRROR.receive_finalize2 () ~dbg ~id
1755+
S.DATA.MIRROR.receive_finalize2 (fun dbg mirror_id sr url verify_dest ->
1756+
Impl.DATA.MIRROR.receive_finalize2 () ~dbg ~mirror_id ~sr ~url
1757+
~verify_dest
17171758
) ;
17181759
S.DATA.import_activate (fun dbg dp sr vdi vm ->
17191760
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
@@ -780,23 +780,25 @@ module Mux = struct
780780
~similar
781781

782782
(** see storage_smapiv{1,3}_migrate.receive_start2 *)
783-
let receive_start2 () ~dbg:_ ~sr:_ ~vdi_info:_ ~id:_ ~similar:_ ~vm:_ =
783+
let receive_start2 () ~dbg:_ ~sr:_ ~vdi_info:_ ~mirror_id:_ ~similar:_
784+
~vm:_ =
784785
u __FUNCTION__
785786

786787
let receive_finalize () ~dbg ~id =
787788
with_dbg ~name:"DATA.MIRROR.receive_finalize" ~dbg @@ fun di ->
788789
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
789-
Storage_migrate.receive_finalize ~dbg:di.log ~id
790+
Storage_smapiv1_migrate.MIRROR.receive_finalize () ~dbg:di.log ~id
790791

791-
let receive_finalize2 () ~dbg ~id =
792-
with_dbg ~name:"DATA.MIRROR.receive_finalize2" ~dbg @@ fun di ->
793-
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
794-
Storage_migrate.receive_finalize2 ~dbg:di.log ~id
792+
let receive_finalize2 () ~dbg:_ ~mirror_id:_ ~sr:_ ~url:_ ~verify_dest:_ =
793+
u __FUNCTION__
795794

796795
let receive_cancel () ~dbg ~id =
797796
with_dbg ~name:"DATA.MIRROR.receive_cancel" ~dbg @@ fun di ->
798797
info "%s dbg: %s mirror_id: %s" __FUNCTION__ dbg id ;
799-
Storage_migrate.receive_cancel ~dbg:di.log ~id
798+
Storage_smapiv1_migrate.MIRROR.receive_cancel () ~dbg:di.log ~id
799+
800+
let receive_cancel2 () ~dbg:_ ~mirror_id:_ ~url:_ ~verify_dest:_ =
801+
u __FUNCTION__
800802
end
801803
end
802804

ocaml/xapi/storage_smapiv1.ml

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

1230-
let receive_start2 _context ~dbg:_ ~sr:_ ~vdi_info:_ ~id:_ ~similar:_
1231-
~vm:_ =
1230+
let receive_start2 _context ~dbg:_ ~sr:_ ~vdi_info:_ ~mirror_id:_
1231+
~similar:_ ~vm:_ ~url:_ ~verify_dest:_ =
12321232
assert false
12331233

12341234
let receive_finalize _context ~dbg:_ ~id:_ = assert false
12351235

1236-
let receive_finalize2 _context ~dbg:_ ~id:_ = assert false
1236+
let receive_finalize2 _context ~dbg:_ ~mirror_id:_ ~sr:_ ~url:_
1237+
~verify_dest:_ =
1238+
assert false
12371239

12381240
let receive_cancel _context ~dbg:_ ~id:_ = assert false
1241+
1242+
let receive_cancel2 _context ~dbg:_ ~mirror_id:_ ~url:_ ~verify_dest:_ =
1243+
assert false
12391244
end
12401245
end
12411246

0 commit comments

Comments
 (0)